test_nuke_webextension_wrappers.js (1847B)
1 // See https://bugzilla.mozilla.org/show_bug.cgi?id=1273251 2 3 const {NetUtil} = ChromeUtils.importESModule("resource://gre/modules/NetUtil.sys.mjs"); 4 const {TestUtils} = ChromeUtils.importESModule("resource://testing-common/TestUtils.sys.mjs"); 5 6 function getWindowlessBrowser(url) { 7 let ssm = Services.scriptSecurityManager; 8 9 let uri = NetUtil.newURI(url); 10 11 let principal = ssm.createContentPrincipal(uri, {}); 12 13 let webnav = Services.appShell.createWindowlessBrowser(false); 14 15 let docShell = webnav.docShell; 16 17 docShell.createAboutBlankDocumentViewer(principal, principal); 18 19 return webnav; 20 } 21 22 function StubPolicy(id) { 23 return new WebExtensionPolicy({ 24 id, 25 mozExtensionHostname: id, 26 baseURL: `file:///{id}`, 27 28 allowedOrigins: new MatchPatternSet([]), 29 localizeCallback(string) {}, 30 }); 31 } 32 33 add_task(async function() { 34 let policy = StubPolicy("foo"); 35 policy.active = true; 36 37 let webnavA = getWindowlessBrowser("moz-extension://foo/a.html"); 38 let webnavB = getWindowlessBrowser("moz-extension://foo/b.html"); 39 40 let winA = Cu.waiveXrays(webnavA.document.defaultView); 41 let winB = Cu.waiveXrays(webnavB.document.defaultView); 42 43 winB.winA = winA; 44 winB.eval(`winA.thing = {foo: "bar"};`); 45 46 let getThing = winA.eval(String(() => { 47 try { 48 return thing.foo; 49 } catch (e) { 50 return String(e); 51 } 52 })); 53 54 // Check that the object can be accessed normally before windowB is closed. 55 equal(getThing(), "bar"); 56 57 webnavB.close(); 58 59 // Wrappers are nuked asynchronously, so wait for that to happen. 60 await TestUtils.topicObserved("inner-window-nuked"); 61 62 // Check that it can't be accessed after he window has been closed. 63 let result = getThing(); 64 ok(/dead object/.test(result), 65 `Result should show a dead wrapper error: ${result}`); 66 67 webnavA.close(); 68 69 policy.active = false; 70 });