Bug 998083 - Introduce Cu.getObjectPrincipal and kill nsIScriptSecurityManager::GetObjectPrincipal. r=gabor
authorBobby Holley <bobbyholley@gmail.com>
Sat, 19 Apr 2014 10:39:59 -0700
changeset 197855 65aa67280bfb399219ab971ac1bd6856ff19e8f3
parent 197854 c7925215ca327f482c3b439c1148b8c63cf410e6
child 197856 443dcdf8eed26aa7a2134d970c003d2bd7b85903
push id3624
push userasasaki@mozilla.com
push dateMon, 09 Jun 2014 21:49:01 +0000
treeherdermozilla-beta@b1a5da15899a [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersgabor
bugs998083
milestone31.0a1
first release with
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
last release without
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
Bug 998083 - Introduce Cu.getObjectPrincipal and kill nsIScriptSecurityManager::GetObjectPrincipal. r=gabor
caps/idl/nsIScriptSecurityManager.idl
caps/src/nsScriptSecurityManager.cpp
js/xpconnect/idl/xpccomponents.idl
js/xpconnect/src/XPCComponents.cpp
js/xpconnect/tests/unit/test_getObjectPrincipal.js
toolkit/devtools/DevToolsUtils.js
--- a/caps/idl/nsIScriptSecurityManager.idl
+++ b/caps/idl/nsIScriptSecurityManager.idl
@@ -6,17 +6,17 @@
 #include "nsISupports.idl"
 #include "nsIPrincipal.idl"
 #include "nsIXPCSecurityManager.idl"
 interface nsIURI;
 interface nsIChannel;
 interface nsIDocShell;
 interface nsIDomainPolicy;
 
-[scriptable, uuid(3b6e408b-e774-4612-89e8-3ef303564392)]
+[scriptable, uuid(4c087cc3-e0cc-4ec3-88df-8d68f3023b45)]
 interface nsIScriptSecurityManager : nsIXPCSecurityManager
 {
     /**
      * Check that the script currently running in context "cx" can load "uri".
      *
      * Will return error code NS_ERROR_DOM_BAD_URI if the load request
      * should be denied.
      *
@@ -146,21 +146,16 @@ interface nsIScriptSecurityManager : nsI
     /**
      * Legacy name for getNoAppCodebasePrincipal.
      *
      * @deprecated use getNoAppCodebasePrincipal instead.
      */
     [deprecated] nsIPrincipal getCodebasePrincipal(in nsIURI uri);
 
     /**
-     * Return the principal of the specified object in the specified context.
-     */
-    [implicit_jscontext] nsIPrincipal getObjectPrincipal(in jsval aObject);
-
-    /**
      * Returns true if the principal of the currently running script is the
      * system principal, false otherwise.
      */
     [noscript] boolean subjectPrincipalIsSystem();
 
     /**
      * Returns OK if aJSContext and target have the same "origin"
      * (scheme, host, and port).
--- a/caps/src/nsScriptSecurityManager.cpp
+++ b/caps/src/nsScriptSecurityManager.cpp
@@ -1113,28 +1113,16 @@ nsScriptSecurityManager::GetSubjectPrinc
     // The context should always be in a compartment, either one it has entered
     // or the one associated with its global.
     MOZ_ASSERT(!!compartment);
 
     JSPrincipals *principals = JS_GetCompartmentPrincipals(compartment);
     return nsJSPrincipals::get(principals);
 }
 
-NS_IMETHODIMP
-nsScriptSecurityManager::GetObjectPrincipal(JS::Handle<JS::Value> aObjectVal,
-                                            JSContext *aCx,
-                                            nsIPrincipal **result)
-{
-    NS_ENSURE_TRUE(aObjectVal.isObject(), NS_ERROR_FAILURE);
-    JS::RootedObject obj(aCx, &aObjectVal.toObject());
-    nsCOMPtr<nsIPrincipal> principal = doGetObjectPrincipal(obj);
-    principal.forget(result);
-    return NS_OK;
-}
-
 // static
 nsIPrincipal*
 nsScriptSecurityManager::doGetObjectPrincipal(JSObject *aObj)
 {
     JSCompartment *compartment = js::GetObjectCompartment(aObj);
     JSPrincipals *principals = JS_GetCompartmentPrincipals(compartment);
     return nsJSPrincipals::get(principals);
 }
--- a/js/xpconnect/idl/xpccomponents.idl
+++ b/js/xpconnect/idl/xpccomponents.idl
@@ -116,17 +116,17 @@ interface nsIXPCComponents_utils_Sandbox
 interface ScheduledGCCallback : nsISupports
 {
     void callback();
 };
 
 /**
 * interface of Components.utils
 */
-[scriptable, uuid(5e253a02-f91f-4fb3-9335-db0fca23f2e0)]
+[scriptable, uuid(45b80e00-fb0d-439e-b7bf-54f24af0c4a6)]
 interface nsIXPCComponents_Utils : nsISupports
 {
 
     /* reportError is designed to be called from JavaScript only.
      *
      * It will report a JS Error object to the JS console, and return. It
      * is meant for use in exception handler blocks which want to "eat"
      * an exception, but still want to report it to the console.
@@ -563,16 +563,23 @@ interface nsIXPCComponents_Utils : nsISu
      *
      * Hence the notion of the "WebIDL Caller". If the current Entry Script on
      * the Script Settings Stack represents the invocation of JS-implemented
      * WebIDL, this API returns the principal of the caller at the time
      * of invocation. Otherwise (i.e. outside of JS-implemented WebIDL), this
      * function throws. If it throws, you probably shouldn't be using it.
      */
     nsIPrincipal getWebIDLCallerPrincipal();
+
+    /*
+     * Gets the principal of a script object, after unwrapping any cross-
+     * compartment wrappers.
+     */
+    [implicit_jscontext]
+    nsIPrincipal getObjectPrincipal(in jsval obj);
 };
 
 /**
 * Interface for the 'Components' object.
 *
 * The first interface contains things that are available to non-chrome XBL code
 * that runs in a scope with an nsExpandedPrincipal. The second interface
 * includes members that are only exposed to chrome.
--- a/js/xpconnect/src/XPCComponents.cpp
+++ b/js/xpconnect/src/XPCComponents.cpp
@@ -3252,33 +3252,33 @@ nsXPCComponents_Utils::NukeSandbox(Handl
 NS_IMETHODIMP
 nsXPCComponents_Utils::BlockScriptForGlobal(HandleValue globalArg,
                                             JSContext *cx)
 {
     NS_ENSURE_TRUE(globalArg.isObject(), NS_ERROR_INVALID_ARG);
     RootedObject global(cx, UncheckedUnwrap(&globalArg.toObject(),
                                             /* stopAtOuter = */ false));
     NS_ENSURE_TRUE(JS_IsGlobalObject(global), NS_ERROR_INVALID_ARG);
-    if (nsContentUtils::IsSystemPrincipal(GetObjectPrincipal(global))) {
+    if (nsContentUtils::IsSystemPrincipal(xpc::GetObjectPrincipal(global))) {
         JS_ReportError(cx, "Script may not be disabled for system globals");
         return NS_ERROR_FAILURE;
     }
     Scriptability::Get(global).Block();
     return NS_OK;
 }
 
 NS_IMETHODIMP
 nsXPCComponents_Utils::UnblockScriptForGlobal(HandleValue globalArg,
                                               JSContext *cx)
 {
     NS_ENSURE_TRUE(globalArg.isObject(), NS_ERROR_INVALID_ARG);
     RootedObject global(cx, UncheckedUnwrap(&globalArg.toObject(),
                                             /* stopAtOuter = */ false));
     NS_ENSURE_TRUE(JS_IsGlobalObject(global), NS_ERROR_INVALID_ARG);
-    if (nsContentUtils::IsSystemPrincipal(GetObjectPrincipal(global))) {
+    if (nsContentUtils::IsSystemPrincipal(xpc::GetObjectPrincipal(global))) {
         JS_ReportError(cx, "Script may not be disabled for system globals");
         return NS_ERROR_FAILURE;
     }
     Scriptability::Get(global).Unblock();
     return NS_OK;
 }
 
 NS_IMETHODIMP
@@ -3611,16 +3611,31 @@ nsXPCComponents_Utils::GetWebIDLCallerPr
     // and we throw.
     nsCOMPtr<nsIPrincipal> callerPrin = mozilla::dom::GetWebIDLCallerPrincipal();
     if (!callerPrin)
         return NS_ERROR_NOT_AVAILABLE;
     callerPrin.forget(aResult);
     return NS_OK;
 }
 
+NS_IMETHODIMP
+nsXPCComponents_Utils::GetObjectPrincipal(HandleValue val, JSContext *cx,
+                                          nsIPrincipal **result)
+{
+    if (!val.isObject())
+        return NS_ERROR_INVALID_ARG;
+    RootedObject obj(cx, &val.toObject());
+    obj = js::CheckedUnwrap(obj);
+    MOZ_ASSERT(obj);
+
+    nsCOMPtr<nsIPrincipal> prin = nsContentUtils::GetObjectPrincipal(obj);
+    prin.forget(result);
+    return NS_OK;
+}
+
 /***************************************************************************/
 /***************************************************************************/
 /***************************************************************************/
 
 
 nsXPCComponentsBase::nsXPCComponentsBase(XPCWrappedNativeScope* aScope)
     :   mScope(aScope)
 {
--- a/js/xpconnect/tests/unit/test_getObjectPrincipal.js
+++ b/js/xpconnect/tests/unit/test_getObjectPrincipal.js
@@ -1,6 +1,11 @@
+const Cc = Components.classes;
+const Ci = Components.interfaces;
+const Cu = Components.utils;
+
 function run_test() {
-  var secMan = Components.classes["@mozilla.org/scriptsecuritymanager;1"].getService(
-    Components.interfaces.nsIScriptSecurityManager);
-
-  do_check_true(secMan.isSystemPrincipal(secMan.getObjectPrincipal({})));
+  var secMan = Cc["@mozilla.org/scriptsecuritymanager;1"].getService(Ci.nsIScriptSecurityManager);
+  do_check_true(secMan.isSystemPrincipal(Cu.getObjectPrincipal({})));
+  var sb = new Cu.Sandbox('http://www.example.com');
+  Cu.evalInSandbox('var obj = { foo: 42 };', sb);
+  do_check_eq(Cu.getObjectPrincipal(sb.obj).origin, 'http://www.example.com');
 }
--- a/toolkit/devtools/DevToolsUtils.js
+++ b/toolkit/devtools/DevToolsUtils.js
@@ -290,17 +290,17 @@ exports.hasSafeGetter = function hasSafe
  *         True if it is safe to read properties from aObj, or false otherwise.
  */
 exports.isSafeJSObject = function isSafeJSObject(aObj) {
   if (Cu.getGlobalForObject(aObj) ==
       Cu.getGlobalForObject(exports.isSafeJSObject)) {
     return true; // aObj is not a cross-compartment wrapper.
   }
 
-  let principal = Services.scriptSecurityManager.getObjectPrincipal(aObj);
+  let principal = Cu.getObjectPrincipal(aObj);
   if (Services.scriptSecurityManager.isSystemPrincipal(principal)) {
     return true; // allow chrome objects
   }
 
   return Cu.isXrayWrapper(aObj);
 };
 
 exports.dumpn = function dumpn(str) {