Bug 839792 - Do XBL lookups on the shadow prototype. r=bz

This commit is contained in:
Bobby Holley 2013-02-13 19:16:19 +01:00
parent 31e5c808a7
commit b0e2149774
2 changed files with 18 additions and 12 deletions

View File

@ -1435,16 +1435,19 @@ nsXBLBinding::LookupMember(JSContext* aCx, JS::HandleId aId,
return false;
}
// Get the scope of mBoundElement.
// Get the scope of mBoundElement and the associated XBL scope. We should only
// be calling into this machinery if we're running in a separate XBL scope.
JSObject* boundScope =
js::GetGlobalForObjectCrossCompartment(mBoundElement->GetWrapper());
JSObject* xblScope = xpc::GetXBLScope(aCx, boundScope);
MOZ_ASSERT(boundScope != xblScope);
// Enter the compartment of mBoundElement and invoke the internal version.
// Enter the xbl scope and invoke the internal version.
{
JSAutoCompartment ac(aCx, boundScope);
JSAutoCompartment ac(aCx, xblScope);
js::RootedId id(aCx, aId);
if (!JS_WrapId(aCx, id.address()) ||
!LookupMemberInternal(aCx, name, id, aDesc, boundScope))
!LookupMemberInternal(aCx, name, id, aDesc, xblScope))
{
return false;
}
@ -1458,7 +1461,7 @@ bool
nsXBLBinding::LookupMemberInternal(JSContext* aCx, nsString& aName,
JS::HandleId aNameAsId,
JSPropertyDescriptor* aDesc,
JSObject* aBoundScope)
JSObject* aXBLScope)
{
// First, see if we have a JSClass. If we don't, it means that this binding
// doesn't have a class object, and thus doesn't have any members. Skip it.
@ -1467,13 +1470,13 @@ nsXBLBinding::LookupMemberInternal(JSContext* aCx, nsString& aName,
return true;
}
return mNextBinding->LookupMemberInternal(aCx, aName, aNameAsId,
aDesc, aBoundScope);
aDesc, aXBLScope);
}
// Find our class object. It's permanent, so it should be there no matter
// what.
// Find our class object. It's in a protected scope and permanent just in case,
// so should be there no matter what.
js::RootedValue classObject(aCx);
if (!JS_GetProperty(aCx, aBoundScope, mJSClass->name, classObject.address())) {
if (!JS_GetProperty(aCx, aXBLScope, mJSClass->name, classObject.address())) {
return false;
}
MOZ_ASSERT(classObject.isObject());
@ -1491,7 +1494,7 @@ nsXBLBinding::LookupMemberInternal(JSContext* aCx, nsString& aName,
}
return mNextBinding->LookupMemberInternal(aCx, aName, aNameAsId, aDesc,
aBoundScope);
aXBLScope);
}
bool

View File

@ -72,6 +72,9 @@ public:
* Does a lookup for a method or attribute provided by one of the bindings'
* prototype implementation. If found, |desc| will be set up appropriately,
* and wrapped into cx->compartment.
*
* May only be called when XBL code is being run in a separate scope, because
* otherwise we don't have untainted data with which to do a proper lookup.
*/
bool LookupMember(JSContext* aCx, JS::HandleId aId, JSPropertyDescriptor* aDesc);
@ -83,10 +86,10 @@ public:
protected:
/*
* Internal version. Requires that aCx is in the compartment of aBoundScope.
* Internal version. Requires that aCx is in appropriate xbl scope.
*/
bool LookupMemberInternal(JSContext* aCx, nsString& aName, JS::HandleId aNameAsId,
JSPropertyDescriptor* aDesc, JSObject* aBoundScope);
JSPropertyDescriptor* aDesc, JSObject* aXBLScope);
public: