From 26a029d407be480d791972afb5975cf62c9360a6 Mon Sep 17 00:00:00 2001 From: Daniel Baumann Date: Fri, 19 Apr 2024 02:47:55 +0200 Subject: Adding upstream version 124.0.1. Signed-off-by: Daniel Baumann --- .../test_ext_web_accessible_resources_matches.js | 546 +++++++++++++++++++++ 1 file changed, 546 insertions(+) create mode 100644 toolkit/components/extensions/test/xpcshell/test_ext_web_accessible_resources_matches.js (limited to 'toolkit/components/extensions/test/xpcshell/test_ext_web_accessible_resources_matches.js') diff --git a/toolkit/components/extensions/test/xpcshell/test_ext_web_accessible_resources_matches.js b/toolkit/components/extensions/test/xpcshell/test_ext_web_accessible_resources_matches.js new file mode 100644 index 0000000000..1cd5074780 --- /dev/null +++ b/toolkit/components/extensions/test/xpcshell/test_ext_web_accessible_resources_matches.js @@ -0,0 +1,546 @@ +"use strict"; + +Services.prefs.setBoolPref("extensions.manifestV3.enabled", true); + +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; + +add_task(async function test_web_accessible_resources_matching() { + let extension = ExtensionTestUtils.loadExtension({ + manifest: { + manifest_version: 3, + web_accessible_resources: [ + { + resources: ["/accessible.html"], + }, + ], + }, + }); + + await Assert.rejects( + extension.startup(), + /web_accessible_resources requires one of "matches" or "extension_ids"/, + "web_accessible_resources object format incorrect" + ); + + extension = ExtensionTestUtils.loadExtension({ + manifest: { + manifest_version: 3, + web_accessible_resources: [ + { + resources: ["/accessible.html"], + matches: ["http://example.com/data/*"], + }, + ], + }, + }); + + await extension.startup(); + ok(true, "web_accessible_resources with matches loads"); + await extension.unload(); + + extension = ExtensionTestUtils.loadExtension({ + manifest: { + manifest_version: 3, + web_accessible_resources: [ + { + resources: ["/accessible.html"], + extension_ids: ["foo@mochitest"], + }, + ], + }, + }); + + await extension.startup(); + ok(true, "web_accessible_resources with extensions loads"); + await extension.unload(); + + extension = ExtensionTestUtils.loadExtension({ + manifest: { + manifest_version: 3, + web_accessible_resources: [ + { + resources: ["/accessible.html"], + matches: ["http://example.com/data/*"], + extension_ids: ["foo@mochitest"], + }, + ], + }, + }); + + await extension.startup(); + ok(true, "web_accessible_resources with matches and extensions loads"); + await extension.unload(); + + extension = ExtensionTestUtils.loadExtension({ + manifest: { + manifest_version: 3, + web_accessible_resources: [ + { + resources: ["/accessible.html"], + extension_ids: [], + }, + ], + }, + }); + + await extension.startup(); + ok(true, "web_accessible_resources with empty extensions loads"); + await extension.unload(); + + extension = ExtensionTestUtils.loadExtension({ + manifest: { + manifest_version: 3, + web_accessible_resources: [ + { + resources: ["/accessible.html"], + matches: ["http://example.com/data/*"], + extension_ids: [], + }, + ], + }, + }); + + await extension.startup(); + ok(true, "web_accessible_resources with matches and empty extensions loads"); + await extension.unload(); +}); + +add_task(async function test_web_accessible_resources() { + async function contentScript() { + let canLoad = window.location.href.startsWith("http://example.com"); + let urls = [ + { + name: "iframe", + path: "accessible.html", + shouldLoad: canLoad, + }, + { + name: "iframe", + path: "inaccessible.html", + shouldLoad: false, + }, + { + name: "img", + path: "image.png", + shouldLoad: true, + }, + { + name: "script", + path: "script.js", + shouldLoad: canLoad, + }, + ]; + + function test_element_src(name, url) { + return new Promise(resolve => { + let elem = document.createElement(name); + // Set the src via wrappedJSObject so the load is triggered with the + // content page's principal rather than ours. + elem.wrappedJSObject.setAttribute("src", url); + elem.addEventListener( + "load", + () => { + resolve(true); + }, + { once: true } + ); + elem.addEventListener( + "error", + () => { + resolve(false); + }, + { once: true } + ); + document.body.appendChild(elem); + }); + } + for (let test of urls) { + let loaded = await test_element_src( + test.name, + browser.runtime.getURL(test.path) + ); + browser.test.assertEq( + loaded, + test.shouldLoad, + `resource loaded ${test.path} in ${window.location.href}` + ); + } + browser.test.sendMessage("complete"); + } + + let extension = ExtensionTestUtils.loadExtension({ + manifest: { + manifest_version: 3, + content_scripts: [ + { + matches: ["http://example.com/data/*", "http://example.org/data/*"], + js: ["content_script.js"], + run_at: "document_idle", + }, + ], + host_permissions: ["http://example.com/*", "http://example.org/*"], + granted_host_permissions: true, + + web_accessible_resources: [ + { + resources: ["/accessible.html", "/script.js"], + matches: ["http://example.com/data/*"], + }, + { + resources: ["/image.png"], + matches: [""], + }, + ], + }, + temporarilyInstalled: true, + + files: { + "content_script.js": contentScript, + + "accessible.html": ` + + `, + + "inaccessible.html": ` + + `, + + "image.png": IMAGE_ARRAYBUFFER, + "script.js": () => { + // empty script + }, + }, + }); + + await extension.startup(); + + let page = await ExtensionTestUtils.loadContentPage( + "http://example.com/data/" + ); + + await extension.awaitMessage("complete"); + await page.close(); + + // None of the test resources are loadable in example.org + page = await ExtensionTestUtils.loadContentPage("http://example.org/data/"); + + await extension.awaitMessage("complete"); + + await page.close(); + await extension.unload(); +}); + +async function pageScript() { + function test_element_src(data) { + return new Promise(resolve => { + let elem = document.createElement(data.elem); + let elemContext = + data.content_context && elem.wrappedJSObject + ? elem.wrappedJSObject + : elem; + elemContext.setAttribute("src", data.url); + elem.addEventListener( + "load", + () => { + browser.test.log(`got load event for ${data.url}`); + resolve(true); + }, + { once: true } + ); + elem.addEventListener( + "error", + () => { + browser.test.log(`got error event for ${data.url}`); + resolve(false); + }, + { once: true } + ); + document.body.appendChild(elem); + }); + } + browser.test.onMessage.addListener(async msg => { + browser.test.log(`testing ${JSON.stringify(msg)}`); + let loaded = await test_element_src(msg); + browser.test.assertEq(loaded, msg.shouldLoad, `${msg.name} loaded`); + browser.test.sendMessage("web-accessible-resources"); + }); + browser.test.sendMessage("page-loaded"); +} + +add_task(async function test_web_accessible_resources_extensions() { + let other = ExtensionTestUtils.loadExtension({ + manifest: { + browser_specific_settings: { gecko: { id: "other@mochitest" } }, + }, + files: { + "page.js": pageScript, + + "page.html": ` + + + `, + }, + }); + + let extension = ExtensionTestUtils.loadExtension({ + manifest: { + manifest_version: 3, + browser_specific_settings: { gecko: { id: "this@mochitest" } }, + web_accessible_resources: [ + { + resources: ["/image.png"], + extension_ids: ["other@mochitest"], + }, + ], + }, + + files: { + "image.png": IMAGE_ARRAYBUFFER, + "inaccessible.png": IMAGE_ARRAYBUFFER, + "page.js": pageScript, + + "page.html": ` + + + `, + }, + }); + + await extension.startup(); + let extensionUrl = `moz-extension://${extension.uuid}/`; + + await other.startup(); + let pageUrl = `moz-extension://${other.uuid}/page.html`; + + let page = await ExtensionTestUtils.loadContentPage(pageUrl); + await other.awaitMessage("page-loaded"); + + other.sendMessage({ + name: "accessible resource", + elem: "img", + url: `${extensionUrl}image.png`, + shouldLoad: true, + }); + await other.awaitMessage("web-accessible-resources"); + + other.sendMessage({ + name: "inaccessible resource", + elem: "img", + url: `${extensionUrl}inaccessible.png`, + shouldLoad: false, + }); + await other.awaitMessage("web-accessible-resources"); + + await page.close(); + + // test that the extension may load it's own web accessible resource + page = await ExtensionTestUtils.loadContentPage(`${extensionUrl}page.html`); + await extension.awaitMessage("page-loaded"); + + extension.sendMessage({ + name: "accessible resource", + elem: "img", + url: `${extensionUrl}image.png`, + shouldLoad: true, + }); + await extension.awaitMessage("web-accessible-resources"); + + await page.close(); + await extension.unload(); + await other.unload(); +}); + +// test that a web page not in matches cannot load the resource +add_task(async function test_web_accessible_resources_inaccessible() { + let extension = ExtensionTestUtils.loadExtension({ + temporarilyInstalled: true, + manifest: { + manifest_version: 3, + browser_specific_settings: { gecko: { id: "web@mochitest" } }, + content_scripts: [ + { + matches: ["http://example.com/data/*"], + js: ["page.js"], + run_at: "document_idle", + }, + ], + web_accessible_resources: [ + { + resources: ["/image.png"], + extension_ids: ["some_other_ext@mochitest"], + }, + ], + host_permissions: ["*://example.com/*"], + granted_host_permissions: true, + }, + + files: { + "image.png": IMAGE_ARRAYBUFFER, + "page.js": pageScript, + + "page.html": ` + + + `, + }, + }); + + await extension.startup(); + let extensionUrl = `moz-extension://${extension.uuid}/`; + let page = await ExtensionTestUtils.loadContentPage( + "http://example.com/data/" + ); + await extension.awaitMessage("page-loaded"); + + extension.sendMessage({ + name: "cannot access resource", + elem: "img", + url: `${extensionUrl}image.png`, + content_context: true, + shouldLoad: false, + }); + await extension.awaitMessage("web-accessible-resources"); + + await page.close(); + await extension.unload(); +}); + +add_task(async function test_web_accessible_resources_empty_extension_ids() { + let extension = ExtensionTestUtils.loadExtension({ + manifest: { + manifest_version: 3, + web_accessible_resources: [ + { + resources: ["/file.txt"], + matches: ["http://example.com/data/*"], + extension_ids: [], + }, + ], + }, + + files: { + "file.txt": "some content", + }, + }); + let secondExtension = ExtensionTestUtils.loadExtension({ + files: { + "page.html": "", + }, + }); + + await extension.startup(); + await secondExtension.startup(); + + const fileURL = extension.extension.baseURI.resolve("file.txt"); + Assert.equal( + await ExtensionTestUtils.fetch("http://example.com/data/", fileURL), + "some content", + "expected access to the extension's resource" + ); + + await Assert.rejects( + ExtensionTestUtils.fetch( + secondExtension.extension.baseURI.resolve("page.html"), + fileURL + ), + e => e?.message === "NetworkError when attempting to fetch resource.", + "other extension should not be able to fetch when extension_ids is empty" + ); + + await extension.unload(); + await secondExtension.unload(); +}); + +add_task(async function test_web_accessible_resources_empty_array() { + let extension = ExtensionTestUtils.loadExtension({ + manifest: { + manifest_version: 3, + web_accessible_resources: [], + }, + }); + await extension.startup(); + ok(true, "empty web_accessible_resources loads"); + await extension.unload(); +}); + +add_task(async function test_web_accessible_resources_empty_resources() { + let extension = ExtensionTestUtils.loadExtension({ + manifest: { + manifest_version: 3, + web_accessible_resources: [{ resources: [], matches: ["*://*/*"] }], + }, + }); + await extension.startup(); + ok(true, "empty web_accessible_resources[0].resources loads"); + await extension.unload(); +}); + +add_task(async function test_web_accessible_resources_empty_everything() { + let extension = ExtensionTestUtils.loadExtension({ + manifest: { + manifest_version: 3, + web_accessible_resources: [ + { resources: [], matches: [], extension_ids: [] }, + ], + }, + }); + await extension.startup(); + ok(true, "empty resources, matches & extension_ids loads"); + await extension.unload(); +}); + +add_task(async function test_web_accessible_resources_empty_matches() { + let extension = ExtensionTestUtils.loadExtension({ + manifest: { + manifest_version: 3, + web_accessible_resources: [{ resources: ["file.txt"], matches: [] }], + }, + files: { + "file.txt": "some content", + }, + }); + await extension.startup(); + ok(true, "empty web_accessible_resources[0].matches loads"); + + const fileURL = extension.extension.baseURI.resolve("file.txt"); + await Assert.rejects( + ExtensionTestUtils.fetch("http://example.com", fileURL), + e => e?.message === "NetworkError when attempting to fetch resource.", + "empty matches[] = not web-accessible" + ); + await extension.unload(); +}); + +add_task(async function test_web_accessible_resources_unknown_property() { + let extension = ExtensionTestUtils.loadExtension({ + manifest: { + manifest_version: 3, + web_accessible_resources: [{ resources: [], matches: [], idk: null }], + }, + }); + + let { messages } = await promiseConsoleOutput(async () => { + ExtensionTestUtils.failOnSchemaWarnings(false); + await extension.startup(); + ExtensionTestUtils.failOnSchemaWarnings(true); + }); + + AddonTestUtils.checkMessages(messages, { + expected: [ + { + message: + /Reading manifest: Warning processing web_accessible_resources.0.idk: An unexpected property was found in the WebExtension manifest./, + }, + ], + }); + await extension.unload(); +}); -- cgit v1.2.3