/* * GNU LibreJS - A browser add-on to block nonfree nontrivial JavaScript. * * Copyright (C) 2018 Giorgio Maone * * This file is part of GNU LibreJS. * * GNU LibreJS is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * GNU LibreJS is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with GNU LibreJS. If not, see . */ "use strict"; describe("LibreJS' components", () => { let LibreJS = browser.extension.getBackgroundPage().LibreJS; let license = { id: 'GPL-3.0', url: 'http://www.gnu.org/licenses/gpl-3.0.html', magnet: 'magnet:?xt=urn:btih:1f739d935676111cfff4b4693e3816e664797050&dn=gpl-3.0.txt', }; let unknownLicense = { id: 'Acme-proprietary-1.5', url: 'http://www.acme.com/license-1.5.html', magnet: 'magnet:?xt=urn:btih:2f739d935676111cfff4b4693e3816e664797050&dn=acme-1.5.txt' }; let trivial = "1+1"; let nontrivial = `function nt() { document.documentElement.innerHTML=""; nt(); }`; let licensed = `// @license ${license.magnet} ${license.id}\n${nontrivial}\n// @license-end`; let unknownLicensed = `// @license ${unknownLicense.magnet} ${unknownLicense.id}\n${nontrivial}\n// @license-end`; let malformedLicensed = `// @license\n${nontrivial}`; let tab, documentUrl; beforeAll(async () => { let url = browser.extension.getURL("/test/resources/index.html"); tab = (await browser.tabs.query({url}))[0] || (await browser.tabs.create({url})); documentUrl = url; }); describe("The whitelist/blacklist manager", () => { let {ListManager, ListStore, Storage} = LibreJS; let lm = new ListManager(new ListStore("_test.whitelist", Storage.CSV), new ListStore("_test.blacklist", Storage.CSV), new Set()); let forgot = ["http://formerly.whitelist.ed/", "http://formerly.blacklist.ed/"]; beforeAll(async () => { await lm.whitelist("https://fsf.org/*", "https://*.gnu.org/*", forgot[0]); await lm.blacklist("https://*.evil.gnu.org/*", "https://verybad.com/*", forgot[1]); }); it("Should handle basic CRUD operations", async () => { expect(lm.getStatus(forgot[0])).toBe("whitelisted"); expect(lm.getStatus(forgot[1])).toBe("blacklisted"); await lm.forget(...forgot); for (let url of forgot) { expect(lm.getStatus(url)).toBe("unknown"); } }); it("Should support full path wildcards", () => { expect(lm.getStatus("https://unknown.org")).toBe("unknown"); expect(lm.getStatus("https://fsf.org/some/path")).toBe("whitelisted"); expect(lm.getStatus("https://fsf.org/")).toBe("whitelisted"); expect(lm.getStatus("https://fsf.org")).toBe("whitelisted"); expect(lm.getStatus("https://subdomain.fsf.org")).toBe("unknown"); expect(lm.getStatus("https://verybad.com/some/other/path?with=querystring")).toBe("blacklisted"); }); it("Should support subdomain wildcards", () => { expect(lm.getStatus("https://gnu.org")).toBe("whitelisted"); expect(lm.getStatus("https://www.gnu.org")).toBe("whitelisted"); expect(lm.getStatus("https://evil.gnu.org")).toBe("blacklisted"); expect(lm.getStatus("https://more.evil.gnu.org")).toBe("blacklisted"); expect(lm.getStatus("https://more.evil.gnu.org/some/evil/path?too")).toBe("blacklisted"); }); }) describe("The external script source processor", () => { let url = "https://www.gnu.org/mock-script.js"; let processScript = async (source, whitelisted = false) => await LibreJS.handle_script({ text: source, request: {url, tabId: tab.id, documentUrl, frameId: 0}, }, whitelisted); it("should accept whitelisted scripts", async () => { expect(await processScript(nontrivial, true) || nontrivial).toContain(nontrivial); }); it("should block trivial scripts too", async () => { let processed = await processScript(trivial); expect(processed || trivial).not.toContain(trivial); }); it("should block non-trivial scripts", async () => { let processed = await processScript(nontrivial); expect(processed || nontrivial).not.toContain(nontrivial); }); it("should accept scripts with known free license tags", async () => { let processed = await processScript(licensed); expect(processed || licensed).toContain(nontrivial); }); it("should block scripts with unknown license tags", async () => { let processed = await processScript(unknownLicensed); expect(processed).not.toContain(nontrivial); }); it("should block scripts with malformed license tags", async () => { let processed = await processScript(malformedLicensed); expect(processed).not.toContain(nontrivial); }); }); describe("The HTML processor", () => { let processHtml = async (html, whitelisted = false) => LibreJS.editHtml(html, tab.url, tab.id, 0, whitelisted); let addScript = (html, script, before = "") => html.replace(before, `${before}`); let addToBody = (html, fragment) => html.replace("", `${fragment}`); let jsUrl = js => `javascript:${encodeURIComponent(js)}`; function extractScripts(html, def = "") { let matches = html && html.match(/