icecat: add release icecat-140.6.0-1gnu1 for aramo

This commit is contained in:
Ark74 2026-01-17 18:56:47 -06:00
parent 92fef42cd6
commit 17ba0259bf
3382 changed files with 457689 additions and 569094 deletions

View file

@ -415,11 +415,7 @@ const CookieBannerExecutedRecordCleaner = {
// A cleaner for cleaning fingerprinting protection states.
const FingerprintingProtectionStateCleaner = {
async _maybeClearSiteSpecificZoom(
deleteAll,
aSchemelessSite,
aOriginAttributes = {}
) {
async _maybeClearSiteSpecificZoom(aSchemelessSite, aOriginAttributes = {}) {
if (
!ChromeUtils.shouldResistFingerprinting("SiteSpecificZoom", null, true)
) {
@ -432,8 +428,24 @@ const FingerprintingProtectionStateCleaner = {
const ZOOM_PREF_NAME = "browser.content.full-zoom";
await new Promise((aResolve, aReject) => {
if (deleteAll) {
cps2.removeByName(ZOOM_PREF_NAME, null, {
aOriginAttributes =
ChromeUtils.fillNonDefaultOriginAttributes(aOriginAttributes);
let loadContext;
if (
aOriginAttributes.privateBrowsingId ==
Services.scriptSecurityManager.DEFAULT_PRIVATE_BROWSING_ID
) {
loadContext = Cu.createLoadContext();
} else {
loadContext = Cu.createPrivateLoadContext();
}
cps2.removeBySubdomainAndName(
aSchemelessSite,
ZOOM_PREF_NAME,
loadContext,
{
handleCompletion: aReason => {
if (aReason === cps2.COMPLETE_ERROR) {
aReject();
@ -441,50 +453,19 @@ const FingerprintingProtectionStateCleaner = {
aResolve();
}
},
});
} else {
aOriginAttributes =
ChromeUtils.fillNonDefaultOriginAttributes(aOriginAttributes);
let loadContext;
if (
aOriginAttributes.privateBrowsingId ==
Services.scriptSecurityManager.DEFAULT_PRIVATE_BROWSING_ID
) {
loadContext = Cu.createLoadContext();
} else {
loadContext = Cu.createPrivateLoadContext();
}
cps2.removeBySubdomainAndName(
aSchemelessSite,
ZOOM_PREF_NAME,
loadContext,
{
handleCompletion: aReason => {
if (aReason === cps2.COMPLETE_ERROR) {
aReject();
} else {
aResolve();
}
},
}
);
}
);
});
},
async deleteAll() {
Services.rfp.cleanAllRandomKeys();
await this._maybeClearSiteSpecificZoom(true);
},
async deleteByPrincipal(aPrincipal) {
Services.rfp.cleanRandomKeyByPrincipal(aPrincipal);
await this._maybeClearSiteSpecificZoom(
false,
aPrincipal.host,
aPrincipal.originAttributes
);
@ -497,7 +478,6 @@ const FingerprintingProtectionStateCleaner = {
);
await this._maybeClearSiteSpecificZoom(
false,
aSchemelessSite,
aOriginAttributesPattern
);
@ -509,11 +489,7 @@ const FingerprintingProtectionStateCleaner = {
JSON.stringify(aOriginAttributesPattern)
);
await this._maybeClearSiteSpecificZoom(
false,
aHost,
aOriginAttributesPattern
);
await this._maybeClearSiteSpecificZoom(aHost, aOriginAttributesPattern);
},
async deleteByOriginAttributes(aOriginAttributesString) {

View file

@ -1467,7 +1467,7 @@ export class ExtensionData {
),
data_collection: newPermissions.data_collection.filter(
perm =>
!oldPermissions.data_collection.includes(perm) && perm !== "none"
!oldPermissions.data_collection?.includes(perm) && perm !== "none"
),
};
}

View file

@ -132,6 +132,7 @@ JAR_MANIFESTS += ["jar.mn"]
BROWSER_CHROME_MANIFESTS += [
"test/browser/browser.toml",
"test/browser/protocol-remote-false/browser.toml",
]
MOCHITEST_MANIFESTS += [

View file

@ -79,7 +79,7 @@ const openOAuthWindow = (details, redirectURI) => {
// Early exit if channel isn't related to the oauth dialog.
let wrapper = ChannelWrapper.get(channel);
if (
!wrapper.browserElement &&
!wrapper.browserElement ||
wrapper.browserElement !== window.gBrowser.selectedBrowser
) {
return;

View file

@ -659,7 +659,8 @@
"optional": true,
"default": []
}
}
},
"additionalProperties": { "$ref": "UnrecognizedProperty" }
}
},
"additionalProperties": { "$ref": "UnrecognizedProperty" }

View file

@ -0,0 +1,7 @@
[DEFAULT]
prefs = [
"extensions.webextensions.remote=false", # Needed to display index of unpacked ext
"extensions.webextensions.protocol.remote=false"
]
["browser_ext_dir_listing.js"]

View file

@ -0,0 +1,130 @@
/* -*- Mode: indent-tabs-mode: nil; js-indent-level: 2 -*- */
/* vim: set sts=2 sw=2 et tw=80: */
"use strict";
const { AddonTestUtils } = ChromeUtils.importESModule(
"resource://testing-common/AddonTestUtils.sys.mjs"
);
// eslint-disable-next-line mozilla/no-redeclare-with-import-autofix
const { ExtensionTestCommon } = ChromeUtils.importESModule(
"resource://testing-common/ExtensionTestCommon.sys.mjs"
);
AddonTestUtils.initMochitest(this);
async function checkNoFileOrJarURLs(extensionURL) {
// Load the root of the extension using moz-extension:// protocol
await BrowserTestUtils.withNewTab(
{
gBrowser,
url: extensionURL,
},
async browser => {
info("Successfully loaded extension root page");
// Check the page title
let title = await SpecialPowers.spawn(browser, [], () => {
return content.document.title;
});
is(
title,
`Index of ${extensionURL}`,
`Page title should start with "Index of moz-extension://", got: ${title}`
);
// Check that at least the manifest entry is there
let hasManifest = await SpecialPowers.spawn(browser, [], () => {
for (let elem of content.document.querySelectorAll("[href]")) {
let url = elem.href;
if (url.endsWith("manifest.json")) {
return true;
}
}
return false;
});
ok(hasManifest, "Directory listing should include manifest.json");
// Check that no URLs are file:// or jar://
let invalidURLs = await SpecialPowers.spawn(browser, [], () => {
let invalid = [];
for (let elem of content.document.querySelectorAll("[href],[src]")) {
let url = elem.href || elem.src;
if (url.startsWith("file:") || url.startsWith("jar:")) {
invalid.push(elem.outerHTML);
}
}
return invalid;
});
Assert.deepEqual(
invalidURLs,
[],
"No URLs should use file:// or jar:// schemes."
);
}
);
}
// Test that all the URLs in the dirlisting of an extensions root dir
// does not include any file or jar URLs when extensions.webextensions.protocol.remote
// is false.
add_task(async function test_webextension_dir_listing() {
// Verify the pref is set correctly
is(
Services.prefs.getBoolPref("extensions.webextensions.protocol.remote"),
false,
"extensions.webextensions.protocol.remote should be false"
);
// Get the extension's base URL. This is a packed extension
// that happens to already be a part of the test environment.
let policy = WebExtensionPolicy.getByID("mochikit@mozilla.org");
ok(policy, "This extension must exist");
let extensionURL = policy.getURL("/");
info(`Extension base URL: ${extensionURL}`);
await checkNoFileOrJarURLs(extensionURL);
});
add_task(async function test_temp_webextension_dir_listing() {
// Verify the pref is set correctly
is(
Services.prefs.getBoolPref("extensions.webextensions.protocol.remote"),
false,
"extensions.webextensions.protocol.remote should be false"
);
const ID = "addon@tests.mozilla.org";
const addonDir = AddonTestUtils.tempDir.clone().clone();
addonDir.append("exttest");
await AddonTestUtils.promiseWriteFilesToDir(
addonDir.path,
ExtensionTestCommon.generateFiles({
manifest: {
browser_specific_settings: { gecko: { id: ID } },
version: "1.0",
},
})
);
// Wait for the extension to start up
let startupPromise = AddonTestUtils.promiseWebExtensionStartup(ID);
let addon = await AddonManager.installTemporaryAddon(addonDir);
await startupPromise;
// Get the extension policy
let policy = WebExtensionPolicy.getByID(ID);
ok(policy, "Extension policy found");
// Get the extension's base URL and check it
let extensionURL = policy.getURL("/");
info(`Temporary extension base URL: ${extensionURL}`);
await checkNoFileOrJarURLs(extensionURL);
// Unload the extension
await addon.uninstall();
// Clean up the temporary directory
addonDir.remove(true);
});

View file

@ -12,6 +12,8 @@ tags = "webextensions"
["test_ext_native_messaging.js"]
run-sequentially = "very high failure rate in parallel"
["test_ext_native_messaging_concurrent.js"]
["test_ext_native_messaging_perf.js"]
skip-if = ["tsan"] # Unreasonably slow, bug 1612707

View file

@ -227,3 +227,28 @@ add_task(async function test_permissions_have_localization_strings() {
}
}
});
add_task(async function test_allow_unknown_props() {
const extension = await getExtension({
manifest: {
browser_specific_settings: {
gecko: {
data_collection_permissions: {
required: ["none"],
unknown_prop: true,
},
},
},
},
});
Assert.ok(
extension.warnings[0]?.includes(
"Warning processing browser_specific_settings.gecko.data_collection_permissions.unknown_prop: " +
"An unexpected property was found in the WebExtension manifest."
),
`Expected a warning about the unknown property`
);
await extension.cleanupGeneratedFile();
});

View file

@ -0,0 +1,107 @@
/* -*- Mode: indent-tabs-mode: nil; js-indent-level: 2 -*- */
/* vim: set sts=2 sw=2 et tw=80: */
"use strict";
AddonTestUtils.init(this);
const ECHO_BODY = String.raw`
import struct
import sys
stdin = getattr(sys.stdin, 'buffer', sys.stdin)
stdout = getattr(sys.stdout, 'buffer', sys.stdout)
while True:
rawlen = stdin.read(4)
if len(rawlen) == 0:
sys.exit(0)
msglen = struct.unpack('@I', rawlen)[0]
msg = stdin.read(msglen)
stdout.write(struct.pack('@I', msglen))
stdout.write(msg)
`;
const SCRIPTS = [
{
name: "echo",
description: "a native app that echoes back messages it receives",
script: ECHO_BODY.replace(/^ {2}/gm, ""),
},
];
function loadTestExtension({ background }) {
return ExtensionTestUtils.loadExtension({
background,
manifest: {
browser_specific_settings: { gecko: { id: ID } },
permissions: ["nativeMessaging"],
},
});
}
add_setup(async () => {
await ExtensionTestUtils.startAddonManager();
await setupHosts(SCRIPTS);
});
// Regression test for https://bugzilla.mozilla.org/show_bug.cgi?id=1979546
add_task(async function test_many_connectNative_calls() {
let extension = loadTestExtension({
async background() {
// Prior to bug 1979546 being fixed, the test got stuck on Windows at 16.
// Let's verify that things run smoothly even if we launch "many" more,
// e.g. 70 (arbitrarily chosen, higher than 64).
const NUMBER_OF_CONCURRENT_NATIVE_MESSAGING_APPS = 70;
const openPorts = [];
const remainingMsgs = new Set();
const firstMessagePromises = [];
for (let i = 0; i < NUMBER_OF_CONCURRENT_NATIVE_MESSAGING_APPS; ++i) {
const dummyMsg = `pingpong-${i}`;
const port = browser.runtime.connectNative("echo");
openPorts[i] = port;
remainingMsgs.add(i);
firstMessagePromises[i] = new Promise(resolve => {
port.onMessage.addListener(msg => {
browser.test.assertEq(dummyMsg, msg, `Echoed back message ${i}`);
remainingMsgs.delete(i);
browser.test.log(`Remaining: ${Array.from(remainingMsgs)}`);
resolve();
});
port.onDisconnect.addListener(() => {
if (remainingMsgs.delete(i)) {
// If the program somehow exits before it responded, note the
// failure and continue (do not stay stuck).
browser.test.fail(`onDisconnect fired before onMessage: ${i}`);
resolve();
} else {
// onDisconnect should not fire when we call port.disconnect()
// below.
browser.test.fail(`Unexpected port.onDisconnect: ${i}`);
}
});
});
port.postMessage(dummyMsg);
}
browser.test.log(`Awaiting replies to: ${Array.from(remainingMsgs)}`);
await Promise.all(firstMessagePromises);
browser.test.log("Now verifying sendNativeMessage behavior");
browser.test.assertEq(
await browser.runtime.sendNativeMessage("echo", "one_off_msg"),
"one_off_msg",
"sendNativeMessage can still roundtrip after so many connectNative"
);
for (const port of openPorts) {
port.disconnect();
}
browser.test.sendMessage("done");
},
});
await extension.startup();
await extension.awaitMessage("done");
info("Waiting for all echo processes to have exit");
await waitForSubprocessExit();
await extension.unload();
});

View file

@ -61,9 +61,11 @@ add_task(async function test_selector_db_out_of_date() {
region: "default",
});
Assert.deepEqual(
result.engines.map(e => e.identifier),
["google", "bing", "ddg", "wikipedia"],
"Should have returned the correct data."
let engineIdentifiers = result.engines.map(e => e.identifier);
Assert.ok(
["google", "bing", "ddg", "wikipedia"].every(id =>
engineIdentifiers.includes(id)
),
"Should have returned the correct engine identifiers."
);
});