diff options
author | Daniel Baumann <daniel.baumann@progress-linux.org> | 2024-04-07 17:32:43 +0000 |
---|---|---|
committer | Daniel Baumann <daniel.baumann@progress-linux.org> | 2024-04-07 17:32:43 +0000 |
commit | 6bf0a5cb5034a7e684dcc3500e841785237ce2dd (patch) | |
tree | a68f146d7fa01f0134297619fbe7e33db084e0aa /toolkit/components/extensions/test/xpcshell/test_ext_web_accessible_resources.js | |
parent | Initial commit. (diff) | |
download | thunderbird-6bf0a5cb5034a7e684dcc3500e841785237ce2dd.tar.xz thunderbird-6bf0a5cb5034a7e684dcc3500e841785237ce2dd.zip |
Adding upstream version 1:115.7.0.upstream/1%115.7.0upstream
Signed-off-by: Daniel Baumann <daniel.baumann@progress-linux.org>
Diffstat (limited to 'toolkit/components/extensions/test/xpcshell/test_ext_web_accessible_resources.js')
-rw-r--r-- | toolkit/components/extensions/test/xpcshell/test_ext_web_accessible_resources.js | 148 |
1 files changed, 148 insertions, 0 deletions
diff --git a/toolkit/components/extensions/test/xpcshell/test_ext_web_accessible_resources.js b/toolkit/components/extensions/test/xpcshell/test_ext_web_accessible_resources.js new file mode 100644 index 0000000000..0b34dd8127 --- /dev/null +++ b/toolkit/components/extensions/test/xpcshell/test_ext_web_accessible_resources.js @@ -0,0 +1,148 @@ +"use strict"; + +const server = createHttpServer({ hosts: ["example.com", "example.org"] }); +server.registerDirectory("/data/", do_get_file("data")); + +let image = atob( + "iVBORw0KGgoAAAANSUhEUgAAAAEAAAABAQMAAAAl21bKAAAAA1BMVEUAA" + + "ACnej3aAAAAAXRSTlMAQObYZgAAAApJREFUCNdjYAAAAAIAAeIhvDMAAAAASUVORK5CYII=" +); +const IMAGE_ARRAYBUFFER = Uint8Array.from(image, byte => + byte.charCodeAt(0) +).buffer; + +async function testImageLoading(src, expectedAction) { + let imageLoadingPromise = new Promise((resolve, reject) => { + let cleanupListeners; + let testImage = document.createElement("img"); + // Set the src via wrappedJSObject so the load is triggered with the + // content page's principal rather than ours. + testImage.wrappedJSObject.setAttribute("src", src); + + let loadListener = () => { + cleanupListeners(); + resolve(expectedAction === "loaded"); + }; + + let errorListener = () => { + cleanupListeners(); + resolve(expectedAction === "blocked"); + }; + + cleanupListeners = () => { + testImage.removeEventListener("load", loadListener); + testImage.removeEventListener("error", errorListener); + }; + + testImage.addEventListener("load", loadListener); + testImage.addEventListener("error", errorListener); + + document.body.appendChild(testImage); + }); + + let success = await imageLoadingPromise; + browser.runtime.sendMessage({ + name: "image-loading", + expectedAction, + success, + }); +} + +add_task(async function test_web_accessible_resources_csp() { + function background() { + browser.runtime.onMessage.addListener((msg, sender) => { + if (msg.name === "image-loading") { + browser.test.assertTrue(msg.success, `Image was ${msg.expectedAction}`); + browser.test.sendMessage(`image-${msg.expectedAction}`); + } else { + browser.test.sendMessage(msg); + } + }); + + browser.test.sendMessage("background-ready"); + } + + function content() { + window.addEventListener("message", function rcv(event) { + browser.runtime.sendMessage("script-ran"); + window.removeEventListener("message", rcv); + }); + + testImageLoading(browser.runtime.getURL("image.png"), "loaded"); + + let testScriptElement = document.createElement("script"); + // Set the src via wrappedJSObject so the load is triggered with the + // content page's principal rather than ours. + testScriptElement.wrappedJSObject.setAttribute( + "src", + browser.runtime.getURL("test_script.js") + ); + document.head.appendChild(testScriptElement); + browser.runtime.sendMessage("script-loaded"); + } + + function testScript() { + window.postMessage("test-script-loaded", "*"); + } + + let extension = ExtensionTestUtils.loadExtension({ + manifest: { + content_scripts: [ + { + matches: ["http://example.com/*/file_csp.html"], + run_at: "document_end", + js: ["content_script_helper.js", "content_script.js"], + }, + ], + web_accessible_resources: ["image.png", "test_script.js"], + }, + background, + files: { + "content_script_helper.js": `${testImageLoading}`, + "content_script.js": content, + "test_script.js": testScript, + "image.png": IMAGE_ARRAYBUFFER, + }, + }); + + await Promise.all([ + extension.startup(), + extension.awaitMessage("background-ready"), + ]); + + let page = await ExtensionTestUtils.loadContentPage( + `http://example.com/data/file_sample.html` + ); + await page.legacySpawn(null, () => { + this.obs = { + events: [], + observe(subject, topic, data) { + this.events.push(subject.QueryInterface(Ci.nsIURI).spec); + }, + done() { + Services.obs.removeObserver(this, "csp-on-violate-policy"); + return this.events; + }, + }; + Services.obs.addObserver(this.obs, "csp-on-violate-policy"); + content.location.href = "http://example.com/data/file_csp.html"; + }); + + await Promise.all([ + extension.awaitMessage("image-loaded"), + extension.awaitMessage("script-loaded"), + extension.awaitMessage("script-ran"), + ]); + + let events = await page.legacySpawn(null, () => this.obs.done()); + equal(events.length, 2, "Two items were rejected by CSP"); + for (let url of events) { + ok( + url.includes("file_image_bad.png") || url.includes("file_script_bad.js"), + `Expected file: ${url} rejected by CSP` + ); + } + + await page.close(); + await extension.unload(); +}); |