Bug 1148750, part 12 - Reject redefinition of non-writable non-configurable data property as writable. This fixes bug 1073808. r=efaust.
authorJason Orendorff <jorendorff@mozilla.com>
Thu, 09 Apr 2015 15:55:37 -0500
changeset 240431 cefbe81af44a3cce40507ed2a32a4e153283207c
parent 240430 9ff0866822397d3407076ed3d618d3814c48363f
child 240432 fe7d4e55db5542632f640725a96961f2169a5f9e
push id28636
push userkwierso@gmail.com
push dateThu, 23 Apr 2015 00:16:12 +0000
treeherdermozilla-central@a5af73b32ac8 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersefaust
bugs1148750, 1073808
milestone40.0a1
first release with
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
last release without
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
Bug 1148750, part 12 - Reject redefinition of non-writable non-configurable data property as writable. This fixes bug 1073808. r=efaust.
js/src/jit-test/tests/collections/Array-of-nonconfigurable-1.js
js/src/jit-test/tests/collections/Array-of-nonconfigurable-2.js
js/src/vm/NativeObject.cpp
new file mode 100644
--- /dev/null
+++ b/js/src/jit-test/tests/collections/Array-of-nonconfigurable-1.js
@@ -0,0 +1,8 @@
+// If Array.of tries to overwrite a non-configurable property, it throws a TypeError.
+
+load(libdir + "asserts.js");
+
+function C() {
+    Object.defineProperty(this, 0, {value: "v", configurable: false});
+}
+assertThrowsInstanceOf(() => Array.of.call(C, 1, 2, 3), TypeError);
new file mode 100644
--- /dev/null
+++ b/js/src/jit-test/tests/collections/Array-of-nonconfigurable-2.js
@@ -0,0 +1,16 @@
+// Array.of does not overwrite non-configurable properties.
+
+load(libdir + "asserts.js");
+
+var obj;
+function C() {
+    obj = this;
+    Object.defineProperty(this, 0, {value: "v", configurable: false});
+}
+try { Array.of.call(C, 1); } catch (e) {}
+assertDeepEq(Object.getOwnPropertyDescriptor(obj, 0), {
+    configurable: false,
+    enumerable: false,
+    value: "v",
+    writable: false
+});
--- a/js/src/vm/NativeObject.cpp
+++ b/js/src/vm/NativeObject.cpp
@@ -1438,16 +1438,20 @@ js::NativeDefineProperty(ExclusiveContex
                 return false;
             shape = obj->lookup(cx, id);
         }
 
         // Fill in desc fields with default values (steps 7.b.i and 7.c.i).
         CompletePropertyDescriptor(&desc);
     } else if (desc.isDataDescriptor()) {
         // Step 8.
+        bool frozen = !IsConfigurable(shapeAttrs) && !IsWritable(shapeAttrs);
+        if (frozen && desc.hasWritable() && desc.writable() && !skipRedefineChecks)
+            return result.fail(JSMSG_CANT_REDEFINE_PROP);
+
         if (desc.hasValue()) {
             // If any other JSPROP_IGNORE_* attributes are present, copy the
             // corresponding JSPROP_* attributes from the existing property.
             if (IsImplicitDenseOrTypedArrayElement(shape)) {
                 desc.setAttributes(ApplyAttributes(desc.attributes(), true, true,
                                                    !IsAnyTypedArray(obj)));
             } else {
                 desc.setAttributes(ApplyOrDefaultAttributes(desc.attributes(), shape));