Bug 784551 - remove JSSecurityCallbacks::findObjectPrincipals (r=mrbkap)
authorLuke Wagner <luke@mozilla.com>
Thu, 23 Aug 2012 09:51:09 -0700
changeset 105228 a41978cc803f6320d4907cf75a7fe2331edf9c7c
parent 105227 00646164061dfcf3d35f796e9c54ef09a2195bc8
child 105229 52453ab440ec85a6bbde0310d88f43a938ab0849
push id55
push usershu@rfrn.org
push dateThu, 30 Aug 2012 01:33:09 +0000
reviewersmrbkap
bugs784551
milestone17.0a1
Bug 784551 - remove JSSecurityCallbacks::findObjectPrincipals (r=mrbkap)
caps/include/nsScriptSecurityManager.h
caps/src/nsScriptSecurityManager.cpp
js/src/builtin/Eval.cpp
js/src/jsapi-tests/testOriginPrincipals.cpp
js/src/jsapi.h
js/src/jsdbgapi.cpp
js/src/jsobj.h
js/src/jsobjinlines.h
js/src/shell/js.cpp
js/src/vm/Debugger.cpp
js/xpconnect/shell/xpcshell.cpp
--- a/caps/include/nsScriptSecurityManager.h
+++ b/caps/include/nsScriptSecurityManager.h
@@ -388,19 +388,16 @@ private:
     // GetScriptSecurityManager is the only call that can make one
     nsScriptSecurityManager();
     virtual ~nsScriptSecurityManager();
 
     static JSBool
     CheckObjectAccess(JSContext *cx, JSHandleObject obj,
                       JSHandleId id, JSAccessMode mode,
                       jsval *vp);
-
-    static JSPrincipals *
-    ObjectPrincipalFinder(JSObject *obj);
     
     // Decides, based on CSP, whether or not eval() and stuff can be executed.
     static JSBool
     ContentSecurityPolicyPermitsJSAction(JSContext *cx);
 
     // Returns null if a principal cannot be found; generally callers
     // should error out at that point.
     static nsIPrincipal* doGetObjectPrincipal(JSObject *obj);
--- a/caps/src/nsScriptSecurityManager.cpp
+++ b/caps/src/nsScriptSecurityManager.cpp
@@ -462,22 +462,16 @@ NS_IMPL_ISUPPORTS4(nsScriptSecurityManag
                    nsIObserver)
 
 ///////////////////////////////////////////////////
 // Methods implementing nsIScriptSecurityManager //
 ///////////////////////////////////////////////////
 
 ///////////////// Security Checks /////////////////
 
-/* static */ JSPrincipals *
-nsScriptSecurityManager::ObjectPrincipalFinder(JSObject *aObj)
-{
-    return nsJSPrincipals::get(doGetObjectPrincipal(aObj));
-}
-
 JSBool
 nsScriptSecurityManager::ContentSecurityPolicyPermitsJSAction(JSContext *cx)
 {
     // Get the security manager
     nsScriptSecurityManager *ssm =
         nsScriptSecurityManager::GetScriptSecurityManager();
 
     NS_ASSERTION(ssm, "Failed to get security manager service");
@@ -486,23 +480,18 @@ nsScriptSecurityManager::ContentSecurity
 
     nsresult rv;
     nsIPrincipal* subjectPrincipal = ssm->GetSubjectPrincipal(cx, &rv);
 
     NS_ASSERTION(NS_SUCCEEDED(rv), "CSP: Failed to get nsIPrincipal from js context");
     if (NS_FAILED(rv))
         return JS_FALSE; // Not just absence of principal, but failure.
 
-    if (!subjectPrincipal) {
-        // See bug 553448 for discussion of this case.
-        NS_ASSERTION(!JS_GetSecurityCallbacks(js::GetRuntime(cx))->findObjectPrincipals,
-                     "CSP: Should have been able to find subject principal. "
-                     "Reluctantly granting access.");
+    if (!subjectPrincipal)
         return JS_TRUE;
-    }
 
     nsCOMPtr<nsIContentSecurityPolicy> csp;
     rv = subjectPrincipal->GetCsp(getter_AddRefs(csp));
     NS_ASSERTION(NS_SUCCEEDED(rv), "CSP: Failed to get CSP from principal.");
 
     // don't do anything unless there's a CSP
     if (!csp)
         return JS_TRUE;
@@ -3043,17 +3032,16 @@ nsresult nsScriptSecurityManager::Init()
         do_QueryInterface(sXPConnect, &rv);
     NS_ENSURE_SUCCESS(rv, rv);
 
     rv = runtimeService->GetRuntime(&sRuntime);
     NS_ENSURE_SUCCESS(rv, rv);
 
     static const JSSecurityCallbacks securityCallbacks = {
         CheckObjectAccess,
-        ObjectPrincipalFinder,
         ContentSecurityPolicyPermitsJSAction
     };
 
     MOZ_ASSERT(!JS_GetSecurityCallbacks(sRuntime));
     JS_SetSecurityCallbacks(sRuntime, &securityCallbacks);
     JS_InitDestroyPrincipalsCallback(sRuntime, nsJSPrincipals::Destroy);
 
     JS_SetTrustedPrincipals(sRuntime, system);
--- a/js/src/builtin/Eval.cpp
+++ b/js/src/builtin/Eval.cpp
@@ -361,10 +361,10 @@ js::PrincipalsForCompiledCode(const Call
     // subsume the callee's.
     //
     // In the converse situation, where the callee has lower privileges than the
     // caller, we might initially guess that the caller would want to retain
     // their higher privileges in the generated code. However, since the
     // compiled code will be run with the callee's scope chain, this would make
     // fp->script()->compartment() != fp->compartment().
 
-    return call.callee().principals(cx);
+    return call.callee().compartment()->principals;
 }
--- a/js/src/jsapi-tests/testOriginPrincipals.cpp
+++ b/js/src/jsapi-tests/testOriginPrincipals.cpp
@@ -1,45 +1,29 @@
 /* This Source Code Form is subject to the terms of the Mozilla Public
  * License, v. 2.0. If a copy of the MPL was not distributed with this
  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
 
 #include "tests.h"
 #include "jsdbgapi.h"
 #include "jsobjinlines.h"
 
-JSPrincipals *sCurrentGlobalPrincipals = NULL;
-
-JSPrincipals *
-ObjectPrincipalsFinder(JSObject *)
-{
-    return sCurrentGlobalPrincipals;
-}
-
-static const JSSecurityCallbacks seccb = {
-    NULL,
-    ObjectPrincipalsFinder,
-    NULL
-};
-
 JSPrincipals *sOriginPrincipalsInErrorReporter = NULL;
 
 static void
 ErrorReporter(JSContext *cx, const char *message, JSErrorReport *report)
 {
     sOriginPrincipalsInErrorReporter = report->originPrincipals;
 }
 
 JSPrincipals prin1 = { 1 };
 JSPrincipals prin2 = { 1 };
 
 BEGIN_TEST(testOriginPrincipals)
 {
-    JS_SetSecurityCallbacks(rt, &seccb);
-
     /*
      * Currently, the only way to set a non-trivial originPrincipal is to use
      * JS_EvaluateUCScriptForPrincipalsVersionOrigin. This does not expose the
      * compiled script, so we can only test nested scripts.
      */
 
     CHECK(testOuter("function f() {return 1}; f;"));
     CHECK(testOuter("function outer() { return (function () {return 2}); }; outer();"));
@@ -72,17 +56,21 @@ bool
 eval(const char *asciiChars, JSPrincipals *principals, JSPrincipals *originPrincipals, jsval *rval)
 {
     size_t len = strlen(asciiChars);
     jschar *chars = new jschar[len+1];
     for (size_t i = 0; i < len; ++i)
         chars[i] = asciiChars[i];
     chars[len] = 0;
 
-    JS::RootedObject global(cx, JS_GetGlobalObject(cx));
+    JS::RootedObject global(cx, JS_NewGlobalObject(cx, getGlobalClass(), principals));
+    CHECK(global);
+    JSAutoEnterCompartment ac;
+    CHECK(ac.enter(cx, global));
+    CHECK(JS_InitStandardClasses(cx, global));
     bool ok = JS_EvaluateUCScriptForPrincipalsVersionOrigin(cx, global,
                                                             principals,
                                                             originPrincipals,
                                                             chars, len, "", 0, rval,
                                                             JSVERSION_DEFAULT);
     delete[] chars;
     return ok;
 }
@@ -93,18 +81,16 @@ testOuter(const char *asciiChars)
     CHECK(testInner(asciiChars, &prin1, &prin1));
     CHECK(testInner(asciiChars, &prin1, &prin2));
     return true;
 }
 
 bool
 testInner(const char *asciiChars, JSPrincipals *principal, JSPrincipals *originPrincipal)
 {
-    sCurrentGlobalPrincipals = principal;
-
     jsval rval;
     CHECK(eval(asciiChars, principal, originPrincipal, &rval));
 
     JSScript *script = JS_GetFunctionScript(cx, JSVAL_TO_OBJECT(rval)->toFunction());
     CHECK(JS_GetScriptPrincipals(script) == principal);
     CHECK(JS_GetScriptOriginPrincipals(script) == originPrincipal);
 
     return true;
--- a/js/src/jsapi.h
+++ b/js/src/jsapi.h
@@ -1993,27 +1993,16 @@ typedef JSBool
 /*
  * Security protocol types.
  */
 
 typedef void
 (* JSDestroyPrincipalsOp)(JSPrincipals *principals);
 
 /*
- * Return a weak reference to the principals associated with obj, possibly via
- * the immutable parent chain leading from obj to a top-level container (e.g.,
- * a window object in the DOM level 0).  If there are no principals associated
- * with obj, return null.  Therefore null does not mean an error was reported;
- * in no event should an error be reported or an exception be thrown by this
- * callback's implementation.
- */
-typedef JSPrincipals *
-(* JSObjectPrincipalsFinder)(JSObject *obj);
-
-/*
  * Used to check if a CSP instance wants to disable eval() and friends.
  * See js_CheckCSPPermitsJSAction() in jsobj.
  */
 typedef JSBool
 (* JSCSPEvalChecker)(JSContext *cx);
 
 /*
  * Callback used to ask the embedding for the cross compartment wrapper handler
@@ -4903,17 +4892,16 @@ struct JSPrincipals {
 extern JS_PUBLIC_API(void)
 JS_HoldPrincipals(JSPrincipals *principals);
 
 extern JS_PUBLIC_API(void)
 JS_DropPrincipals(JSRuntime *rt, JSPrincipals *principals);
 
 struct JSSecurityCallbacks {
     JSCheckAccessOp            checkObjectAccess;
-    JSObjectPrincipalsFinder   findObjectPrincipals;
     JSCSPEvalChecker           contentSecurityPolicyAllows;
 };
 
 extern JS_PUBLIC_API(void)
 JS_SetSecurityCallbacks(JSRuntime *rt, const JSSecurityCallbacks *callbacks);
 
 extern JS_PUBLIC_API(const JSSecurityCallbacks *)
 JS_GetSecurityCallbacks(JSRuntime *rt);
--- a/js/src/jsdbgapi.cpp
+++ b/js/src/jsdbgapi.cpp
@@ -517,19 +517,17 @@ JS_GetFramePC(JSContext *cx, JSStackFram
     return fp->pcQuadratic(cx->stack, 100);
 }
 
 JS_PUBLIC_API(void *)
 JS_GetFrameAnnotation(JSContext *cx, JSStackFrame *fpArg)
 {
     StackFrame *fp = Valueify(fpArg);
     if (fp->annotation() && fp->isScriptFrame()) {
-        JSPrincipals *principals = fp->scopeChain()->principals(cx);
-
-        if (principals) {
+        if (fp->scopeChain()->compartment()->principals) {
             /*
              * Give out an annotation only if privileges have not been revoked
              * or disabled globally.
              */
             return fp->annotation();
         }
     }
 
--- a/js/src/jsobj.h
+++ b/js/src/jsobj.h
@@ -510,19 +510,16 @@ struct JSObject : public js::ObjectImpl
      * Get the enclosing scope of an object. When called on non-scope object,
      * this will just be the global (the name "enclosing scope" still applies
      * in this situation because non-scope objects can be on the scope chain).
      */
     inline JSObject *enclosingScope();
 
     inline js::GlobalObject &global() const;
 
-    /* N.B. Infallible: NULL means 'no principal', not an error. */
-    inline JSPrincipals *principals(JSContext *cx);
-
     /* Remove the type (and prototype) or parent from a new object. */
     static inline bool clearType(JSContext *cx, js::HandleObject obj);
     static bool clearParent(JSContext *cx, js::HandleObject obj);
 
     /*
      * ES5 meta-object properties and operations.
      */
 
--- a/js/src/jsobjinlines.h
+++ b/js/src/jsobjinlines.h
@@ -907,24 +907,16 @@ JSObject::hasProperty(JSContext *cx, js:
 }
 
 inline bool
 JSObject::isCallable()
 {
     return isFunction() || getClass()->call;
 }
 
-inline JSPrincipals *
-JSObject::principals(JSContext *cx)
-{
-    if (JSObjectPrincipalsFinder find = cx->runtime->securityCallbacks->findObjectPrincipals)
-        return find(this);
-    return cx->compartment ? cx->compartment->principals : NULL;
-}
-
 inline void
 JSObject::nativeSetSlot(unsigned slot, const js::Value &value)
 {
     JS_ASSERT(isNative());
     JS_ASSERT(slot < slotSpan());
     return setSlot(slot, value);
 }
 
--- a/js/src/shell/js.cpp
+++ b/js/src/shell/js.cpp
@@ -4885,17 +4885,16 @@ JSPrincipals shellTrustedPrincipals = { 
 JSBool
 CheckObjectAccess(JSContext *cx, HandleObject obj, HandleId id, JSAccessMode mode, jsval *vp)
 {
     return true;
 }
 
 JSSecurityCallbacks securityCallbacks = {
     CheckObjectAccess,
-    NULL,
     NULL
 };
 
 int
 main(int argc, char **argv, char **envp)
 {
     int stackDummy;
     JSRuntime *rt;
--- a/js/src/vm/Debugger.cpp
+++ b/js/src/vm/Debugger.cpp
@@ -3445,17 +3445,17 @@ js::EvaluateInEnv(JSContext *cx, Handle<
     }
 
     /*
      * NB: This function breaks the assumption that the compiler can see all
      * calls and properly compute a static level. In practice, any non-zero
      * static level will suffice.
      */
     CompileOptions options(cx);
-    options.setPrincipals(fp->scopeChain()->principals(cx))
+    options.setPrincipals(fp->scopeChain()->compartment()->principals)
            .setCompileAndGo(true)
            .setNoScriptRval(false)
            .setFileAndLine(filename, lineno);
     RootedScript script(cx, frontend::CompileScript(cx, env, fp, options, chars, length,
                                                     /* source = */ NULL, /* staticLimit = */ 1));
     if (!script)
         return false;
 
--- a/js/xpconnect/shell/xpcshell.cpp
+++ b/js/xpconnect/shell/xpcshell.cpp
@@ -1650,22 +1650,16 @@ GetCurrentWorkingDirectory(nsAString& wo
     // size back down to the actual string length
     cwd.SetLength(strlen(result) + 1);
     cwd.Replace(cwd.Length() - 1, 1, '/');
     workingDirectory = NS_ConvertUTF8toUTF16(cwd);
 #endif
     return true;
 }
 
-static JSPrincipals *
-FindObjectPrincipals(JSObject *obj)
-{
-    return gJSPrincipals;
-}
-
 static JSSecurityCallbacks shellSecurityCallbacks;
 
 int
 main(int argc, char **argv, char **envp)
 {
 #ifdef XP_MACOSX
     InitAutoreleasePool();
 #endif
@@ -1834,17 +1828,16 @@ main(int argc, char **argv, char **envp)
             } else {
                 fprintf(gErrFile, "+++ Failed to get ScriptSecurityManager service, running without principals");
             }
         }
 
         const JSSecurityCallbacks *scb = JS_GetSecurityCallbacks(rt);
         NS_ASSERTION(scb, "We are assuming that nsScriptSecurityManager::Init() has been run");
         shellSecurityCallbacks = *scb;
-        shellSecurityCallbacks.findObjectPrincipals = FindObjectPrincipals;
         JS_SetSecurityCallbacks(rt, &shellSecurityCallbacks);
 
 #ifdef TEST_TranslateThis
         nsCOMPtr<nsIXPCFunctionThisTranslator>
             translator(new nsXPCFunctionThisTranslator);
         xpc->SetFunctionThisTranslator(NS_GET_IID(nsITestXPCFunctionCallback), translator, nullptr);
 #endif