Bug 1153475 - Always ignore desc.object() in DefineProperty functions that take a PropertyDescriptor argument. r=efaust.

This commit is contained in:
Jason Orendorff 2015-03-23 14:32:33 -05:00
parent 97fbe83d2b
commit 7a0cf66b4b
5 changed files with 30 additions and 11 deletions

View File

@ -128,14 +128,20 @@ js::InformalValueTypeName(const Value& v)
}
bool
js::FromPropertyDescriptor(JSContext* cx, Handle<PropertyDescriptor> desc,
MutableHandleValue vp)
js::FromPropertyDescriptor(JSContext* cx, Handle<PropertyDescriptor> desc, MutableHandleValue vp)
{
if (!desc.object()) {
vp.setUndefined();
return true;
}
return FromPropertyDescriptorToObject(cx, desc, vp);
}
bool
js::FromPropertyDescriptorToObject(JSContext* cx, Handle<PropertyDescriptor> desc,
MutableHandleValue vp)
{
RootedObject obj(cx, NewBuiltinClassInstance<PlainObject>(cx));
if (!obj)
return false;
@ -968,8 +974,6 @@ js::SetIntegrityLevel(JSContext* cx, HandleObject obj, IntegrityLevel level)
desc.setAttributes(AllowConfigureAndWritable | JSPROP_PERMANENT | JSPROP_READONLY);
}
desc.object().set(obj);
// 8.a.i-ii. / 9.a.iii.3-4
if (!StandardDefineProperty(cx, obj, id, desc))
return false;
@ -3081,7 +3085,7 @@ js::DefineProperty(ExclusiveContext* cx, HandleObject obj, HandleId id, HandleVa
MOZ_ASSERT(!(attrs & JSPROP_PROPOP_ACCESSORS));
Rooted<PropertyDescriptor> desc(cx);
desc.initFields(obj, value, attrs, getter, setter);
desc.initFields(NullPtr(), value, attrs, getter, setter);
if (DefinePropertyOp op = obj->getOps()->defineProperty) {
if (!cx->shouldBeJSContext())
return false;

View File

@ -1222,10 +1222,26 @@ GetOwnPropertyDescriptor(JSContext* cx, HandleObject obj, HandleId id,
bool
GetOwnPropertyDescriptor(JSContext* cx, HandleObject obj, HandleId id, MutableHandleValue vp);
/* ES6 draft rev 32 (2015 Feb 2) 6.2.4.4 FromPropertyDescriptor(Desc) */
bool
/*
* ES6 draft rev 32 (2015 Feb 2) 6.2.4.4 FromPropertyDescriptor(Desc).
*
* If desc.object() is null, then vp is set to undefined.
*/
extern bool
FromPropertyDescriptor(JSContext* cx, Handle<PropertyDescriptor> desc, MutableHandleValue vp);
/*
* Like FromPropertyDescriptor, but ignore desc.object() and always set vp
* to an object on success.
*
* Use FromPropertyDescriptor for getOwnPropertyDescriptor, since desc.object()
* is used to indicate whether a result was found or not. Use this instead for
* defineProperty: it would be senseless to define a "missing" property.
*/
extern bool
FromPropertyDescriptorToObject(JSContext* cx, Handle<PropertyDescriptor> desc,
MutableHandleValue vp);
extern bool
IsDelegate(JSContext* cx, HandleObject obj, const Value& v, bool* result);

View File

@ -574,7 +574,7 @@ ScriptedDirectProxyHandler::defineProperty(JSContext* cx, HandleObject proxy, Ha
// step 9
RootedValue descObj(cx);
if (!FromPropertyDescriptor(cx, desc, &descObj))
if (!FromPropertyDescriptorToObject(cx, desc, &descObj))
return false;
// steps 10-11

View File

@ -203,7 +203,7 @@ ScriptedIndirectProxyHandler::defineProperty(JSContext* cx, HandleObject proxy,
RootedObject handler(cx, GetIndirectProxyHandlerObject(proxy));
RootedValue fval(cx), value(cx);
return GetFundamentalTrap(cx, handler, cx->names().defineProperty, &fval) &&
FromPropertyDescriptor(cx, desc, &value) &&
FromPropertyDescriptorToObject(cx, desc, &value) &&
Trap2(cx, handler, fval, id, value, &value) &&
result.succeed();
}
@ -407,7 +407,6 @@ ScriptedIndirectProxyHandler::derivedSet(JSContext* cx, HandleObject proxy, Hand
if (!receiver.isObject())
return result.fail(JSMSG_SET_NON_OBJECT_RECEIVER);
RootedObject receiverObj(cx, &receiver.toObject());
desc.object().set(receiverObj);
return DefineProperty(cx, receiverObj, id, desc, result);
}

View File

@ -1477,7 +1477,7 @@ js::NativeDefineProperty(ExclusiveContext* cx, HandleNativeObject obj, HandleId
ObjectOpResult& result)
{
Rooted<PropertyDescriptor> desc(cx);
desc.initFields(obj, value, attrs, getter, setter);
desc.initFields(NullPtr(), value, attrs, getter, setter);
return NativeDefineProperty(cx, obj, id, desc, result);
}