Bug 950407 - Fix broken scripted proxy prototype set forwarding. (r=bholley)

This commit is contained in:
Eric Faust 2014-01-06 11:34:26 -08:00
parent 1802a49532
commit def585f7f4
3 changed files with 17 additions and 21 deletions

View File

@ -422,6 +422,22 @@ JSObject::setProto(JSContext *cx, JS::HandleObject obj, JS::HandleObject proto,
return js::Proxy::setPrototypeOf(cx, obj, proto, succeeded);
}
/*
* Disallow mutating the [[Prototype]] on ArrayBuffer objects, which
* due to their complicated delegate-object shenanigans can't easily
* have a mutable [[Prototype]].
*/
if (obj->is<js::ArrayBufferObject>()) {
JS_ReportErrorNumber(cx, js_GetErrorMessage, nullptr, JSMSG_SETPROTOTYPEOF_FAIL);
return false;
}
unsigned dummy;
js::RootedId nid(cx, NameToId(cx->names().proto));
js::RootedValue v(cx);
if (!CheckAccess(cx, obj, nid, JSAccessMode(JSACC_PROTO | JSACC_WRITE), &v, &dummy))
return false;
/* ES6 9.1.2 step 5 forbids changing [[Prototype]] if not [[Extensible]]. */
bool extensible;
if (!JSObject::isExtensible(cx, obj, &extensible))

View File

@ -3249,15 +3249,12 @@ proxy(JSContext *cx, unsigned argc, jsval *vp)
RootedObject handler(cx, NonNullObject(cx, args[1]));
if (!handler)
return false;
RootedObject proto(cx);
if (!JSObject::getProto(cx, target, &proto))
return false;
RootedValue priv(cx, ObjectValue(*target));
ProxyOptions options;
options.setCallable(target->isCallable());
ProxyObject *proxy =
ProxyObject::New(cx, &ScriptedDirectProxyHandler::singleton,
priv, TaggedProto(proto), cx->global(),
priv, TaggedProto(TaggedProto::LazyProto), cx->global(),
options);
if (!proxy)
return false;

View File

@ -123,17 +123,6 @@ ProtoSetterImpl(JSContext *cx, CallArgs args)
Rooted<JSObject*> obj(cx, &args.thisv().toObject());
/*
* Disallow mutating the [[Prototype]] on ArrayBuffer objects, which
* due to their complicated delegate-object shenanigans can't easily
* have a mutable [[Prototype]].
*/
if (obj->is<ArrayBufferObject>()) {
JS_ReportErrorNumber(cx, js_GetErrorMessage, nullptr, JSMSG_INCOMPATIBLE_PROTO,
"Object", "__proto__ setter", "ArrayBuffer");
return false;
}
/* Do nothing if __proto__ isn't being set to an object or null. */
if (args.length() == 0 || !args[0].isObjectOrNull()) {
args.rval().setUndefined();
@ -142,12 +131,6 @@ ProtoSetterImpl(JSContext *cx, CallArgs args)
Rooted<JSObject*> newProto(cx, args[0].toObjectOrNull());
unsigned dummy;
RootedId nid(cx, NameToId(cx->names().proto));
RootedValue v(cx);
if (!CheckAccess(cx, obj, nid, JSAccessMode(JSACC_PROTO | JSACC_WRITE), &v, &dummy))
return false;
bool success;
if (!JSObject::setProto(cx, obj, newProto, &success))
return false;