Bug 1148750, part 14 - Reject redefining a non-writable non-configurable data property to have a different value. r=efaust.
authorJason Orendorff <jorendorff@mozilla.com>
Fri, 03 Apr 2015 16:25:12 -0500
changeset 240433 b417da735191b8799d284d08ed7891c10c163d70
parent 240432 fe7d4e55db5542632f640725a96961f2169a5f9e
child 240434 caaa22357ca60f09d6ea0a8b612921cedd117bbf
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
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 14 - Reject redefining a non-writable non-configurable data property to have a different value. r=efaust.
js/src/vm/NativeObject.cpp
--- a/js/src/vm/NativeObject.cpp
+++ b/js/src/vm/NativeObject.cpp
@@ -1442,40 +1442,54 @@ js::NativeDefineProperty(ExclusiveContex
         // 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.hasWritable())
-            desc.setWritable(IsWritable(shapeAttrs));
-
-        if (!desc.hasValue()) {
-            // We have been asked merely to update JSPROP_READONLY (and possibly
-            // JSPROP_CONFIGURABLE and/or JSPROP_ENUMERABLE, handled above).
-
-            // Don't forget about arrays.
+        if (frozen || !desc.hasValue()) {
             if (IsImplicitDenseOrTypedArrayElement(shape)) {
                 MOZ_ASSERT(!IsAnyTypedArray(obj));
                 if (!NativeObject::sparsifyDenseElement(cx, obj, JSID_TO_INT(id)))
                     return false;
                 shape = obj->lookup(cx, id);
             }
 
-            // We are at most changing some attributes. Take everything from
-            // the shape that we aren't changing.
-            desc.setGetter(shape->getter());
-            desc.setSetter(shape->setter());
-            if (shape->hasSlot())
-                desc.value().set(obj->getSlot(shape->slot()));
+            RootedValue currentValue(cx);
+            if (!GetExistingPropertyValue(cx, obj, id, shape, &currentValue))
+                return false;
+
+            if (!desc.hasValue()) {
+                // We have been asked merely to update JSPROP_READONLY (and possibly
+                // JSPROP_CONFIGURABLE and/or JSPROP_ENUMERABLE, handled above).
+                // Take everything else from shape.
+                desc.setGetter(shape->getter());
+                desc.setSetter(shape->setter());
+
+                // Fill in desc.[[Value]].
+                desc.setValue(currentValue);
+            } else {
+                // Step 8.a.ii.1.
+                bool same;
+                if (!cx->shouldBeJSContext())
+                    return false;
+                if (!SameValue(cx->asJSContext(), desc.value(), currentValue, &same))
+                    return false;
+                if (!same && !skipRedefineChecks)
+                    return result.fail(JSMSG_CANT_REDEFINE_PROP);
+            }
         }
+
+        if (!desc.hasWritable())
+            desc.setWritable(IsWritable(shapeAttrs));
     } else {
         // Step 9.
+        MOZ_ASSERT(shape->isAccessorDescriptor());
         MOZ_ASSERT(desc.isAccessorDescriptor());
 
         // If defining a getter or setter, we must check for its counterpart
         // and update the attributes and property ops.  A getter or setter is
         // really only half of a property.
 
         // If we are defining a getter whose setter was already defined, or
         // vice versa, finish the job via obj->changeProperty.