diff options
author | mstarzinger@chromium.org <mstarzinger@chromium.org> | 2012-10-15 15:23:22 +0000 |
---|---|---|
committer | The Qt Project <gerrit-noreply@qt-project.org> | 2012-10-18 16:23:26 +0200 |
commit | 4cbcad7fbb5606e6f183062b5f15be08b9568ecb (patch) | |
tree | 96d32bbe8e673100680b421310e0d78203b31b5e | |
parent | adb6125097d6e73650d4eea0e4447a4001a0766c (diff) |
[V8] Fix bug in deletion of indexed propertiesv5.0.0-beta2
The delete operator always return true in case of indexed property. It
should return false if an indexed property can't be deleted (eg.
DontDelete attribute is set or a string object is the holder).
Contributed by Peter Varga <pvarga@inf.u-szeged.hu>
BUG=none
TEST=mjsunit/delete-non-configurable
Review URL: https://codereview.chromium.org/11094021
Patch from Peter Varga <pvarga@inf.u-szeged.hu>.
git-svn-id: https://v8.googlecode.com/svn/branches/bleeding_edge@12736 ce2b1a6d-e550-0410-aec6-3dcde31c8c00
Change-Id: I05bcd4625c5a2b868306e6979ea3c687a404dbf2
Signed-off-by: Peter Varga <pvarga@inf.u-szeged.hu>
Reviewed-by: Simon Hausmann <simon.hausmann@digia.com>
-rw-r--r-- | src/3rdparty/v8/src/elements.cc | 43 | ||||
-rw-r--r-- | src/3rdparty/v8/src/objects.cc | 15 | ||||
-rw-r--r-- | src/3rdparty/v8/test/mjsunit/delete-non-configurable.js | 74 |
3 files changed, 110 insertions, 22 deletions
diff --git a/src/3rdparty/v8/src/elements.cc b/src/3rdparty/v8/src/elements.cc index d367af8..9b8548d 100644 --- a/src/3rdparty/v8/src/elements.cc +++ b/src/3rdparty/v8/src/elements.cc @@ -1079,30 +1079,29 @@ class DictionaryElementsAccessor int entry = dictionary->FindEntry(key); if (entry != SeededNumberDictionary::kNotFound) { Object* result = dictionary->DeleteProperty(entry, mode); - if (result == heap->true_value()) { - MaybeObject* maybe_elements = dictionary->Shrink(key); - FixedArray* new_elements = NULL; - if (!maybe_elements->To(&new_elements)) { - return maybe_elements; - } - if (is_arguments) { - FixedArray::cast(obj->elements())->set(1, new_elements); - } else { - obj->set_elements(new_elements); + if (result == heap->false_value()) { + if (mode == JSObject::STRICT_DELETION) { + // Deleting a non-configurable property in strict mode. + HandleScope scope(isolate); + Handle<Object> holder(obj); + Handle<Object> name = isolate->factory()->NewNumberFromUint(key); + Handle<Object> args[2] = { name, holder }; + Handle<Object> error = + isolate->factory()->NewTypeError("strict_delete_property", + HandleVector(args, 2)); + return isolate->Throw(*error); } + return heap->false_value(); } - if (mode == JSObject::STRICT_DELETION && - result == heap->false_value()) { - // In strict mode, attempting to delete a non-configurable property - // throws an exception. - HandleScope scope(isolate); - Handle<Object> holder(obj); - Handle<Object> name = isolate->factory()->NewNumberFromUint(key); - Handle<Object> args[2] = { name, holder }; - Handle<Object> error = - isolate->factory()->NewTypeError("strict_delete_property", - HandleVector(args, 2)); - return isolate->Throw(*error); + MaybeObject* maybe_elements = dictionary->Shrink(key); + FixedArray* new_elements = NULL; + if (!maybe_elements->To(&new_elements)) { + return maybe_elements; + } + if (is_arguments) { + FixedArray::cast(obj->elements())->set(1, new_elements); + } else { + obj->set_elements(new_elements); } } return heap->true_value(); diff --git a/src/3rdparty/v8/src/objects.cc b/src/3rdparty/v8/src/objects.cc index 5ed2e2c..7373384 100644 --- a/src/3rdparty/v8/src/objects.cc +++ b/src/3rdparty/v8/src/objects.cc @@ -3900,6 +3900,21 @@ MaybeObject* JSObject::DeleteElement(uint32_t index, DeleteMode mode) { return isolate->heap()->false_value(); } + if (IsStringObjectWithCharacterAt(index)) { + if (mode == STRICT_DELETION) { + // Deleting a non-configurable property in strict mode. + HandleScope scope(isolate); + Handle<Object> holder(this); + Handle<Object> name = isolate->factory()->NewNumberFromUint(index); + Handle<Object> args[2] = { name, holder }; + Handle<Object> error = + isolate->factory()->NewTypeError("strict_delete_property", + HandleVector(args, 2)); + return isolate->Throw(*error); + } + return isolate->heap()->false_value(); + } + if (IsJSGlobalProxy()) { Object* proto = GetPrototype(); if (proto->IsNull()) return isolate->heap()->false_value(); diff --git a/src/3rdparty/v8/test/mjsunit/delete-non-configurable.js b/src/3rdparty/v8/test/mjsunit/delete-non-configurable.js new file mode 100644 index 0000000..8991f43 --- /dev/null +++ b/src/3rdparty/v8/test/mjsunit/delete-non-configurable.js @@ -0,0 +1,74 @@ +// Copyright 2012 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. + +// Delete elements of a String object. +var TIPLI = "tipli" +var so = new String(TIPLI); +var length = so.length; + +for (var i = 0; i < length; i++) { + assertFalse(delete so[i]); + assertThrows("'use strict'; delete so[i];", TypeError); + assertFalse(delete so[i.toString()]); + assertThrows("'use strict'; delete so[i.toString()];", TypeError); +} + +assertEquals(length, so.length); +assertEquals(new String(TIPLI), so); + +// Delete elements of an Array. +var arr = new Array(length); + +for (var i = 0; i < length; i++) { + arr[i] = i; + Object.defineProperty(arr, i, { configurable: false }); +} + +for (var i = 0; i < length; i++) { + assertFalse(delete arr[i]); + assertThrows("'use strict'; delete arr[i];", TypeError); + assertFalse(delete arr[i.toString()]); + assertThrows("'use strict'; delete arr[i.toString()];", TypeError); + assertEquals(i, arr[i]); +} + +assertEquals(length, arr.length); +assertTrue(delete arr[length]); + +// Delete an element of an Object. +var INDEX = 28; +var obj = new Object(); + +obj[INDEX] = TIPLI; +Object.defineProperty(obj, INDEX, { configurable: false }); + +assertFalse(delete obj[INDEX]); +assertThrows("'use strict'; delete obj[INDEX];", TypeError); +assertFalse(delete obj[INDEX.toString()]); +assertThrows("'use strict'; delete obj[INDEX.toString()];", TypeError); +assertEquals(TIPLI, obj[INDEX]); +assertTrue(delete arr[INDEX+1]); |