Bug 825392 - Add xpc::GetXBLScopeOrGlobal and Sprinkle some calls to it where necessary. r=bz

This commit is contained in:
Bobby Holley 2014-03-19 13:35:45 -03:00
parent e9b2546e5d
commit bb4da51f82
7 changed files with 31 additions and 12 deletions

View File

@ -745,9 +745,10 @@ nsBindingManager::GetBindingImplementation(nsIContent* aContent, REFNSIID aIID,
// binding, some of which may not be exposed on the prototype of
// untrusted content.
//
// If there's no separate XBL scope, we'll end up with the global of the
// reflector, and this will all be a no-op.
JS::Rooted<JSObject*> xblScope(cx, xpc::GetXBLScope(cx, jsobj));
// If there's no separate XBL scope, or if the reflector itself lives in
// the XBL scope, we'll end up with the global of the reflector, and this
// will all be a no-op.
JS::Rooted<JSObject*> xblScope(cx, xpc::GetXBLScopeOrGlobal(cx, jsobj));
JSAutoCompartment ac(cx, xblScope);
bool ok = JS_WrapObject(cx, &jsobj);
NS_ENSURE_TRUE(ok, NS_ERROR_OUT_OF_MEMORY);

View File

@ -1125,8 +1125,15 @@ nsXBLBinding::LookupMember(JSContext* aCx, JS::Handle<jsid> aId,
// 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.
//
// Note that we only end up in LookupMember for XrayWrappers from XBL scopes
// into content. So for NAC reflectors that live in the XBL scope, we should
// never get here. But on the off-chance that someone adds new callsites to
// LookupMember, we do a release-mode assertion as belt-and-braces.
// We do a release-mode assertion here to be extra safe.
JS::Rooted<JSObject*> boundScope(aCx,
js::GetGlobalForObjectCrossCompartment(mBoundElement->GetWrapper()));
MOZ_RELEASE_ASSERT(!xpc::IsInXBLScope(boundScope));
JS::Rooted<JSObject*> xblScope(aCx, xpc::GetXBLScope(aCx, boundScope));
NS_ENSURE_TRUE(xblScope, false);
MOZ_ASSERT(boundScope != xblScope);

View File

@ -80,7 +80,7 @@ nsXBLProtoImpl::InstallImplementation(nsXBLPrototypeBinding* aPrototypeBinding,
// not be the same compartment as globalObject.
JS::Rooted<JSObject*> globalObject(cx,
GetGlobalForObjectCrossCompartment(targetClassObject));
JS::Rooted<JSObject*> scopeObject(cx, xpc::GetXBLScope(cx, globalObject));
JS::Rooted<JSObject*> scopeObject(cx, xpc::GetXBLScopeOrGlobal(cx, globalObject));
NS_ENSURE_TRUE(scopeObject, NS_ERROR_OUT_OF_MEMORY);
JSAutoCompartment ac(cx, scopeObject);

View File

@ -312,7 +312,7 @@ nsXBLProtoImplField::InstallAccessors(JSContext* aCx,
{
MOZ_ASSERT(js::IsObjectInContextCompartment(aTargetClassObject, aCx));
JS::Rooted<JSObject*> globalObject(aCx, JS_GetGlobalForObject(aCx, aTargetClassObject));
JS::Rooted<JSObject*> scopeObject(aCx, xpc::GetXBLScope(aCx, globalObject));
JS::Rooted<JSObject*> scopeObject(aCx, xpc::GetXBLScopeOrGlobal(aCx, globalObject));
NS_ENSURE_TRUE(scopeObject, NS_ERROR_OUT_OF_MEMORY);
// Don't install it if the field is empty; see also InstallField which also must
@ -419,7 +419,7 @@ nsXBLProtoImplField::InstallField(nsIScriptContext* aContext,
// First, enter the xbl scope, wrap the node, and use that as the scope for
// the evaluation.
JS::Rooted<JSObject*> scopeObject(cx, xpc::GetXBLScope(cx, aBoundNode));
JS::Rooted<JSObject*> scopeObject(cx, xpc::GetXBLScopeOrGlobal(cx, aBoundNode));
NS_ENSURE_TRUE(scopeObject, NS_ERROR_OUT_OF_MEMORY);
JSAutoCompartment ac(cx, scopeObject);

View File

@ -310,7 +310,7 @@ nsXBLProtoImplAnonymousMethod::Execute(nsIContent* aBoundElement)
MOZ_ASSERT(cx == nsContentUtils::GetCurrentJSContext());
JS::Rooted<JSObject*> thisObject(cx, &v.toObject());
JS::Rooted<JSObject*> scopeObject(cx, xpc::GetXBLScope(cx, globalObject));
JS::Rooted<JSObject*> scopeObject(cx, xpc::GetXBLScopeOrGlobal(cx, globalObject));
NS_ENSURE_TRUE(scopeObject, NS_ERROR_OUT_OF_MEMORY);
JSAutoCompartment ac(cx, scopeObject);

View File

@ -286,7 +286,7 @@ nsXBLPrototypeHandler::ExecuteHandler(EventTarget* aTarget,
NS_ENSURE_SUCCESS(rv, rv);
JS::Rooted<JSObject*> globalObject(cx, boundGlobal->GetGlobalJSObject());
JS::Rooted<JSObject*> scopeObject(cx, xpc::GetXBLScope(cx, globalObject));
JS::Rooted<JSObject*> scopeObject(cx, xpc::GetXBLScopeOrGlobal(cx, globalObject));
NS_ENSURE_TRUE(scopeObject, NS_ERROR_OUT_OF_MEMORY);
// Bind it to the bound element. Note that if we're using a separate XBL scope,
@ -363,7 +363,7 @@ nsXBLPrototypeHandler::EnsureEventHandler(nsIScriptGlobalObject* aGlobal,
NS_ENSURE_TRUE(!handlerText.IsEmpty(), NS_ERROR_FAILURE);
JS::Rooted<JSObject*> globalObject(cx, aGlobal->GetGlobalJSObject());
JS::Rooted<JSObject*> scopeObject(cx, xpc::GetXBLScope(cx, globalObject));
JS::Rooted<JSObject*> scopeObject(cx, xpc::GetXBLScopeOrGlobal(cx, globalObject));
NS_ENSURE_TRUE(scopeObject, NS_ERROR_OUT_OF_MEMORY);
nsAutoCString bindingURI;

View File

@ -70,6 +70,9 @@ private:
JSObject *
TransplantObject(JSContext *cx, JS::HandleObject origobj, JS::HandleObject target);
bool IsXBLScope(JSCompartment *compartment);
bool IsInXBLScope(JSObject *obj);
// Return a raw XBL scope object corresponding to contentScope, which must
// be an object whose global is a DOM window.
//
@ -79,9 +82,20 @@ TransplantObject(JSContext *cx, JS::HandleObject origobj, JS::HandleObject targe
// Also note that XBL scopes are lazily created, so the return-value should be
// null-checked unless the caller can ensure that the scope must already
// exist.
//
// This function asserts if |contentScope| is itself in an XBL scope to catch
// sloppy consumers. Conversely, GetXBLScopeOrGlobal will handle objects that
// are in XBL scope (by just returning the global).
JSObject *
GetXBLScope(JSContext *cx, JSObject *contentScope);
inline JSObject *
GetXBLScopeOrGlobal(JSContext *cx, JSObject *obj) {
if (IsInXBLScope(obj))
return js::GetGlobalForObjectCrossCompartment(obj);
return GetXBLScope(cx, obj);
}
// Returns whether XBL scopes have been explicitly disabled for code running
// in this compartment. See the comment around mAllowXBLScope.
bool
@ -345,9 +359,6 @@ bool StringToJsval(JSContext* cx, mozilla::dom::DOMString& str,
nsIPrincipal *GetCompartmentPrincipal(JSCompartment *compartment);
bool IsXBLScope(JSCompartment *compartment);
bool IsInXBLScope(JSObject *obj);
void SetLocationForGlobal(JSObject *global, const nsACString& location);
void SetLocationForGlobal(JSObject *global, nsIURI *locationURI);