Bug 1431533: Part 3 - Define ChromeUtils on chrome-privileged Sandboxes that need it. r?mixedpuppy draft
authorKris Maglione <maglione.k@gmail.com>
Thu, 18 Jan 2018 14:52:39 -0800
changeset 723882 f01a298948f94b79447ef0b525c91774ee84b9f3
parent 723881 9d054457dd2fed77b506fbbd98f1666887713ae8
child 723883 e6571b91f68022653889e8bdf7da7a9e3bb24367
push id96567
push usermaglione.k@gmail.com
push dateWed, 24 Jan 2018 00:47:30 +0000
reviewersmixedpuppy
bugs1431533
milestone59.0a1
Bug 1431533: Part 3 - Define ChromeUtils on chrome-privileged Sandboxes that need it. r?mixedpuppy This is necessary before we enable the ESLint rule to require using ChromeUtils for module imports rather than older methods. MozReview-Commit-ID: mKqByUS0o2
testing/mochitest/tests/Harness_sanity/test_SpecialPowersLoadChromeScript.html
testing/specialpowers/content/SpecialPowersObserverAPI.js
toolkit/components/extensions/ExtensionCommon.jsm
toolkit/mozapps/extensions/internal/XPIProvider.jsm
--- a/testing/mochitest/tests/Harness_sanity/test_SpecialPowersLoadChromeScript.html
+++ b/testing/mochitest/tests/Harness_sanity/test_SpecialPowersLoadChromeScript.html
@@ -35,17 +35,17 @@ function endOfFirstTest() {
   // wantGlobalProperties should add the specified properties to the sandbox
   // that is used to run the chrome script.
   script2 = SpecialPowers.loadChromeScript(_ => {
     addMessageListener("valid-assert", function (message) {
       assert.equal(typeof XMLHttpRequest, "function", "XMLHttpRequest is defined");
       assert.equal(typeof CSS, "undefined", "CSS is not defined");
       sendAsyncMessage("valid-assert-done");
     });
-  }, { wantGlobalProperties: ["XMLHttpRequest"] });
+  }, { wantGlobalProperties: ["ChromeUtils", "XMLHttpRequest"] });
 
   script2.sendAsyncMessage("valid-assert");
   script2.addMessageListener("valid-assert-done", endOfTest);
 
 }
 
 function endOfTest() {
   script2.destroy();
--- a/testing/specialpowers/content/SpecialPowersObserverAPI.js
+++ b/testing/specialpowers/content/SpecialPowersObserverAPI.js
@@ -480,20 +480,18 @@ SpecialPowersObserverAPI.prototype = {
         } else {
           throw new SpecialPowersError("SPLoadChromeScript: Invalid script");
         }
 
         // Setup a chrome sandbox that has access to sendAsyncMessage
         // and addMessageListener in order to communicate with
         // the mochitest.
         let systemPrincipal = Services.scriptSecurityManager.getSystemPrincipal();
-        let sandboxOptions = aMessage.json.sandboxOptions;
-        if (!sandboxOptions) {
-          sandboxOptions = {};
-        }
+        let sandboxOptions = Object.assign({wantGlobalProperties: ["ChromeUtils"]},
+                                           aMessage.json.sandboxOptions);
         let sb = Components.utils.Sandbox(systemPrincipal, sandboxOptions);
         let mm = aMessage.target.frameLoader
                          .messageManager;
         sb.sendAsyncMessage = (name, message) => {
           mm.sendAsyncMessage("SPChromeScriptMessage",
                               { id, name, message });
         };
         sb.addMessageListener = (name, listener) => {
--- a/toolkit/components/extensions/ExtensionCommon.jsm
+++ b/toolkit/components/extensions/ExtensionCommon.jsm
@@ -131,16 +131,17 @@ var ExtensionAPIs = {
 
     let {script, schema} = api;
 
     let addonId = `${apiName}@experiments.addons.mozilla.org`;
     api.sandbox = Cu.Sandbox(global, {
       wantXrays: false,
       sandboxName: script,
       addonId,
+      wantGlobalProperties: ["ChromeUtils"],
       metadata: {addonID: addonId},
     });
 
     api.sandbox.ExtensionAPI = ExtensionAPI;
 
     // Create a console getter which lazily provide a ConsoleAPI instance.
     XPCOMUtils.defineLazyGetter(api.sandbox, "console", () => {
       return new ConsoleAPI({prefix: addonId});
@@ -1321,22 +1322,22 @@ class SchemaAPIManager extends EventEmit
    * Create a global object that is used as the shared global for all ext-*.js
    * scripts that are loaded via `loadScript`.
    *
    * @returns {object} A sandbox that is used as the global by `loadScript`.
    */
   _createExtGlobal() {
     let global = Cu.Sandbox(Services.scriptSecurityManager.getSystemPrincipal(), {
       wantXrays: false,
+      wantGlobalProperties: ["ChromeUtils"],
       sandboxName: `Namespace of ext-*.js scripts for ${this.processType} (from: resource://gre/modules/ExtensionCommon.jsm)`,
     });
 
     Object.assign(global, {
       Cc,
-      ChromeUtils,
       ChromeWorker,
       Ci,
       Cr,
       Cu,
       ExtensionAPI,
       ExtensionCommon,
       MatchGlob,
       MatchPattern,
--- a/toolkit/mozapps/extensions/internal/XPIProvider.jsm
+++ b/toolkit/mozapps/extensions/internal/XPIProvider.jsm
@@ -295,17 +295,17 @@ XPCOMUtils.defineLazyGetter(this, "gStar
 
   return Services.prefs.getIntPref(PREF_EM_STARTUP_SCAN_SCOPES, 0);
 });
 
 function loadLazyObjects() {
   let uri = "resource://gre/modules/addons/XPIProviderUtils.js";
   let scope = Cu.Sandbox(Services.scriptSecurityManager.getSystemPrincipal(), {
     sandboxName: uri,
-    wantGlobalProperties: ["TextDecoder"],
+    wantGlobalProperties: ["ChromeUtils", "TextDecoder"],
   });
 
   Object.assign(scope, {
     ADDON_SIGNING: AddonSettings.ADDON_SIGNING,
     SIGNED_TYPES,
     BOOTSTRAP_REASONS,
     DB_SCHEMA,
     AddonInternal,
@@ -4232,16 +4232,17 @@ this.XPIProvider = {
       }
       Cu.allowCPOWsInAddon(aId, true);
     }
 
     if (!aFile.exists()) {
       activeAddon.bootstrapScope =
         new Cu.Sandbox(principal, { sandboxName: aFile.path,
                                     addonId: aId,
+                                    wantGlobalProperties: ["ChromeUtils"],
                                     metadata: { addonID: aId } });
       logger.error("Attempted to load bootstrap scope from missing directory " + aFile.path);
       return;
     }
 
     if (isWebExtension(aType)) {
       activeAddon.bootstrapScope = Extension.getBootstrapScope(aId, aFile);
     } else if (aType === "webextension-langpack") {
@@ -4251,16 +4252,17 @@ this.XPIProvider = {
       if (aType == "dictionary")
         uri = "resource://gre/modules/addons/SpellCheckDictionaryBootstrap.js";
       else if (aType == "apiextension")
         uri = "resource://gre/modules/addons/APIExtensionBootstrap.js";
 
       activeAddon.bootstrapScope =
         new Cu.Sandbox(principal, { sandboxName: uri,
                                     addonId: aId,
+                                    wantGlobalProperties: ["ChromeUtils"],
                                     metadata: { addonID: aId, URI: uri } });
 
       try {
         // Copy the reason values from the global object into the bootstrap scope.
         for (let name in BOOTSTRAP_REASONS)
           activeAddon.bootstrapScope[name] = BOOTSTRAP_REASONS[name];
 
         // Add other stuff that extensions want.