Bug 672026 - Ensure that there is an object principals finder during early startup (r=mrbkap,a=asa)
authorLuke Wagner <luke@mozilla.com>
Mon, 18 Jul 2011 17:37:19 -0700
changeset 70537 2c2a8a2007ff7d508eeb9c47bff41babf204b845
parent 70536 4bdc7ebdf1fa530b0488595d44f342fb4dcdd4df
child 70538 4137513fe9324bc0e77e4e8a7dde9843150e13de
push id1
push usersledru@mozilla.com
push dateThu, 04 Dec 2014 17:57:20 +0000
reviewersmrbkap, asa
bugs672026
milestone6.0
Bug 672026 - Ensure that there is an object principals finder during early startup (r=mrbkap,a=asa)
caps/src/nsScriptSecurityManager.cpp
js/src/xpconnect/shell/xpcshell.cpp
--- a/caps/src/nsScriptSecurityManager.cpp
+++ b/caps/src/nsScriptSecurityManager.cpp
@@ -3364,16 +3364,51 @@ nsScriptSecurityManager::Observe(nsISupp
             PL_strcpy(lastDot + 1, id);
             const char** idPrefArray = (const char**)&message;
             rv = InitPrincipals(1, idPrefArray);
         }
     }
     return rv;
 }
 
+///////////////////////////////////
+// Default ObjectPrincipalFinder //
+///////////////////////////////////
+
+// The default JSSecurityCallbacks::findObjectPrincipals is necessary since
+// scripts run (and ask for object principals) during startup before
+// nsJSRuntime::Init() has been called (which resets findObjectPrincipals).
+
+// Defined NS_EXPORT for linkage with debug-only assert in xpcshell
+NS_EXPORT JSPrincipals *
+NS_DefaultObjectPrincipalFinder(JSContext *cx, JSObject *obj)
+{
+    nsScriptSecurityManager *ssm = nsScriptSecurityManager::GetScriptSecurityManager();
+    if (!ssm) {
+        return nsnull;
+    }
+
+    nsCOMPtr<nsIPrincipal> principal;
+    nsresult rv = ssm->GetObjectPrincipal(cx, obj, getter_AddRefs(principal));
+    if (NS_FAILED(rv) || !principal) {
+        return nsnull;
+    }
+
+    JSPrincipals *jsPrincipals = nsnull;
+    principal->GetJSPrincipals(cx, &jsPrincipals);
+
+    // nsIPrincipal::GetJSPrincipals() returns a strong reference to the
+    // JS principals, but the caller of this function expects a weak
+    // reference. So we need to release here.
+
+    JSPRINCIPALS_DROP(cx, jsPrincipals);
+
+    return jsPrincipals;
+}
+
 /////////////////////////////////////////////
 // Constructor, Destructor, Initialization //
 /////////////////////////////////////////////
 nsScriptSecurityManager::nsScriptSecurityManager(void)
     : mOriginToPolicyMap(nsnull),
       mDefaultPolicy(nsnull),
       mCapabilities(nsnull),
       mContextPrincipals(nsnull),
@@ -3437,17 +3472,17 @@ nsresult nsScriptSecurityManager::Init()
     NS_ENSURE_SUCCESS(rv, rv);
 
     rv = runtimeService->GetRuntime(&sRuntime);
     NS_ENSURE_SUCCESS(rv, rv);
 
     static JSSecurityCallbacks securityCallbacks = {
         CheckObjectAccess,
         NULL,
-        NULL,
+        NS_DefaultObjectPrincipalFinder,
         ContentSecurityPolicyPermitsJSAction
     };
 
 #ifdef DEBUG
     JSSecurityCallbacks *oldcallbacks =
 #endif
     JS_SetRuntimeSecurityCallbacks(sRuntime, &securityCallbacks);
     NS_ASSERTION(!oldcallbacks, "Someone else set security callbacks!");
--- a/js/src/xpconnect/shell/xpcshell.cpp
+++ b/js/src/xpconnect/shell/xpcshell.cpp
@@ -1754,16 +1754,20 @@ GetCurrentWorkingDirectory(nsAString& wo
 }
 
 static JSPrincipals *
 FindObjectPrincipals(JSContext *cx, JSObject *obj)
 {
     return gJSPrincipals;
 }
 
+// defined in nsScriptSecurityManager.cpp
+NS_IMPORT JSPrincipals *
+NS_DefaultObjectPrincipalFinder(JSContext *cx, JSObject *obj);
+
 int
 main(int argc, char **argv, char **envp)
 {
 #ifdef XP_MACOSX
     InitAutoreleasePool();
 #endif
     JSRuntime *rt;
     JSContext *cx;
@@ -1907,17 +1911,17 @@ main(int argc, char **argv, char **envp)
                 }
             } else {
                 fprintf(gErrFile, "+++ Failed to get ScriptSecurityManager service, running without principals");
             }
         }
 
         JSSecurityCallbacks *cb = JS_GetRuntimeSecurityCallbacks(rt);
         NS_ASSERTION(cb, "We are assuming that nsScriptSecurityManager::Init() has been run");
-        NS_ASSERTION(!cb->findObjectPrincipals, "Your pigeon is in my hole!");
+        NS_ASSERTION(cb->findObjectPrincipals == NS_DefaultObjectPrincipalFinder, "Your pigeon is in my hole!");
         cb->findObjectPrincipals = FindObjectPrincipals;
 
 #ifdef TEST_TranslateThis
         nsCOMPtr<nsIXPCFunctionThisTranslator>
             translator(new nsXPCFunctionThisTranslator);
         xpc->SetFunctionThisTranslator(NS_GET_IID(nsITestXPCFunctionCallback), translator, nsnull);
 #endif