Bug 1148750, part 14 - Reject redefining a non-writable non-configurable data property to have a different value. r=efaust.

This commit is contained in:
Jason Orendorff 2015-04-03 16:25:12 -05:00
parent 2f9a24b3c7
commit 4bfe6cdf2b

View File

@ -1447,14 +1447,7 @@ js::NativeDefineProperty(ExclusiveContext* cx, HandleNativeObject obj, HandleId
if (frozen && desc.hasWritable() && desc.writable() && !skipRedefineChecks) if (frozen && desc.hasWritable() && desc.writable() && !skipRedefineChecks)
return result.fail(JSMSG_CANT_REDEFINE_PROP); return result.fail(JSMSG_CANT_REDEFINE_PROP);
if (!desc.hasWritable()) if (frozen || !desc.hasValue()) {
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 (IsImplicitDenseOrTypedArrayElement(shape)) { if (IsImplicitDenseOrTypedArrayElement(shape)) {
MOZ_ASSERT(!IsAnyTypedArray(obj)); MOZ_ASSERT(!IsAnyTypedArray(obj));
if (!NativeObject::sparsifyDenseElement(cx, obj, JSID_TO_INT(id))) if (!NativeObject::sparsifyDenseElement(cx, obj, JSID_TO_INT(id)))
@ -1462,15 +1455,36 @@ js::NativeDefineProperty(ExclusiveContext* cx, HandleNativeObject obj, HandleId
shape = obj->lookup(cx, id); shape = obj->lookup(cx, id);
} }
// We are at most changing some attributes. Take everything from RootedValue currentValue(cx);
// the shape that we aren't changing. if (!GetExistingPropertyValue(cx, obj, id, shape, &currentValue))
desc.setGetter(shape->getter()); return false;
desc.setSetter(shape->setter());
if (shape->hasSlot()) if (!desc.hasValue()) {
desc.value().set(obj->getSlot(shape->slot())); // 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 { } else {
// Step 9. // Step 9.
MOZ_ASSERT(shape->isAccessorDescriptor());
MOZ_ASSERT(desc.isAccessorDescriptor()); MOZ_ASSERT(desc.isAccessorDescriptor());
// If defining a getter or setter, we must check for its counterpart // If defining a getter or setter, we must check for its counterpart