Bug 1276738 - Ensure that .open() on web content called with chrome privileges results in a new window with the appropriate principal. r=Gijs
authorMike Conley <mconley@mozilla.com>
Mon, 02 May 2016 17:36:12 -0400
changeset 339208 e5abd4c6319dc6296fa322cac1c4e0f853ae6757
parent 339207 c66723bf292698444a723269dca9c9bb58ab3d21
child 339209 0997a7d078e2ee01436c24a22cc894589a57f3f8
push id6249
push userjlund@mozilla.com
push dateMon, 01 Aug 2016 13:59:36 +0000
treeherdermozilla-beta@bad9d4f5bf7e [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersGijs
bugs1276738
milestone49.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 1276738 - Ensure that .open() on web content called with chrome privileges results in a new window with the appropriate principal. r=Gijs MozReview-Commit-ID: IG9ioQLTI78
embedding/components/windowwatcher/test/browser.ini
embedding/components/windowwatcher/test/browser_new_content_window_from_chrome_principal.js
testing/mochitest/BrowserTestUtils/BrowserTestUtils.jsm
--- a/embedding/components/windowwatcher/test/browser.ini
+++ b/embedding/components/windowwatcher/test/browser.ini
@@ -1,7 +1,8 @@
 [DEFAULT]
 tags = openwindow
 
 [browser_new_remote_window_flags.js]
 run-if = e10s
+[browser_new_content_window_from_chrome_principal.js]
 [browser_new_sized_window.js]
 skip-if = os == 'win' # Bug 1276802 - Opening windows from content on Windows might not get the size right
new file mode 100644
--- /dev/null
+++ b/embedding/components/windowwatcher/test/browser_new_content_window_from_chrome_principal.js
@@ -0,0 +1,34 @@
+"use strict";
+
+/**
+ * Tests that if chrome-privileged code calls .open() on an
+ * unprivileged window, that the principal in the newly
+ * opened window is appropriately set.
+ */
+add_task(function* test_chrome_opens_window() {
+  // This magic value of 2 means that by default, when content tries
+  // to open a new window, it'll actually open in a new window instead
+  // of a new tab.
+  yield SpecialPowers.pushPrefEnv({"set": [
+    ["browser.link.open_newwindow", 2],
+  ]});
+
+  let newWinPromise = BrowserTestUtils.waitForNewWindow(true, "http://example.com/");
+
+  yield ContentTask.spawn(gBrowser.selectedBrowser, null, function*() {
+    content.open("http://example.com/", "_blank");
+  });
+
+  let win = yield newWinPromise;
+  let browser = win.gBrowser.selectedBrowser;
+
+  yield ContentTask.spawn(browser, null, function*() {
+    Assert.ok(!content.document.nodePrincipal.isSystemPrincipal,
+              "We should not have a system principal.")
+    Assert.equal(content.document.nodePrincipal.origin,
+                 "http://example.com",
+                 "Should have the example.com principal");
+  });
+
+  yield BrowserTestUtils.closeWindow(win);
+});
\ No newline at end of file
--- a/testing/mochitest/BrowserTestUtils/BrowserTestUtils.jsm
+++ b/testing/mochitest/BrowserTestUtils/BrowserTestUtils.jsm
@@ -274,25 +274,57 @@ this.BrowserTestUtils = {
 
       });
     });
   },
 
   /**
    * Waits for the next browser window to open and be fully loaded.
    *
+   * @param {bool} delayedStartup (optional)
+   *        Whether or not to wait for the browser-delayed-startup-finished
+   *        observer notification before resolving. Defaults to true.
+   * @param {string} initialBrowserLoaded (optional)
+   *        If set, we will wait until the initial browser in the new
+   *        window has loaded a particular page. If unset, the initial
+   *        browser may or may not have finished loading its first page
+   *        when the resulting Promise resolves.
    * @return {Promise}
    *         A Promise which resolves the next time that a DOM window
    *         opens and the delayed startup observer notification fires.
    */
-  waitForNewWindow: Task.async(function* (delayedStartup=true) {
+  waitForNewWindow: Task.async(function* (delayedStartup=true,
+                                          initialBrowserLoaded=null) {
     let win = yield this.domWindowOpened();
 
-    yield TestUtils.topicObserved("browser-delayed-startup-finished",
-                                   subject => subject == win);
+    let promises = [
+      TestUtils.topicObserved("browser-delayed-startup-finished",
+                              subject => subject == win),
+    ];
+
+    if (initialBrowserLoaded) {
+      yield this.waitForEvent(win, "DOMContentLoaded");
+
+      let browser = win.gBrowser.selectedBrowser;
+
+      // Retrieve the given browser's current process type.
+      let process =
+        browser.isRemoteBrowser ? Ci.nsIXULRuntime.PROCESS_TYPE_CONTENT
+                                : Ci.nsIXULRuntime.PROCESS_TYPE_DEFAULT;
+      if (win.gMultiProcessBrowser &&
+          !E10SUtils.canLoadURIInProcess(initialBrowserLoaded, process)) {
+        yield this.waitForEvent(browser, "XULFrameLoaderCreated");
+      }
+
+      let loadPromise = this.browserLoaded(browser, false, initialBrowserLoaded);
+      promises.push(loadPromise);
+    }
+
+    yield Promise.all(promises);
+
     return win;
   }),
 
   /**
    * Loads a new URI in the given browser and waits until we really started
    * loading. In e10s browser.loadURI() can be an asynchronous operation due
    * to having to switch the browser's remoteness and keep its shistory data.
    *