Bug 1335890 - Factor out nsContentUtils::SubjectPrincipal version that takes JSContext
MozReview-Commit-ID: CGRipgKUm7g
--- a/dom/base/nsContentUtils.cpp
+++ b/dom/base/nsContentUtils.cpp
@@ -2079,21 +2079,18 @@ nsContentUtils::CanCallerAccess(nsPIDOMW
bool
nsContentUtils::CallerHasPermission(JSContext* aCx, const nsAString& aPerm)
{
// Chrome gets access by default.
if (IsSystemCaller(aCx)) {
return true;
}
- JSCompartment* c = js::GetContextCompartment(aCx);
- nsIPrincipal* p = nsJSPrincipals::get(JS_GetCompartmentPrincipals(c));
-
// Otherwise, only allow if caller is an addon with the permission.
- return BasePrincipal::Cast(p)->AddonHasPermission(aPerm);
+ return BasePrincipal::Cast(SubjectPrincipal(aCx))->AddonHasPermission(aPerm);
}
//static
bool
nsContentUtils::InProlog(nsINode *aNode)
{
NS_PRECONDITION(aNode, "missing node to nsContentUtils::InProlog");
@@ -2169,26 +2166,18 @@ nsContentUtils::IsCallerContentXBL()
}
return xpc::IsContentXBLScope(c);
}
bool
nsContentUtils::IsSystemCaller(JSContext* aCx)
{
- MOZ_ASSERT(NS_IsMainThread());
-
- // This is similar to what SubjectPrincipal() does, except we do in fact
- // assume that we're in a compartment here; anyone who calls this function in
- // situations where that's not the case is doing it wrong.
- JSCompartment *compartment = js::GetContextCompartment(aCx);
- MOZ_ASSERT(compartment);
-
- JSPrincipals *principals = JS_GetCompartmentPrincipals(compartment);
- return nsJSPrincipals::get(principals) == sSystemPrincipal;
+ // Note that SubjectPrincipal() assumes we are in a compartment here.
+ return SubjectPrincipal(aCx) == sSystemPrincipal;
}
bool
nsContentUtils::ThreadsafeIsSystemCaller(JSContext* aCx)
{
if (NS_IsMainThread()) {
return IsSystemCaller(aCx);
}
@@ -2774,16 +2763,32 @@ nsContentUtils::GenerateStateKey(nsICont
}
}
return NS_OK;
}
// static
nsIPrincipal*
+nsContentUtils::SubjectPrincipal(JSContext* aCx)
+{
+ MOZ_ASSERT(NS_IsMainThread());
+
+ // As opposed to SubjectPrincipal(), we do in fact assume that
+ // we're in a compartment here; anyone who calls this function
+ // in situations where that's not the case is doing it wrong.
+ JSCompartment* compartment = js::GetContextCompartment(aCx);
+ MOZ_ASSERT(compartment);
+
+ JSPrincipals* principals = JS_GetCompartmentPrincipals(compartment);
+ return nsJSPrincipals::get(principals);
+}
+
+// static
+nsIPrincipal*
nsContentUtils::SubjectPrincipal()
{
MOZ_ASSERT(IsInitialized());
MOZ_ASSERT(NS_IsMainThread());
JSContext* cx = GetCurrentJSContext();
if (!cx) {
MOZ_CRASH("Accessing the Subject Principal without an AutoJSAPI on the stack is forbidden");
}
@@ -2798,29 +2803,28 @@ nsContentUtils::SubjectPrincipal()
//
// So we want to return _something_ here - and definitely not the System
// Principal, since that would make an AutoJSAPI a very dangerous thing to
// instantiate.
//
// The natural thing to return is a null principal. Ideally, we'd return a
// different null principal each time, to avoid any unexpected interactions
// when the principal accidentally gets inherited somewhere. But
- // GetSubjectPrincipal doesn't return strong references, so there's no way to
+ // SubjectPrincipal doesn't return strong references, so there's no way to
// sanely manage the lifetime of multiple null principals.
//
// So we use a singleton null principal. To avoid it being accidentally
// inherited and becoming a "real" subject or object principal, we do a
// release-mode assert during compartment creation against using this
// principal on an actual global.
if (!compartment) {
return sNullSubjectPrincipal;
}
- JSPrincipals *principals = JS_GetCompartmentPrincipals(compartment);
- return nsJSPrincipals::get(principals);
+ return SubjectPrincipal(cx);
}
// static
nsIPrincipal*
nsContentUtils::ObjectPrincipal(JSObject* aObj)
{
MOZ_ASSERT(NS_IsMainThread());
--- a/dom/base/nsContentUtils.h
+++ b/dom/base/nsContentUtils.h
@@ -540,16 +540,20 @@ public:
* Get the cache security manager service. Can return null if the layout
* module has been shut down.
*/
static nsIScriptSecurityManager* GetSecurityManager()
{
return sSecurityManager;
}
+ // Returns the subject principal from the JSContext. May only be called
+ // from the main thread and assumes an existing compartment.
+ static nsIPrincipal* SubjectPrincipal(JSContext* aCx);
+
// Returns the subject principal. Guaranteed to return non-null. May only
// be called when nsContentUtils is initialized.
static nsIPrincipal* SubjectPrincipal();
// Returns the prinipal of the given JS object. This may only be called on
// the main thread for objects from the main thread's JSRuntime.
static nsIPrincipal* ObjectPrincipal(JSObject* aObj);