Bug 976305. Use the callee, not the irrelevant this value, to figure out the GlobalObject for a static WebIDL method. r=bholley

This commit is contained in:
Boris Zbarsky 2014-03-20 23:19:43 -04:00
parent b138bfaeec
commit 0708700fcb
2 changed files with 17 additions and 9 deletions

View File

@ -1791,7 +1791,6 @@ GlobalObject::GlobalObject(JSContext* aCx, JSObject* aObject)
mCx(aCx), mCx(aCx),
mGlobalObject(nullptr) mGlobalObject(nullptr)
{ {
Maybe<JSAutoCompartment> ac;
JS::Rooted<JSObject*> obj(aCx, aObject); JS::Rooted<JSObject*> obj(aCx, aObject);
if (js::IsWrapper(obj)) { if (js::IsWrapper(obj)) {
obj = js::CheckedUnwrap(obj, /* stopAtOuter = */ false); obj = js::CheckedUnwrap(obj, /* stopAtOuter = */ false);
@ -1805,10 +1804,9 @@ GlobalObject::GlobalObject(JSContext* aCx, JSObject* aObject)
Throw(aCx, NS_ERROR_XPC_SECURITY_MANAGER_VETO); Throw(aCx, NS_ERROR_XPC_SECURITY_MANAGER_VETO);
return; return;
} }
ac.construct(aCx, obj);
} }
mGlobalJSObject = JS_GetGlobalForObject(aCx, obj); mGlobalJSObject = js::GetGlobalForObjectCrossCompartment(obj);
} }
nsISupports* nsISupports*

View File

@ -5169,6 +5169,8 @@ class CGPerSignatureCall(CGThing):
setter=False, isConstructor=False): setter=False, isConstructor=False):
assert idlNode.isMethod() == (not getter and not setter) assert idlNode.isMethod() == (not getter and not setter)
assert idlNode.isAttr() == (getter or setter) assert idlNode.isAttr() == (getter or setter)
# Constructors are always static
assert not isConstructor or static
CGThing.__init__(self) CGThing.__init__(self)
self.returnType = returnType self.returnType = returnType
@ -5192,11 +5194,20 @@ class CGPerSignatureCall(CGThing):
if static: if static:
nativeMethodName = "%s::%s" % (descriptor.nativeType, nativeMethodName = "%s::%s" % (descriptor.nativeType,
nativeMethodName) nativeMethodName)
cgThings.append(CGGeneric("""GlobalObject global(cx, obj); # If we're a constructor, "obj" may not be a function, so calling
# XrayAwareCalleeGlobal() on it is not safe. Of course in the
# constructor case either "obj" is an Xray or we're already in the
# content compartment, not the Xray compartment, so just
# constructing the GlobalObject from "obj" is fine.
if isConstructor:
objForGlobalObject = "obj"
else:
objForGlobalObject = "xpc::XrayAwareCalleeGlobal(obj)"
cgThings.append(CGGeneric("""GlobalObject global(cx, %s);
if (global.Failed()) { if (global.Failed()) {
return false; return false;
} }
""")) """ % objForGlobalObject))
argsPre.append("global") argsPre.append("global")
# For JS-implemented interfaces we do not want to base the # For JS-implemented interfaces we do not want to base the
@ -5997,11 +6008,10 @@ class CGAbstractStaticBindingMethod(CGAbstractStaticMethod):
CGAbstractStaticMethod.__init__(self, descriptor, name, "bool", args) CGAbstractStaticMethod.__init__(self, descriptor, name, "bool", args)
def definition_body(self): def definition_body(self):
# Make sure that "obj" is in the same compartment as "cx", since we'll
# later use it to wrap return values.
unwrap = CGGeneric("""JS::CallArgs args = JS::CallArgsFromVp(argc, vp); unwrap = CGGeneric("""JS::CallArgs args = JS::CallArgsFromVp(argc, vp);
JS::Rooted<JSObject*> obj(cx, args.computeThis(cx).toObjectOrNull()); JS::Rooted<JSObject*> obj(cx, &args.callee());""")
if (!obj) {
return false;
}""")
return CGList([ CGIndenter(unwrap), return CGList([ CGIndenter(unwrap),
self.generate_code() ], "\n\n").define() self.generate_code() ], "\n\n").define()