Bug 1273251: Part 6 - Test that extension window wrappers are nuked on close. r=billm
authorKris Maglione <maglione.k@gmail.com>
Thu, 17 Nov 2016 12:44:30 -0800
changeset 375055 00519f64027bb8dabf6da2e08c8956eee0fe1d20
parent 375054 d406d6d99be9294f04ee0f7090e8b93f6f882a96
child 375056 8e9b98f6319257c65bfab9974516a13e22032203
push id6996
push userjlorenzo@mozilla.com
push dateMon, 06 Mar 2017 20:48:21 +0000
treeherdermozilla-beta@d89512dab048 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersbillm
bugs1273251
milestone53.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 1273251: Part 6 - Test that extension window wrappers are nuked on close. r=billm MozReview-Commit-ID: 3sWNuLqZBzp
js/xpconnect/tests/unit/test_nuke_webextension_wrappers.js
js/xpconnect/tests/unit/xpcshell.ini
new file mode 100644
--- /dev/null
+++ b/js/xpconnect/tests/unit/test_nuke_webextension_wrappers.js
@@ -0,0 +1,75 @@
+// See https://bugzilla.mozilla.org/show_bug.cgi?id=1273251
+
+const {classes: Cc, interfaces: Ci, utils: Cu, results: Cr} = Components;
+
+Cu.import("resource://gre/modules/Services.jsm");
+Cu.import("resource://gre/modules/NetUtil.jsm");
+Cu.import("resource://gre/modules/Timer.jsm");
+
+function promiseEvent(target, event) {
+  return new Promise(resolve => {
+    target.addEventListener(event, resolve, {capture: true, once: true});
+  });
+}
+
+let aps = Cc["@mozilla.org/addons/policy-service;1"].getService(Ci.nsIAddonPolicyService).wrappedJSObject;
+
+let oldAddonIdCallback = aps.setExtensionURIToAddonIdCallback(uri => uri.host);
+do_register_cleanup(() => {
+  aps.setExtensionURIToAddonIdCallback(oldAddonIdCallback);
+});
+
+function getWindowlessBrowser(url) {
+  let ssm = Services.scriptSecurityManager;
+
+  let uri = NetUtil.newURI(url);
+  // TODO: Remove when addonId origin attribute is removed.
+  let attrs = {addonId: uri.host};
+
+  let principal = ssm.createCodebasePrincipal(uri, attrs);
+
+  let webnav = Services.appShell.createWindowlessBrowser(false);
+
+  let docShell = webnav.QueryInterface(Ci.nsIInterfaceRequestor)
+                       .getInterface(Ci.nsIDocShell);
+
+  docShell.createAboutBlankContentViewer(principal);
+
+  return webnav;
+}
+
+add_task(function*() {
+  let ssm = Services.scriptSecurityManager;
+
+  let webnavA = getWindowlessBrowser("moz-extension://foo/a.html");
+  let webnavB = getWindowlessBrowser("moz-extension://foo/b.html");
+
+  let winA = Cu.waiveXrays(webnavA.document.defaultView);
+  let winB = Cu.waiveXrays(webnavB.document.defaultView);
+
+  winB.winA = winA;
+  winB.eval(`winA.thing = {foo: "bar"};`);
+
+  let getThing = winA.eval(String(() => {
+    try {
+      return thing.foo;
+    } catch (e) {
+      return String(e);
+    }
+  }));
+
+  // Check that the object can be accessed normally before windowB is closed.
+  equal(getThing(), "bar");
+
+  webnavB.close();
+
+  // Wrappers are nuked asynchronously, so wait a tick.
+  yield new Promise(resolve => setTimeout(resolve, 0));
+
+  // Check that it can't be accessed after he window has been closed.
+  let result = getThing();
+  ok(/dead object/.test(result),
+     `Result should show a dead wrapper error: ${result}`);
+
+  webnavA.close();
+});
--- a/js/xpconnect/tests/unit/xpcshell.ini
+++ b/js/xpconnect/tests/unit/xpcshell.ini
@@ -93,16 +93,17 @@ fail-if = os == "android"
 [test_params.js]
 [test_tearoffs.js]
 [test_want_components.js]
 [test_components.js]
 [test_allowedDomains.js]
 [test_allowedDomainsXHR.js]
 [test_nuke_sandbox.js]
 [test_nuke_sandbox_event_listeners.js]
+[test_nuke_webextension_wrappers.js]
 [test_sandbox_metadata.js]
 [test_exportFunction.js]
 [test_promise.js]
 [test_returncode.js]
 [test_textDecoder.js]
 [test_url.js]
 [test_URLSearchParams.js]
 [test_fileReader.js]