From d8bbc7858622b6d9c278469aab701ca0b609cddf Mon Sep 17 00:00:00 2001 From: Daniel Baumann Date: Wed, 15 May 2024 05:35:49 +0200 Subject: Merging upstream version 126.0. Signed-off-by: Daniel Baumann --- toolkit/mozapps/extensions/.eslintrc.js | 4 +- toolkit/mozapps/extensions/AbuseReporter.sys.mjs | 8 +- toolkit/mozapps/extensions/AddonContentPolicy.cpp | 2 +- toolkit/mozapps/extensions/AddonManager.sys.mjs | 22 +- .../mozapps/extensions/amInstallTrigger.sys.mjs | 6 +- toolkit/mozapps/extensions/amManager.sys.mjs | 10 +- toolkit/mozapps/extensions/amWebAPI.sys.mjs | 6 +- .../mozapps/extensions/content/aboutaddons.html | 3 - toolkit/mozapps/extensions/content/aboutaddons.js | 62 ++- .../extensions/content/aboutaddonsCommon.js | 17 +- .../mozapps/extensions/content/abuse-reports.js | 2 +- toolkit/mozapps/extensions/content/shortcuts.js | 2 +- .../mozapps/extensions/content/view-controller.js | 2 +- .../extensions/internal/AddonRepository.sys.mjs | 6 +- .../extensions/internal/AddonTestUtils.sys.mjs | 31 +- .../extensions/internal/GMPProvider.sys.mjs | 6 +- .../internal/ProductAddonChecker.sys.mjs | 37 +- .../internal/SitePermsAddonProvider.sys.mjs | 4 +- .../extensions/internal/XPIDatabase.sys.mjs | 61 +-- .../mozapps/extensions/internal/XPIInstall.sys.mjs | 107 ++++- .../extensions/internal/XPIProvider.sys.mjs | 6 +- .../extensions/internal/crypto-utils.sys.mjs | 10 +- .../mozapps/extensions/test/browser/.eslintrc.js | 2 +- .../addons/browser_dragdrop1/META-INF/manifest.mf | 8 - .../addons/browser_dragdrop1/META-INF/mozilla.rsa | Bin 4210 -> 0 bytes .../addons/browser_dragdrop1/META-INF/mozilla.sf | 5 - .../addons/browser_dragdrop2/META-INF/manifest.mf | 8 - .../addons/browser_dragdrop2/META-INF/mozilla.rsa | Bin 4210 -> 0 bytes .../addons/browser_dragdrop2/META-INF/mozilla.sf | 5 - .../browser_dragdrop_incompat/META-INF/manifest.mf | 8 - .../browser_dragdrop_incompat/META-INF/mozilla.rsa | Bin 4218 -> 0 bytes .../browser_dragdrop_incompat/META-INF/mozilla.sf | 5 - .../addons/browser_installssl/META-INF/manifest.mf | 8 - .../addons/browser_installssl/META-INF/mozilla.rsa | Bin 4213 -> 0 bytes .../addons/browser_installssl/META-INF/mozilla.sf | 5 - .../addons/options_signed/META-INF/manifest.mf | 12 - .../addons/options_signed/META-INF/mozilla.rsa | Bin 4197 -> 0 bytes .../addons/options_signed/META-INF/mozilla.sf | 4 - .../browser/addons/options_signed/manifest.json | 11 - .../browser/addons/options_signed/options.html | 9 - .../mozapps/extensions/test/browser/browser.toml | 3 - .../browser/browser_AMBrowserExtensionsImport.js | 2 +- .../extensions/test/browser/browser_bug572561.js | 8 +- .../extensions/test/browser/browser_dragdrop.js | 2 +- .../test/browser/browser_html_abuse_report.js | 10 +- .../browser/browser_html_detail_permissions.js | 2 +- .../test/browser/browser_html_discover_view.js | 2 +- .../browser_html_list_view_recommendations.js | 2 +- .../test/browser/browser_html_options_ui_in_tab.js | 21 +- .../test/browser/browser_html_updates.js | 2 +- .../test/browser/browser_installtrigger_install.js | 7 +- .../test/browser/browser_local_install.js | 2 +- .../browser/browser_page_options_install_addon.js | 2 +- .../browser/browser_shortcuts_duplicate_check.js | 2 +- .../browser/browser_sidebar_hidden_categories.js | 2 +- .../extensions/test/browser/browser_updatessl.js | 9 +- .../test/browser/browser_webapi_install.js | 34 +- .../test/browser/browser_webapi_theme.js | 2 +- toolkit/mozapps/extensions/test/browser/head.js | 24 +- .../extensions/test/browser/head_abuse_report.js | 4 +- toolkit/mozapps/extensions/test/browser/moz.build | 1 - .../mozapps/extensions/test/xpcshell/.eslintrc.js | 4 +- .../data/signing_checks/langpack_signed.xpi | Bin 4452 -> 7593 bytes .../test/xpcshell/data/signing_checks/long.xpi | Bin 4761 -> 7872 bytes .../xpcshell/data/signing_checks/privileged.xpi | Bin 4659 -> 7772 bytes .../test/xpcshell/data/signing_checks/signed1.xpi | Bin 4702 -> 7772 bytes .../test/xpcshell/data/signing_checks/signed2.xpi | Bin 4697 -> 7766 bytes .../test/xpcshell/data/webext-implicit-id.xpi | Bin 4182 -> 21274 bytes .../extensions/test/xpcshell/head_addons.js | 11 +- .../extensions/test/xpcshell/head_compat.js | 2 +- .../rs-blocklist/test_blocklist_appversion.js | 2 +- .../xpcshell/rs-blocklist/test_blocklist_mlbf.js | 44 ++- .../rs-blocklist/test_blocklist_mlbf_update.js | 2 +- .../rs-blocklist/test_blocklist_severities.js | 2 +- .../xpcshell/rs-blocklist/test_blocklistchange.js | 10 +- .../rs-blocklist/test_gfxBlacklist_Device.js | 2 +- .../rs-blocklist/test_gfxBlacklist_DriverNew.js | 2 +- .../test_gfxBlacklist_Equal_DriverNew.js | 2 +- .../test_gfxBlacklist_Equal_DriverOld.js | 2 +- .../rs-blocklist/test_gfxBlacklist_Equal_OK.js | 2 +- .../test_gfxBlacklist_GTE_DriverOld.js | 2 +- .../rs-blocklist/test_gfxBlacklist_GTE_OK.js | 2 +- .../test_gfxBlacklist_No_Comparison.js | 2 +- .../xpcshell/rs-blocklist/test_gfxBlacklist_OK.js | 2 +- .../xpcshell/rs-blocklist/test_gfxBlacklist_OS.js | 2 +- .../test_gfxBlacklist_OSVersion_match.js | 2 +- ...fxBlacklist_OSVersion_mismatch_DriverVersion.js | 2 +- ...st_gfxBlacklist_OSVersion_mismatch_OSVersion.js | 2 +- .../rs-blocklist/test_gfxBlacklist_Vendor.js | 2 +- .../rs-blocklist/test_gfxBlacklist_Version.js | 2 +- .../rs-blocklist/test_gfxBlacklist_prefs.js | 4 +- .../test/xpcshell/rs-blocklist/xpcshell.toml | 1 + .../extensions/test/xpcshell/test_AbuseReporter.js | 6 +- .../test/xpcshell/test_AddonRepository.js | 2 +- .../test_AddonRepository_appIsShuttingDown.js | 4 +- .../test/xpcshell/test_AddonRepository_cache.js | 2 +- .../xpcshell/test_AddonRepository_cache_locale.js | 4 +- .../test_ProductAddonChecker_signatures.js | 15 +- .../test_addon_manager_telemetry_events.js | 10 +- .../xpcshell/test_delay_update_webextension.js | 8 +- .../test/xpcshell/test_installOrigins.js | 16 +- .../test/xpcshell/test_install_cancel.js | 2 +- .../test/xpcshell/test_provider_markSafe.js | 2 +- .../test/xpcshell/test_provider_shutdown.js | 2 +- .../extensions/test/xpcshell/test_reload.js | 4 +- .../test/xpcshell/test_signed_install.js | 103 ++--- .../test/xpcshell/test_signed_langpack.js | 2 +- .../extensions/test/xpcshell/test_signed_long.js | 2 +- .../extensions/test/xpcshell/test_signed_verify.js | 438 ++++++++++++++++++++- .../test/xpcshell/test_system_delay_update.js | 2 +- .../test/xpcshell/test_system_repository.js | 2 +- .../extensions/test/xpcshell/test_system_reset.js | 4 +- .../test/xpcshell/test_system_update_blank.js | 2 +- .../xpcshell/test_system_update_checkSizeHash.js | 2 +- .../test/xpcshell/test_system_update_custom.js | 2 +- .../test/xpcshell/test_system_update_empty.js | 2 +- .../test_system_update_installTelemetryInfo.js | 2 +- .../test/xpcshell/test_system_update_newset.js | 2 +- .../xpcshell/test_system_update_overlapping.js | 2 +- .../xpcshell/test_system_update_uninstall_check.js | 2 +- .../test/xpcshell/test_system_update_upgrades.js | 2 +- .../test/xpcshell/test_system_upgrades.js | 2 +- .../extensions/test/xpcshell/test_temporary.js | 4 +- .../extensions/test/xpcshell/test_update.js | 41 +- .../extensions/test/xpcshell/test_updateCancel.js | 2 +- .../test/xpcshell/test_update_addontype.js | 2 +- .../xpcshell/test_update_noSystemAddonUpdate.js | 2 +- .../extensions/test/xpcshell/test_updateid.js | 2 +- .../extensions/test/xpcshell/test_updateversion.js | 2 +- .../extensions/test/xpcshell/test_webextension.js | 67 ++++ .../test/xpcshell/test_webextension_install.js | 4 +- .../mozapps/extensions/test/xpcshell/xpcshell.toml | 7 +- .../test/xpinstall/amosigned-mv3-cose.xpi | Bin 0 -> 7475 bytes .../test/xpinstall/amosigned-sha1only.xpi | Bin 0 -> 4287 bytes .../extensions/test/xpinstall/amosigned.xpi | Bin 4287 -> 7460 bytes .../mozapps/extensions/test/xpinstall/browser.toml | 2 +- .../extensions/test/xpinstall/browser_auth.js | 2 +- .../extensions/test/xpinstall/browser_auth4.js | 2 +- .../extensions/test/xpinstall/browser_bug645699.js | 2 +- .../xpinstall/browser_bug645699_postDownload.js | 2 +- .../extensions/test/xpinstall/browser_bug672485.js | 2 +- .../test/xpinstall/browser_doorhanger_installs.js | 50 ++- .../extensions/test/xpinstall/browser_enabled.js | 6 +- .../extensions/test/xpinstall/browser_hash.js | 23 +- .../extensions/test/xpinstall/browser_hash2.js | 23 +- .../extensions/test/xpinstall/browser_httphash.js | 34 +- .../extensions/test/xpinstall/browser_httphash3.js | 34 +- .../extensions/test/xpinstall/browser_httphash5.js | 30 +- .../test/xpinstall/browser_localfile3.js | 2 +- .../test/xpinstall/browser_localfile4.js | 2 +- .../xpinstall/browser_localfile4_postDownload.js | 2 +- .../extensions/test/xpinstall/browser_offline.js | 2 +- .../xpinstall/browser_unsigned_trigger_xorigin.js | 2 +- toolkit/mozapps/extensions/test/xpinstall/head.js | 9 +- .../extensions/test/xpinstall/restartless.xpi | Bin 4447 -> 0 bytes .../extensions/test/xpinstall/triggerredirect.html | 2 +- 156 files changed, 1173 insertions(+), 602 deletions(-) delete mode 100644 toolkit/mozapps/extensions/test/browser/addons/browser_dragdrop1/META-INF/manifest.mf delete mode 100644 toolkit/mozapps/extensions/test/browser/addons/browser_dragdrop1/META-INF/mozilla.rsa delete mode 100644 toolkit/mozapps/extensions/test/browser/addons/browser_dragdrop1/META-INF/mozilla.sf delete mode 100644 toolkit/mozapps/extensions/test/browser/addons/browser_dragdrop2/META-INF/manifest.mf delete mode 100644 toolkit/mozapps/extensions/test/browser/addons/browser_dragdrop2/META-INF/mozilla.rsa delete mode 100644 toolkit/mozapps/extensions/test/browser/addons/browser_dragdrop2/META-INF/mozilla.sf delete mode 100644 toolkit/mozapps/extensions/test/browser/addons/browser_dragdrop_incompat/META-INF/manifest.mf delete mode 100644 toolkit/mozapps/extensions/test/browser/addons/browser_dragdrop_incompat/META-INF/mozilla.rsa delete mode 100644 toolkit/mozapps/extensions/test/browser/addons/browser_dragdrop_incompat/META-INF/mozilla.sf delete mode 100644 toolkit/mozapps/extensions/test/browser/addons/browser_installssl/META-INF/manifest.mf delete mode 100644 toolkit/mozapps/extensions/test/browser/addons/browser_installssl/META-INF/mozilla.rsa delete mode 100644 toolkit/mozapps/extensions/test/browser/addons/browser_installssl/META-INF/mozilla.sf delete mode 100644 toolkit/mozapps/extensions/test/browser/addons/options_signed/META-INF/manifest.mf delete mode 100644 toolkit/mozapps/extensions/test/browser/addons/options_signed/META-INF/mozilla.rsa delete mode 100644 toolkit/mozapps/extensions/test/browser/addons/options_signed/META-INF/mozilla.sf delete mode 100644 toolkit/mozapps/extensions/test/browser/addons/options_signed/manifest.json delete mode 100644 toolkit/mozapps/extensions/test/browser/addons/options_signed/options.html create mode 100644 toolkit/mozapps/extensions/test/xpinstall/amosigned-mv3-cose.xpi create mode 100644 toolkit/mozapps/extensions/test/xpinstall/amosigned-sha1only.xpi delete mode 100644 toolkit/mozapps/extensions/test/xpinstall/restartless.xpi (limited to 'toolkit/mozapps/extensions') diff --git a/toolkit/mozapps/extensions/.eslintrc.js b/toolkit/mozapps/extensions/.eslintrc.js index 2e1909b8fb..ef31f0780e 100644 --- a/toolkit/mozapps/extensions/.eslintrc.js +++ b/toolkit/mozapps/extensions/.eslintrc.js @@ -14,7 +14,7 @@ module.exports = { "no-unused-vars": [ "error", { - args: "none", + argsIgnorePattern: "^_", vars: "all", }, ], @@ -26,7 +26,7 @@ module.exports = { "no-unused-vars": [ "error", { - args: "none", + argsIgnorePattern: "^_", vars: "local", }, ], diff --git a/toolkit/mozapps/extensions/AbuseReporter.sys.mjs b/toolkit/mozapps/extensions/AbuseReporter.sys.mjs index 0d8df5c9f3..944cef507c 100644 --- a/toolkit/mozapps/extensions/AbuseReporter.sys.mjs +++ b/toolkit/mozapps/extensions/AbuseReporter.sys.mjs @@ -102,7 +102,7 @@ export class AbuseReportError extends Error { async function responseToErrorInfo(response) { return JSON.stringify({ status: response.status, - responseText: await response.text().catch(err => ""), + responseText: await response.text().catch(() => ""), }); } @@ -244,7 +244,7 @@ export const AbuseReporter = { } let errorInfo = await responseToErrorInfo(response).catch( - err => undefined + () => undefined ); if (response.status === 404) { @@ -550,7 +550,7 @@ export const AbuseReporter = { * A string that identify how the report has been triggered. */ class AbuseReport { - constructor({ addon, createErrorType, reportData, reportEntryPoint }) { + constructor({ addon, reportData, reportEntryPoint }) { this[PRIVATE_REPORT_PROPS] = { aborted: false, abortController: new AbortController(), @@ -599,7 +599,7 @@ class AbuseReport { // Leave errorInfo empty if there is no response or fails to // be converted into an error info object. const errorInfo = response - ? await responseToErrorInfo(response).catch(err => undefined) + ? await responseToErrorInfo(response).catch(() => undefined) : undefined; throw new AbuseReportError(errorType, errorInfo); diff --git a/toolkit/mozapps/extensions/AddonContentPolicy.cpp b/toolkit/mozapps/extensions/AddonContentPolicy.cpp index 983935f7c5..90d1283309 100644 --- a/toolkit/mozapps/extensions/AddonContentPolicy.cpp +++ b/toolkit/mozapps/extensions/AddonContentPolicy.cpp @@ -319,7 +319,7 @@ AddonContentPolicy::ValidateAddonCSP(const nsAString& aPolicyString, nsCOMPtr selfURI; principal->GetURI(getter_AddRefs(selfURI)); RefPtr csp = new nsCSPContext(); - rv = csp->SetRequestContextWithPrincipal(principal, selfURI, u""_ns, 0); + rv = csp->SetRequestContextWithPrincipal(principal, selfURI, ""_ns, 0); NS_ENSURE_SUCCESS(rv, rv); csp->AppendPolicy(aPolicyString, false, false); diff --git a/toolkit/mozapps/extensions/AddonManager.sys.mjs b/toolkit/mozapps/extensions/AddonManager.sys.mjs index c69cf4029e..a07a651895 100644 --- a/toolkit/mozapps/extensions/AddonManager.sys.mjs +++ b/toolkit/mozapps/extensions/AddonManager.sys.mjs @@ -160,7 +160,7 @@ var PrefObserver = { this.observe(null, NS_PREFBRANCH_PREFCHANGE_TOPIC_ID, PREF_LOGGING_ENABLED); }, - observe(aSubject, aTopic, aData) { + observe(aSubject, aTopic) { if (aTopic == "xpcom-shutdown") { Services.prefs.removeObserver(PREF_LOGGING_ENABLED, this); Services.obs.removeObserver(this, "xpcom-shutdown"); @@ -339,7 +339,7 @@ BrowserListener.prototype = { } }, - observe(subject, topic, data) { + observe(subject) { if (subject != this.messageManager) { return; } @@ -349,7 +349,7 @@ BrowserListener.prototype = { this.cancelInstall(); }, - onLocationChange(webProgress, request, location) { + onLocationChange() { if ( this.browser.contentPrincipal && this.principal.subsumes(this.browser.contentPrincipal) @@ -361,19 +361,19 @@ BrowserListener.prototype = { this.cancelInstall(); }, - onDownloadCancelled(install) { + onDownloadCancelled() { this.unregister(); }, - onDownloadFailed(install) { + onDownloadFailed() { this.unregister(); }, - onInstallFailed(install) { + onInstallFailed() { this.unregister(); }, - onInstallEnded(install) { + onInstallEnded() { this.unregister(); }, @@ -553,7 +553,7 @@ var AddonManagerInternal = { this.pendingProviders.add(aProvider); } - return new Promise((resolve, reject) => { + return new Promise(resolve => { logger.debug("Calling shutdown blocker for " + name); resolve(aProvider.shutdown()); }).catch(err => { @@ -1311,7 +1311,7 @@ var AddonManagerInternal = { } updates.push( - new Promise((resolve, reject) => { + new Promise(resolve => { addon.findUpdates( { onUpdateAvailable(aAddon, aInstall) { @@ -3892,7 +3892,7 @@ export var AddonManagerPrivate = { * This can be used as an implementation for Addon.findUpdates() when * no update mechanism is available. */ - callNoUpdateListeners(addon, listener, reason, appVersion, platformVersion) { + callNoUpdateListeners(addon, listener) { if ("onNoCompatibilityUpdateAvailable" in listener) { safeCall(listener.onNoCompatibilityUpdateAvailable.bind(listener), addon); } @@ -4739,7 +4739,7 @@ AMTelemetry = { // Observer Service notification callback. - observe(subject, topic, data) { + observe(subject, topic) { switch (topic) { case "addon-install-blocked": { const { installs } = subject.wrappedJSObject; diff --git a/toolkit/mozapps/extensions/amInstallTrigger.sys.mjs b/toolkit/mozapps/extensions/amInstallTrigger.sys.mjs index 068c0f07c4..b7cabba5b6 100644 --- a/toolkit/mozapps/extensions/amInstallTrigger.sys.mjs +++ b/toolkit/mozapps/extensions/amInstallTrigger.sys.mjs @@ -62,7 +62,7 @@ RemoteMediator.prototype = { } }, - enabled(url) { + enabled() { let params = { mimetype: XPINSTALL_MIMETYPE, }; @@ -237,14 +237,14 @@ InstallTrigger.prototype = { ); }, - startSoftwareUpdate(url, flags) { + startSoftwareUpdate(url) { let filename = Services.io.newURI(url).QueryInterface(Ci.nsIURL).filename; let args = {}; args[filename] = { URL: url }; return this.install(args); }, - installChrome(type, url, skin) { + installChrome(type, url) { return this.startSoftwareUpdate(url); }, diff --git a/toolkit/mozapps/extensions/amManager.sys.mjs b/toolkit/mozapps/extensions/amManager.sys.mjs index 5ce396d601..2571af55e4 100644 --- a/toolkit/mozapps/extensions/amManager.sys.mjs +++ b/toolkit/mozapps/extensions/amManager.sys.mjs @@ -67,7 +67,7 @@ export function amManager() { } amManager.prototype = { - observe(aSubject, aTopic, aData) { + observe(aSubject, aTopic) { switch (aTopic) { case "addons-startup": AddonManagerPrivate.startup(); @@ -129,7 +129,7 @@ amManager.prototype = { if (aCallback) { aInstall.addListener({ - onDownloadCancelled(aInstall) { + onDownloadCancelled() { callCallback(USER_CANCELLED); }, @@ -141,11 +141,11 @@ amManager.prototype = { } }, - onInstallFailed(aInstall) { + onInstallFailed() { callCallback(EXECUTION_ERROR); }, - onInstallEnded(aInstall, aStatus) { + onInstallEnded() { callCallback(SUCCESS); }, }); @@ -165,7 +165,7 @@ amManager.prototype = { return retval; }, - notify(aTimer) { + notify() { AddonManagerPrivate.backgroundUpdateTimerHandler(); }, diff --git a/toolkit/mozapps/extensions/amWebAPI.sys.mjs b/toolkit/mozapps/extensions/amWebAPI.sys.mjs index abe838af89..ae1b94cac7 100644 --- a/toolkit/mozapps/extensions/amWebAPI.sys.mjs +++ b/toolkit/mozapps/extensions/amWebAPI.sys.mjs @@ -214,7 +214,7 @@ export class WebAPI extends APIObject { super.init(window, broker, {}); - window.addEventListener("unload", event => { + window.addEventListener("unload", () => { this.broker.sendCleanup(this.allInstalls); }); } @@ -263,7 +263,7 @@ export class WebAPI extends APIObject { return lazy.AMO_ABUSEREPORT; } - eventListenerAdded(type) { + eventListenerAdded() { if (this.listenerCount == 0) { this.broker.setAddonListener(data => { let event = new this.window.AddonEvent(data.event, data); @@ -273,7 +273,7 @@ export class WebAPI extends APIObject { this.listenerCount++; } - eventListenerRemoved(type) { + eventListenerRemoved() { this.listenerCount--; if (this.listenerCount == 0) { this.broker.setAddonListener(null); diff --git a/toolkit/mozapps/extensions/content/aboutaddons.html b/toolkit/mozapps/extensions/content/aboutaddons.html index 55d6625c08..d0930ef42d 100644 --- a/toolkit/mozapps/extensions/content/aboutaddons.html +++ b/toolkit/mozapps/extensions/content/aboutaddons.html @@ -13,9 +13,6 @@ content="default-src chrome:; style-src chrome: 'unsafe-inline'; img-src chrome: file: jar: https: http:; connect-src chrome: data: https: http:; object-src 'none'" /> - - - { + onInstallEnded: () => { detachUpdateHandler(install); install.removeListener(updateListener); resolve({ installed: true, pending: false, found: true }); }, - onInstallPostponed: (...args) => { + onInstallPostponed: () => { detachUpdateHandler(install); install.removeListener(updateListener); resolve({ installed: false, pending: true, found: true }); @@ -375,7 +375,7 @@ const OPTIONS_TYPE_MAP = { // Check if an add-on has the provided options type, accounting for the pref // to disable inline options. -function getOptionsType(addon, type) { +function getOptionsType(addon) { return OPTIONS_TYPE_MAP[addon.optionsType]; } @@ -1064,7 +1064,7 @@ class AddonPageOptions extends HTMLElement { } } - async checkForUpdates(e) { + async checkForUpdates() { let message = document.getElementById("updates-message"); message.state = "updating"; message.hidden = false; @@ -2096,11 +2096,11 @@ class AddonDetails extends HTMLElement { } } - onDisabled(addon) { + onDisabled() { this.extensionShutdown(); } - onEnabled(addon) { + onEnabled() { this.extensionStartup(); } @@ -2451,45 +2451,27 @@ class AddonCard extends HTMLElement { async setAddonPermission(permission, type, action) { let { addon } = this; - let origins = [], - permissions = []; + let perms = { origins: [], permissions: [] }; + if (!["add", "remove"].includes(action)) { throw new Error("invalid action for permission change"); } - if (type == "permission") { - if ( - action == "add" && - !addon.optionalPermissions.permissions.includes(permission) - ) { - throw new Error("permission missing from manifest"); - } - permissions = [permission]; - } else if (type == "origin") { - if (action === "add") { - let { origins } = addon.optionalPermissions; - let patternSet = new MatchPatternSet(origins, { ignorePath: true }); - if (!patternSet.subsumes(new MatchPattern(permission))) { - throw new Error("origin missing from manifest"); - } - } - origins = [permission]; - // If this is one of the "all sites" permissions - if (Extension.isAllSitesPermission(permission)) { - // Grant/revoke ALL "all sites" optional permissions from the manifest. - origins = addon.optionalPermissions.origins.filter(perm => - Extension.isAllSitesPermission(perm) - ); - } + if (type === "permission") { + perms.permissions = [permission]; + } else if (type === "origin") { + perms.origins = [permission]; } else { throw new Error("unknown permission type changed"); } - let policy = WebExtensionPolicy.getByID(addon.id); - ExtensionPermissions[action]( - addon.id, - { origins, permissions }, - policy?.extension + + let normalized = ExtensionPermissions.normalizeOptional( + perms, + addon.optionalPermissions ); + + let policy = WebExtensionPolicy.getByID(addon.id); + ExtensionPermissions[action](addon.id, normalized, policy?.extension); } async handleEvent(e) { @@ -2968,18 +2950,18 @@ class AddonCard extends HTMLElement { this.sendEvent("update-postponed"); } - onDisabled(addon) { + onDisabled() { if (!this.reloading) { this.update(); } } - onEnabled(addon) { + onEnabled() { this.reloading = false; this.update(); } - onInstalled(addon) { + onInstalled() { // When a temporary addon is reloaded, onInstalled is triggered instead of // onEnabled. this.reloading = false; diff --git a/toolkit/mozapps/extensions/content/aboutaddonsCommon.js b/toolkit/mozapps/extensions/content/aboutaddonsCommon.js index 9315e35861..fd91ba58be 100644 --- a/toolkit/mozapps/extensions/content/aboutaddonsCommon.js +++ b/toolkit/mozapps/extensions/content/aboutaddonsCommon.js @@ -5,7 +5,7 @@ "use strict"; -/* exported attachUpdateHandler, detachUpdateHandler, gBrowser, +/* exported attachUpdateHandler, detachUpdateHandler, * getBrowserElement, installAddonsFromFilePicker, * isCorrectlySigned, isDisabledUnsigned, isDiscoverEnabled, * isPending, loadReleaseNotes, openOptionsInTab, promiseEvent, @@ -196,21 +196,6 @@ function showPermissionsPrompt(addon) { }); } -// Stub tabbrowser implementation for use by the tab-modal alert code -// when an alert/prompt/confirm method is called in a WebExtensions options_ui -// page (See Bug 1385548 for rationale). -var gBrowser = { - getTabModalPromptBox(browser) { - const parentWindow = window.docShell.chromeEventHandler.ownerGlobal; - - if (parentWindow.gBrowser) { - return parentWindow.gBrowser.getTabModalPromptBox(browser); - } - - return null; - }, -}; - function isCorrectlySigned(addon) { // Add-ons without an "isCorrectlySigned" property are correctly signed as // they aren't the correct type for signing. diff --git a/toolkit/mozapps/extensions/content/abuse-reports.js b/toolkit/mozapps/extensions/content/abuse-reports.js index c6461a071b..38fa0f9f46 100644 --- a/toolkit/mozapps/extensions/content/abuse-reports.js +++ b/toolkit/mozapps/extensions/content/abuse-reports.js @@ -185,7 +185,7 @@ async function openAbuseReport({ addonId, reportEntryPoint }) { // to be async, but it is so that both the implementations will be providing // the same type signatures (returning a promise) to the callers, independently // from which abuse reporting feature is enabled. -async function openAbuseReportAMOForm({ addonId, reportEntryPoint }) { +async function openAbuseReportAMOForm({ addonId }) { const amoUrl = AbuseReporter.getAMOFormURL({ addonId }); windowRoot.ownerGlobal.openTrustedLinkIn(amoUrl, "tab", { // Make sure the newly open tab is going to be focused, independently diff --git a/toolkit/mozapps/extensions/content/shortcuts.js b/toolkit/mozapps/extensions/content/shortcuts.js index 59420226df..99ab1c5161 100644 --- a/toolkit/mozapps/extensions/content/shortcuts.js +++ b/toolkit/mozapps/extensions/content/shortcuts.js @@ -283,7 +283,7 @@ ChromeUtils.defineESModuleGetters(this, { } return Object.entries(modifierMap) - .filter(([key, isDown]) => isDown) + .filter(([, isDown]) => isDown) .map(([key]) => key) .concat(getStringForEvent(e)) .join("+"); diff --git a/toolkit/mozapps/extensions/content/view-controller.js b/toolkit/mozapps/extensions/content/view-controller.js index 978a44d176..b82c1d6e6d 100644 --- a/toolkit/mozapps/extensions/content/view-controller.js +++ b/toolkit/mozapps/extensions/content/view-controller.js @@ -89,7 +89,7 @@ var gViewController = { } }, - observe(subject, topic, data) { + observe(subject, topic) { if (topic == "EM-ping") { this.readyForLoadView = true; Services.obs.notifyObservers(window, "EM-pong"); diff --git a/toolkit/mozapps/extensions/internal/AddonRepository.sys.mjs b/toolkit/mozapps/extensions/internal/AddonRepository.sys.mjs index e53e4af7a4..8d4d178924 100644 --- a/toolkit/mozapps/extensions/internal/AddonRepository.sys.mjs +++ b/toolkit/mozapps/extensions/internal/AddonRepository.sys.mjs @@ -466,13 +466,13 @@ export var AddonRepository = { request.open("GET", url, true); request.responseType = "json"; - request.addEventListener("error", aEvent => { + request.addEventListener("error", () => { reject(new Error(`GET ${url} failed`)); }); - request.addEventListener("timeout", aEvent => { + request.addEventListener("timeout", () => { reject(new Error(`GET ${url} timed out`)); }); - request.addEventListener("load", aEvent => { + request.addEventListener("load", () => { let response = request.response; if (!response || (request.status != 200 && request.status != 0)) { reject(new Error(`GET ${url} failed (status ${request.status})`)); diff --git a/toolkit/mozapps/extensions/internal/AddonTestUtils.sys.mjs b/toolkit/mozapps/extensions/internal/AddonTestUtils.sys.mjs index f53d32092d..7e4adacd11 100644 --- a/toolkit/mozapps/extensions/internal/AddonTestUtils.sys.mjs +++ b/toolkit/mozapps/extensions/internal/AddonTestUtils.sys.mjs @@ -3,7 +3,7 @@ */ /* eslint "mozilla/no-aArgs": 1 */ -/* eslint "no-unused-vars": [2, {"args": "none", "varsIgnorePattern": "^(Cc|Ci|Cr|Cu|EXPORTED_SYMBOLS)$"}] */ +/* eslint "no-unused-vars": [2, {"argsIgnorePattern": "^_", "varsIgnorePattern": "^(Cc|Ci|Cr|Cu|EXPORTED_SYMBOLS)$"}] */ /* eslint "semi": [2, "always"] */ /* eslint "valid-jsdoc": [2, {requireReturn: false}] */ @@ -424,6 +424,35 @@ export var AddonTestUtils = { }); }, + getXPIExports() { + return ChromeUtils.importESModule( + "resource://gre/modules/addons/XPIExports.sys.mjs" + ).XPIExports; + }, + + getWeakSignatureInstallPrefName() { + return this.getXPIExports().XPIInstall.getWeakSignatureInstallPrefName(); + }, + + setWeakSignatureInstallAllowed(allowed) { + const prefName = this.getWeakSignatureInstallPrefName(); + let cleanupCalled = false; + const cleanup = () => { + if (cleanupCalled) { + return; + } + this.testScope.info( + `=== clear ${prefName} pref value set by this test file ===` + ); + Services.prefs.clearUserPref(prefName); + cleanupCalled = true; + }; + this.testScope.registerCleanupFunction(cleanup); + this.testScope.info(`=== set ${prefName} pref value to ${allowed} ===`); + Services.prefs.setBoolPref(prefName, allowed); + return cleanup; + }, + /** * Iterates over the entries in a given directory. * diff --git a/toolkit/mozapps/extensions/internal/GMPProvider.sys.mjs b/toolkit/mozapps/extensions/internal/GMPProvider.sys.mjs index aaac109fc0..22ca2365d1 100644 --- a/toolkit/mozapps/extensions/internal/GMPProvider.sys.mjs +++ b/toolkit/mozapps/extensions/internal/GMPProvider.sys.mjs @@ -340,7 +340,7 @@ GMPWrapper.prototype = { return { source: "gmp-plugin" }; }, - isCompatibleWith(aAppVersion, aPlatformVersion) { + isCompatibleWith() { return true; }, @@ -377,7 +377,7 @@ GMPWrapper.prototype = { * Widevine is not yet installed, or if the user toggles prefs to enable EME. * For the function used in those cases see `checkForUpdates`. */ - findUpdates(aListener, aReason, aAppVersion, aPlatformVersion) { + findUpdates(aListener, aReason) { this._log.trace( "findUpdates() - " + this._plugin.id + " - reason=" + aReason ); @@ -895,7 +895,7 @@ var GMPProvider = { } }, - observe(subject, topic, data) { + observe(subject, topic) { if (topic == FIRST_CONTENT_PROCESS_TOPIC) { lazy.AddonManagerPrivate.registerProvider(GMPProvider, ["plugin"]); Services.obs.notifyObservers(null, "gmp-provider-registered"); diff --git a/toolkit/mozapps/extensions/internal/ProductAddonChecker.sys.mjs b/toolkit/mozapps/extensions/internal/ProductAddonChecker.sys.mjs index 1615a551c8..64b337af3f 100644 --- a/toolkit/mozapps/extensions/internal/ProductAddonChecker.sys.mjs +++ b/toolkit/mozapps/extensions/internal/ProductAddonChecker.sys.mjs @@ -118,12 +118,18 @@ async function conservativeFetch(input) { * @param contentSignatureHeader * The contents of the 'content-signature' header received along with * `data`. + * @param trustedRoot + * The identifier of the trusted root to use for certificate validation. * @return A promise that will resolve to nothing if the signature verification * succeeds, or rejects on failure, with an Error that sets its * addonCheckerErr property disambiguate failure cases and a message * explaining the error. */ -async function verifyGmpContentSignature(data, contentSignatureHeader) { +async function verifyGmpContentSignature( + data, + contentSignatureHeader, + trustedRoot +) { if (!contentSignatureHeader) { logger.warn( "Unexpected missing content signature header during content signature validation" @@ -186,13 +192,6 @@ async function verifyGmpContentSignature(data, contentSignatureHeader) { "@mozilla.org/security/contentsignatureverifier;1" ].createInstance(Ci.nsIContentSignatureVerifier); - // See bug 1771992. In the future, this may need to handle staging and dev - // environments in addition to just production and testing. - let root = Ci.nsIContentSignatureVerifier.ContentSignatureProdRoot; - if (Services.env.exists("XPCSHELL_TEST_PROFILE_DIR")) { - root = Ci.nsIX509CertDB.AppXPCShellRoot; - } - let valid; try { valid = await verifier.asyncVerifyContentSignature( @@ -200,7 +199,7 @@ async function verifyGmpContentSignature(data, contentSignatureHeader) { signature, certChain, "aus.content-signature.mozilla.org", - root + trustedRoot ); } catch (err) { logger.warn(`Unexpected error while validating content signature: ${err}`); @@ -329,6 +328,9 @@ function downloadXMLWithRequest( * @param verifyContentSignature * When true, will verify the content signature information from the * response header. Failure to verify will result in an error. + * @param trustedContentSignatureRoot + * The trusted root to use for certificate validation. + * Must be set if verifyContentSignature is true. * @return a promise that resolves to the DOM document downloaded or rejects * with a JS exception in case of error. */ @@ -336,7 +338,8 @@ async function downloadXML( url, allowNonBuiltIn = false, allowedCerts = null, - verifyContentSignature = false + verifyContentSignature = false, + trustedContentSignatureRoot = null ) { let request = await downloadXMLWithRequest( url, @@ -346,7 +349,8 @@ async function downloadXML( if (verifyContentSignature) { await verifyGmpContentSignature( request.response, - request.getResponseHeader("content-signature") + request.getResponseHeader("content-signature"), + trustedContentSignatureRoot ); } return request.responseXML; @@ -422,7 +426,7 @@ function downloadFile(url, options = { httpsOnlyNoUpgrade: false }) { return new Promise((resolve, reject) => { let sr = new lazy.ServiceRequest(); - sr.onload = function (response) { + sr.onload = function () { logger.info("downloadFile File download. status=" + sr.status); if (sr.status != 200 && sr.status != 206) { reject(Components.Exception("File download failed", sr.status)); @@ -535,6 +539,9 @@ export const ProductAddonChecker = { * @param verifyContentSignature * When true, will verify the content signature information from the * response header. Failure to verify will result in an error. + * @param trustedContentSignatureRoot + * The trusted root to use for certificate validation. + * Must be set if verifyContentSignature is true. * @return a promise that resolves to an object containing the list of add-ons * and whether the local fallback was used, or rejects with a JS * exception in case of error. In the case of an error, a best effort @@ -545,13 +552,15 @@ export const ProductAddonChecker = { url, allowNonBuiltIn = false, allowedCerts = null, - verifyContentSignature = false + verifyContentSignature = false, + trustedContentSignatureRoot = null ) { return downloadXML( url, allowNonBuiltIn, allowedCerts, - verifyContentSignature + verifyContentSignature, + trustedContentSignatureRoot ).then(parseXML); }, diff --git a/toolkit/mozapps/extensions/internal/SitePermsAddonProvider.sys.mjs b/toolkit/mozapps/extensions/internal/SitePermsAddonProvider.sys.mjs index 7ca952dc8a..8af3c2affe 100644 --- a/toolkit/mozapps/extensions/internal/SitePermsAddonProvider.sys.mjs +++ b/toolkit/mozapps/extensions/internal/SitePermsAddonProvider.sys.mjs @@ -190,7 +190,7 @@ class SitePermsAddonWrapper { return 0; } - async updateBlocklistState(options = {}) {} + async updateBlocklistState() {} get blocklistState() { return Ci.nsIBlocklistService.STATE_NOT_BLOCKED; @@ -277,7 +277,7 @@ class SitePermsAddonWrapper { return { source: "siteperm-addon-provider", method: "synthetic-install" }; } - isCompatibleWith(aAppVersion, aPlatformVersion) { + isCompatibleWith() { return true; } } diff --git a/toolkit/mozapps/extensions/internal/XPIDatabase.sys.mjs b/toolkit/mozapps/extensions/internal/XPIDatabase.sys.mjs index af0b02444a..d7541167fa 100644 --- a/toolkit/mozapps/extensions/internal/XPIDatabase.sys.mjs +++ b/toolkit/mozapps/extensions/internal/XPIDatabase.sys.mjs @@ -31,6 +31,7 @@ ChromeUtils.defineESModuleGetters(lazy, { DeferredTask: "resource://gre/modules/DeferredTask.sys.mjs", ExtensionData: "resource://gre/modules/Extension.sys.mjs", ExtensionUtils: "resource://gre/modules/ExtensionUtils.sys.mjs", + ObjectUtils: "resource://gre/modules/ObjectUtils.sys.mjs", PermissionsUtils: "resource://gre/modules/PermissionsUtils.sys.mjs", QuarantinedDomains: "resource://gre/modules/ExtensionPermissions.sys.mjs", }); @@ -192,6 +193,7 @@ const PROP_JSON_FIELDS = [ "targetApplications", "targetPlatforms", "signedState", + "signedTypes", "signedDate", "seen", "dependencies", @@ -1556,6 +1558,7 @@ function defineAddonWrapperProperty(name, getter) { "validInstallOrigins", "dependencies", "signedState", + "signedTypes", "sitePermissions", "siteOrigin", "isCorrectlySigned", @@ -2175,7 +2178,7 @@ export const XPIDatabase = { */ async verifySignatures() { try { - let addons = await this.getAddonList(a => true); + let addons = await this.getAddonList(() => true); let changes = { enabled: [], @@ -2188,17 +2191,31 @@ export const XPIDatabase = { continue; } - let signedState = await XPIExports.verifyBundleSignedState( - addon._sourceBundle, - addon - ); + let { signedState, signedTypes } = + await XPIExports.verifyBundleSignedState(addon._sourceBundle, addon); + + const changedProperties = []; if (signedState != addon.signedState) { addon.signedState = signedState; + changedProperties.push("signedState"); + } + + if ( + !lazy.ObjectUtils.deepEqual( + signedTypes?.toSorted(), + addon.signedTypes?.toSorted() + ) + ) { + addon.signedTypes = signedTypes; + changedProperties.push("signedTypes"); + } + + if (changedProperties.length) { lazy.AddonManagerPrivate.callAddonListeners( "onPropertyChanged", addon.wrapper, - ["signedState"] + changedProperties ); } @@ -2426,7 +2443,7 @@ export const XPIDatabase = { if (!this.addonDB) { return []; } - return _filterDB(this.addonDB, aAddon => true); + return _filterDB(this.addonDB, () => true); }, /** @@ -3084,24 +3101,11 @@ export const XPIDatabaseReconcile = { * The new state of the add-on * @param {AddonInternal?} [aNewAddon] * The manifest for the new add-on if it has already been loaded - * @param {string?} [aOldAppVersion] - * The version of the application last run with this profile or null - * if it is a new profile or the version is unknown - * @param {string?} [aOldPlatformVersion] - * The version of the platform last run with this profile or null - * if it is a new profile or the version is unknown * @returns {boolean} * A boolean indicating if flushing caches is required to complete * changing this add-on */ - addMetadata( - aLocation, - aId, - aAddonState, - aNewAddon, - aOldAppVersion, - aOldPlatformVersion - ) { + addMetadata(aLocation, aId, aAddonState, aNewAddon) { logger.debug(`New add-on ${aId} installed in ${aLocation.name}`); // We treat this is a new install if, @@ -3348,6 +3352,10 @@ export const XPIDatabaseReconcile = { let signedDateMissing = aOldAddon.signedDate === undefined && (aOldAddon.signedState || checkSigning); + // signedTypes must be set if signedState is set. + let signedTypesMissing = + aOldAddon.signedTypes === undefined && + (aOldAddon.signedState || checkSigning); // If maxVersion was inadvertently updated for a locale, force a reload // from the manifest. See Bug 1646016 for details. @@ -3360,7 +3368,12 @@ export const XPIDatabaseReconcile = { } let manifest = null; - if (checkSigning || aReloadMetadata || signedDateMissing) { + if ( + checkSigning || + aReloadMetadata || + signedDateMissing || + signedTypesMissing + ) { try { manifest = XPIExports.XPIInstall.syncLoadManifest( aAddonState, @@ -3384,6 +3397,10 @@ export const XPIDatabaseReconcile = { aOldAddon.signedDate = manifest.signedDate; } + if (signedTypesMissing) { + aOldAddon.signedTypes = manifest.signedTypes; + } + // May be updating from a version of the app that didn't support all the // properties of the currently-installed add-ons. if (aReloadMetadata) { diff --git a/toolkit/mozapps/extensions/internal/XPIInstall.sys.mjs b/toolkit/mozapps/extensions/internal/XPIInstall.sys.mjs index 0402c2f2ca..4a26785da8 100644 --- a/toolkit/mozapps/extensions/internal/XPIInstall.sys.mjs +++ b/toolkit/mozapps/extensions/internal/XPIInstall.sys.mjs @@ -21,6 +21,7 @@ import { XPIExports } from "resource://gre/modules/addons/XPIExports.sys.mjs"; import { computeSha256HashAsString, getHashStringForCrypto, + hasStrongSignature, } from "resource://gre/modules/addons/crypto-utils.sys.mjs"; import { AppConstants } from "resource://gre/modules/AppConstants.sys.mjs"; import { @@ -94,6 +95,9 @@ const PREF_XPI_ENABLED = "xpinstall.enabled"; const PREF_XPI_DIRECT_WHITELISTED = "xpinstall.whitelist.directRequest"; const PREF_XPI_FILE_WHITELISTED = "xpinstall.whitelist.fileRequest"; const PREF_XPI_WHITELIST_REQUIRED = "xpinstall.whitelist.required"; +const PREF_XPI_WEAK_SIGNATURES_ALLOWED = + "xpinstall.signatures.weakSignaturesTemporarilyAllowed"; +const PREF_XPI_WEAK_SIGNATURES_ALLOWED_DEFAULT = true; const PREF_SELECTED_THEME = "extensions.activeThemeID"; @@ -230,7 +234,15 @@ class Package { let root = Ci.nsIX509CertDB.AddonsPublicRoot; if ( - !AppConstants.MOZ_REQUIRE_SIGNING && + (!AppConstants.MOZ_REQUIRE_SIGNING || + // Allow mochitests to switch to dev-root on all channels. + Cu.isInAutomation || + // Allow xpcshell tests to switch to dev-root on all channels, + // included tests where "security.turn_off_all_security_so_that_viruses_can_take_over_this_computer" + // pref is set to false and Cu.isInAutomation is going to be false (e.g. test_signed_langpack.js). + // TODO(Bug 1598804): we should be able to remove the following checks once Cu.isAutomation is fixed. + (Services.env.exists("XPCSHELL_TEST_PROFILE_DIR") && + Services.appinfo.name === "XPCShell")) && Services.prefs.getBoolPref(PREF_XPI_SIGNATURES_DEV_ROOT, false) ) { root = Ci.nsIX509CertDB.AddonsStageRoot; @@ -287,7 +299,7 @@ DirPackage = class DirPackage extends Package { return IOUtils.read(PathUtils.join(this.filePath, ...path)); } - async verifySignedStateForRoot(addonId, root) { + async verifySignedStateForRoot() { return { signedState: AddonManager.SIGNEDSTATE_UNKNOWN, cert: null }; } }; @@ -341,8 +353,11 @@ XPIPackage = class XPIPackage extends Package { aZipReader.close(); } resolve({ - signedState: getSignedStatus(aRv, cert, addonId), cert, + signedState: getSignedStatus(aRv, cert, addonId), + signedTypes: aSignatureInfos?.map( + signatureInfo => signatureInfo.signatureAlgorithm + ), }); }, }; @@ -511,17 +526,18 @@ async function loadManifestFromWebManifest(aPackage, aLocation) { addon.siteOrigin = manifest.install_origins[0]; } - if (manifest.options_ui) { + const { optionsPageProperties } = extension; + if (optionsPageProperties) { // Store just the relative path here, the AddonWrapper getURL // wrapper maps this to a full URL. - addon.optionsURL = manifest.options_ui.page; - if (manifest.options_ui.open_in_tab) { + addon.optionsURL = optionsPageProperties.page; + if (optionsPageProperties.open_in_tab) { addon.optionsType = AddonManager.OPTIONS_TYPE_TAB; } else { addon.optionsType = AddonManager.OPTIONS_TYPE_INLINE_BROWSER; } - addon.optionsBrowserStyle = manifest.options_ui.browser_style; + addon.optionsBrowserStyle = optionsPageProperties.browser_style; } // WebExtensions don't use iconURLs @@ -693,9 +709,13 @@ var loadManifest = async function (aPackage, aLocation, aOldAddon) { addon.rootURI = aPackage.rootURI.spec; addon.location = aLocation; - let { signedState, cert } = verifiedSignedState; + let { cert, signedState, signedTypes } = verifiedSignedState; addon.signedState = signedState; addon.signedDate = cert?.validity?.notBefore / 1000 || null; + // An array of the algorithms used by the signatures found in the signed XPI files, + // as an array of integers (see nsIAppSignatureInfo_SignatureAlgorithm enum defined + // in nsIX509CertDB.idl). + addon.signedTypes = signedTypes; if (!addon.id) { if (cert) { @@ -909,18 +929,21 @@ function shouldVerifySignedState(aAddonType, aLocation) { * The nsIFile for the bundle to check, either a directory or zip file. * @param {AddonInternal} aAddon * The add-on object to verify. - * @returns {Promise} - * A Promise that resolves to an AddonManager.SIGNEDSTATE_* constant. + * @returns {Promise<{ signedState: number, signedTypes: Array}>?} + * A Promise that resolves to object including a signedState property set to + * an AddonManager.SIGNEDSTATE_* constant and a signedTypes property set to + * either an array of Ci.nsIAppSignatureInfo SignatureAlgorithm enum values + * or undefined if the file wasn't signed. */ export var verifyBundleSignedState = async function (aBundle, aAddon) { let pkg = Package.get(aBundle); try { - let { signedState } = await pkg.verifySignedState( + let { signedState, signedTypes } = await pkg.verifySignedState( aAddon.id, aAddon.type, aAddon.location ); - return signedState; + return { signedState, signedTypes }; } finally { pkg.close(); } @@ -1633,6 +1656,49 @@ class AddonInstall { "signature verification failed", ]); } + + // Restrict install for signed extension only signed with weak signature algorithms, unless the + // restriction is explicitly disabled through prefs or enterprise policies. + if ( + !XPIInstall.isWeakSignatureInstallAllowed() && + this.addon.signedDate && + !hasStrongSignature(this.addon) + ) { + const addonAllowedByPolicies = Services.policies.getExtensionSettings( + this.addon.id + )?.temporarily_allow_weak_signatures; + + const globallyAllowedByPolicies = + Services.policies.getExtensionSettings( + "*" + )?.temporarily_allow_weak_signatures; + + const allowedByPolicies = + (globallyAllowedByPolicies && + (addonAllowedByPolicies || addonAllowedByPolicies == null)) || + addonAllowedByPolicies; + + if ( + !allowedByPolicies && + (!this.existingAddon || hasStrongSignature(this.existingAddon)) + ) { + // Reject if it is a new install or installing over an existing addon including + // strong cryptographic signatures. + return Promise.reject([ + AddonManager.ERROR_CORRUPT_FILE, + "install rejected due to the package not including a strong cryptographic signature", + ]); + } + + // Still allow installs using weak signatures to install if either: + // - it is explicitly allowed through Enterprise Policies Settings + // - or there is an existing addon with a weak signature. + logger.warn( + allowedByPolicies + ? `Allow weak signature install for ${this.addon.id} XPI due to Enterprise Policies` + : `Allow weak signature install over existing "${this.existingAddon.id}" XPI` + ); + } } } finally { pkg.close(); @@ -2321,7 +2387,7 @@ var DownloadAddonInstall = class extends AddonInstall { } } - observe(aSubject, aTopic, aData) { + observe() { // Network is going offline this.cancel(); } @@ -2592,7 +2658,7 @@ var DownloadAddonInstall = class extends AddonInstall { new UpdateChecker( this.addon, { - onUpdateFinished: aAddon => this.downloadCompleted(), + onUpdateFinished: () => this.downloadCompleted(), }, AddonManager.UPDATE_WHEN_ADDON_INSTALLED ); @@ -3880,7 +3946,7 @@ class SystemAddonInstaller extends DirectoryInstaller { } // old system add-on upgrade dirs get automatically removed - uninstallAddon(aAddon) {} + uninstallAddon() {} } var AppUpdate = { @@ -4344,6 +4410,17 @@ export var XPIInstall = { return Services.prefs.getBoolPref(PREF_XPI_FILE_WHITELISTED, true); }, + isWeakSignatureInstallAllowed() { + return Services.prefs.getBoolPref( + PREF_XPI_WEAK_SIGNATURES_ALLOWED, + PREF_XPI_WEAK_SIGNATURES_ALLOWED_DEFAULT + ); + }, + + getWeakSignatureInstallPrefName() { + return PREF_XPI_WEAK_SIGNATURES_ALLOWED; + }, + /** * Called to test whether installing XPI add-ons from a URI is allowed. * diff --git a/toolkit/mozapps/extensions/internal/XPIProvider.sys.mjs b/toolkit/mozapps/extensions/internal/XPIProvider.sys.mjs index 12d4fa1172..3c090b5f0f 100644 --- a/toolkit/mozapps/extensions/internal/XPIProvider.sys.mjs +++ b/toolkit/mozapps/extensions/internal/XPIProvider.sys.mjs @@ -120,7 +120,7 @@ const XPI_PERMISSION = "install"; const XPI_SIGNATURE_CHECK_PERIOD = 24 * 60 * 60; -const DB_SCHEMA = 35; +const DB_SCHEMA = 36; XPCOMUtils.defineLazyPreferenceGetter( lazy, @@ -1598,7 +1598,7 @@ var XPIStates = { * * @returns {XPIState?} */ - findAddon(aId, aFilter = location => true) { + findAddon(aId, aFilter = () => true) { // Fortunately the Map iterator returns in order of insertion, which is // also our highest -> lowest priority order. for (let location of this.locations()) { @@ -2706,7 +2706,7 @@ export var XPIProvider = { "profile-before-change", "test-load-xpi-database", ]; - let observer = (subject, topic, data) => { + let observer = (subject, topic) => { if ( topic == "xul-window-visible" && !Services.wm.getMostRecentWindow("devtools:toolbox") diff --git a/toolkit/mozapps/extensions/internal/crypto-utils.sys.mjs b/toolkit/mozapps/extensions/internal/crypto-utils.sys.mjs index b1304bcdfc..9ef096df0f 100644 --- a/toolkit/mozapps/extensions/internal/crypto-utils.sys.mjs +++ b/toolkit/mozapps/extensions/internal/crypto-utils.sys.mjs @@ -8,6 +8,14 @@ const CryptoHash = Components.Constructor( "initWithString" ); +const XPI_WEAK_SIGNATURES = [Ci.nsIAppSignatureInfo.PKCS7_WITH_SHA1]; + +export function hasStrongSignature(addon) { + return !!addon.signedTypes?.filter( + algorithm => !XPI_WEAK_SIGNATURES.includes(algorithm) + ).length; +} + export function computeHashAsString(hashType, input) { const data = new Uint8Array(new TextEncoder().encode(input)); const crypto = CryptoHash(hashType); @@ -42,7 +50,7 @@ export function computeSha1HashAsString(input) { /** * Returns the string representation (hex) of a given CryptoHashInstance. * - * @param {CryptoHash} aCrypto + * @param {nsICryptoHash} aCrypto * @returns {string} * The hex representation of a SHA256 hash. */ diff --git a/toolkit/mozapps/extensions/test/browser/.eslintrc.js b/toolkit/mozapps/extensions/test/browser/.eslintrc.js index f2b9e072f9..6987757bdc 100644 --- a/toolkit/mozapps/extensions/test/browser/.eslintrc.js +++ b/toolkit/mozapps/extensions/test/browser/.eslintrc.js @@ -8,7 +8,7 @@ module.exports = { rules: { "no-unused-vars": [ "error", - { args: "none", varsIgnorePattern: "^end_test$" }, + { argsIgnorePattern: "^_", varsIgnorePattern: "^end_test$" }, ], }, }; diff --git a/toolkit/mozapps/extensions/test/browser/addons/browser_dragdrop1/META-INF/manifest.mf b/toolkit/mozapps/extensions/test/browser/addons/browser_dragdrop1/META-INF/manifest.mf deleted file mode 100644 index 725ac8016f..0000000000 --- a/toolkit/mozapps/extensions/test/browser/addons/browser_dragdrop1/META-INF/manifest.mf +++ /dev/null @@ -1,8 +0,0 @@ -Manifest-Version: 1.0 - -Name: manifest.json -Digest-Algorithms: MD5 SHA1 SHA256 -MD5-Digest: mCLu38qfGN3trj7qKQQeEA== -SHA1-Digest: A1BaJErQY6KqnYDijP0lglrehk0= -SHA256-Digest: p2vjGP7DRqrK81NfT4LqnF7a5p8+lEuout5WLBhk9AA= - diff --git a/toolkit/mozapps/extensions/test/browser/addons/browser_dragdrop1/META-INF/mozilla.rsa b/toolkit/mozapps/extensions/test/browser/addons/browser_dragdrop1/META-INF/mozilla.rsa deleted file mode 100644 index 046a0285c7..0000000000 Binary files a/toolkit/mozapps/extensions/test/browser/addons/browser_dragdrop1/META-INF/mozilla.rsa and /dev/null differ diff --git a/toolkit/mozapps/extensions/test/browser/addons/browser_dragdrop1/META-INF/mozilla.sf b/toolkit/mozapps/extensions/test/browser/addons/browser_dragdrop1/META-INF/mozilla.sf deleted file mode 100644 index ad4e81b574..0000000000 --- a/toolkit/mozapps/extensions/test/browser/addons/browser_dragdrop1/META-INF/mozilla.sf +++ /dev/null @@ -1,5 +0,0 @@ -Signature-Version: 1.0 -MD5-Digest-Manifest: LrrwWBKNYWeVd205Hq+JwQ== -SHA1-Digest-Manifest: MeqqQN+uuf0MVesMXxbBtYN+5tU= -SHA256-Digest-Manifest: iWCxfAJX593Cn4l8R63jaQETO5HX3XOhcnpQ7nMiPlg= - diff --git a/toolkit/mozapps/extensions/test/browser/addons/browser_dragdrop2/META-INF/manifest.mf b/toolkit/mozapps/extensions/test/browser/addons/browser_dragdrop2/META-INF/manifest.mf deleted file mode 100644 index 1da3c41b23..0000000000 --- a/toolkit/mozapps/extensions/test/browser/addons/browser_dragdrop2/META-INF/manifest.mf +++ /dev/null @@ -1,8 +0,0 @@ -Manifest-Version: 1.0 - -Name: manifest.json -Digest-Algorithms: MD5 SHA1 SHA256 -MD5-Digest: 3dL7JFDBPC63pSFI5x+Z7Q== -SHA1-Digest: l1cKPyWJIYdZyvumH9VfJ6fpqVA= -SHA256-Digest: QHTjPqTMXxt5tl8zOaAzpQ8FZLqZx8LRF9LmzY+RCDQ= - diff --git a/toolkit/mozapps/extensions/test/browser/addons/browser_dragdrop2/META-INF/mozilla.rsa b/toolkit/mozapps/extensions/test/browser/addons/browser_dragdrop2/META-INF/mozilla.rsa deleted file mode 100644 index 170a361620..0000000000 Binary files a/toolkit/mozapps/extensions/test/browser/addons/browser_dragdrop2/META-INF/mozilla.rsa and /dev/null differ diff --git a/toolkit/mozapps/extensions/test/browser/addons/browser_dragdrop2/META-INF/mozilla.sf b/toolkit/mozapps/extensions/test/browser/addons/browser_dragdrop2/META-INF/mozilla.sf deleted file mode 100644 index 5301e431f7..0000000000 --- a/toolkit/mozapps/extensions/test/browser/addons/browser_dragdrop2/META-INF/mozilla.sf +++ /dev/null @@ -1,5 +0,0 @@ -Signature-Version: 1.0 -MD5-Digest-Manifest: c30hzcI1ISlt46ODjVVJ2w== -SHA1-Digest-Manifest: 2yMpQHuLM0J61T7vt11NHoYI1tU= -SHA256-Digest-Manifest: qtsYxiv1zGWBp7JWxLWrIztIdxIt+i3CToReEx5fkyw= - diff --git a/toolkit/mozapps/extensions/test/browser/addons/browser_dragdrop_incompat/META-INF/manifest.mf b/toolkit/mozapps/extensions/test/browser/addons/browser_dragdrop_incompat/META-INF/manifest.mf deleted file mode 100644 index e508bcd22f..0000000000 --- a/toolkit/mozapps/extensions/test/browser/addons/browser_dragdrop_incompat/META-INF/manifest.mf +++ /dev/null @@ -1,8 +0,0 @@ -Manifest-Version: 1.0 - -Name: manifest.json -Digest-Algorithms: MD5 SHA1 SHA256 -MD5-Digest: Wzo/k6fhArpFb4UB2hIKlg== -SHA1-Digest: D/WDy9api0X7OgRM6Gkvfbyzogo= -SHA256-Digest: IWBdbytHgPLtCMKKhiZ3jenxKmKiRAhh3ce8iP5AVWU= - diff --git a/toolkit/mozapps/extensions/test/browser/addons/browser_dragdrop_incompat/META-INF/mozilla.rsa b/toolkit/mozapps/extensions/test/browser/addons/browser_dragdrop_incompat/META-INF/mozilla.rsa deleted file mode 100644 index a026680e91..0000000000 Binary files a/toolkit/mozapps/extensions/test/browser/addons/browser_dragdrop_incompat/META-INF/mozilla.rsa and /dev/null differ diff --git a/toolkit/mozapps/extensions/test/browser/addons/browser_dragdrop_incompat/META-INF/mozilla.sf b/toolkit/mozapps/extensions/test/browser/addons/browser_dragdrop_incompat/META-INF/mozilla.sf deleted file mode 100644 index 16a1461f37..0000000000 --- a/toolkit/mozapps/extensions/test/browser/addons/browser_dragdrop_incompat/META-INF/mozilla.sf +++ /dev/null @@ -1,5 +0,0 @@ -Signature-Version: 1.0 -MD5-Digest-Manifest: ovtNeIie34gMM5l18zP2MA== -SHA1-Digest-Manifest: c5owdrvcOINxKp/HprYkWXXI/js= -SHA256-Digest-Manifest: uLPmoONlxFYxWeSTOEPJ9hN2yMDDZMJL1PoNIWcqKG4= - diff --git a/toolkit/mozapps/extensions/test/browser/addons/browser_installssl/META-INF/manifest.mf b/toolkit/mozapps/extensions/test/browser/addons/browser_installssl/META-INF/manifest.mf deleted file mode 100644 index eea5cbd501..0000000000 --- a/toolkit/mozapps/extensions/test/browser/addons/browser_installssl/META-INF/manifest.mf +++ /dev/null @@ -1,8 +0,0 @@ -Manifest-Version: 1.0 - -Name: manifest.json -Digest-Algorithms: MD5 SHA1 SHA256 -MD5-Digest: b4Q2C4GsIJfRLsXc7T2ldQ== -SHA1-Digest: UG5rHxpzKmdlGrquXaguiAGDu8E= -SHA256-Digest: WZrN9SdGBux9t3lV7TVIvyUG/L1px4er2dU3TsBpC4s= - diff --git a/toolkit/mozapps/extensions/test/browser/addons/browser_installssl/META-INF/mozilla.rsa b/toolkit/mozapps/extensions/test/browser/addons/browser_installssl/META-INF/mozilla.rsa deleted file mode 100644 index 68621e19be..0000000000 Binary files a/toolkit/mozapps/extensions/test/browser/addons/browser_installssl/META-INF/mozilla.rsa and /dev/null differ diff --git a/toolkit/mozapps/extensions/test/browser/addons/browser_installssl/META-INF/mozilla.sf b/toolkit/mozapps/extensions/test/browser/addons/browser_installssl/META-INF/mozilla.sf deleted file mode 100644 index fe6baa8dac..0000000000 --- a/toolkit/mozapps/extensions/test/browser/addons/browser_installssl/META-INF/mozilla.sf +++ /dev/null @@ -1,5 +0,0 @@ -Signature-Version: 1.0 -MD5-Digest-Manifest: zqRm8+jxS0iRUGWeArGkXg== -SHA1-Digest-Manifest: pa/31Ll1PYx0dPBQ6C+fd1/wJO4= -SHA256-Digest-Manifest: DJELIyswfwgeL0kaRqogXW2bzUKhn+Pickfv6WHBsW8= - diff --git a/toolkit/mozapps/extensions/test/browser/addons/options_signed/META-INF/manifest.mf b/toolkit/mozapps/extensions/test/browser/addons/options_signed/META-INF/manifest.mf deleted file mode 100644 index a8c72c4794..0000000000 --- a/toolkit/mozapps/extensions/test/browser/addons/options_signed/META-INF/manifest.mf +++ /dev/null @@ -1,12 +0,0 @@ -Manifest-Version: 1.0 - -Name: manifest.json -Digest-Algorithms: MD5 SHA1 -MD5-Digest: Rnoaa6yWePDor5y5/SLFaw== -SHA1-Digest: k51DtKj7bYrwkFJDdmYNDQeUBlA= - -Name: options.html -Digest-Algorithms: MD5 SHA1 -MD5-Digest: vTjxWlRpioEhTZGKTNUqIw== -SHA1-Digest: Y/mr6A34LsvekgRpdhyZRwPF1Vw= - diff --git a/toolkit/mozapps/extensions/test/browser/addons/options_signed/META-INF/mozilla.rsa b/toolkit/mozapps/extensions/test/browser/addons/options_signed/META-INF/mozilla.rsa deleted file mode 100644 index 8b6320adda..0000000000 Binary files a/toolkit/mozapps/extensions/test/browser/addons/options_signed/META-INF/mozilla.rsa and /dev/null differ diff --git a/toolkit/mozapps/extensions/test/browser/addons/options_signed/META-INF/mozilla.sf b/toolkit/mozapps/extensions/test/browser/addons/options_signed/META-INF/mozilla.sf deleted file mode 100644 index ba5fd22caa..0000000000 --- a/toolkit/mozapps/extensions/test/browser/addons/options_signed/META-INF/mozilla.sf +++ /dev/null @@ -1,4 +0,0 @@ -Signature-Version: 1.0 -MD5-Digest-Manifest: rdmx8VMNzkZ5tRf7tt8G1w== -SHA1-Digest-Manifest: gjtTe8X9Tg46Hz2h4Tru3T02hmE= - diff --git a/toolkit/mozapps/extensions/test/browser/addons/options_signed/manifest.json b/toolkit/mozapps/extensions/test/browser/addons/options_signed/manifest.json deleted file mode 100644 index e808cd5ab6..0000000000 --- a/toolkit/mozapps/extensions/test/browser/addons/options_signed/manifest.json +++ /dev/null @@ -1,11 +0,0 @@ -{ - "manifest_version": 2, - - "name": "Test options_ui", - "description": "Test add-ons manager handling options_ui with no id in manifest.json", - "version": "1.2", - - "options_ui": { - "page": "options.html" - } -} diff --git a/toolkit/mozapps/extensions/test/browser/addons/options_signed/options.html b/toolkit/mozapps/extensions/test/browser/addons/options_signed/options.html deleted file mode 100644 index ea804601b5..0000000000 --- a/toolkit/mozapps/extensions/test/browser/addons/options_signed/options.html +++ /dev/null @@ -1,9 +0,0 @@ - - - - - - -
- - diff --git a/toolkit/mozapps/extensions/test/browser/browser.toml b/toolkit/mozapps/extensions/test/browser/browser.toml index 0b4a2d8f0a..6556b95584 100644 --- a/toolkit/mozapps/extensions/test/browser/browser.toml +++ b/toolkit/mozapps/extensions/test/browser/browser.toml @@ -8,8 +8,6 @@ support-files = [ "addons/browser_dragdrop_incompat.xpi", "addons/browser_installssl.xpi", "addons/browser_theme.xpi", - "addons/options_signed.xpi", - "addons/options_signed/*", "addon_prefs.xhtml", "discovery/api_response.json", "discovery/api_response_empty.json", @@ -40,7 +38,6 @@ generated-files = [ "addons/browser_dragdrop_incompat.xpi", "addons/browser_installssl.xpi", "addons/browser_theme.xpi", - "addons/options_signed.xpi", ] skip-if = [ diff --git a/toolkit/mozapps/extensions/test/browser/browser_AMBrowserExtensionsImport.js b/toolkit/mozapps/extensions/test/browser/browser_AMBrowserExtensionsImport.js index 654e3cd91e..0d3956f941 100644 --- a/toolkit/mozapps/extensions/test/browser/browser_AMBrowserExtensionsImport.js +++ b/toolkit/mozapps/extensions/test/browser/browser_AMBrowserExtensionsImport.js @@ -43,7 +43,7 @@ const ADDON_SEARCH_RESULTS = {}; const mockAddonRepository = ({ addons = [] }) => { return { - async getMappedAddons(browserID, extensionIDs) { + async getMappedAddons() { return Promise.resolve({ addons, matchedIDs: [], diff --git a/toolkit/mozapps/extensions/test/browser/browser_bug572561.js b/toolkit/mozapps/extensions/test/browser/browser_bug572561.js index 6f8a56bfba..51493570da 100644 --- a/toolkit/mozapps/extensions/test/browser/browser_bug572561.js +++ b/toolkit/mozapps/extensions/test/browser/browser_bug572561.js @@ -17,22 +17,22 @@ var gInstallProperties = [ var gInstall; var gExpectedCancel = false; var gTestInstallListener = { - onInstallStarted(aInstall) { + onInstallStarted() { check_hidden(false); }, - onInstallEnded(aInstall) { + onInstallEnded() { check_hidden(false); run_next_test(); }, - onInstallCancelled(aInstall) { + onInstallCancelled() { ok(gExpectedCancel, "Should expect install cancel"); check_hidden(false); run_next_test(); }, - onInstallFailed(aInstall) { + onInstallFailed() { ok(false, "Did not expect onInstallFailed"); run_next_test(); }, diff --git a/toolkit/mozapps/extensions/test/browser/browser_dragdrop.js b/toolkit/mozapps/extensions/test/browser/browser_dragdrop.js index ae8625a18a..52881b39d1 100644 --- a/toolkit/mozapps/extensions/test/browser/browser_dragdrop.js +++ b/toolkit/mozapps/extensions/test/browser/browser_dragdrop.js @@ -16,7 +16,7 @@ const dragService = Cc["@mozilla.org/widget/dragservice;1"].getService( async function checkInstallConfirmation(...names) { let notificationCount = 0; let observer = { - observe(aSubject, aTopic, aData) { + observe(aSubject) { let installInfo = aSubject.wrappedJSObject; isnot( installInfo.browser, diff --git a/toolkit/mozapps/extensions/test/browser/browser_html_abuse_report.js b/toolkit/mozapps/extensions/test/browser/browser_html_abuse_report.js index 3ad8510aea..f20e5b357b 100644 --- a/toolkit/mozapps/extensions/test/browser/browser_html_abuse_report.js +++ b/toolkit/mozapps/extensions/test/browser/browser_html_abuse_report.js @@ -603,7 +603,7 @@ add_task(async function test_abusereport_messagebars() { await AbuseReportTestUtils.promiseReportRendered(); AbuseReportTestUtils.triggerSubmit("fake-reason", "fake-message"); }, - ([submittingDetails, submittedDetails]) => { + ([, submittedDetails]) => { const buttonsL10nId = Array.from( submittedDetails.messagebar.querySelectorAll("button") ).map(el => el.getAttribute("data-l10n-id")); @@ -634,10 +634,8 @@ add_task(async function test_abusereport_messagebars() { await addon.uninstall(true); AbuseReportTestUtils.triggerSubmit("fake-reason", "fake-message"); }; - const assertMessageBarDetails = async ([ - submittingDetails, - submittedDetails, - ]) => AbuseReportTestUtils.assertFluentStrings(submittedDetails.messagebar); + const assertMessageBarDetails = async ([, submittedDetails]) => + AbuseReportTestUtils.assertFluentStrings(submittedDetails.messagebar); await assertMessageBars( ["submitting", "submitted-and-removed"], testFn, @@ -657,7 +655,7 @@ add_task(async function test_abusereport_messagebars() { await AbuseReportTestUtils.promiseReportRendered(); AbuseReportTestUtils.triggerSubmit("fake-reason", "fake-message"); }, - ([submittingDetails, submittedDetails]) => + ([, submittedDetails]) => AbuseReportTestUtils.assertFluentStrings(submittedDetails.messagebar) ); diff --git a/toolkit/mozapps/extensions/test/browser/browser_html_detail_permissions.js b/toolkit/mozapps/extensions/test/browser/browser_html_detail_permissions.js index 939fe421c3..32543f3bc9 100644 --- a/toolkit/mozapps/extensions/test/browser/browser_html_detail_permissions.js +++ b/toolkit/mozapps/extensions/test/browser/browser_html_detail_permissions.js @@ -613,7 +613,7 @@ add_task(async function testPermissionsViewStates() { let card = getAddonCard(view, addon.id); await Assert.rejects( card.setAddonPermission("webRequest", "permission", "add"), - /permission missing from manifest/, + /was not declared in optional_permissions/, "unable to set the addon permission" ); diff --git a/toolkit/mozapps/extensions/test/browser/browser_html_discover_view.js b/toolkit/mozapps/extensions/test/browser/browser_html_discover_view.js index bc84ffaf89..30cb45dc60 100644 --- a/toolkit/mozapps/extensions/test/browser/browser_html_discover_view.js +++ b/toolkit/mozapps/extensions/test/browser/browser_html_discover_view.js @@ -76,7 +76,7 @@ class DiscoveryAPIHandler { }); } - unblockResponses(responseText) { + unblockResponses() { throw new Error("You need to call blockNextResponses first!"); } diff --git a/toolkit/mozapps/extensions/test/browser/browser_html_list_view_recommendations.js b/toolkit/mozapps/extensions/test/browser/browser_html_list_view_recommendations.js index db4067ab35..bc6ae47a8f 100644 --- a/toolkit/mozapps/extensions/test/browser/browser_html_list_view_recommendations.js +++ b/toolkit/mozapps/extensions/test/browser/browser_html_list_view_recommendations.js @@ -119,7 +119,7 @@ async function installAddon({ card, recommendedList, manifestExtra = {} }) { return extension; } -async function testListRecommendations({ type, manifestExtra = {} }) { +async function testListRecommendations({ type }) { let win = await loadInitialView(type); let doc = win.document; diff --git a/toolkit/mozapps/extensions/test/browser/browser_html_options_ui_in_tab.js b/toolkit/mozapps/extensions/test/browser/browser_html_options_ui_in_tab.js index 68faecfec0..fec3911bcd 100644 --- a/toolkit/mozapps/extensions/test/browser/browser_html_options_ui_in_tab.js +++ b/toolkit/mozapps/extensions/test/browser/browser_html_options_ui_in_tab.js @@ -10,15 +10,19 @@ add_task(async function enableHtmlViews() { }); }); -async function testOptionsInTab({ id, options_ui_options }) { +async function testOptionsInTab({ + id, + options_ui_options = {}, + manifest = { + manifest_version: 2, + options_ui: { page: "options.html", ...options_ui_options }, + }, +}) { let extension = ExtensionTestUtils.loadExtension({ manifest: { name: "Prefs extension", browser_specific_settings: { gecko: { id } }, - options_ui: { - page: "options.html", - ...options_ui_options, - }, + ...manifest, }, background() { browser.test.sendMessage( @@ -84,10 +88,15 @@ async function testOptionsInTab({ id, options_ui_options }) { } add_task(async function testPreferencesLink() { - let id = "prefs@mochi.test"; + let id = "options_ui_open_in_tab@mochi.test"; await testOptionsInTab({ id, options_ui_options: { open_in_tab: true } }); }); +add_task(async function testOptionsPageOpensInNewTab() { + let id = "options_page@mochi.test"; + await testOptionsInTab({ id, manifest: { options_page: "options.html" } }); +}); + add_task(async function testPreferencesInlineDisabled() { await SpecialPowers.pushPrefEnv({ set: [["extensions.htmlaboutaddons.inline-options.enabled", false]], diff --git a/toolkit/mozapps/extensions/test/browser/browser_html_updates.js b/toolkit/mozapps/extensions/test/browser/browser_html_updates.js index 78ffc5678c..757c322829 100644 --- a/toolkit/mozapps/extensions/test/browser/browser_html_updates.js +++ b/toolkit/mozapps/extensions/test/browser/browser_html_updates.js @@ -53,7 +53,7 @@ add_task(async function testChangeAutoUpdates() { let win = await loadInitialView("extension"); let doc = win.document; - let getInputs = updateRow => ({ + let getInputs = () => ({ default: updatesRow.querySelector('input[value="1"]'), on: updatesRow.querySelector('input[value="2"]'), off: updatesRow.querySelector('input[value="0"]'), diff --git a/toolkit/mozapps/extensions/test/browser/browser_installtrigger_install.js b/toolkit/mozapps/extensions/test/browser/browser_installtrigger_install.js index 1d50da2833..b8e8ac80d0 100644 --- a/toolkit/mozapps/extensions/test/browser/browser_installtrigger_install.js +++ b/toolkit/mozapps/extensions/test/browser/browser_installtrigger_install.js @@ -243,6 +243,7 @@ add_task(async function testInstallTriggerFromSubframe() { const testCases = [ ["blank iframe with no attributes", SECURE_TESTROOT, {}, expected.http], + ["iframe srcdoc=''", SECURE_TESTROOT, { srcdoc: "" }, expected.http], // These are blocked by a Firefox doorhanger and the user can't allow it neither. [ @@ -257,12 +258,6 @@ add_task(async function testInstallTriggerFromSubframe() { { src: "blob:" }, expected.otherBlockedOnOrigin, ], - [ - "iframe srcdoc=''", - SECURE_TESTROOT, - { srcdoc: "" }, - expected.httpBlockedOnOrigin, - ], [ "blank iframe embedded into a top-level sandbox page", `${SECURE_TESTROOT}sandboxed.html`, diff --git a/toolkit/mozapps/extensions/test/browser/browser_local_install.js b/toolkit/mozapps/extensions/test/browser/browser_local_install.js index 5200b69e39..a26a4e283b 100644 --- a/toolkit/mozapps/extensions/test/browser/browser_local_install.js +++ b/toolkit/mozapps/extensions/test/browser/browser_local_install.js @@ -66,7 +66,7 @@ AddonTestUtils.registerJSON(server, "/updates-now-compatible.json", { add_task(async function test_local_install_blocklisted() { let id = "amosigned-xpi@tests.mozilla.org"; - let version = "2.1"; + let version = "2.2"; await AddonTestUtils.loadBlocklistRawData({ extensionsMLBF: [ diff --git a/toolkit/mozapps/extensions/test/browser/browser_page_options_install_addon.js b/toolkit/mozapps/extensions/test/browser/browser_page_options_install_addon.js index 7bc7c08345..586f2b7720 100644 --- a/toolkit/mozapps/extensions/test/browser/browser_page_options_install_addon.js +++ b/toolkit/mozapps/extensions/test/browser/browser_page_options_install_addon.js @@ -10,7 +10,7 @@ MockFilePicker.init(window.browsingContext); async function checkInstallConfirmation(...names) { let notificationCount = 0; let observer = { - observe(aSubject, aTopic, aData) { + observe(aSubject) { var installInfo = aSubject.wrappedJSObject; isnot( installInfo.browser, diff --git a/toolkit/mozapps/extensions/test/browser/browser_shortcuts_duplicate_check.js b/toolkit/mozapps/extensions/test/browser/browser_shortcuts_duplicate_check.js index 912ce8d62f..a8de1f96aa 100644 --- a/toolkit/mozapps/extensions/test/browser/browser_shortcuts_duplicate_check.js +++ b/toolkit/mozapps/extensions/test/browser/browser_shortcuts_duplicate_check.js @@ -235,7 +235,7 @@ add_task(async function testDuplicateShortcutOnMacOSCtrlKey() { ); }; - const clearWarning = async inputEl => { + const clearWarning = async () => { anotherCommandInput.blur(); await TestUtils.waitForCondition( () => BrowserTestUtils.isHidden(errorEl), diff --git a/toolkit/mozapps/extensions/test/browser/browser_sidebar_hidden_categories.js b/toolkit/mozapps/extensions/test/browser/browser_sidebar_hidden_categories.js index 4cb641c2a0..0bb59d7748 100644 --- a/toolkit/mozapps/extensions/test/browser/browser_sidebar_hidden_categories.js +++ b/toolkit/mozapps/extensions/test/browser/browser_sidebar_hidden_categories.js @@ -18,7 +18,7 @@ function installLocale() { return new Promise(resolve => { gInstall = gProvider.createInstalls(gInstallProperties)[0]; gInstall.addTestListener({ - onInstallEnded(aInstall) { + onInstallEnded() { gInstall.removeTestListener(this); resolve(); }, diff --git a/toolkit/mozapps/extensions/test/browser/browser_updatessl.js b/toolkit/mozapps/extensions/test/browser/browser_updatessl.js index 9dbeec4a84..792c24de58 100644 --- a/toolkit/mozapps/extensions/test/browser/browser_updatessl.js +++ b/toolkit/mozapps/extensions/test/browser/browser_updatessl.js @@ -25,14 +25,7 @@ var gStart = 0; var gLast = 0; var HTTPObserver = { - observeActivity( - aChannel, - aType, - aSubtype, - aTimestamp, - aSizeData, - aStringData - ) { + observeActivity(aChannel, aType, aSubtype) { aChannel.QueryInterface(Ci.nsIChannel); dump( diff --git a/toolkit/mozapps/extensions/test/browser/browser_webapi_install.js b/toolkit/mozapps/extensions/test/browser/browser_webapi_install.js index 24d34c3f4d..a5823517d6 100644 --- a/toolkit/mozapps/extensions/test/browser/browser_webapi_install.js +++ b/toolkit/mozapps/extensions/test/browser/browser_webapi_install.js @@ -17,12 +17,11 @@ const TESTPAGE = `${SECURE_TESTROOT}${TESTPATH}`; const XPI_URL = `${SECURE_TESTROOT}../xpinstall/amosigned.xpi`; const XPI_ADDON_ID = "amosigned-xpi@tests.mozilla.org"; -const XPI_SHA = - "sha256:91121ed2c27f670f2307b9aebdd30979f147318c7fb9111c254c14ddbb84e4b0"; - const ID = "amosigned-xpi@tests.mozilla.org"; -// eh, would be good to just stat the real file instead of this... -const XPI_LEN = 4287; +// Actual XPI file size and hash are computed in the add_setup callback. +let XPI_LEN = -1; +let XPI_SHA = + "sha256:0000000000000000000000000000000000000000000000000000000000000000"; AddonTestUtils.initMochitest(this); @@ -50,6 +49,17 @@ add_setup(async function () { ], }); info("added preferences"); + + // Get the file size (used in this test file to assert the + // expected maxProgress value set in the addon download + // dialog). + const xpiFilePath = getTestFilePath("../xpinstall/amosigned.xpi"); + const xpiStat = await IOUtils.stat(xpiFilePath); + XPI_LEN = xpiStat.size; + + // Compute the file hash. + const xpiFileHash = await IOUtils.computeHexDigest(xpiFilePath, "sha256"); + XPI_SHA = `sha256:${xpiFileHash}`; }); // Wrapper around a common task to run in the content process to test @@ -95,7 +105,7 @@ async function testInstall(browser, args, steps, description) { let receivedEvents = []; let prevEvent = null; events.forEach(event => { - install.addEventListener(event, e => { + install.addEventListener(event, () => { receivedEvents.push({ event, state: install.state, @@ -165,7 +175,7 @@ async function testInstall(browser, args, steps, description) { } } catch (err) { if (!nextStep.expectError) { - throw new Error("Install failed unexpectedly"); + throw new Error("Install failed unexpectedly: " + err); } } } else if (nextStep.action == "cancel") { @@ -287,12 +297,12 @@ add_task( "install with empty string for hash works" ) ); -add_task( - makeRegularTest( +add_task(async function test_install_successfully_with_filehash() { + await makeRegularTest( { url: XPI_URL, addonId, hash: XPI_SHA }, "install with hash works" - ) -); + ); +}); add_task( makeInstallTest(async function (browser) { @@ -531,7 +541,7 @@ add_task( add_task( makeInstallTest(async function (browser) { let id = "amosigned-xpi@tests.mozilla.org"; - let version = "2.1"; + let version = "2.2"; await AddonTestUtils.loadBlocklistRawData({ extensionsMLBF: [ diff --git a/toolkit/mozapps/extensions/test/browser/browser_webapi_theme.js b/toolkit/mozapps/extensions/test/browser/browser_webapi_theme.js index dd1df90907..f271cbd9e3 100644 --- a/toolkit/mozapps/extensions/test/browser/browser_webapi_theme.js +++ b/toolkit/mozapps/extensions/test/browser/browser_webapi_theme.js @@ -13,7 +13,7 @@ add_task(async function test_theme_install() { await BrowserTestUtils.withNewTab(TESTPAGE, async browser => { let updates = []; - function observer(subject, topic, data) { + function observer(subject) { updates.push(JSON.stringify(subject.wrappedJSObject)); } Services.obs.addObserver(observer, "lightweight-theme-styling-update"); diff --git a/toolkit/mozapps/extensions/test/browser/head.js b/toolkit/mozapps/extensions/test/browser/head.js index 482429177c..949b375ec0 100644 --- a/toolkit/mozapps/extensions/test/browser/head.js +++ b/toolkit/mozapps/extensions/test/browser/head.js @@ -204,7 +204,7 @@ function run_next_test() { executeSoon(() => log_exceptions(test)); } -var get_tooltip_info = async function (addonEl, managerWindow) { +var get_tooltip_info = async function (addonEl) { // Extract from title attribute. const { addon } = addonEl; const name = addon.name; @@ -324,7 +324,7 @@ function open_manager( aLongerTimeout, aWin = window ) { - let p = new Promise((resolve, reject) => { + let p = new Promise(resolve => { async function setup_manager(aManagerWindow) { if (aLoadCallback) { log_exceptions(aLoadCallback, aManagerWindow); @@ -354,7 +354,7 @@ function open_manager( } info("Loading manager window in tab"); - Services.obs.addObserver(function observer(aSubject, aTopic, aData) { + Services.obs.addObserver(function observer(aSubject, aTopic) { Services.obs.removeObserver(observer, aTopic); if (aSubject.location.href != MANAGER_URI) { info("Ignoring load event for " + aSubject.location.href); @@ -434,7 +434,7 @@ function wait_for_window_open(aCallback) { ); }, - onCloseWindow(aWindow) {}, + onCloseWindow() {}, }); }); @@ -487,7 +487,7 @@ function promiseAddonsByIDs(aIDs) { */ async function install_addon(path, cb, pathPrefix = TESTROOT) { let install = await AddonManager.getInstallForURL(pathPrefix + path); - let p = new Promise((resolve, reject) => { + let p = new Promise(resolve => { install.addListener({ onInstallEnded: () => resolve(install.addon), }); @@ -946,7 +946,7 @@ MockProvider.prototype = { * true if the newly enabled add-on will only become enabled after a * restart */ - addonChanged: function MP_addonChanged(aId, aType, aPendingRestart) { + addonChanged: function MP_addonChanged() { // Not implemented }, @@ -965,7 +965,7 @@ MockProvider.prototype = { * @param {object} aOptions * Options for the install */ - getInstallForURL: function MP_getInstallForURL(aUrl, aOptions) { + getInstallForURL: function MP_getInstallForURL() { // Not yet implemented }, @@ -975,7 +975,7 @@ MockProvider.prototype = { * @param aFile * The file to be installed */ - getInstallForFile: function MP_getInstallForFile(aFile) { + getInstallForFile: function MP_getInstallForFile() { // Not yet implemented }, @@ -996,7 +996,7 @@ MockProvider.prototype = { * The mimetype to check for * @return true if the mimetype is supported */ - supportsMimetype: function MP_supportsMimetype(aMimetype) { + supportsMimetype: function MP_supportsMimetype() { return false; }, @@ -1007,7 +1007,7 @@ MockProvider.prototype = { * The URI being installed from * @return true if installing is allowed */ - isInstallAllowed: function MP_isInstallAllowed(aUri) { + isInstallAllowed: function MP_isInstallAllowed() { return false; }, }; @@ -1143,11 +1143,11 @@ MockAddon.prototype = { ]); }, - isCompatibleWith(aAppVersion, aPlatformVersion) { + isCompatibleWith() { return true; }, - findUpdates(aListener, aReason, aAppVersion, aPlatformVersion) { + findUpdates() { // Tests can implement this if they need to }, diff --git a/toolkit/mozapps/extensions/test/browser/head_abuse_report.js b/toolkit/mozapps/extensions/test/browser/head_abuse_report.js index f3a683e8d5..78c9206e0a 100644 --- a/toolkit/mozapps/extensions/test/browser/head_abuse_report.js +++ b/toolkit/mozapps/extensions/test/browser/head_abuse_report.js @@ -66,7 +66,7 @@ function waitForNewWindow() { } function waitClosedWindow(win) { - return new Promise((resolve, reject) => { + return new Promise(resolve => { function onWindowClosed() { if (win && !win.closed) { // If a specific window reference has been passed, then check @@ -215,7 +215,7 @@ const AbuseReportTestUtils = { return abuseReportEl.ownerGlobal.ABUSE_REPORT_REASONS[reason]; }, - async promiseReportOpened({ addonId, reportEntryPoint, managerWindow }) { + async promiseReportOpened({ addonId, reportEntryPoint }) { let abuseReportEl; if (!this.getReportDialog()) { diff --git a/toolkit/mozapps/extensions/test/browser/moz.build b/toolkit/mozapps/extensions/test/browser/moz.build index 4cc6314d0e..74095966b1 100644 --- a/toolkit/mozapps/extensions/test/browser/moz.build +++ b/toolkit/mozapps/extensions/test/browser/moz.build @@ -14,7 +14,6 @@ addons = [ "browser_dragdrop_incompat", "browser_installssl", "browser_theme", - "options_signed", ] output_dir = ( diff --git a/toolkit/mozapps/extensions/test/xpcshell/.eslintrc.js b/toolkit/mozapps/extensions/test/xpcshell/.eslintrc.js index 8e3971b385..26a3e6177f 100644 --- a/toolkit/mozapps/extensions/test/xpcshell/.eslintrc.js +++ b/toolkit/mozapps/extensions/test/xpcshell/.eslintrc.js @@ -4,7 +4,7 @@ module.exports = { rules: { "no-unused-vars": [ "error", - { args: "none", varsIgnorePattern: "^end_test$" }, + { argsIgnorePattern: "^_", varsIgnorePattern: "^end_test$" }, ], }, overrides: [ @@ -14,7 +14,7 @@ module.exports = { "no-unused-vars": [ "error", { - args: "none", + argsIgnorePattern: "^_", vars: "local", }, ], diff --git a/toolkit/mozapps/extensions/test/xpcshell/data/signing_checks/langpack_signed.xpi b/toolkit/mozapps/extensions/test/xpcshell/data/signing_checks/langpack_signed.xpi index f60d00348e..ab7db3926e 100644 Binary files a/toolkit/mozapps/extensions/test/xpcshell/data/signing_checks/langpack_signed.xpi and b/toolkit/mozapps/extensions/test/xpcshell/data/signing_checks/langpack_signed.xpi differ diff --git a/toolkit/mozapps/extensions/test/xpcshell/data/signing_checks/long.xpi b/toolkit/mozapps/extensions/test/xpcshell/data/signing_checks/long.xpi index f95f3df91e..78124db3ae 100644 Binary files a/toolkit/mozapps/extensions/test/xpcshell/data/signing_checks/long.xpi and b/toolkit/mozapps/extensions/test/xpcshell/data/signing_checks/long.xpi differ diff --git a/toolkit/mozapps/extensions/test/xpcshell/data/signing_checks/privileged.xpi b/toolkit/mozapps/extensions/test/xpcshell/data/signing_checks/privileged.xpi index c22acaacd2..111385485b 100644 Binary files a/toolkit/mozapps/extensions/test/xpcshell/data/signing_checks/privileged.xpi and b/toolkit/mozapps/extensions/test/xpcshell/data/signing_checks/privileged.xpi differ diff --git a/toolkit/mozapps/extensions/test/xpcshell/data/signing_checks/signed1.xpi b/toolkit/mozapps/extensions/test/xpcshell/data/signing_checks/signed1.xpi index e2ba7d6fd8..2e9d976a34 100644 Binary files a/toolkit/mozapps/extensions/test/xpcshell/data/signing_checks/signed1.xpi and b/toolkit/mozapps/extensions/test/xpcshell/data/signing_checks/signed1.xpi differ diff --git a/toolkit/mozapps/extensions/test/xpcshell/data/signing_checks/signed2.xpi b/toolkit/mozapps/extensions/test/xpcshell/data/signing_checks/signed2.xpi index ccb20796f2..2d6b9c020b 100644 Binary files a/toolkit/mozapps/extensions/test/xpcshell/data/signing_checks/signed2.xpi and b/toolkit/mozapps/extensions/test/xpcshell/data/signing_checks/signed2.xpi differ diff --git a/toolkit/mozapps/extensions/test/xpcshell/data/webext-implicit-id.xpi b/toolkit/mozapps/extensions/test/xpcshell/data/webext-implicit-id.xpi index 6b4abaa691..05a5ea2881 100644 Binary files a/toolkit/mozapps/extensions/test/xpcshell/data/webext-implicit-id.xpi and b/toolkit/mozapps/extensions/test/xpcshell/data/webext-implicit-id.xpi differ diff --git a/toolkit/mozapps/extensions/test/xpcshell/head_addons.js b/toolkit/mozapps/extensions/test/xpcshell/head_addons.js index 23614cdb2a..2f26d940f0 100644 --- a/toolkit/mozapps/extensions/test/xpcshell/head_addons.js +++ b/toolkit/mozapps/extensions/test/xpcshell/head_addons.js @@ -935,7 +935,7 @@ class EventChecker { return this.checkAddonEvent("onInstalled", addon); } - onUninstalling(addon, requiresRestart) { + onUninstalling(addon) { return this.checkAddonEvent("onUninstalling", addon); } @@ -1033,7 +1033,7 @@ class EventChecker { }); } - onInstallEnded(install, newAddon) { + onInstallEnded(install) { return this.checkInstall("onInstallEnded", install, { state: "STATE_INSTALLED", error: 0, @@ -1221,3 +1221,10 @@ async function installBuiltinExtension(extensionData, waitForStartup = true) { } return wrapper; } + +function useAMOStageCert() { + // NOTE: add_task internally calls add_test which mutate the add_task properties object, + // and so we should not reuse the same object as add_task options passed to multiple + // add_task calls. + return { pref_set: [["xpinstall.signatures.dev-root", true]] }; +} diff --git a/toolkit/mozapps/extensions/test/xpcshell/head_compat.js b/toolkit/mozapps/extensions/test/xpcshell/head_compat.js index 79ddb8dd3f..76fafee50e 100644 --- a/toolkit/mozapps/extensions/test/xpcshell/head_compat.js +++ b/toolkit/mozapps/extensions/test/xpcshell/head_compat.js @@ -22,7 +22,7 @@ AddonManager.addExternalExtensionLoader({ Object.assign(addon, manifest); return addon; }, - loadScope(addon, file) { + loadScope() { return { install() {}, uninstall() {}, diff --git a/toolkit/mozapps/extensions/test/xpcshell/rs-blocklist/test_blocklist_appversion.js b/toolkit/mozapps/extensions/test/xpcshell/rs-blocklist/test_blocklist_appversion.js index e8d03f088b..08e41b47fd 100644 --- a/toolkit/mozapps/extensions/test/xpcshell/rs-blocklist/test_blocklist_appversion.js +++ b/toolkit/mozapps/extensions/test/xpcshell/rs-blocklist/test_blocklist_appversion.js @@ -227,7 +227,7 @@ function createAddon(addon) { * If a lastTest is provided checks that the notification dialog got passed * the newly blocked items compared to the previous test. */ -async function checkState(test, lastTest, callback) { +async function checkState(test) { let addons = await AddonManager.getAddonsByIDs(ADDONS.map(a => a.id)); const bls = Ci.nsIBlocklistService; diff --git a/toolkit/mozapps/extensions/test/xpcshell/rs-blocklist/test_blocklist_mlbf.js b/toolkit/mozapps/extensions/test/xpcshell/rs-blocklist/test_blocklist_mlbf.js index 1f6cb3db05..f7e3a57152 100644 --- a/toolkit/mozapps/extensions/test/xpcshell/rs-blocklist/test_blocklist_mlbf.js +++ b/toolkit/mozapps/extensions/test/xpcshell/rs-blocklist/test_blocklist_mlbf.js @@ -11,11 +11,11 @@ createAppInfo("xpcshell@tests.mozilla.org", "XPCShell", "1", "1"); AddonTestUtils.useRealCertChecks = true; // A real, signed XPI for use in the test. -const SIGNED_ADDON_XPI_FILE = do_get_file("../data/webext-implicit-id.xpi"); -const SIGNED_ADDON_ID = "webext_implicit_id@tests.mozilla.org"; -const SIGNED_ADDON_VERSION = "1.0"; +const SIGNED_ADDON_XPI_FILE = do_get_file("amosigned.xpi"); +const SIGNED_ADDON_ID = "amosigned-xpi@tests.mozilla.org"; +const SIGNED_ADDON_VERSION = "2.2"; const SIGNED_ADDON_KEY = `${SIGNED_ADDON_ID}:${SIGNED_ADDON_VERSION}`; -const SIGNED_ADDON_SIGN_TIME = 1459980789000; // notBefore of certificate. +const SIGNED_ADDON_SIGN_TIME = 1711462525000; // notBefore of certificate. // A real, signed sitepermission XPI for use in the test. const SIGNED_SITEPERM_XPI_FILE = do_get_file("webmidi_permission.xpi"); @@ -78,7 +78,7 @@ add_task(async function signed_xpi_initially_unblocked() { await Blocklist.getAddonBlocklistEntry(addon), { state: Ci.nsIBlocklistService.STATE_BLOCKED, - url: "https://addons.mozilla.org/en-US/xpcshell/blocked-addon/webext_implicit_id@tests.mozilla.org/1.0/", + url: `https://addons.mozilla.org/en-US/xpcshell/blocked-addon/${SIGNED_ADDON_ID}/${SIGNED_ADDON_VERSION}/`, }, "Blocked addon should have blocked entry" ); @@ -174,7 +174,9 @@ add_task(async function signed_temporary() { await Assert.rejects( AddonManager.installTemporaryAddon(SIGNED_ADDON_XPI_FILE), - /Add-on webext_implicit_id@tests.mozilla.org is not compatible with application version/, + new RegExp( + `Add-on ${SIGNED_ADDON_ID} is not compatible with application version` + ), "Blocklisted add-on cannot be installed" ); }); @@ -183,19 +185,27 @@ add_task(async function signed_temporary() { // It can still be blocked by a stash, which is tested in // privileged_addon_blocked_by_stash in test_blocklist_mlbf_stashes.js. add_task(async function privileged_xpi_not_blocked() { + const PRIV_ADDON_ID = "test@tests.mozilla.org"; + const PRIV_ADDON_VERSION = "2.0buildid20240326.152244"; mockMLBF({ - blocked: ["test@tests.mozilla.org:2.0"], + blocked: [`${PRIV_ADDON_ID}:${PRIV_ADDON_VERSION}`], notblocked: [], generationTime: 1546297200000, // 1 jan 2019 = after the cert's notBefore }); await ExtensionBlocklistMLBF._onUpdate(); + // Prevent install to fail due to privileged.xpi version using + // an addon version that hits a manifest warning (see PRIV_ADDON_VERSION). + // TODO(Bug 1824240): remove this once privileged.xpi can be resigned with a + // version format that does not hit a manifest warning. + ExtensionTestUtils.failOnSchemaWarnings(false); const install = await promiseInstallFile( do_get_file("../data/signing_checks/privileged.xpi") ); + ExtensionTestUtils.failOnSchemaWarnings(true); Assert.equal(install.error, 0, "Install should not have an error"); - let addon = await promiseAddonByID("test@tests.mozilla.org"); + let addon = await promiseAddonByID(PRIV_ADDON_ID); Assert.equal(addon.signedState, AddonManager.SIGNEDSTATE_PRIVILEGED); Assert.equal(addon.blocklistState, Ci.nsIBlocklistService.STATE_NOT_BLOCKED); await addon.uninstall(); @@ -205,13 +215,17 @@ add_task(async function privileged_xpi_not_blocked() { // It can still be blocked by a stash, which is tested in // langpack_blocked_by_stash in test_blocklist_mlbf_stashes.js. add_task( - // We do not support langpacks on Android. - { skip_if: () => AppConstants.platform == "android" }, + { + // langpack_signed.xpi is signed with AMO staging signature. + pref_set: [["xpinstall.signatures.dev-root", true]], + // We do not support langpacks on Android. + skip_if: () => AppConstants.platform == "android", + }, async function langpack_not_blocked_on_Nightly() { mockMLBF({ blocked: ["langpack-klingon@firefox.mozilla.org:1.0"], notblocked: [], - generationTime: 1546297200000, // 1 jan 2019 = after the cert's notBefore + generationTime: 1712243366640, // 4 apr 2024 = after the cert's notBefore }); await ExtensionBlocklistMLBF._onUpdate(); @@ -226,12 +240,16 @@ add_task( Assert.equal( addon.blocklistState, Ci.nsIBlocklistService.STATE_NOT_BLOCKED, - "Langpacks cannot be blocked via the MLBF" + "Langpacks cannot be blocked via the MLBF on nightly" ); } else { // On non-Nightly, langpacks are submitted through AMO so we will enforce // the MLBF blocklist for them. - Assert.equal(addon.blocklistState, Ci.nsIBlocklistService.STATE_BLOCKED); + Assert.equal( + addon.blocklistState, + Ci.nsIBlocklistService.STATE_BLOCKED, + "Langpacks can be blocked via the MLBF on non-Nightly channels" + ); } await addon.uninstall(); } diff --git a/toolkit/mozapps/extensions/test/xpcshell/rs-blocklist/test_blocklist_mlbf_update.js b/toolkit/mozapps/extensions/test/xpcshell/rs-blocklist/test_blocklist_mlbf_update.js index b98d6e345d..77e5df2540 100644 --- a/toolkit/mozapps/extensions/test/xpcshell/rs-blocklist/test_blocklist_mlbf_update.js +++ b/toolkit/mozapps/extensions/test/xpcshell/rs-blocklist/test_blocklist_mlbf_update.js @@ -25,7 +25,7 @@ add_task(async function collapse_multiple_pending_update_requests() { // Add a spy to the RemoteSettings client, so we can verify that the number // of RemoteSettings accesses matches with what we expect. const originalClientGet = ExtensionBlocklistMLBF._client.get; - const spyClientGet = (tag, returnValue) => { + const spyClientGet = tag => { ExtensionBlocklistMLBF._client.get = async function () { // Record the method call. observed.push(tag); diff --git a/toolkit/mozapps/extensions/test/xpcshell/rs-blocklist/test_blocklist_severities.js b/toolkit/mozapps/extensions/test/xpcshell/rs-blocklist/test_blocklist_severities.js index fffbb8a51e..059d014197 100644 --- a/toolkit/mozapps/extensions/test/xpcshell/rs-blocklist/test_blocklist_severities.js +++ b/toolkit/mozapps/extensions/test/xpcshell/rs-blocklist/test_blocklist_severities.js @@ -451,7 +451,7 @@ add_task(async function test_pt4() { await promiseRestartManager(); await checkInitialState(); - await loadBlocklist("empty", args => { + await loadBlocklist("empty", () => { dump("Checking notification pt 4\n"); // See note in other callback - we no longer notify for non-blocked add-ons. ok(false, "Should not get a notification as there are no blocked addons."); diff --git a/toolkit/mozapps/extensions/test/xpcshell/rs-blocklist/test_blocklistchange.js b/toolkit/mozapps/extensions/test/xpcshell/rs-blocklist/test_blocklistchange.js index 7383e093ee..b021a13c80 100644 --- a/toolkit/mozapps/extensions/test/xpcshell/rs-blocklist/test_blocklistchange.js +++ b/toolkit/mozapps/extensions/test/xpcshell/rs-blocklist/test_blocklistchange.js @@ -40,7 +40,7 @@ const useMLBF = Services.prefs.getBoolPref( var testserver = createHttpServer({ hosts: ["example.com"] }); -function permissionPromptHandler(subject, topic, data) { +function permissionPromptHandler(subject) { ok( subject?.wrappedJSObject?.info?.resolve, "Got a permission prompt notification as expected" @@ -280,7 +280,7 @@ if (useMLBF) { } // XXXgijs: according to https://bugzilla.mozilla.org/show_bug.cgi?id=1257565#c111 -// this code and the related code in Blocklist.jsm (specific to XML blocklist) is +// this code and the related code in Blocklist.sys.mjs (specific to XML blocklist) is // dead code and can be removed. See https://bugzilla.mozilla.org/show_bug.cgi?id=1549550 . // // Don't need the full interface, attempts to call other methods will just @@ -343,16 +343,16 @@ function Pload_blocklist(aId) { // Does a background update check for add-ons and returns a promise that // resolves when any started installs complete function Pbackground_update() { - return new Promise((resolve, reject) => { + return new Promise(resolve => { let installCount = 0; let backgroundCheckCompleted = false; AddonManager.addInstallListener({ - onNewInstall(aInstall) { + onNewInstall() { installCount++; }, - onInstallEnded(aInstall) { + onInstallEnded() { installCount--; // Wait until all started installs have completed if (installCount) { diff --git a/toolkit/mozapps/extensions/test/xpcshell/rs-blocklist/test_gfxBlacklist_Device.js b/toolkit/mozapps/extensions/test/xpcshell/rs-blocklist/test_gfxBlacklist_Device.js index 9b1d84b77d..68c9357356 100644 --- a/toolkit/mozapps/extensions/test/xpcshell/rs-blocklist/test_gfxBlacklist_Device.js +++ b/toolkit/mozapps/extensions/test/xpcshell/rs-blocklist/test_gfxBlacklist_Device.js @@ -63,7 +63,7 @@ async function run_test() { do_test_finished(); } - Services.obs.addObserver(function (aSubject, aTopic, aData) { + Services.obs.addObserver(function () { // If we wait until after we go through the event loop, gfxInfo is sure to // have processed the gfxItems event. executeSoon(checkBlacklist); diff --git a/toolkit/mozapps/extensions/test/xpcshell/rs-blocklist/test_gfxBlacklist_DriverNew.js b/toolkit/mozapps/extensions/test/xpcshell/rs-blocklist/test_gfxBlacklist_DriverNew.js index a1bcde5566..fa274bde2d 100644 --- a/toolkit/mozapps/extensions/test/xpcshell/rs-blocklist/test_gfxBlacklist_DriverNew.js +++ b/toolkit/mozapps/extensions/test/xpcshell/rs-blocklist/test_gfxBlacklist_DriverNew.js @@ -57,7 +57,7 @@ async function run_test() { do_test_finished(); } - Services.obs.addObserver(function (aSubject, aTopic, aData) { + Services.obs.addObserver(function () { // If we wait until after we go through the event loop, gfxInfo is sure to // have processed the gfxItems event. executeSoon(checkBlacklist); diff --git a/toolkit/mozapps/extensions/test/xpcshell/rs-blocklist/test_gfxBlacklist_Equal_DriverNew.js b/toolkit/mozapps/extensions/test/xpcshell/rs-blocklist/test_gfxBlacklist_Equal_DriverNew.js index ec74d813ae..a6a1dc1435 100644 --- a/toolkit/mozapps/extensions/test/xpcshell/rs-blocklist/test_gfxBlacklist_Equal_DriverNew.js +++ b/toolkit/mozapps/extensions/test/xpcshell/rs-blocklist/test_gfxBlacklist_Equal_DriverNew.js @@ -102,7 +102,7 @@ async function run_test() { do_test_finished(); } - Services.obs.addObserver(function (aSubject, aTopic, aData) { + Services.obs.addObserver(function () { // If we wait until after we go through the event loop, gfxInfo is sure to // have processed the gfxItems event. executeSoon(checkBlacklist); diff --git a/toolkit/mozapps/extensions/test/xpcshell/rs-blocklist/test_gfxBlacklist_Equal_DriverOld.js b/toolkit/mozapps/extensions/test/xpcshell/rs-blocklist/test_gfxBlacklist_Equal_DriverOld.js index ff887a92eb..93ca432c6d 100644 --- a/toolkit/mozapps/extensions/test/xpcshell/rs-blocklist/test_gfxBlacklist_Equal_DriverOld.js +++ b/toolkit/mozapps/extensions/test/xpcshell/rs-blocklist/test_gfxBlacklist_Equal_DriverOld.js @@ -58,7 +58,7 @@ async function run_test() { do_test_finished(); } - Services.obs.addObserver(function (aSubject, aTopic, aData) { + Services.obs.addObserver(function () { // If we wait until after we go through the event loop, gfxInfo is sure to // have processed the gfxItems event. executeSoon(checkBlacklist); diff --git a/toolkit/mozapps/extensions/test/xpcshell/rs-blocklist/test_gfxBlacklist_Equal_OK.js b/toolkit/mozapps/extensions/test/xpcshell/rs-blocklist/test_gfxBlacklist_Equal_OK.js index 1eef119663..4be9215161 100644 --- a/toolkit/mozapps/extensions/test/xpcshell/rs-blocklist/test_gfxBlacklist_Equal_OK.js +++ b/toolkit/mozapps/extensions/test/xpcshell/rs-blocklist/test_gfxBlacklist_Equal_OK.js @@ -58,7 +58,7 @@ async function run_test() { do_test_finished(); } - Services.obs.addObserver(function (aSubject, aTopic, aData) { + Services.obs.addObserver(function () { // If we wait until after we go through the event loop, gfxInfo is sure to // have processed the gfxItems event. executeSoon(checkBlacklist); diff --git a/toolkit/mozapps/extensions/test/xpcshell/rs-blocklist/test_gfxBlacklist_GTE_DriverOld.js b/toolkit/mozapps/extensions/test/xpcshell/rs-blocklist/test_gfxBlacklist_GTE_DriverOld.js index 182c825ffb..d8b082bedc 100644 --- a/toolkit/mozapps/extensions/test/xpcshell/rs-blocklist/test_gfxBlacklist_GTE_DriverOld.js +++ b/toolkit/mozapps/extensions/test/xpcshell/rs-blocklist/test_gfxBlacklist_GTE_DriverOld.js @@ -58,7 +58,7 @@ async function run_test() { do_test_finished(); } - Services.obs.addObserver(function (aSubject, aTopic, aData) { + Services.obs.addObserver(function () { // If we wait until after we go through the event loop, gfxInfo is sure to // have processed the gfxItems event. executeSoon(checkBlacklist); diff --git a/toolkit/mozapps/extensions/test/xpcshell/rs-blocklist/test_gfxBlacklist_GTE_OK.js b/toolkit/mozapps/extensions/test/xpcshell/rs-blocklist/test_gfxBlacklist_GTE_OK.js index 2cc3686007..0e419ec761 100644 --- a/toolkit/mozapps/extensions/test/xpcshell/rs-blocklist/test_gfxBlacklist_GTE_OK.js +++ b/toolkit/mozapps/extensions/test/xpcshell/rs-blocklist/test_gfxBlacklist_GTE_OK.js @@ -60,7 +60,7 @@ async function run_test() { do_test_finished(); } - Services.obs.addObserver(function (aSubject, aTopic, aData) { + Services.obs.addObserver(function () { // If we wait until after we go through the event loop, gfxInfo is sure to // have processed the gfxItems event. executeSoon(checkBlacklist); diff --git a/toolkit/mozapps/extensions/test/xpcshell/rs-blocklist/test_gfxBlacklist_No_Comparison.js b/toolkit/mozapps/extensions/test/xpcshell/rs-blocklist/test_gfxBlacklist_No_Comparison.js index 169cdc5e62..4d457cff14 100644 --- a/toolkit/mozapps/extensions/test/xpcshell/rs-blocklist/test_gfxBlacklist_No_Comparison.js +++ b/toolkit/mozapps/extensions/test/xpcshell/rs-blocklist/test_gfxBlacklist_No_Comparison.js @@ -59,7 +59,7 @@ async function run_test() { do_test_finished(); } - Services.obs.addObserver(function (aSubject, aTopic, aData) { + Services.obs.addObserver(function () { // If we wait until after we go through the event loop, gfxInfo is sure to // have processed the gfxItems event. executeSoon(checkBlacklist); diff --git a/toolkit/mozapps/extensions/test/xpcshell/rs-blocklist/test_gfxBlacklist_OK.js b/toolkit/mozapps/extensions/test/xpcshell/rs-blocklist/test_gfxBlacklist_OK.js index 04d766e027..991bfa8a96 100644 --- a/toolkit/mozapps/extensions/test/xpcshell/rs-blocklist/test_gfxBlacklist_OK.js +++ b/toolkit/mozapps/extensions/test/xpcshell/rs-blocklist/test_gfxBlacklist_OK.js @@ -59,7 +59,7 @@ async function run_test() { do_test_finished(); } - Services.obs.addObserver(function (aSubject, aTopic, aData) { + Services.obs.addObserver(function () { // If we wait until after we go through the event loop, gfxInfo is sure to // have processed the gfxItems event. executeSoon(checkBlacklist); diff --git a/toolkit/mozapps/extensions/test/xpcshell/rs-blocklist/test_gfxBlacklist_OS.js b/toolkit/mozapps/extensions/test/xpcshell/rs-blocklist/test_gfxBlacklist_OS.js index ce5a61cb75..3f525b48ce 100644 --- a/toolkit/mozapps/extensions/test/xpcshell/rs-blocklist/test_gfxBlacklist_OS.js +++ b/toolkit/mozapps/extensions/test/xpcshell/rs-blocklist/test_gfxBlacklist_OS.js @@ -58,7 +58,7 @@ async function run_test() { do_test_finished(); } - Services.obs.addObserver(function (aSubject, aTopic, aData) { + Services.obs.addObserver(function () { // If we wait until after we go through the event loop, gfxInfo is sure to // have processed the gfxItems event. executeSoon(checkBlacklist); diff --git a/toolkit/mozapps/extensions/test/xpcshell/rs-blocklist/test_gfxBlacklist_OSVersion_match.js b/toolkit/mozapps/extensions/test/xpcshell/rs-blocklist/test_gfxBlacklist_OSVersion_match.js index 7a4ec276ee..d9d357be76 100644 --- a/toolkit/mozapps/extensions/test/xpcshell/rs-blocklist/test_gfxBlacklist_OSVersion_match.js +++ b/toolkit/mozapps/extensions/test/xpcshell/rs-blocklist/test_gfxBlacklist_OSVersion_match.js @@ -60,7 +60,7 @@ async function run_test() { do_test_finished(); } - Services.obs.addObserver(function (aSubject, aTopic, aData) { + Services.obs.addObserver(function () { // If we wait until after we go through the event loop, gfxInfo is sure to // have processed the gfxItems event. executeSoon(checkBlacklist); diff --git a/toolkit/mozapps/extensions/test/xpcshell/rs-blocklist/test_gfxBlacklist_OSVersion_mismatch_DriverVersion.js b/toolkit/mozapps/extensions/test/xpcshell/rs-blocklist/test_gfxBlacklist_OSVersion_mismatch_DriverVersion.js index 61dba8db96..a1c8107f1d 100644 --- a/toolkit/mozapps/extensions/test/xpcshell/rs-blocklist/test_gfxBlacklist_OSVersion_mismatch_DriverVersion.js +++ b/toolkit/mozapps/extensions/test/xpcshell/rs-blocklist/test_gfxBlacklist_OSVersion_mismatch_DriverVersion.js @@ -60,7 +60,7 @@ async function run_test() { do_test_finished(); } - Services.obs.addObserver(function (aSubject, aTopic, aData) { + Services.obs.addObserver(function () { // If we wait until after we go through the event loop, gfxInfo is sure to // have processed the gfxItems event. executeSoon(checkBlacklist); diff --git a/toolkit/mozapps/extensions/test/xpcshell/rs-blocklist/test_gfxBlacklist_OSVersion_mismatch_OSVersion.js b/toolkit/mozapps/extensions/test/xpcshell/rs-blocklist/test_gfxBlacklist_OSVersion_mismatch_OSVersion.js index 117e2a34ee..be076d98c3 100644 --- a/toolkit/mozapps/extensions/test/xpcshell/rs-blocklist/test_gfxBlacklist_OSVersion_mismatch_OSVersion.js +++ b/toolkit/mozapps/extensions/test/xpcshell/rs-blocklist/test_gfxBlacklist_OSVersion_mismatch_OSVersion.js @@ -61,7 +61,7 @@ async function run_test() { do_test_finished(); } - Services.obs.addObserver(function (aSubject, aTopic, aData) { + Services.obs.addObserver(function () { // If we wait until after we go through the event loop, gfxInfo is sure to // have processed the gfxItems event. executeSoon(checkBlacklist); diff --git a/toolkit/mozapps/extensions/test/xpcshell/rs-blocklist/test_gfxBlacklist_Vendor.js b/toolkit/mozapps/extensions/test/xpcshell/rs-blocklist/test_gfxBlacklist_Vendor.js index 37bc0d3c89..e5d137db60 100644 --- a/toolkit/mozapps/extensions/test/xpcshell/rs-blocklist/test_gfxBlacklist_Vendor.js +++ b/toolkit/mozapps/extensions/test/xpcshell/rs-blocklist/test_gfxBlacklist_Vendor.js @@ -58,7 +58,7 @@ async function run_test() { do_test_finished(); } - Services.obs.addObserver(function (aSubject, aTopic, aData) { + Services.obs.addObserver(function () { // If we wait until after we go through the event loop, gfxInfo is sure to // have processed the gfxItems event. executeSoon(checkBlacklist); diff --git a/toolkit/mozapps/extensions/test/xpcshell/rs-blocklist/test_gfxBlacklist_Version.js b/toolkit/mozapps/extensions/test/xpcshell/rs-blocklist/test_gfxBlacklist_Version.js index 9a6a904465..cbd1699d53 100644 --- a/toolkit/mozapps/extensions/test/xpcshell/rs-blocklist/test_gfxBlacklist_Version.js +++ b/toolkit/mozapps/extensions/test/xpcshell/rs-blocklist/test_gfxBlacklist_Version.js @@ -180,7 +180,7 @@ async function run_test() { do_test_finished(); } - Services.obs.addObserver(function (aSubject, aTopic, aData) { + Services.obs.addObserver(function () { // If we wait until after we go through the event loop, gfxInfo is sure to // have processed the gfxItems event. executeSoon(checkBlocklist); diff --git a/toolkit/mozapps/extensions/test/xpcshell/rs-blocklist/test_gfxBlacklist_prefs.js b/toolkit/mozapps/extensions/test/xpcshell/rs-blocklist/test_gfxBlacklist_prefs.js index 34e92b0e80..6e5f71b364 100644 --- a/toolkit/mozapps/extensions/test/xpcshell/rs-blocklist/test_gfxBlacklist_prefs.js +++ b/toolkit/mozapps/extensions/test/xpcshell/rs-blocklist/test_gfxBlacklist_prefs.js @@ -53,7 +53,7 @@ async function run_test() { createAppInfo("xpcshell@tests.mozilla.org", "XPCShell", "3", "8"); await promiseStartupManager(); - function blacklistAdded(aSubject, aTopic, aData) { + function blacklistAdded() { // If we wait until after we go through the event loop, gfxInfo is sure to // have processed the gfxItems event. executeSoon(ensureBlacklistSet); @@ -95,7 +95,7 @@ async function run_test() { ]); } - function blacklistRemoved(aSubject, aTopic, aData) { + function blacklistRemoved() { // If we wait until after we go through the event loop, gfxInfo is sure to // have processed the gfxItems event. executeSoon(ensureBlacklistUnset); diff --git a/toolkit/mozapps/extensions/test/xpcshell/rs-blocklist/xpcshell.toml b/toolkit/mozapps/extensions/test/xpcshell/rs-blocklist/xpcshell.toml index 2aee95e952..edb77da1bc 100644 --- a/toolkit/mozapps/extensions/test/xpcshell/rs-blocklist/xpcshell.toml +++ b/toolkit/mozapps/extensions/test/xpcshell/rs-blocklist/xpcshell.toml @@ -5,6 +5,7 @@ firefox-appdir = "browser" support-files = [ "../data/**", "../../xpinstall/webmidi_permission.xpi", + "../../xpinstall/amosigned.xpi", ] ["test_android_blocklist_dump.js"] diff --git a/toolkit/mozapps/extensions/test/xpcshell/test_AbuseReporter.js b/toolkit/mozapps/extensions/test/xpcshell/test_AbuseReporter.js index e5dffe0b00..c94ef29e31 100644 --- a/toolkit/mozapps/extensions/test/xpcshell/test_AbuseReporter.js +++ b/toolkit/mozapps/extensions/test/xpcshell/test_AbuseReporter.js @@ -800,11 +800,7 @@ add_task(async function test_report_recommended() { }); add_task(async function test_query_amo_details() { - async function assertReportOnAMODetails({ - addonId, - addonType = "extension", - expectedReport, - } = {}) { + async function assertReportOnAMODetails({ addonId, expectedReport } = {}) { // Clear last report timestamp and any telemetry event recorded so far. clearAbuseReportState(); Services.telemetry.clearEvents(); diff --git a/toolkit/mozapps/extensions/test/xpcshell/test_AddonRepository.js b/toolkit/mozapps/extensions/test/xpcshell/test_AddonRepository.js index 6f1c99eaa8..9071328680 100644 --- a/toolkit/mozapps/extensions/test/xpcshell/test_AddonRepository.js +++ b/toolkit/mozapps/extensions/test/xpcshell/test_AddonRepository.js @@ -2,7 +2,7 @@ * http://creativecommons.org/publicdomain/zero/1.0/ */ -// Tests AddonRepository.jsm +// Tests AddonRepository.sys.mjs var gServer = createHttpServer({ hosts: ["example.com"] }); diff --git a/toolkit/mozapps/extensions/test/xpcshell/test_AddonRepository_appIsShuttingDown.js b/toolkit/mozapps/extensions/test/xpcshell/test_AddonRepository_appIsShuttingDown.js index 4f23026ed3..c1f63496a3 100644 --- a/toolkit/mozapps/extensions/test/xpcshell/test_AddonRepository_appIsShuttingDown.js +++ b/toolkit/mozapps/extensions/test/xpcshell/test_AddonRepository_appIsShuttingDown.js @@ -2,8 +2,8 @@ * http://creativecommons.org/publicdomain/zero/1.0/ */ -// Tests AddonRepository.jsm when backgroundUpdateChecks are hit while the application -// shutdown has been already initiated (See Bug 1841444). +// Tests AddonRepository.sys.mjs when backgroundUpdateChecks are hit while the +// application shutdown has been already initiated (See Bug 1841444). const { sinon } = ChromeUtils.importESModule( "resource://testing-common/Sinon.sys.mjs" diff --git a/toolkit/mozapps/extensions/test/xpcshell/test_AddonRepository_cache.js b/toolkit/mozapps/extensions/test/xpcshell/test_AddonRepository_cache.js index 2a1bc2721b..c7b10afa19 100644 --- a/toolkit/mozapps/extensions/test/xpcshell/test_AddonRepository_cache.js +++ b/toolkit/mozapps/extensions/test/xpcshell/test_AddonRepository_cache.js @@ -465,7 +465,7 @@ function check_cache(aExpectedToFind, aExpectedImmediately) { for (let i = 0; i < REPOSITORY_ADDONS.length; i++) { lookups.push( - new Promise((resolve, reject) => { + new Promise(resolve => { let immediatelyFound = true; let expected = aExpectedToFind[i] ? REPOSITORY_ADDONS[i] : null; // can't Promise-wrap this because we're also testing whether the callback is diff --git a/toolkit/mozapps/extensions/test/xpcshell/test_AddonRepository_cache_locale.js b/toolkit/mozapps/extensions/test/xpcshell/test_AddonRepository_cache_locale.js index 37e60e27dd..cf47e388d5 100644 --- a/toolkit/mozapps/extensions/test/xpcshell/test_AddonRepository_cache_locale.js +++ b/toolkit/mozapps/extensions/test/xpcshell/test_AddonRepository_cache_locale.js @@ -152,7 +152,7 @@ function promiseLocaleChanged(requestedLocale) { } return new Promise(resolve => { let localeObserver = { - observe(aSubject, aTopic, aData) { + observe(aSubject, aTopic) { switch (aTopic) { case REQ_LOC_CHANGE_EVENT: let reqLocs = Services.locale.requestedLocales; @@ -169,7 +169,7 @@ function promiseLocaleChanged(requestedLocale) { function promiseMetaDataUpdate() { return new Promise(resolve => { - let listener = args => { + let listener = () => { Services.prefs.removeObserver(PREF_METADATA_LASTUPDATE, listener); resolve(); }; diff --git a/toolkit/mozapps/extensions/test/xpcshell/test_ProductAddonChecker_signatures.js b/toolkit/mozapps/extensions/test/xpcshell/test_ProductAddonChecker_signatures.js index 5ae61568ef..93602ffac9 100644 --- a/toolkit/mozapps/extensions/test/xpcshell/test_ProductAddonChecker_signatures.js +++ b/toolkit/mozapps/extensions/test/xpcshell/test_ProductAddonChecker_signatures.js @@ -98,7 +98,8 @@ add_task(async function test_valid_content_signature() { signedBaseUri + goodXmlPath + "?" + validSignatureQuery, /*allowNonBuiltIn*/ false, /*allowedCerts*/ false, - /*verifyContentSignature*/ true + /*verifyContentSignature*/ true, + /*trustedContentSignatureRoot*/ Ci.nsIX509CertDB.AppXPCShellRoot ); Assert.ok(true, "Should successfully get addon list"); @@ -122,7 +123,8 @@ add_task(async function test_invalid_content_signature() { signedBaseUri + goodXmlPath + "?" + invalidSignatureQuery, /*allowNonBuiltIn*/ false, /*allowedCerts*/ false, - /*verifyContentSignature*/ true + /*verifyContentSignature*/ true, + /*trustedContentSignatureRoot*/ Ci.nsIX509CertDB.AppXPCShellRoot ); Assert.ok(false, "Should fail to get addon list"); } catch (e) { @@ -143,7 +145,8 @@ add_task(async function test_missing_content_signature_header() { signedBaseUri + goodXmlPath + "?" + missingSignatureQuery, /*allowNonBuiltIn*/ false, /*allowedCerts*/ false, - /*verifyContentSignature*/ true + /*verifyContentSignature*/ true, + /*trustedContentSignatureRoot*/ Ci.nsIX509CertDB.AppXPCShellRoot ); Assert.ok(false, "Should fail to get addon list"); } catch (e) { @@ -165,7 +168,8 @@ add_task(async function test_incomplete_content_signature_header() { signedBaseUri + goodXmlPath + "?" + incompleteSignatureQuery, /*allowNonBuiltIn*/ false, /*allowedCerts*/ false, - /*verifyContentSignature*/ true + /*verifyContentSignature*/ true, + /*trustedContentSignatureRoot*/ Ci.nsIX509CertDB.AppXPCShellRoot ); Assert.ok(false, "Should fail to get addon list"); } catch (e) { @@ -187,7 +191,8 @@ add_task(async function test_bad_x5u_content_signature_header() { signedBaseUri + goodXmlPath + "?" + badX5uSignatureQuery, /*allowNonBuiltIn*/ false, /*allowedCerts*/ false, - /*verifyContentSignature*/ true + /*verifyContentSignature*/ true, + /*trustedContentSignatureRoot*/ Ci.nsIX509CertDB.AppXPCShellRoot ); Assert.ok(false, "Should fail to get addon list"); } catch (e) { diff --git a/toolkit/mozapps/extensions/test/xpcshell/test_addon_manager_telemetry_events.js b/toolkit/mozapps/extensions/test/xpcshell/test_addon_manager_telemetry_events.js index 6a533f540a..d4103420ff 100644 --- a/toolkit/mozapps/extensions/test/xpcshell/test_addon_manager_telemetry_events.js +++ b/toolkit/mozapps/extensions/test/xpcshell/test_addon_manager_telemetry_events.js @@ -40,7 +40,7 @@ function getTelemetryEvents(includeMethods = EVENT_METHODS) { ); return snapshot.parent - .filter(([timestamp, category, method]) => { + .filter(([, category, method]) => { const includeMethod = includeMethods ? includeMethods.includes(method) : true; @@ -68,11 +68,9 @@ function assertNoTelemetryEvents() { return; } - let filteredEvents = snapshot.parent.filter( - ([timestamp, category, method]) => { - return category === EVENT_CATEGORY; - } - ); + let filteredEvents = snapshot.parent.filter(([_timestamp, category]) => { + return category === EVENT_CATEGORY; + }); Assert.deepEqual(filteredEvents, [], "Got no AMTelemetry events as expected"); } diff --git a/toolkit/mozapps/extensions/test/xpcshell/test_delay_update_webextension.js b/toolkit/mozapps/extensions/test/xpcshell/test_delay_update_webextension.js index 7b1c6fbef9..579f99687f 100644 --- a/toolkit/mozapps/extensions/test/xpcshell/test_delay_update_webextension.js +++ b/toolkit/mozapps/extensions/test/xpcshell/test_delay_update_webextension.js @@ -206,7 +206,7 @@ add_task(async function delay_updates_complete() { }, }, background() { - browser.runtime.onUpdateAvailable.addListener(details => { + browser.runtime.onUpdateAvailable.addListener(() => { browser.test.notifyPass("reload"); browser.runtime.reload(); }); @@ -273,7 +273,7 @@ add_task(async function delay_updates_defer() { }, }, background() { - browser.runtime.onUpdateAvailable.addListener(details => { + browser.runtime.onUpdateAvailable.addListener(() => { // Upgrade will only proceed when "allow" message received. browser.test.onMessage.addListener(msg => { if (msg == "allow") { @@ -371,7 +371,7 @@ add_task(async function delay_updates_staged() { }, }, background() { - browser.runtime.onUpdateAvailable.addListener(details => { + browser.runtime.onUpdateAvailable.addListener(() => { browser.test.sendMessage("denied"); }); browser.test.sendMessage("ready"); @@ -443,7 +443,7 @@ add_task(async function delay_updates_staged_no_update_url() { }, }, background() { - browser.runtime.onUpdateAvailable.addListener(details => { + browser.runtime.onUpdateAvailable.addListener(() => { browser.test.sendMessage("denied"); }); browser.test.sendMessage("ready"); diff --git a/toolkit/mozapps/extensions/test/xpcshell/test_installOrigins.js b/toolkit/mozapps/extensions/test/xpcshell/test_installOrigins.js index 7ef584b54d..0b1690f5a8 100644 --- a/toolkit/mozapps/extensions/test/xpcshell/test_installOrigins.js +++ b/toolkit/mozapps/extensions/test/xpcshell/test_installOrigins.js @@ -179,7 +179,7 @@ function testInstallEvent(expectTelemetry) { let events = snapshot.parent .filter( - ([timestamp, category, method, object, value, extra]) => + ([, category, method, , , extra]) => category === "addonsManager" && method == "install" && extra.step == expectTelemetry.step @@ -229,15 +229,13 @@ function promiseCompleteWebInstall( installInfo.install(); }); - TestUtils.topicObserved("addon-install-confirmation").then( - (subject, data) => { - info(`==== test got addon-install-confirmation`); - let installInfo = subject.wrappedJSObject; - for (let installer of installInfo.installs) { - installer.install(); - } + TestUtils.topicObserved("addon-install-confirmation").then(subject => { + info(`==== test got addon-install-confirmation`); + let installInfo = subject.wrappedJSObject; + for (let installer of installInfo.installs) { + installer.install(); } - ); + }); TestUtils.topicObserved("webextension-permission-prompt").then( ([subject]) => { const { info } = subject.wrappedJSObject || {}; diff --git a/toolkit/mozapps/extensions/test/xpcshell/test_install_cancel.js b/toolkit/mozapps/extensions/test/xpcshell/test_install_cancel.js index 0be6ec0359..b5902bc6ba 100644 --- a/toolkit/mozapps/extensions/test/xpcshell/test_install_cancel.js +++ b/toolkit/mozapps/extensions/test/xpcshell/test_install_cancel.js @@ -35,7 +35,7 @@ class TestListener { function startListener(listener) { let observer = { - observe(subject, topic, data) { + observe(subject) { let channel = subject.QueryInterface(Ci.nsIHttpChannel); if (channel.URI.spec === "http://example.com/addons/test.xpi") { let channelListener = new TestListener(listener); diff --git a/toolkit/mozapps/extensions/test/xpcshell/test_provider_markSafe.js b/toolkit/mozapps/extensions/test/xpcshell/test_provider_markSafe.js index e8062a2caf..033acf3dfc 100644 --- a/toolkit/mozapps/extensions/test/xpcshell/test_provider_markSafe.js +++ b/toolkit/mozapps/extensions/test/xpcshell/test_provider_markSafe.js @@ -12,7 +12,7 @@ function mockAddonProvider(name) { AddonManager.isInstallEnabled("made-up-mimetype"); }, - supportsMimetype(mimetype) { + supportsMimetype() { this.apiAccessed = true; return false; }, diff --git a/toolkit/mozapps/extensions/test/xpcshell/test_provider_shutdown.js b/toolkit/mozapps/extensions/test/xpcshell/test_provider_shutdown.js index 498b28a0c9..47612f1565 100644 --- a/toolkit/mozapps/extensions/test/xpcshell/test_provider_shutdown.js +++ b/toolkit/mozapps/extensions/test/xpcshell/test_provider_shutdown.js @@ -31,7 +31,7 @@ function mockAddonProvider(aName) { mockProvider.doneResolve = resolve; mockProvider.doneReject = reject; }); - mockProvider.shutdownPromise = new Promise((resolve, reject) => { + mockProvider.shutdownPromise = new Promise(resolve => { mockProvider.shutdownResolve = resolve; }); return mockProvider; diff --git a/toolkit/mozapps/extensions/test/xpcshell/test_reload.js b/toolkit/mozapps/extensions/test/xpcshell/test_reload.js index 993c4a9c53..92e67c53c1 100644 --- a/toolkit/mozapps/extensions/test/xpcshell/test_reload.js +++ b/toolkit/mozapps/extensions/test/xpcshell/test_reload.js @@ -99,11 +99,11 @@ add_task(async function test_can_reload_permanent_addon() { let disabledCalled = false; let enabledCalled = false; AddonManager.addAddonListener({ - onDisabled: aAddon => { + onDisabled: () => { Assert.ok(!enabledCalled); disabledCalled = true; }, - onEnabled: aAddon => { + onEnabled: () => { Assert.ok(disabledCalled); enabledCalled = true; }, diff --git a/toolkit/mozapps/extensions/test/xpcshell/test_signed_install.js b/toolkit/mozapps/extensions/test/xpcshell/test_signed_install.js index 065463864d..99b6bca376 100644 --- a/toolkit/mozapps/extensions/test/xpcshell/test_signed_install.js +++ b/toolkit/mozapps/extensions/test/xpcshell/test_signed_install.js @@ -195,25 +195,25 @@ async function test_update_working(file1, file2, expectedSignedState) { await install.addon.uninstall(); } -add_task(async function setup() { +add_setup(async function setup() { createAppInfo("xpcshell@tests.mozilla.org", "XPCShell", "4", "4"); await promiseStartupManager(); }); // Try to install a broken add-on -add_task(async function test_install_invalid_modified() { +add_task(useAMOStageCert(), async function test_install_invalid_modified() { let file = createBrokenAddonModify(do_get_file(DATA + ADDONS.signed1)); await test_install_broken(file, AddonManager.ERROR_CORRUPT_FILE); file.remove(true); }); -add_task(async function test_install_invalid_added() { +add_task(useAMOStageCert(), async function test_install_invalid_added() { let file = createBrokenAddonAdd(do_get_file(DATA + ADDONS.signed1)); await test_install_broken(file, AddonManager.ERROR_CORRUPT_FILE); file.remove(true); }); -add_task(async function test_install_invalid_removed() { +add_task(useAMOStageCert(), async function test_install_invalid_removed() { let file = createBrokenAddonRemove(do_get_file(DATA + ADDONS.signed1)); await test_install_broken(file, AddonManager.ERROR_CORRUPT_FILE); file.remove(true); @@ -226,58 +226,62 @@ add_task(async function test_install_invalid_unsigned() { }); // Try to install a signed add-on -add_task(async function test_install_valid() { +add_task(useAMOStageCert(), async function test_install_valid() { let file = do_get_file(DATA + ADDONS.signed1); await test_install_working(file, AddonManager.SIGNEDSTATE_SIGNED); }); add_task( - { - pref_set: [["xpinstall.signatures.dev-root", true]], - // `xpinstall.signatures.dev-root` is not taken into account on release - // builds because `MOZ_REQUIRE_SIGNING` is set to `true`. - skip_if: () => AppConstants.MOZ_REQUIRE_SIGNING, - }, - async function test_install_valid_file_with_different_root_cert() { - const TEST_CASES = [ - { - title: "XPI without ID in manifest", - xpi: "data/webext-implicit-id.xpi", - expectedMessage: - /Cannot find id for addon .+ Preference xpinstall.signatures.dev-root is set/, - }, - { - title: "XPI with ID in manifest", - xpi: DATA + ADDONS.signed1, - expectedMessage: /Add-on test@somewhere.com is not correctly signed/, - }, - ]; + useAMOStageCert(), + async function test_install_implicit_id_with_different_root_cert() { + info( + `test install error on fail to verify signature on XPI without ID in manifest` + ); - for (const { title, xpi, expectedMessage } of TEST_CASES) { - info(`test_install_valid_file_with_different_root_cert: ${title}`); + const xpi = do_get_file("data/webext-implicit-id.xpi"); + const expectedMessage = + /Cannot find id for addon .+ Preference xpinstall.signatures.dev-root is set/; - const file = do_get_file(xpi); + const { messages } = await AddonTestUtils.promiseConsoleOutput(async () => { + await test_install_broken( + xpi, + AddonManager.ERROR_CORRUPT_FILE, + // We don't expect the `addon` property on the `install` object to be + // `null` because that seems to happen later (when the signature is + // checked). + false + ); + }); - const awaitConsole = new Promise(resolve => { - Services.console.registerListener(function listener(message) { - if (expectedMessage.test(message.message)) { - Services.console.unregisterListener(listener); - resolve(); - } - }); - }); + AddonTestUtils.checkMessages(messages, { + expected: [{ message: expectedMessage }], + }); + } +); +add_task( + async function test_install_stage_signed_invalid_with_prod_root_cert() { + info( + `test install error on fail to verify signature on XPI with ID in manifest` + ); + + const xpi = do_get_file(DATA + ADDONS.signed1); + const expectedMessage = /Add-on test@somewhere.com is not correctly signed/; + + const { messages } = await AddonTestUtils.promiseConsoleOutput(async () => { await test_install_broken( - file, + xpi, AddonManager.ERROR_CORRUPT_FILE, // We don't expect the `addon` property on the `install` object to be // `null` because that seems to happen later (when the signature is // checked). false ); + }); - await awaitConsole; - } + AddonTestUtils.checkMessages(messages, { + expected: [{ message: expectedMessage }], + }); } ); @@ -291,25 +295,34 @@ add_task(async function test_install_valid_sha256() { // Try to install an add-on with the "Mozilla Extensions" OU add_task(async function test_install_valid_privileged() { let file = do_get_file(DATA + ADDONS.privileged); - await test_install_working(file, AddonManager.SIGNEDSTATE_PRIVILEGED); + try { + // Prevent install to fail due to privileged.xpi version using + // a version format that hits a manifest warning. + // TODO(Bug 1824240): remove this once privileged.xpi can be resigned with a + // version format that does not hit a manifest warning. + ExtensionTestUtils.failOnSchemaWarnings(false); + await test_install_working(file, AddonManager.SIGNEDSTATE_PRIVILEGED); + } finally { + ExtensionTestUtils.failOnSchemaWarnings(true); + } }); // Try to update to a broken add-on -add_task(async function test_update_invalid_modified() { +add_task(useAMOStageCert(), async function test_update_invalid_modified() { let file1 = do_get_file(DATA + ADDONS.signed1); let file2 = createBrokenAddonModify(do_get_file(DATA + ADDONS.signed2)); await test_update_broken(file1, file2, AddonManager.ERROR_CORRUPT_FILE); file2.remove(true); }); -add_task(async function test_update_invalid_added() { +add_task(useAMOStageCert(), async function test_update_invalid_added() { let file1 = do_get_file(DATA + ADDONS.signed1); let file2 = createBrokenAddonAdd(do_get_file(DATA + ADDONS.signed2)); await test_update_broken(file1, file2, AddonManager.ERROR_CORRUPT_FILE); file2.remove(true); }); -add_task(async function test_update_invalid_removed() { +add_task(useAMOStageCert(), async function test_update_invalid_removed() { let file1 = do_get_file(DATA + ADDONS.signed1); let file2 = createBrokenAddonRemove(do_get_file(DATA + ADDONS.signed2)); await test_update_broken(file1, file2, AddonManager.ERROR_CORRUPT_FILE); @@ -317,7 +330,7 @@ add_task(async function test_update_invalid_removed() { }); // Try to update to an unsigned add-on -add_task(async function test_update_invalid_unsigned() { +add_task(useAMOStageCert(), async function test_update_invalid_unsigned() { let file1 = do_get_file(DATA + ADDONS.signed1); let file2 = do_get_file(DATA + ADDONS.unsigned); await test_update_broken( @@ -328,7 +341,7 @@ add_task(async function test_update_invalid_unsigned() { }); // Try to update to a signed add-on -add_task(async function test_update_valid() { +add_task(useAMOStageCert(), async function test_update_valid() { let file1 = do_get_file(DATA + ADDONS.signed1); let file2 = do_get_file(DATA + ADDONS.signed2); await test_update_working(file1, file2, AddonManager.SIGNEDSTATE_SIGNED); diff --git a/toolkit/mozapps/extensions/test/xpcshell/test_signed_langpack.js b/toolkit/mozapps/extensions/test/xpcshell/test_signed_langpack.js index 8ad83b2ecb..421d40f4a0 100644 --- a/toolkit/mozapps/extensions/test/xpcshell/test_signed_langpack.js +++ b/toolkit/mozapps/extensions/test/xpcshell/test_signed_langpack.js @@ -32,7 +32,7 @@ async function installShouldFail(file) { // Test that the preference controlling langpack signing works properly // (and that the general preference for addon signing does not affect // language packs). -add_task(async function () { +add_task(useAMOStageCert(), async function () { AddonTestUtils.useRealCertChecks = true; createAppInfo("xpcshell@tests.mozilla.org", "XPCShell", "1", "1.9"); diff --git a/toolkit/mozapps/extensions/test/xpcshell/test_signed_long.js b/toolkit/mozapps/extensions/test/xpcshell/test_signed_long.js index 2aa76e8ff8..6213aa0f1b 100644 --- a/toolkit/mozapps/extensions/test/xpcshell/test_signed_long.js +++ b/toolkit/mozapps/extensions/test/xpcshell/test_signed_long.js @@ -4,7 +4,7 @@ const ID = "123456789012345678901234567890123456789012345678901@somewhere.com"; // Tests that signature verification works correctly on an extension with // an ID that does not fit into a certificate CN field. -add_task(async function test_long_id() { +add_task(useAMOStageCert(), async function test_long_id() { createAppInfo("xpcshell@tests.mozilla.org", "XPCShell", "1", "1"); await promiseStartupManager(); diff --git a/toolkit/mozapps/extensions/test/xpcshell/test_signed_verify.js b/toolkit/mozapps/extensions/test/xpcshell/test_signed_verify.js index c17cb941cb..e801485c73 100644 --- a/toolkit/mozapps/extensions/test/xpcshell/test_signed_verify.js +++ b/toolkit/mozapps/extensions/test/xpcshell/test_signed_verify.js @@ -25,9 +25,439 @@ function verifySignatures() { createAppInfo("xpcshell@tests.mozilla.org", "XPCShell", "4", "4"); -add_task(async function test_no_change() { +add_setup(async () => { await promiseStartupManager(); +}); + +add_task(function test_hasStrongSignature_helper() { + const { hasStrongSignature } = ChromeUtils.importESModule( + "resource://gre/modules/addons/crypto-utils.sys.mjs" + ); + const { PKCS7_WITH_SHA1, PKCS7_WITH_SHA256, COSE_WITH_SHA256 } = + Ci.nsIAppSignatureInfo; + const testCases = [ + [false, "SHA1 only", [PKCS7_WITH_SHA1]], + [true, "SHA256 only", [PKCS7_WITH_SHA256]], + [true, "COSE only", [COSE_WITH_SHA256]], + [true, "SHA1 and SHA256", [PKCS7_WITH_SHA1, PKCS7_WITH_SHA256]], + [true, "SHA1 and COSE", [PKCS7_WITH_SHA1, COSE_WITH_SHA256]], + [true, "SHA256 and COSE", [PKCS7_WITH_SHA256, COSE_WITH_SHA256]], + ]; + for (const [expect, msg, signedTypes] of testCases) { + Assert.equal(hasStrongSignature({ signedTypes }), expect, msg); + } +}); + +add_task(async function test_addon_signedTypes() { + // This test is allowing weak signatures to run assertions on the AddonWrapper.signedTypes + // property also for extensions only including SHA1 signatures. + const resetWeakSignaturePref = + AddonTestUtils.setWeakSignatureInstallAllowed(true); + + const { PKCS7_WITH_SHA1, COSE_WITH_SHA256 } = Ci.nsIAppSignatureInfo; + + const { addon: addonSignedCOSE } = await promiseInstallFile( + do_get_file("amosigned-mv3-cose.xpi") + ); + const { addon: addonSignedSHA1 } = await promiseInstallFile( + do_get_file("amosigned-sha1only.xpi") + ); + + Assert.deepEqual( + addonSignedCOSE.signedTypes.sort(), + [COSE_WITH_SHA256, PKCS7_WITH_SHA1].sort(), + `Expect ${addonSignedCOSE.id} to be signed with both COSE and SHA1` + ); + + Assert.deepEqual( + addonSignedSHA1.signedTypes, + [PKCS7_WITH_SHA1], + `Expect ${addonSignedSHA1.id} to be signed with SHA1 only` + ); + + await addonSignedSHA1.uninstall(); + await addonSignedCOSE.uninstall(); + + resetWeakSignaturePref(); +}); + +add_task( + async function test_install_error_on_new_install_with_weak_signature() { + // Ensure restrictions on weak signatures are enabled (this should be removed when + // the new behavior is riding the train). + const resetWeakSignaturePref = + AddonTestUtils.setWeakSignatureInstallAllowed(false); + + const { messages } = await AddonTestUtils.promiseConsoleOutput(async () => { + let install = await AddonManager.getInstallForFile( + do_get_file("amosigned-sha1only.xpi") + ); + + await Assert.equal( + install.state, + AddonManager.STATE_DOWNLOAD_FAILED, + "Expect install state to be STATE_DOWNLOAD_FAILED" + ); + + await Assert.rejects( + install.install(), + /Install failed: onDownloadFailed/, + "Expected install to fail" + ); + }); + + resetWeakSignaturePref(); + + // Checking the message expected to be logged in the Browser Console. + AddonTestUtils.checkMessages(messages, { + expected: [ + { + message: + /Invalid XPI: install rejected due to the package not including a strong cryptographic signature/, + }, + ], + }); + } +); + +/** + * Test helper used to simulate an update from a given pre-installed add-on xpi to a new xpi file for the same + * add-on and assert the expected result and logged messages. + * + * @param {object} params + * @param {string} params.currentAddonXPI + * The path to the add-on xpi to be pre-installed and then updated to `newAddonXPI`. + * @param {string} params.newAddonXPI + * The path to the add-on xpi to be installed as an update over `currentAddonXPI`. + * @param {string} params.newAddonVersion + * The add-on version expected for `newAddonXPI`. + * @param {boolean} params.expectedInstallOK + * Set to true for an update scenario that is expected to be successful. + * @param {Array} params.expectedMessages + * Array of strings or RegExp for console messages expected to be logged. + * @param {Array} params.forbiddenMessages + * Array of strings or RegExp for console messages expected to NOT be logged. + */ +async function testWeakSignatureXPIUpdate({ + currentAddonXPI, + newAddonXPI, + newAddonVersion, + expectedInstallOK, + expectedMessages, + forbiddenMessages, +}) { + // Temporarily allow weak signature to install the xpi as a new install. + let resetWeakSignaturePref = + AddonTestUtils.setWeakSignatureInstallAllowed(true); + + const { addon: addonFirstInstall } = await promiseInstallFile( + currentAddonXPI + ); + const addonId = addonFirstInstall.id; + const initialAddonVersion = addonFirstInstall.version; + + resetWeakSignaturePref(); + + // Make sure the install over is executed while weak signature is not allowed + // for new installs to confirm that installing over is allowed. + resetWeakSignaturePref = AddonTestUtils.setWeakSignatureInstallAllowed(false); + + info("Install over the existing installed addon"); + let addonInstalledOver; + const { messages } = await AddonTestUtils.promiseConsoleOutput(async () => { + const fileURL = Services.io.newFileURI(newAddonXPI).spec; + let install = await AddonManager.getInstallForURL(fileURL, { + existingAddon: addonFirstInstall, + version: newAddonVersion, + }); + + addonInstalledOver = await install.install().catch(err => { + if (expectedInstallOK) { + ok(false, `Unexpected error hit on installing update XPI: ${err}`); + } else { + ok(true, `Install failed as expected: ${err}`); + } + }); + }); + + resetWeakSignaturePref(); + + if (expectedInstallOK) { + Assert.equal( + addonInstalledOver.id, + addonFirstInstall.id, + "Expect addon id to be the same" + ); + Assert.equal( + addonInstalledOver.version, + newAddonVersion, + "Got expected addon version after update xpi install completed" + ); + await addonInstalledOver.uninstall(); + } else { + Assert.equal( + addonInstalledOver?.version, + undefined, + "Expect update addon xpi not installed successfully" + ); + Assert.equal( + (await AddonManager.getAddonByID(addonId)).version, + initialAddonVersion, + "Expect the addon version to match the initial XPI version" + ); + await addonFirstInstall.uninstall(); + } + + Assert.equal( + await AddonManager.getAddonByID(addonId), + undefined, + "Expect the test addon to be fully uninstalled" + ); + + // Checking the message logged in the Browser Console. + AddonTestUtils.checkMessages(messages, { + expected: expectedMessages, + forbidden: forbiddenMessages, + }); +} + +add_task(async function test_weak_install_over_weak_existing() { + const addonId = "amosigned-xpi@tests.mozilla.org"; + await testWeakSignatureXPIUpdate({ + currentAddonXPI: do_get_file("amosigned-sha1only.xpi"), + newAddonXPI: do_get_file("amosigned-sha1only.xpi"), + newAddonVersion: "2.1", + expectedInstallOK: true, + expectedMessages: [ + { + message: new RegExp( + `Allow weak signature install over existing "${addonId}" XPI` + ), + }, + ], + }); +}); + +add_task(async function test_update_weak_to_strong_signature() { + const addonId = "amosigned-xpi@tests.mozilla.org"; + await testWeakSignatureXPIUpdate({ + currentAddonXPI: do_get_file("amosigned-sha1only.xpi"), + newAddonXPI: do_get_file("amosigned.xpi"), + newAddonVersion: "2.2", + expectedInstallOK: true, + forbiddenMessages: [ + { + message: new RegExp( + `Allow weak signature install over existing "${addonId}" XPI` + ), + }, + ], + }); +}); + +add_task(async function test_update_strong_to_weak_signature() { + const addonId = "amosigned-xpi@tests.mozilla.org"; + await testWeakSignatureXPIUpdate({ + currentAddonXPI: do_get_file("amosigned.xpi"), + newAddonXPI: do_get_file("amosigned-sha1only.xpi"), + newAddonVersion: "2.1", + expectedInstallOK: false, + expectedMessages: [ + { + message: new RegExp( + "Invalid XPI: install rejected due to the package not including a strong cryptographic signature" + ), + }, + ], + forbiddenMessages: [ + { + message: new RegExp( + `Allow weak signature install over existing "${addonId}" XPI` + ), + }, + ], + }); +}); + +add_task(async function test_signedTypes_stored_in_addonDB() { + const { addon: addonAfterInstalled } = await promiseInstallFile( + do_get_file("amosigned-mv3-cose.xpi") + ); + const addonId = addonAfterInstalled.id; + + const { PKCS7_WITH_SHA1, COSE_WITH_SHA256 } = Ci.nsIAppSignatureInfo; + const expectedSignedTypes = [COSE_WITH_SHA256, PKCS7_WITH_SHA1].sort(); + + Assert.deepEqual( + addonAfterInstalled.signedTypes.sort(), + expectedSignedTypes, + `Got expected ${addonId} signedTyped after install` + ); + + await promiseRestartManager(); + + const addonAfterAOMRestart = await AddonManager.getAddonByID(addonId); + + Assert.deepEqual( + addonAfterAOMRestart.signedTypes.sort(), + expectedSignedTypes, + `Got expected ${addonId} signedTyped after AOM restart` + ); + + const removeSignedStateFromAddonDB = async () => { + const addon_db_file = Services.dirsvc.get("ProfD", Ci.nsIFile); + addon_db_file.append("extensions.json"); + const addon_db_data = await IOUtils.readJSON(addon_db_file.path); + + const addon_db_data_tampered = { + ...addon_db_data, + addons: addon_db_data.addons.map(addonData => { + // Tamper the data of the test extension to mock the + // scenario. + delete addonData.signedTypes; + return addonData; + }), + }; + await IOUtils.writeJSON(addon_db_file.path, addon_db_data_tampered); + }; + + // Shutdown the AddonManager and tamper the AddonDB to confirm XPIProvider.checkForChanges + // calls originated internally when opening a profile created from a previous Firefox version + // is going to populate the new signedTypes property. + info( + "Check that XPIProvider.checkForChanges(true) will recompute missing signedTypes properties" + ); + await promiseShutdownManager(); + await removeSignedStateFromAddonDB(); + await promiseStartupManager(); + + // Expect the signedTypes property to be undefined because of the + // AddonDB data being tampered earlier in this test. + const addonAfterAppUpgrade = await AddonManager.getAddonByID(addonId); + Assert.deepEqual( + addonAfterAppUpgrade.signedTypes, + undefined, + `Got empty ${addonId} signedTyped set to undefied after AddonDB data tampered` + ); + + // Mock call to XPIDatabase.checkForChanges expected to be hit when the application + // is updated. + AddonTestUtils.getXPIExports().XPIProvider.checkForChanges( + /* aAppChanged */ true + ); + + Assert.deepEqual( + addonAfterAppUpgrade.signedTypes?.sort(), + expectedSignedTypes.sort(), + `Got expected ${addonId} signedTyped after XPIProvider.checkForChanges recomputed it` + ); + + // Shutdown the AddonManager and tamper the AddonDB to confirm XPIDatabase.updateCompatibility + // would populate signedTypes if missing. + info( + "Check that XPIDatabase.updateCompatibility will recompute missing signedTypes properties" + ); + await promiseShutdownManager(); + await removeSignedStateFromAddonDB(); + await promiseStartupManager(); + + // Expect the signedTypes property to be undefined because of the + // AddonDB data being tampered earlier in this test. + const addonAfterUpdateCompatibility = await AddonManager.getAddonByID( + addonId + ); + Assert.deepEqual( + addonAfterUpdateCompatibility.signedTypes, + undefined, + `Got empty ${addonId} signedTyped set to undefied after AddonDB data tampered` + ); + + // Mock call to XPIDatabase.updateCompatibility expected to be originated from + // XPIDatabaseReconcile.processFileChanges and confirm that signedTypes has been + // recomputed as expected. + AddonTestUtils.getXPIExports().XPIDatabaseReconcile.processFileChanges( + {}, + true + ); + Assert.deepEqual( + addonAfterUpdateCompatibility.signedTypes?.sort(), + expectedSignedTypes.sort(), + `Got expected ${addonId} signedTyped after XPIDatabase.updateCompatibility recomputed it` + ); + + // Restart the AddonManager and confirm that XPIDatabase.verifySignatures would not recompute + // the content of the signedTypes array if all values are still the same. + info( + "Check that XPIDatabase.updateCompatibility will recompute missing signedTypes properties" + ); + await promiseRestartManager(); + + let listener = { + onPropertyChanged(_addon, properties) { + Assert.deepEqual( + properties, + [], + `No properties should have been changed for ${_addon.id}` + ); + Assert.ok( + false, + `onPropertyChanged should have not been called for ${_addon.id}` + ); + }, + }; + + AddonManager.addAddonListener(listener); + await verifySignatures(); + AddonManager.removeAddonListener(listener); + + // Shutdown the AddonManager and tamper the AddonDB to set signedTypes to undefined + // then confirm that XPIDatabase.verifySignatures does not hit an exception due to + // signedTypes assumed to always be set to an array. + info( + "Check that XPIDatabase.verifySignatures does not fail when signedTypes is undefined" + ); + await promiseShutdownManager(); + await removeSignedStateFromAddonDB(); + await promiseStartupManager(); + + // Expect the signedTypes property to be undefined because of the + // AddonDB data being tampered earlier in this test. + const addonUndefinedSignedTypes = await AddonManager.getAddonByID(addonId); + Assert.deepEqual( + addonUndefinedSignedTypes.signedTypes, + undefined, + `Got empty ${addonId} signedTyped set to undefied after AddonDB data tampered` + ); + await verifySignatures(); + Assert.deepEqual( + addonUndefinedSignedTypes.signedTypes?.sort(), + expectedSignedTypes.sort(), + `Got expected ${addonId} signedTyped after XPIDatabase.verifySignatures recomputed it` + ); + + await addonUndefinedSignedTypes.uninstall(); +}); + +add_task( + { + pref_set: [["xpinstall.signatures.required", false]], + // Skip this test on builds where disabling xpi signature checks is not supported. + skip_if: () => AppConstants.MOZ_REQUIRE_SIGNING, + }, + async function test_weak_signature_not_restricted_on_disabled_signature_checks() { + // Ensure the restriction on installing xpi using only weak signatures is enabled. + let resetWeakSignaturePref = + AddonTestUtils.setWeakSignatureInstallAllowed(false); + const { addon } = await promiseInstallFile( + do_get_file("amosigned-sha1only.xpi") + ); + Assert.notEqual(addon, null, "Expect addon to be installed"); + resetWeakSignaturePref(); + await addon.uninstall(); + } +); +add_task(useAMOStageCert(), async function test_no_change() { // Install the first add-on await promiseInstallFile(do_get_file(`${DATA}/signed1.xpi`)); @@ -43,7 +473,7 @@ add_task(async function test_no_change() { await manuallyInstall(do_get_file(`${DATA}/signed2.xpi`), profileDir, ID); let listener = { - onPropetyChanged(_addon, properties) { + onPropertyChanged(_addon) { Assert.ok(false, `Got unexpected onPropertyChanged for ${_addon.id}`); }, }; @@ -63,7 +493,7 @@ add_task(async function test_no_change() { AddonManager.removeAddonListener(listener); }); -add_task(async function test_diable() { +add_task(useAMOStageCert(), async function test_disable() { // Install the first add-on await promiseInstallFile(do_get_file(`${DATA}/signed1.xpi`)); @@ -96,7 +526,7 @@ add_task(async function test_diable() { Assert.deepEqual( changedProperties, - ["signedState", "appDisabled"], + ["signedState", "signedTypes", "appDisabled"], "Got onPropertyChanged events for signedState and appDisabled" ); diff --git a/toolkit/mozapps/extensions/test/xpcshell/test_system_delay_update.js b/toolkit/mozapps/extensions/test/xpcshell/test_system_delay_update.js index 4490ec065b..b7dfd0ba72 100644 --- a/toolkit/mozapps/extensions/test/xpcshell/test_system_delay_update.js +++ b/toolkit/mozapps/extensions/test/xpcshell/test_system_delay_update.js @@ -26,7 +26,7 @@ registerCleanupFunction(() => { distroDir.remove(true); }); -AddonTestUtils.usePrivilegedSignatures = id => "system"; +AddonTestUtils.usePrivilegedSignatures = () => "system"; createAppInfo("xpcshell@tests.mozilla.org", "XPCShell", "1", "42"); diff --git a/toolkit/mozapps/extensions/test/xpcshell/test_system_repository.js b/toolkit/mozapps/extensions/test/xpcshell/test_system_repository.js index dc1c96e7bc..342410992b 100644 --- a/toolkit/mozapps/extensions/test/xpcshell/test_system_repository.js +++ b/toolkit/mozapps/extensions/test/xpcshell/test_system_repository.js @@ -29,7 +29,7 @@ add_task(async function test_app_addons() { `http://localhost:${gServer.identity.primaryPort}/get?%IDS%` ); - gServer.registerPathHandler("/get", (request, response) => { + gServer.registerPathHandler("/get", () => { do_throw("Unexpected request to server."); }); diff --git a/toolkit/mozapps/extensions/test/xpcshell/test_system_reset.js b/toolkit/mozapps/extensions/test/xpcshell/test_system_reset.js index 93e4c516fa..37e056c140 100644 --- a/toolkit/mozapps/extensions/test/xpcshell/test_system_reset.js +++ b/toolkit/mozapps/extensions/test/xpcshell/test_system_reset.js @@ -3,7 +3,7 @@ const updatesDir = FileUtils.getDir("ProfD", ["features"]); -AddonTestUtils.usePrivilegedSignatures = id => "system"; +AddonTestUtils.usePrivilegedSignatures = () => "system"; add_task(async function setup() { // Build the test sets @@ -489,7 +489,7 @@ add_task(async function test_bad_app_cert() { await promiseShutdownManager(); - AddonTestUtils.usePrivilegedSignatures = id => "system"; + AddonTestUtils.usePrivilegedSignatures = () => "system"; }); // A failed upgrade should revert to the default set. diff --git a/toolkit/mozapps/extensions/test/xpcshell/test_system_update_blank.js b/toolkit/mozapps/extensions/test/xpcshell/test_system_update_blank.js index 56d10436c7..a60d72f8b3 100644 --- a/toolkit/mozapps/extensions/test/xpcshell/test_system_update_blank.js +++ b/toolkit/mozapps/extensions/test/xpcshell/test_system_update_blank.js @@ -6,7 +6,7 @@ let distroDir = FileUtils.getDir("ProfD", ["sysfeatures", "empty"]); distroDir.create(Ci.nsIFile.DIRECTORY_TYPE, FileUtils.PERMS_DIRECTORY); registerDirectory("XREAppFeat", distroDir); -AddonTestUtils.usePrivilegedSignatures = id => "system"; +AddonTestUtils.usePrivilegedSignatures = () => "system"; add_task(() => initSystemAddonDirs()); diff --git a/toolkit/mozapps/extensions/test/xpcshell/test_system_update_checkSizeHash.js b/toolkit/mozapps/extensions/test/xpcshell/test_system_update_checkSizeHash.js index f9ac09255a..456164dfae 100644 --- a/toolkit/mozapps/extensions/test/xpcshell/test_system_update_checkSizeHash.js +++ b/toolkit/mozapps/extensions/test/xpcshell/test_system_update_checkSizeHash.js @@ -6,7 +6,7 @@ let distroDir = FileUtils.getDir("ProfD", ["sysfeatures", "empty"]); distroDir.create(Ci.nsIFile.DIRECTORY_TYPE, FileUtils.PERMS_DIRECTORY); registerDirectory("XREAppFeat", distroDir); -AddonTestUtils.usePrivilegedSignatures = id => "system"; +AddonTestUtils.usePrivilegedSignatures = () => "system"; /** * Defines the set of initial conditions to run each test against. Each should diff --git a/toolkit/mozapps/extensions/test/xpcshell/test_system_update_custom.js b/toolkit/mozapps/extensions/test/xpcshell/test_system_update_custom.js index b0310d3ceb..22250d6724 100644 --- a/toolkit/mozapps/extensions/test/xpcshell/test_system_update_custom.js +++ b/toolkit/mozapps/extensions/test/xpcshell/test_system_update_custom.js @@ -6,7 +6,7 @@ let distroDir = FileUtils.getDir("ProfD", ["sysfeatures", "empty"]); distroDir.create(Ci.nsIFile.DIRECTORY_TYPE, FileUtils.PERMS_DIRECTORY); registerDirectory("XREAppFeat", distroDir); -AddonTestUtils.usePrivilegedSignatures = id => "system"; +AddonTestUtils.usePrivilegedSignatures = () => "system"; add_task(initSystemAddonDirs); diff --git a/toolkit/mozapps/extensions/test/xpcshell/test_system_update_empty.js b/toolkit/mozapps/extensions/test/xpcshell/test_system_update_empty.js index 3fae4272be..16c2084842 100644 --- a/toolkit/mozapps/extensions/test/xpcshell/test_system_update_empty.js +++ b/toolkit/mozapps/extensions/test/xpcshell/test_system_update_empty.js @@ -6,7 +6,7 @@ let distroDir = FileUtils.getDir("ProfD", ["sysfeatures", "empty"]); distroDir.create(Ci.nsIFile.DIRECTORY_TYPE, FileUtils.PERMS_DIRECTORY); registerDirectory("XREAppFeat", distroDir); -AddonTestUtils.usePrivilegedSignatures = id => "system"; +AddonTestUtils.usePrivilegedSignatures = () => "system"; add_task(() => initSystemAddonDirs()); diff --git a/toolkit/mozapps/extensions/test/xpcshell/test_system_update_installTelemetryInfo.js b/toolkit/mozapps/extensions/test/xpcshell/test_system_update_installTelemetryInfo.js index f67894289d..bc690cad71 100644 --- a/toolkit/mozapps/extensions/test/xpcshell/test_system_update_installTelemetryInfo.js +++ b/toolkit/mozapps/extensions/test/xpcshell/test_system_update_installTelemetryInfo.js @@ -7,7 +7,7 @@ let distroDir = FileUtils.getDir("ProfD", ["sysfeatures", "empty"]); distroDir.create(Ci.nsIFile.DIRECTORY_TYPE, FileUtils.PERMS_DIRECTORY); registerDirectory("XREAppFeat", distroDir); -AddonTestUtils.usePrivilegedSignatures = id => "system"; +AddonTestUtils.usePrivilegedSignatures = () => "system"; add_task(() => initSystemAddonDirs()); diff --git a/toolkit/mozapps/extensions/test/xpcshell/test_system_update_newset.js b/toolkit/mozapps/extensions/test/xpcshell/test_system_update_newset.js index fd93ba5d38..3a1746d28c 100644 --- a/toolkit/mozapps/extensions/test/xpcshell/test_system_update_newset.js +++ b/toolkit/mozapps/extensions/test/xpcshell/test_system_update_newset.js @@ -6,7 +6,7 @@ let distroDir = FileUtils.getDir("ProfD", ["sysfeatures", "empty"]); distroDir.create(Ci.nsIFile.DIRECTORY_TYPE, FileUtils.PERMS_DIRECTORY); registerDirectory("XREAppFeat", distroDir); -AddonTestUtils.usePrivilegedSignatures = id => "system"; +AddonTestUtils.usePrivilegedSignatures = () => "system"; add_task(() => initSystemAddonDirs()); diff --git a/toolkit/mozapps/extensions/test/xpcshell/test_system_update_overlapping.js b/toolkit/mozapps/extensions/test/xpcshell/test_system_update_overlapping.js index a6c5bc905c..61d3d91300 100644 --- a/toolkit/mozapps/extensions/test/xpcshell/test_system_update_overlapping.js +++ b/toolkit/mozapps/extensions/test/xpcshell/test_system_update_overlapping.js @@ -7,7 +7,7 @@ distroDir.create(Ci.nsIFile.DIRECTORY_TYPE, FileUtils.PERMS_DIRECTORY); registerDirectory("XREAppFeat", distroDir); add_task(() => initSystemAddonDirs()); -AddonTestUtils.usePrivilegedSignatures = id => "system"; +AddonTestUtils.usePrivilegedSignatures = () => "system"; /** * Defines the set of initial conditions to run each test against. Each should diff --git a/toolkit/mozapps/extensions/test/xpcshell/test_system_update_uninstall_check.js b/toolkit/mozapps/extensions/test/xpcshell/test_system_update_uninstall_check.js index bf2dd85772..b2daa307db 100644 --- a/toolkit/mozapps/extensions/test/xpcshell/test_system_update_uninstall_check.js +++ b/toolkit/mozapps/extensions/test/xpcshell/test_system_update_uninstall_check.js @@ -35,7 +35,7 @@ add_task(async function test_systems_update_uninstall_check() { }, ]); - const listener = (msg, { method, params, reason }) => { + const listener = (msg, { method, params }) => { if (params.id === "system2@tests.mozilla.org" && method === "uninstall") { Assert.ok( false, diff --git a/toolkit/mozapps/extensions/test/xpcshell/test_system_update_upgrades.js b/toolkit/mozapps/extensions/test/xpcshell/test_system_update_upgrades.js index d270f33190..8e2d7776ef 100644 --- a/toolkit/mozapps/extensions/test/xpcshell/test_system_update_upgrades.js +++ b/toolkit/mozapps/extensions/test/xpcshell/test_system_update_upgrades.js @@ -6,7 +6,7 @@ let distroDir = FileUtils.getDir("ProfD", ["sysfeatures", "empty"]); distroDir.create(Ci.nsIFile.DIRECTORY_TYPE, FileUtils.PERMS_DIRECTORY); registerDirectory("XREAppFeat", distroDir); -AddonTestUtils.usePrivilegedSignatures = id => "system"; +AddonTestUtils.usePrivilegedSignatures = () => "system"; add_task(() => initSystemAddonDirs()); diff --git a/toolkit/mozapps/extensions/test/xpcshell/test_system_upgrades.js b/toolkit/mozapps/extensions/test/xpcshell/test_system_upgrades.js index f02003805c..ddf98c73ec 100644 --- a/toolkit/mozapps/extensions/test/xpcshell/test_system_upgrades.js +++ b/toolkit/mozapps/extensions/test/xpcshell/test_system_upgrades.js @@ -20,7 +20,7 @@ const systemDefaults = FileUtils.getDir("ProfD", [ systemDefaults.create(Ci.nsIFile.DIRECTORY_TYPE, FileUtils.PERMS_DIRECTORY); registerDirectory("XREAppFeat", systemDefaults); -AddonTestUtils.usePrivilegedSignatures = id => "system"; +AddonTestUtils.usePrivilegedSignatures = () => "system"; const ADDON_ID = "updates@test"; diff --git a/toolkit/mozapps/extensions/test/xpcshell/test_temporary.js b/toolkit/mozapps/extensions/test/xpcshell/test_temporary.js index 80faa57fc1..0bef760261 100644 --- a/toolkit/mozapps/extensions/test/xpcshell/test_temporary.js +++ b/toolkit/mozapps/extensions/test/xpcshell/test_temporary.js @@ -80,7 +80,7 @@ add_task(async function test_new_temporary() { Assert.equal(aInstall.version, "1.0"); installedCalled = true; }, - onInstallStarted: aInstall => { + onInstallStarted: () => { do_throw("onInstallStarted called unexpectedly"); }, }); @@ -416,7 +416,7 @@ add_task(async function test_replace_permanent() { } installedCalled = true; }, - onInstallStarted: aInstall => { + onInstallStarted: () => { do_throw("onInstallStarted called unexpectedly"); }, }); diff --git a/toolkit/mozapps/extensions/test/xpcshell/test_update.js b/toolkit/mozapps/extensions/test/xpcshell/test_update.js index 1bd41e8d71..708b9de264 100644 --- a/toolkit/mozapps/extensions/test/xpcshell/test_update.js +++ b/toolkit/mozapps/extensions/test/xpcshell/test_update.js @@ -595,25 +595,22 @@ add_task(async function test_params() { let resultsPromise = new Promise(resolve => { let results = new Map(); - testserver.registerPathHandler( - "/data/param_test.json", - function (request, response) { - let params = new URLSearchParams(request.queryString); - let itemId = params.get("item_id"); - ok( - !results.has(itemId), - `Should not see a duplicate request for item ${itemId}` - ); - - results.set(itemId, params); - - if (results.size === PARAM_IDS.length) { - resolve(results); - } - - request.setStatusLine(null, 500, "Server Error"); + testserver.registerPathHandler("/data/param_test.json", function (request) { + let params = new URLSearchParams(request.queryString); + let itemId = params.get("item_id"); + ok( + !results.has(itemId), + `Should not see a duplicate request for item ${itemId}` + ); + + results.set(itemId, params); + + if (results.size === PARAM_IDS.length) { + resolve(results); } - ); + + request.setStatusLine(null, 500, "Server Error"); + }); }); let addons = await getAddons(PARAM_IDS); @@ -746,11 +743,11 @@ add_task(async function test_no_auto_update() { equal(aInstall.existingAddon.id, "addon1@tests.mozilla.org"); }, - onDownloadFailed(aInstall) { + onDownloadFailed() { ok(false, "Should not have seen onDownloadFailed event"); }, - onDownloadCancelled(aInstall) { + onDownloadCancelled() { ok(false, "Should not have seen onDownloadCancelled event"); }, @@ -764,11 +761,11 @@ add_task(async function test_no_auto_update() { resolve(); }, - onInstallFailed(aInstall) { + onInstallFailed() { ok(false, "Should not have seen onInstallFailed event"); }, - onInstallCancelled(aInstall) { + onInstallCancelled() { ok(false, "Should not have seen onInstallCancelled event"); }, }; diff --git a/toolkit/mozapps/extensions/test/xpcshell/test_updateCancel.js b/toolkit/mozapps/extensions/test/xpcshell/test_updateCancel.js index ac201f434c..bba7a1b77b 100644 --- a/toolkit/mozapps/extensions/test/xpcshell/test_updateCancel.js +++ b/toolkit/mozapps/extensions/test/xpcshell/test_updateCancel.js @@ -27,7 +27,7 @@ function makeCancelListener() { }); return { - onUpdateAvailable(addon, install) { + onUpdateAvailable() { reject("Should not have seen onUpdateAvailable notification"); }, diff --git a/toolkit/mozapps/extensions/test/xpcshell/test_update_addontype.js b/toolkit/mozapps/extensions/test/xpcshell/test_update_addontype.js index ca324cf4ef..221f9e003e 100644 --- a/toolkit/mozapps/extensions/test/xpcshell/test_update_addontype.js +++ b/toolkit/mozapps/extensions/test/xpcshell/test_update_addontype.js @@ -67,7 +67,7 @@ add_task(async function test_update_theme_to_extension() { await Assert.rejects( install.install(), - err => install.error == AddonManager.ERROR_UNEXPECTED_ADDON_TYPE, + () => install.error == AddonManager.ERROR_UNEXPECTED_ADDON_TYPE, "Refusing to change addon type from theme to extension" ); diff --git a/toolkit/mozapps/extensions/test/xpcshell/test_update_noSystemAddonUpdate.js b/toolkit/mozapps/extensions/test/xpcshell/test_update_noSystemAddonUpdate.js index f13187ab33..93ff750066 100644 --- a/toolkit/mozapps/extensions/test/xpcshell/test_update_noSystemAddonUpdate.js +++ b/toolkit/mozapps/extensions/test/xpcshell/test_update_noSystemAddonUpdate.js @@ -25,7 +25,7 @@ add_task(async function test_systems_update_uninstall_check() { await setupSystemAddonConditions(initialSetup, distroDir); const testserver = createHttpServer({ hosts: ["example.com"] }); - testserver.registerPathHandler("/update.json", (request, response) => { + testserver.registerPathHandler("/update.json", request => { Assert.ok( !request._queryString.includes("system2@tests.mozilla.org"), "System addon should not request update from normal update process" diff --git a/toolkit/mozapps/extensions/test/xpcshell/test_updateid.js b/toolkit/mozapps/extensions/test/xpcshell/test_updateid.js index c88c8e637b..06dd536b9a 100644 --- a/toolkit/mozapps/extensions/test/xpcshell/test_updateid.js +++ b/toolkit/mozapps/extensions/test/xpcshell/test_updateid.js @@ -74,7 +74,7 @@ add_task(async function test_update_new_id() { await Assert.rejects( install.install(), - err => install.error == AddonManager.ERROR_INCORRECT_ID, + () => install.error == AddonManager.ERROR_INCORRECT_ID, "Upgrade to a different ID fails" ); diff --git a/toolkit/mozapps/extensions/test/xpcshell/test_updateversion.js b/toolkit/mozapps/extensions/test/xpcshell/test_updateversion.js index 4d1510c40f..5d6e045f21 100644 --- a/toolkit/mozapps/extensions/test/xpcshell/test_updateversion.js +++ b/toolkit/mozapps/extensions/test/xpcshell/test_updateversion.js @@ -65,7 +65,7 @@ add_task(async function test_update_version_mismatch() { await Assert.rejects( install.install(), - err => install.error == AddonManager.ERROR_UNEXPECTED_ADDON_VERSION, + () => install.error == AddonManager.ERROR_UNEXPECTED_ADDON_VERSION, "Should refuse installation when downloaded version does not match" ); diff --git a/toolkit/mozapps/extensions/test/xpcshell/test_webextension.js b/toolkit/mozapps/extensions/test/xpcshell/test_webextension.js index cd4b376117..db5f1d5925 100644 --- a/toolkit/mozapps/extensions/test/xpcshell/test_webextension.js +++ b/toolkit/mozapps/extensions/test/xpcshell/test_webextension.js @@ -316,6 +316,73 @@ add_task(async function test_options_ui() { ); await addon.uninstall(); + + info("Test again with options_page manifest property"); + const ID3 = "options_page_alias@tests.mozilla.org"; + addon = await promiseInstallWebExtension({ + manifest: { + browser_specific_settings: { gecko: { id: ID3 } }, + options_page: "options.html", + }, + }); + + checkAddon(ID3, addon, { + optionsType: AddonManager.OPTIONS_TYPE_TAB, + }); + + ok( + OPTIONS_RE.test(addon.optionsURL), + "Addon should have a moz-extension: options URL for /options.html" + ); + + await addon.uninstall(); + + info("Test options_page and options_page set to a different page"); + + const ID4 = "options_page_warning@tests.mozilla.org"; + addon = await promiseInstallWebExtension({ + manifest: { + browser_specific_settings: { gecko: { id: ID4 } }, + options_page: "options_page.html", + options_ui: { + page: "options.html", + open_in_tab: false, + }, + }, + }); + + checkAddon(ID4, addon, { + optionsType: AddonManager.OPTIONS_TYPE_INLINE_BROWSER, + }); + + ok( + OPTIONS_RE.test(addon.optionsURL), + "Addon should have a moz-extension: options URL for /options.html" + ); + + await addon.uninstall(); + + info("Test options_page and options_page are both set to the same page"); + + const ID5 = "options_page_and_ui_same_page@tests.mozilla.org"; + addon = await promiseInstallWebExtension({ + manifest: { + browser_specific_settings: { gecko: { id: ID5 } }, + options_page: "options.html", + options_ui: { page: "options.html" }, + }, + }); + + checkAddon(ID5, addon, { + optionsType: AddonManager.OPTIONS_TYPE_INLINE_BROWSER, + }); + + ok( + OPTIONS_RE.test(addon.optionsURL), + "Addon should have a moz-extension: options URL for /options.html" + ); + + await addon.uninstall(); }); // Test that experiments permissions add the appropriate dependencies. diff --git a/toolkit/mozapps/extensions/test/xpcshell/test_webextension_install.js b/toolkit/mozapps/extensions/test/xpcshell/test_webextension_install.js index 1b2080e8db..913c802609 100644 --- a/toolkit/mozapps/extensions/test/xpcshell/test_webextension_install.js +++ b/toolkit/mozapps/extensions/test/xpcshell/test_webextension_install.js @@ -11,8 +11,10 @@ add_task(async function setup() { await promiseStartupManager(); }); +// Extension without id in the manifest file and signed with AMO prod root +// (https://addons.mozilla.org/en-US/firefox/addon/reference-static-theme/). const IMPLICIT_ID_XPI = "data/webext-implicit-id.xpi"; -const IMPLICIT_ID_ID = "webext_implicit_id@tests.mozilla.org"; +const IMPLICIT_ID_ID = "{46607a7b-1b2a-40ce-9afe-91cda52c46a6}"; // webext-implicit-id.xpi has a minimal manifest with no // applications or browser_specific_settings, so its id comes diff --git a/toolkit/mozapps/extensions/test/xpcshell/xpcshell.toml b/toolkit/mozapps/extensions/test/xpcshell/xpcshell.toml index 6b1cb010d4..e8d3807ab9 100644 --- a/toolkit/mozapps/extensions/test/xpcshell/xpcshell.toml +++ b/toolkit/mozapps/extensions/test/xpcshell/xpcshell.toml @@ -4,7 +4,12 @@ tags = "addons" head = "head_addons.js" firefox-appdir = "browser" dupe-manifest = true -support-files = ["data/**"] +support-files = [ + "data/**", + "../xpinstall/amosigned.xpi", + "../xpinstall/amosigned-mv3-cose.xpi", + "../xpinstall/amosigned-sha1only.xpi", +] ["test_AMBrowserExtensionsImport.js"] diff --git a/toolkit/mozapps/extensions/test/xpinstall/amosigned-mv3-cose.xpi b/toolkit/mozapps/extensions/test/xpinstall/amosigned-mv3-cose.xpi new file mode 100644 index 0000000000..e09747686b Binary files /dev/null and b/toolkit/mozapps/extensions/test/xpinstall/amosigned-mv3-cose.xpi differ diff --git a/toolkit/mozapps/extensions/test/xpinstall/amosigned-sha1only.xpi b/toolkit/mozapps/extensions/test/xpinstall/amosigned-sha1only.xpi new file mode 100644 index 0000000000..f2948e6994 Binary files /dev/null and b/toolkit/mozapps/extensions/test/xpinstall/amosigned-sha1only.xpi differ diff --git a/toolkit/mozapps/extensions/test/xpinstall/amosigned.xpi b/toolkit/mozapps/extensions/test/xpinstall/amosigned.xpi index f2948e6994..9e895dbbb4 100644 Binary files a/toolkit/mozapps/extensions/test/xpinstall/amosigned.xpi and b/toolkit/mozapps/extensions/test/xpinstall/amosigned.xpi differ diff --git a/toolkit/mozapps/extensions/test/xpinstall/browser.toml b/toolkit/mozapps/extensions/test/xpinstall/browser.toml index f6ca43982e..f2c73b0a1d 100644 --- a/toolkit/mozapps/extensions/test/xpinstall/browser.toml +++ b/toolkit/mozapps/extensions/test/xpinstall/browser.toml @@ -96,7 +96,7 @@ https_first_disabled = true # Bug 1737265 ["browser_doorhanger_installs.js"] https_first_disabled = true # Bug 1737265 skip-if = [ - "os == 'win' && os_version == '10.0' && bits == 64", #Bug 1615449 + "os == 'win' && os_version == '10.2009' && bits == 64", #Bug 1615449 ] ["browser_empty.js"] diff --git a/toolkit/mozapps/extensions/test/xpinstall/browser_auth.js b/toolkit/mozapps/extensions/test/xpinstall/browser_auth.js index 2248af4270..171504049c 100644 --- a/toolkit/mozapps/extensions/test/xpinstall/browser_auth.js +++ b/toolkit/mozapps/extensions/test/xpinstall/browser_auth.js @@ -42,7 +42,7 @@ function get_auth_info() { return ["testuser", "testpass"]; } -function download_failed(install) { +function download_failed() { ok(false, "Install should not have failed"); } diff --git a/toolkit/mozapps/extensions/test/xpinstall/browser_auth4.js b/toolkit/mozapps/extensions/test/xpinstall/browser_auth4.js index 46ee2b5cb6..0763d2e55c 100644 --- a/toolkit/mozapps/extensions/test/xpinstall/browser_auth4.js +++ b/toolkit/mozapps/extensions/test/xpinstall/browser_auth4.js @@ -45,7 +45,7 @@ function get_auth_info() { return ["testuser", "testpass"]; } -function download_failed(install) { +function download_failed() { ok(false, "Install should not have failed"); } diff --git a/toolkit/mozapps/extensions/test/xpinstall/browser_bug645699.js b/toolkit/mozapps/extensions/test/xpinstall/browser_bug645699.js index 690ac2b3eb..ca05f822b6 100644 --- a/toolkit/mozapps/extensions/test/xpinstall/browser_bug645699.js +++ b/toolkit/mozapps/extensions/test/xpinstall/browser_bug645699.js @@ -54,7 +54,7 @@ function allow_blocked(installInfo) { return false; } -function confirm_install(panel) { +function confirm_install() { ok(false, "Should not see the install dialog"); return false; } diff --git a/toolkit/mozapps/extensions/test/xpinstall/browser_bug645699_postDownload.js b/toolkit/mozapps/extensions/test/xpinstall/browser_bug645699_postDownload.js index aa8b948c14..a857d11405 100644 --- a/toolkit/mozapps/extensions/test/xpinstall/browser_bug645699_postDownload.js +++ b/toolkit/mozapps/extensions/test/xpinstall/browser_bug645699_postDownload.js @@ -40,7 +40,7 @@ function allow_blocked(installInfo) { return false; } -function confirm_install(panel) { +function confirm_install() { ok(false, "Should not see the install dialog"); return false; } diff --git a/toolkit/mozapps/extensions/test/xpinstall/browser_bug672485.js b/toolkit/mozapps/extensions/test/xpinstall/browser_bug672485.js index 216d543458..2961d327d3 100644 --- a/toolkit/mozapps/extensions/test/xpinstall/browser_bug672485.js +++ b/toolkit/mozapps/extensions/test/xpinstall/browser_bug672485.js @@ -36,7 +36,7 @@ function test() { ); } -function confirm_install(panel) { +function confirm_install() { ok(false, "Should not see the install dialog"); return false; } diff --git a/toolkit/mozapps/extensions/test/xpinstall/browser_doorhanger_installs.js b/toolkit/mozapps/extensions/test/xpinstall/browser_doorhanger_installs.js index 01c8089180..073c44eecd 100644 --- a/toolkit/mozapps/extensions/test/xpinstall/browser_doorhanger_installs.js +++ b/toolkit/mozapps/extensions/test/xpinstall/browser_doorhanger_installs.js @@ -52,7 +52,7 @@ async function waitForProgressNotification( let topic = getObserverTopic(notificationId); let observerPromise = new Promise(resolve => { - Services.obs.addObserver(function observer(aSubject, aTopic, aData) { + Services.obs.addObserver(function observer(aSubject, aTopic) { // Ignore the progress notification unless that is the notification we want if ( notificationId != PROGRESS_NOTIFICATION && @@ -208,7 +208,7 @@ async function waitForNotification( let observerPromise; if (aId !== "addon-webext-permissions") { observerPromise = new Promise(resolve => { - Services.obs.addObserver(function observer(aSubject, aTopic, aData) { + Services.obs.addObserver(function observer(aSubject, aTopic) { // Ignore the progress notification unless that is the notification we want if ( aId != PROGRESS_NOTIFICATION && @@ -298,7 +298,7 @@ function acceptInstallDialog(installDialog) { installDialog.button.click(); } -async function waitForSingleNotification(aCallback) { +async function waitForSingleNotification() { while (PopupNotifications.panel.childNodes.length != 1) { await new Promise(resolve => executeSoon(resolve)); @@ -697,27 +697,37 @@ var TESTS = [ let installDialogPromise = waitForInstallDialog(); - let tab = await BrowserTestUtils.openNewForegroundTab( - gBrowser, - TESTROOT + "installtrigger.html?" + triggers - ); + try { + // Prevent install to fail due to privileged.xpi version using + // an addon version that hits a manifest warning (see PRIV_ADDON_VERSION). + // TODO(Bug 1824240): remove this once privileged.xpi can be resigned with a + // version format that does not hit a manifest warning. + ExtensionTestUtils.failOnSchemaWarnings(false); + let tab = await BrowserTestUtils.openNewForegroundTab( + gBrowser, + TESTROOT + "installtrigger.html?" + triggers + ); - let notificationPromise = acceptAppMenuNotificationWhenShown( - "addon-installed", - "test@tests.mozilla.org", - { incognitoHidden: true } - ); + let notificationPromise = acceptAppMenuNotificationWhenShown( + "addon-installed", + "test@tests.mozilla.org", + { incognitoHidden: true } + ); - (await installDialogPromise).button.click(); - await notificationPromise; + (await installDialogPromise).button.click(); + await notificationPromise; - let installs = await AddonManager.getAllInstalls(); - is(installs.length, 0, "Should be no pending installs"); + let installs = await AddonManager.getAllInstalls(); + is(installs.length, 0, "Should be no pending installs"); - let addon = await AddonManager.getAddonByID("test@tests.mozilla.org"); - await addon.uninstall(); + let addon = await AddonManager.getAddonByID("test@tests.mozilla.org"); + await addon.uninstall(); + + await BrowserTestUtils.removeTab(tab); + } finally { + ExtensionTestUtils.failOnSchemaWarnings(true); + } - await BrowserTestUtils.removeTab(tab); await SpecialPowers.popPrefEnv(); AddonManager.checkUpdateSecurity = true; }, @@ -1477,7 +1487,7 @@ var TESTS = [ var gTestStart = null; var XPInstallObserver = { - observe(aSubject, aTopic, aData) { + observe(aSubject, aTopic) { var installInfo = aSubject.wrappedJSObject; info( "Observed " + aTopic + " for " + installInfo.installs.length + " installs" diff --git a/toolkit/mozapps/extensions/test/xpinstall/browser_enabled.js b/toolkit/mozapps/extensions/test/xpinstall/browser_enabled.js index b8ee1b254f..f00d6ca0d8 100644 --- a/toolkit/mozapps/extensions/test/xpinstall/browser_enabled.js +++ b/toolkit/mozapps/extensions/test/xpinstall/browser_enabled.js @@ -51,17 +51,17 @@ add_task(async function test_disabled() { add_task(async function test_disabled2() { let installDisabledCalled = false; - Harness.installDisabledCallback = installInfo => { + Harness.installDisabledCallback = () => { installDisabledCalled = true; ok(true, "Saw installation disabled"); }; - Harness.installBlockedCallback = installInfo => { + Harness.installBlockedCallback = () => { ok(false, "Should never see the blocked install notification"); return false; }; - Harness.installConfirmCallback = panel => { + Harness.installConfirmCallback = () => { ok(false, "Should never see an install confirmation dialog"); return false; }; diff --git a/toolkit/mozapps/extensions/test/xpinstall/browser_hash.js b/toolkit/mozapps/extensions/test/xpinstall/browser_hash.js index ab7d21b64e..2563b64dd4 100644 --- a/toolkit/mozapps/extensions/test/xpinstall/browser_hash.js +++ b/toolkit/mozapps/extensions/test/xpinstall/browser_hash.js @@ -1,12 +1,17 @@ // ---------------------------------------------------------------------------- // Test whether an install succeeds when a valid hash is included // This verifies bug 302284 -function test() { +add_task(async function test_install_with_hash() { // This test currently depends on InstallTrigger.install availability. setInstallTriggerPrefs(); - Harness.installEndedCallback = install_ended; - Harness.installsCompletedCallback = finish_test; + const xpiFilePath = getTestFilePath("./amosigned.xpi"); + const xpiFileHash = await IOUtils.computeHexDigest(xpiFilePath, "sha256"); + + const deferredInstallCompleted = Promise.withResolvers(); + + Harness.installEndedCallback = (install, addon) => addon.uninstall(); + Harness.installsCompletedCallback = deferredInstallCompleted.resolve; Harness.setup(); PermissionTestUtils.add( @@ -19,7 +24,7 @@ function test() { JSON.stringify({ "Unsigned XPI": { URL: TESTROOT + "amosigned.xpi", - Hash: "sha1:ee95834ad862245a9ef99ccecc2a857cadc16404", + Hash: `sha256:${xpiFileHash}`, toString() { return this.URL; }, @@ -31,17 +36,13 @@ function test() { gBrowser, TESTROOT + "installtrigger.html?" + triggers ); -} - -function install_ended(install, addon) { - return addon.uninstall(); -} -function finish_test(count) { + info("Wait for the install to be completed"); + const count = await deferredInstallCompleted.promise; is(count, 1, "1 Add-on should have been successfully installed"); PermissionTestUtils.remove("http://example.com", "install"); gBrowser.removeCurrentTab(); Harness.finish(); -} +}); diff --git a/toolkit/mozapps/extensions/test/xpinstall/browser_hash2.js b/toolkit/mozapps/extensions/test/xpinstall/browser_hash2.js index 9fd0c66292..e7779792ac 100644 --- a/toolkit/mozapps/extensions/test/xpinstall/browser_hash2.js +++ b/toolkit/mozapps/extensions/test/xpinstall/browser_hash2.js @@ -1,12 +1,17 @@ // ---------------------------------------------------------------------------- // Test whether an install succeeds using case-insensitive hashes // This verifies bug 603021 -function test() { +add_task(async function test_install_hash_case_insensitive() { // This test currently depends on InstallTrigger.install availability. setInstallTriggerPrefs(); - Harness.installEndedCallback = install_ended; - Harness.installsCompletedCallback = finish_test; + const xpiFilePath = getTestFilePath("./amosigned.xpi"); + const xpiFileHash = await IOUtils.computeHexDigest(xpiFilePath, "sha256"); + + const deferredInstallCompleted = Promise.withResolvers(); + + Harness.installEndedCallback = (install, addon) => addon.uninstall(); + Harness.installsCompletedCallback = deferredInstallCompleted.resolve; Harness.setup(); PermissionTestUtils.add( @@ -19,7 +24,7 @@ function test() { JSON.stringify({ "Unsigned XPI": { URL: TESTROOT + "amosigned.xpi", - Hash: "sha1:EE95834AD862245A9EF99CCECC2A857CADC16404", + Hash: `sha256:${xpiFileHash.toUpperCase()}`, toString() { return this.URL; }, @@ -31,17 +36,13 @@ function test() { gBrowser, TESTROOT + "installtrigger.html?" + triggers ); -} - -function install_ended(install, addon) { - return addon.uninstall(); -} -function finish_test(count) { + info("Wait for the install to be completed"); + const count = await deferredInstallCompleted.promise; is(count, 1, "1 Add-on should have been successfully installed"); PermissionTestUtils.remove("http://example.com", "install"); gBrowser.removeCurrentTab(); Harness.finish(); -} +}); diff --git a/toolkit/mozapps/extensions/test/xpinstall/browser_httphash.js b/toolkit/mozapps/extensions/test/xpinstall/browser_httphash.js index 1ce8eb55af..6f788e5122 100644 --- a/toolkit/mozapps/extensions/test/xpinstall/browser_httphash.js +++ b/toolkit/mozapps/extensions/test/xpinstall/browser_httphash.js @@ -2,12 +2,21 @@ // Test whether an install succeeds when a valid hash is included in the HTTPS // request // This verifies bug 591070 -function test() { +add_task(async function test_instal_hash_https() { // This test currently depends on InstallTrigger.install availability. setInstallTriggerPrefs(); - Harness.installEndedCallback = install_ended; - Harness.installsCompletedCallback = finish_test; + await SpecialPowers.pushPrefEnv({ + set: [[PREF_INSTALL_REQUIREBUILTINCERTS, false]], + }); + + const xpiFilePath = getTestFilePath("./amosigned.xpi"); + const xpiFileHash = await IOUtils.computeHexDigest(xpiFilePath, "sha256"); + + const deferredInstallCompleted = Promise.withResolvers(); + + Harness.installEndedCallback = (install, addon) => addon.uninstall(); + Harness.installsCompletedCallback = deferredInstallCompleted.resolve; Harness.setup(); PermissionTestUtils.add( @@ -15,13 +24,8 @@ function test() { "install", Services.perms.ALLOW_ACTION ); - Services.prefs.setBoolPref(PREF_INSTALL_REQUIREBUILTINCERTS, false); - var url = "https://example.com/browser/" + RELATIVE_DIR + "hashRedirect.sjs"; - url += - "?sha1:ee95834ad862245a9ef99ccecc2a857cadc16404|" + - TESTROOT + - "amosigned.xpi"; + const url = `https://example.com/browser/${RELATIVE_DIR}hashRedirect.sjs?sha256:${xpiFileHash}|${TESTROOT}amosigned.xpi`; var triggers = encodeURIComponent( JSON.stringify({ @@ -38,18 +42,14 @@ function test() { gBrowser, TESTROOT + "installtrigger.html?" + triggers ); -} - -function install_ended(install, addon) { - return addon.uninstall(); -} -function finish_test(count) { + info("Wait for the install to be completed"); + const count = await deferredInstallCompleted.promise; is(count, 1, "1 Add-on should have been successfully installed"); PermissionTestUtils.remove("http://example.com", "install"); - Services.prefs.clearUserPref(PREF_INSTALL_REQUIREBUILTINCERTS); + await SpecialPowers.popPrefEnv(); gBrowser.removeCurrentTab(); Harness.finish(); -} +}); diff --git a/toolkit/mozapps/extensions/test/xpinstall/browser_httphash3.js b/toolkit/mozapps/extensions/test/xpinstall/browser_httphash3.js index ffb5a3ddb4..d76ba58135 100644 --- a/toolkit/mozapps/extensions/test/xpinstall/browser_httphash3.js +++ b/toolkit/mozapps/extensions/test/xpinstall/browser_httphash3.js @@ -1,12 +1,25 @@ // ---------------------------------------------------------------------------- // Tests that the HTTPS hash is ignored when InstallTrigger is passed a hash. // This verifies bug 591070 -function test() { +add_task(async function test_installTrigger_hash_override() { // This test currently depends on InstallTrigger.install availability. + // NOTE: this test is covering a feature that we don't support anymore on any + // on the Firefox channels, and so we can remove this test along with + // removing InstallTrigger implementation (even if the InstallTrigger global + // is going to stay defined as null on all channels). setInstallTriggerPrefs(); - Harness.installEndedCallback = install_ended; - Harness.installsCompletedCallback = finish_test; + await SpecialPowers.pushPrefEnv({ + set: [[PREF_INSTALL_REQUIREBUILTINCERTS, false]], + }); + + const xpiFilePath = getTestFilePath("./amosigned.xpi"); + const xpiFileHash = await IOUtils.computeHexDigest(xpiFilePath, "sha256"); + + const deferredInstallCompleted = Promise.withResolvers(); + + Harness.installEndedCallback = (install, addon) => addon.uninstall(); + Harness.installsCompletedCallback = deferredInstallCompleted.resolve; Harness.setup(); PermissionTestUtils.add( @@ -14,7 +27,6 @@ function test() { "install", Services.perms.ALLOW_ACTION ); - Services.prefs.setBoolPref(PREF_INSTALL_REQUIREBUILTINCERTS, false); var url = "https://example.com/browser/" + RELATIVE_DIR + "hashRedirect.sjs"; url += "?sha1:foobar|" + TESTROOT + "amosigned.xpi"; @@ -23,7 +35,7 @@ function test() { JSON.stringify({ "Unsigned XPI": { URL: url, - Hash: "sha1:ee95834ad862245a9ef99ccecc2a857cadc16404", + Hash: `sha256:${xpiFileHash}`, toString() { return this.URL; }, @@ -35,18 +47,14 @@ function test() { gBrowser, TESTROOT + "installtrigger.html?" + triggers ); -} - -function install_ended(install, addon) { - return addon.uninstall(); -} -function finish_test(count) { + info("Wait for the install to be completed"); + const count = await deferredInstallCompleted.promise; is(count, 1, "1 Add-on should have been successfully installed"); PermissionTestUtils.remove("http://example.com", "install"); - Services.prefs.clearUserPref(PREF_INSTALL_REQUIREBUILTINCERTS); + await SpecialPowers.popPrefEnv(); gBrowser.removeCurrentTab(); Harness.finish(); -} +}); diff --git a/toolkit/mozapps/extensions/test/xpinstall/browser_httphash5.js b/toolkit/mozapps/extensions/test/xpinstall/browser_httphash5.js index 727f13180b..489582dc0a 100644 --- a/toolkit/mozapps/extensions/test/xpinstall/browser_httphash5.js +++ b/toolkit/mozapps/extensions/test/xpinstall/browser_httphash5.js @@ -1,12 +1,21 @@ // ---------------------------------------------------------------------------- // Test that only the first HTTPS hash is used // This verifies bug 591070 -function test() { +add_task(async function test_only_first_https_hash_used() { // This test currently depends on InstallTrigger.install availability. setInstallTriggerPrefs(); - Harness.installEndedCallback = install_ended; - Harness.installsCompletedCallback = finish_test; + await SpecialPowers.pushPrefEnv({ + set: [[PREF_INSTALL_REQUIREBUILTINCERTS, false]], + }); + + const xpiFilePath = getTestFilePath("./amosigned.xpi"); + const xpiFileHash = await IOUtils.computeHexDigest(xpiFilePath, "sha256"); + + const deferredInstallCompleted = Promise.withResolvers(); + + Harness.installEndedCallback = (install, addon) => addon.uninstall(); + Harness.installsCompletedCallback = deferredInstallCompleted.resolve; Harness.setup(); PermissionTestUtils.add( @@ -14,10 +23,9 @@ function test() { "install", Services.perms.ALLOW_ACTION ); - Services.prefs.setBoolPref(PREF_INSTALL_REQUIREBUILTINCERTS, false); var url = "https://example.com/browser/" + RELATIVE_DIR + "hashRedirect.sjs"; - url += "?sha1:ee95834ad862245a9ef99ccecc2a857cadc16404|"; + url += `?sha256:${xpiFileHash}|`; url += "https://example.com/browser/" + RELATIVE_DIR + "hashRedirect.sjs"; url += "?sha1:foobar|" + TESTROOT + "amosigned.xpi"; @@ -36,18 +44,14 @@ function test() { gBrowser, TESTROOT + "installtrigger.html?" + triggers ); -} - -function install_ended(install, addon) { - return addon.uninstall(); -} -function finish_test(count) { + info("Wait for the install to be completed"); + const count = await deferredInstallCompleted.promise; is(count, 1, "1 Add-on should have been successfully installed"); PermissionTestUtils.remove("http://example.com", "install"); - Services.prefs.clearUserPref(PREF_INSTALL_REQUIREBUILTINCERTS); + await SpecialPowers.popPrefEnv(); gBrowser.removeCurrentTab(); Harness.finish(); -} +}); diff --git a/toolkit/mozapps/extensions/test/xpinstall/browser_localfile3.js b/toolkit/mozapps/extensions/test/xpinstall/browser_localfile3.js index c8d8532ed0..6d4014b7e4 100644 --- a/toolkit/mozapps/extensions/test/xpinstall/browser_localfile3.js +++ b/toolkit/mozapps/extensions/test/xpinstall/browser_localfile3.js @@ -27,7 +27,7 @@ function test() { }); } -function allow_blocked(installInfo) { +function allow_blocked() { ok(true, "Seen blocked"); return false; } diff --git a/toolkit/mozapps/extensions/test/xpinstall/browser_localfile4.js b/toolkit/mozapps/extensions/test/xpinstall/browser_localfile4.js index 771832a72b..96052129d4 100644 --- a/toolkit/mozapps/extensions/test/xpinstall/browser_localfile4.js +++ b/toolkit/mozapps/extensions/test/xpinstall/browser_localfile4.js @@ -40,7 +40,7 @@ function test() { ); } -function allow_blocked(installInfo) { +function allow_blocked() { ok(true, "Seen blocked"); return false; } diff --git a/toolkit/mozapps/extensions/test/xpinstall/browser_localfile4_postDownload.js b/toolkit/mozapps/extensions/test/xpinstall/browser_localfile4_postDownload.js index 8f8484a1c9..5e1707611d 100644 --- a/toolkit/mozapps/extensions/test/xpinstall/browser_localfile4_postDownload.js +++ b/toolkit/mozapps/extensions/test/xpinstall/browser_localfile4_postDownload.js @@ -39,7 +39,7 @@ function test() { ); } -function allow_blocked(installInfo) { +function allow_blocked() { ok(true, "Seen blocked"); return false; } diff --git a/toolkit/mozapps/extensions/test/xpinstall/browser_offline.js b/toolkit/mozapps/extensions/test/xpinstall/browser_offline.js index 946ad1dff7..8ab0194519 100644 --- a/toolkit/mozapps/extensions/test/xpinstall/browser_offline.js +++ b/toolkit/mozapps/extensions/test/xpinstall/browser_offline.js @@ -28,7 +28,7 @@ function test() { ); } -function download_progress(addon, value, maxValue) { +function download_progress() { try { // Tests always connect to localhost, and per bug 87717, localhost is now // reachable in offline mode. To avoid this, disable any proxy. diff --git a/toolkit/mozapps/extensions/test/xpinstall/browser_unsigned_trigger_xorigin.js b/toolkit/mozapps/extensions/test/xpinstall/browser_unsigned_trigger_xorigin.js index 7edbf318a0..8b43cc1383 100644 --- a/toolkit/mozapps/extensions/test/xpinstall/browser_unsigned_trigger_xorigin.js +++ b/toolkit/mozapps/extensions/test/xpinstall/browser_unsigned_trigger_xorigin.js @@ -40,7 +40,7 @@ function test() { ); } -function install_blocked(installInfo) { +function install_blocked() { wasOriginBlocked = true; } diff --git a/toolkit/mozapps/extensions/test/xpinstall/head.js b/toolkit/mozapps/extensions/test/xpinstall/head.js index 33ac33c830..a114b6efcd 100644 --- a/toolkit/mozapps/extensions/test/xpinstall/head.js +++ b/toolkit/mozapps/extensions/test/xpinstall/head.js @@ -133,7 +133,6 @@ var Harness = { Services.obs.addObserver(this, "addon-install-failed"); // For browser_auth tests which trigger auth dialogs. - Services.obs.addObserver(this, "tabmodal-dialog-loaded"); Services.obs.addObserver(this, "common-dialog-loaded"); this._boundWin = Cu.getWeakReference(win); // need this so our addon manager listener knows which window to use. @@ -157,7 +156,6 @@ var Harness = { Services.obs.removeObserver(self, "addon-install-blocked"); Services.obs.removeObserver(self, "addon-install-failed"); - Services.obs.removeObserver(self, "tabmodal-dialog-loaded"); Services.obs.removeObserver(self, "common-dialog-loaded"); AddonManager.removeInstallListener(self); @@ -512,7 +510,7 @@ var Harness = { // nsIObserver - observe(subject, topic, data) { + observe(subject, topic) { var installInfo = subject.wrappedJSObject; switch (topic) { case "addon-install-started": @@ -553,11 +551,6 @@ var Harness = { ); }, this); break; - case "tabmodal-dialog-loaded": - let browser = subject.ownerGlobal.gBrowser.selectedBrowser; - let prompt = browser.tabModalPromptBox.getPrompt(subject); - this.promptReady(prompt.Dialog); - break; case "common-dialog-loaded": this.promptReady(subject.Dialog); break; diff --git a/toolkit/mozapps/extensions/test/xpinstall/restartless.xpi b/toolkit/mozapps/extensions/test/xpinstall/restartless.xpi deleted file mode 100644 index 9fee8f60b1..0000000000 Binary files a/toolkit/mozapps/extensions/test/xpinstall/restartless.xpi and /dev/null differ diff --git a/toolkit/mozapps/extensions/test/xpinstall/triggerredirect.html b/toolkit/mozapps/extensions/test/xpinstall/triggerredirect.html index 1b098d6948..40ebd7f0d8 100644 --- a/toolkit/mozapps/extensions/test/xpinstall/triggerredirect.html +++ b/toolkit/mozapps/extensions/test/xpinstall/triggerredirect.html @@ -10,7 +10,7 @@