From 357882a8e5d9d63d90a1a69a816b514fda01e400 Mon Sep 17 00:00:00 2001 From: "rossberg@chromium.org" Date: Tue, 4 Nov 2014 16:13:49 +0000 Subject: [PATCH] `1..isPrototypeOf.call(null)` should return false, not throw TypeError. BUG=v8:3483 LOG=Y R=rossberg@chromium.org Review URL: https://codereview.chromium.org/433413002 Cr-Commit-Position: refs/heads/master@{#25116} git-svn-id: https://v8.googlecode.com/svn/branches/bleeding_edge@25116 ce2b1a6d-e550-0410-aec6-3dcde31c8c00 --- src/v8natives.js | 2 +- test/mjsunit/function-call.js | 21 ++++++++++----------- test/mjsunit/regress/regress-3483.js | 30 ++++++++++++++++++++++++++++++ 3 files changed, 41 insertions(+), 12 deletions(-) create mode 100644 test/mjsunit/regress/regress-3483.js diff --git a/src/v8natives.js b/src/v8natives.js index 20fd649..6215ab0 100644 --- a/src/v8natives.js +++ b/src/v8natives.js @@ -252,8 +252,8 @@ function ObjectHasOwnProperty(V) { // ECMA-262 - 15.2.4.6 function ObjectIsPrototypeOf(V) { - CHECK_OBJECT_COERCIBLE(this, "Object.prototype.isPrototypeOf"); if (!IS_SPEC_OBJECT(V)) return false; + CHECK_OBJECT_COERCIBLE(this, "Object.prototype.isPrototypeOf"); return %IsInPrototypeChain(this, V); } diff --git a/test/mjsunit/function-call.js b/test/mjsunit/function-call.js index 88df353..fb91dcd 100644 --- a/test/mjsunit/function-call.js +++ b/test/mjsunit/function-call.js @@ -162,13 +162,10 @@ for (var i = 0; i < should_throw_on_null_and_undefined.length; i++) { var exception = false; try { - // We call all functions with no parameters, which means that essential - // parameters will have the undefined value. - // The test for whether the "this" value is null or undefined is always - // performed before access to the other parameters, so even if the - // undefined value is an invalid argument value, it mustn't change - // the result of the test. - should_throw_on_null_and_undefined[i].call(null); + // We need to pass a dummy object argument ({}) to these functions because + // of Object.prototype.isPrototypeOf's special behavior, see issue 3483 + // for more details. + should_throw_on_null_and_undefined[i].call(null, {}); } catch (e) { exception = true; checkExpectedMessage(e); @@ -177,7 +174,7 @@ for (var i = 0; i < should_throw_on_null_and_undefined.length; i++) { exception = false; try { - should_throw_on_null_and_undefined[i].call(undefined); + should_throw_on_null_and_undefined[i].call(undefined, {}); } catch (e) { exception = true; checkExpectedMessage(e); @@ -186,7 +183,7 @@ for (var i = 0; i < should_throw_on_null_and_undefined.length; i++) { exception = false; try { - should_throw_on_null_and_undefined[i].apply(null); + should_throw_on_null_and_undefined[i].apply(null, [{}]); } catch (e) { exception = true; checkExpectedMessage(e); @@ -195,7 +192,7 @@ for (var i = 0; i < should_throw_on_null_and_undefined.length; i++) { exception = false; try { - should_throw_on_null_and_undefined[i].apply(undefined); + should_throw_on_null_and_undefined[i].apply(undefined, [{}]); } catch (e) { exception = true; checkExpectedMessage(e); @@ -248,7 +245,9 @@ for (var i = 0; i < non_generic.length; i++) { // Test that we still throw when calling with thisArg null or undefined // through an array mapping function. -var array = [1,2,3,4,5]; +// We need to make sure that the elements of `array` are all object values, +// see issue 3483 for more details. +var array = [{}, [], new Number, new Map, new WeakSet]; for (var j = 0; j < mapping_functions.length; j++) { for (var i = 0; i < should_throw_on_null_and_undefined.length; i++) { exception = false; diff --git a/test/mjsunit/regress/regress-3483.js b/test/mjsunit/regress/regress-3483.js new file mode 100644 index 0000000..dec95c4 --- /dev/null +++ b/test/mjsunit/regress/regress-3483.js @@ -0,0 +1,30 @@ +// Copyright 2014 the V8 project authors. All rights reserved. +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are +// met: +// +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above +// copyright notice, this list of conditions and the following +// disclaimer in the documentation and/or other materials provided +// with the distribution. +// * Neither the name of Google Inc. nor the names of its +// contributors may be used to endorse or promote products derived +// from this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +assertFalse(Object.prototype.isPrototypeOf.call()); +assertFalse(Object.prototype.isPrototypeOf.call(null, 1)); +assertFalse(Object.prototype.isPrototypeOf.call(undefined, 1)); -- 2.7.4