Bug 1276738 - Ensure that .open() on web content called with chrome privileges results in a new window with the appropriate principal. r=Gijs
☠☠ backed out by 59583eadba52 ☠ ☠
authorMike Conley <mconley@mozilla.com>
Mon, 02 May 2016 17:36:12 -0400
changeset 341036 ea2da46bde0a4a3039d69e198ad40afefc92a5ec
parent 341035 1a7d17e9e15d84f22d56a056cb48c28b3ba23c7b
child 341037 0ac161595496d7605cf4aae0282c1451484fea91
push id1183
push userraliiev@mozilla.com
push dateMon, 05 Sep 2016 20:01:49 +0000
treeherdermozilla-release@3148731bed45 [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.
    *