зеркало из https://github.com/mozilla/gecko-dev.git
Bug 1363925: Part 8c - Move isUsableAddon to XPIDatabase.jsm. r=aswan
MozReview-Commit-ID: 1aIA9Lu5sS2 --HG-- extra : rebase_source : ed39e7050d21d116338000234ab0cc4c6d34cf51 extra : histedit_source : f23e525032390d32e203d0b505cbf19d228d5ff6
This commit is contained in:
Родитель
980c561d2e
Коммит
4f17dc56da
|
@ -37,7 +37,6 @@ const {nsIBlocklistService} = Ci;
|
|||
* XPIStates,
|
||||
* descriptorToPath,
|
||||
* isTheme,
|
||||
* isUsableAddon,
|
||||
* isWebExtension,
|
||||
* recordAddonTelemetry,
|
||||
*/
|
||||
|
@ -50,7 +49,6 @@ for (let sym of [
|
|||
"XPIStates",
|
||||
"descriptorToPath",
|
||||
"isTheme",
|
||||
"isUsableAddon",
|
||||
"isWebExtension",
|
||||
"recordAddonTelemetry",
|
||||
]) {
|
||||
|
@ -78,6 +76,7 @@ const PREF_DB_SCHEMA = "extensions.databaseSchema";
|
|||
const PREF_EM_AUTO_DISABLED_SCOPES = "extensions.autoDisableScopes";
|
||||
const PREF_EM_EXTENSION_FORMAT = "extensions.";
|
||||
const PREF_PENDING_OPERATIONS = "extensions.pendingOperations";
|
||||
const PREF_XPI_SIGNATURES_DEV_ROOT = "xpinstall.signatures.dev-root";
|
||||
|
||||
const TOOLKIT_ID = "toolkit@mozilla.org";
|
||||
|
||||
|
@ -119,6 +118,10 @@ const PROP_JSON_FIELDS = ["id", "syncGUID", "location", "version", "type",
|
|||
"userPermissions", "icons", "iconURL", "icon64URL",
|
||||
"blocklistState", "blocklistURL", "startupData"];
|
||||
|
||||
const LEGACY_TYPES = new Set([
|
||||
"extension",
|
||||
]);
|
||||
|
||||
// Time to wait before async save of XPI JSON database, in milliseconds
|
||||
const ASYNC_SAVE_DELAY_MS = 20;
|
||||
|
||||
|
@ -472,7 +475,7 @@ AddonInternal.prototype = {
|
|||
XPIProvider.updateAddonDisabledState(this, userDisabled, softDisabled);
|
||||
XPIDatabase.saveChanges();
|
||||
} else {
|
||||
this.appDisabled = !isUsableAddon(this);
|
||||
this.appDisabled = !XPIDatabase.isUsableAddon(this);
|
||||
if (userDisabled !== undefined) {
|
||||
this.userDisabled = userDisabled;
|
||||
}
|
||||
|
@ -492,7 +495,7 @@ AddonInternal.prototype = {
|
|||
}
|
||||
}
|
||||
}
|
||||
this.appDisabled = !isUsableAddon(this);
|
||||
this.appDisabled = !XPIDatabase.isUsableAddon(this);
|
||||
},
|
||||
|
||||
/**
|
||||
|
@ -551,7 +554,7 @@ AddonInternal.prototype = {
|
|||
}
|
||||
|
||||
// Compatibility info may have changed so update appDisabled
|
||||
this.appDisabled = !isUsableAddon(this);
|
||||
this.appDisabled = !XPIDatabase.isUsableAddon(this);
|
||||
},
|
||||
|
||||
permissions() {
|
||||
|
@ -1891,6 +1894,117 @@ this.XPIDatabase = {
|
|||
return _filterDB(this.addonDB, aAddon => true);
|
||||
},
|
||||
|
||||
|
||||
/**
|
||||
* Returns true if signing is required for the given add-on type.
|
||||
*
|
||||
* @param {string} aType
|
||||
* The add-on type to check.
|
||||
* @returns {boolean}
|
||||
*/
|
||||
mustSign(aType) {
|
||||
if (!SIGNED_TYPES.has(aType))
|
||||
return false;
|
||||
|
||||
if (aType == "webextension-langpack") {
|
||||
return AddonSettings.LANGPACKS_REQUIRE_SIGNING;
|
||||
}
|
||||
|
||||
return AddonSettings.REQUIRE_SIGNING;
|
||||
},
|
||||
|
||||
/**
|
||||
* Determine if this addon should be disabled due to being legacy
|
||||
*
|
||||
* @param {Addon} addon The addon to check
|
||||
*
|
||||
* @returns {boolean} Whether the addon should be disabled for being legacy
|
||||
*/
|
||||
isDisabledLegacy(addon) {
|
||||
return (!AddonSettings.ALLOW_LEGACY_EXTENSIONS &&
|
||||
LEGACY_TYPES.has(addon.type) &&
|
||||
|
||||
// Legacy add-ons are allowed in the system location.
|
||||
!addon._installLocation.isSystem &&
|
||||
|
||||
// Legacy extensions may be installed temporarily in
|
||||
// non-release builds.
|
||||
!(AppConstants.MOZ_ALLOW_LEGACY_EXTENSIONS &&
|
||||
addon._installLocation.name == KEY_APP_TEMPORARY) &&
|
||||
|
||||
// Properly signed legacy extensions are allowed.
|
||||
addon.signedState !== AddonManager.SIGNEDSTATE_PRIVILEGED);
|
||||
},
|
||||
|
||||
/**
|
||||
* Calculates whether an add-on should be appDisabled or not.
|
||||
*
|
||||
* @param {AddonInternal} aAddon
|
||||
* The add-on to check
|
||||
* @returns {boolean}
|
||||
* True if the add-on should not be appDisabled
|
||||
*/
|
||||
isUsableAddon(aAddon) {
|
||||
if (this.mustSign(aAddon.type) && !aAddon.isCorrectlySigned) {
|
||||
logger.warn(`Add-on ${aAddon.id} is not correctly signed.`);
|
||||
if (Services.prefs.getBoolPref(PREF_XPI_SIGNATURES_DEV_ROOT, false)) {
|
||||
logger.warn(`Preference ${PREF_XPI_SIGNATURES_DEV_ROOT} is set.`);
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
if (aAddon.blocklistState == nsIBlocklistService.STATE_BLOCKED) {
|
||||
logger.warn(`Add-on ${aAddon.id} is blocklisted.`);
|
||||
return false;
|
||||
}
|
||||
|
||||
// If we can't read it, it's not usable:
|
||||
if (aAddon.brokenManifest) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (AddonManager.checkUpdateSecurity && !aAddon.providesUpdatesSecurely) {
|
||||
logger.warn(`Updates for add-on ${aAddon.id} must be provided over HTTPS.`);
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
if (!aAddon.isPlatformCompatible) {
|
||||
logger.warn(`Add-on ${aAddon.id} is not compatible with platform.`);
|
||||
return false;
|
||||
}
|
||||
|
||||
if (aAddon.dependencies.length) {
|
||||
let isActive = id => {
|
||||
let active = XPIProvider.activeAddons.get(id);
|
||||
return active && !active.disable;
|
||||
};
|
||||
|
||||
if (aAddon.dependencies.some(id => !isActive(id)))
|
||||
return false;
|
||||
}
|
||||
|
||||
if (this.isDisabledLegacy(aAddon)) {
|
||||
logger.warn(`disabling legacy extension ${aAddon.id}`);
|
||||
return false;
|
||||
}
|
||||
|
||||
if (AddonManager.checkCompatibility) {
|
||||
if (!aAddon.isCompatible) {
|
||||
logger.warn(`Add-on ${aAddon.id} is not compatible with application version.`);
|
||||
return false;
|
||||
}
|
||||
} else {
|
||||
let app = aAddon.matchingTargetApplication;
|
||||
if (!app) {
|
||||
logger.warn(`Add-on ${aAddon.id} is not compatible with target application.`);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
},
|
||||
|
||||
/**
|
||||
* Synchronously adds an AddonInternal's metadata to the database.
|
||||
*
|
||||
|
@ -2251,7 +2365,7 @@ this.XPIDatabaseReconcile = {
|
|||
aInstallLocation.name != KEY_APP_SYSTEM_DEFAULTS;
|
||||
|
||||
// appDisabled depends on whether the add-on is a foreignInstall so update
|
||||
aNewAddon.appDisabled = !isUsableAddon(aNewAddon);
|
||||
aNewAddon.appDisabled = !XPIDatabase.isUsableAddon(aNewAddon);
|
||||
|
||||
if (isDetectedInstall && aNewAddon.foreignInstall) {
|
||||
// If the add-on is a foreign install and is in a scope where add-ons
|
||||
|
@ -2409,7 +2523,7 @@ this.XPIDatabaseReconcile = {
|
|||
copyProperties(manifest, props, aOldAddon);
|
||||
}
|
||||
|
||||
aOldAddon.appDisabled = !isUsableAddon(aOldAddon);
|
||||
aOldAddon.appDisabled = !XPIDatabase.isUsableAddon(aOldAddon);
|
||||
|
||||
return aOldAddon;
|
||||
},
|
||||
|
|
|
@ -78,7 +78,7 @@ const PREF_XPI_DIRECT_WHITELISTED = "xpinstall.whitelist.directRequest";
|
|||
const PREF_XPI_FILE_WHITELISTED = "xpinstall.whitelist.fileRequest";
|
||||
const PREF_XPI_WHITELIST_REQUIRED = "xpinstall.whitelist.required";
|
||||
|
||||
/* globals BOOTSTRAP_REASONS, KEY_APP_SYSTEM_ADDONS, KEY_APP_SYSTEM_DEFAULTS, KEY_APP_TEMPORARY, PREF_BRANCH_INSTALLED_ADDON, PREF_SYSTEM_ADDON_SET, TEMPORARY_ADDON_SUFFIX, SIGNED_TYPES, TOOLKIT_ID, XPI_PERMISSION, XPIStates, getExternalType, isTheme, isUsableAddon, isWebExtension, mustSign */
|
||||
/* globals BOOTSTRAP_REASONS, KEY_APP_SYSTEM_ADDONS, KEY_APP_SYSTEM_DEFAULTS, KEY_APP_TEMPORARY, PREF_BRANCH_INSTALLED_ADDON, PREF_SYSTEM_ADDON_SET, TEMPORARY_ADDON_SUFFIX, SIGNED_TYPES, TOOLKIT_ID, XPI_PERMISSION, XPIStates, getExternalType, isTheme, isWebExtension */
|
||||
const XPI_INTERNAL_SYMBOLS = [
|
||||
"BOOTSTRAP_REASONS",
|
||||
"KEY_APP_SYSTEM_ADDONS",
|
||||
|
@ -93,9 +93,7 @@ const XPI_INTERNAL_SYMBOLS = [
|
|||
"XPIStates",
|
||||
"getExternalType",
|
||||
"isTheme",
|
||||
"isUsableAddon",
|
||||
"isWebExtension",
|
||||
"mustSign",
|
||||
];
|
||||
|
||||
for (let name of XPI_INTERNAL_SYMBOLS) {
|
||||
|
@ -931,7 +929,7 @@ var loadManifest = async function(aPackage, aInstallLocation, aOldAddon) {
|
|||
}
|
||||
|
||||
await addon.updateBlocklistState({oldAddon: aOldAddon});
|
||||
addon.appDisabled = !isUsableAddon(addon);
|
||||
addon.appDisabled = !XPIDatabase.isUsableAddon(addon);
|
||||
|
||||
defineSyncGUID(addon);
|
||||
|
||||
|
@ -1775,7 +1773,7 @@ class AddonInstall {
|
|||
}
|
||||
}
|
||||
|
||||
if (mustSign(this.addon.type)) {
|
||||
if (XPIDatabase.mustSign(this.addon.type)) {
|
||||
if (this.addon.signedState <= AddonManager.SIGNEDSTATE_MISSING) {
|
||||
// This add-on isn't properly signed by a signature that chains to the
|
||||
// trusted root.
|
||||
|
@ -1818,7 +1816,7 @@ class AddonInstall {
|
|||
|
||||
this.addon._repositoryAddon = repoAddon;
|
||||
this.name = this.name || this.addon._repositoryAddon.name;
|
||||
this.addon.appDisabled = !isUsableAddon(this.addon);
|
||||
this.addon.appDisabled = !XPIDatabase.isUsableAddon(this.addon);
|
||||
return undefined;
|
||||
}
|
||||
|
||||
|
@ -3732,7 +3730,7 @@ var XPIInstall = {
|
|||
|
||||
let addon = await loadManifestFromFile(source, location);
|
||||
|
||||
if (mustSign(addon.type) &&
|
||||
if (XPIDatabase.mustSign(addon.type) &&
|
||||
addon.signedState <= AddonManager.SIGNEDSTATE_MISSING) {
|
||||
throw new Error(`Refusing to install staged add-on ${id} with signed state ${addon.signedState}`);
|
||||
}
|
||||
|
|
|
@ -36,8 +36,6 @@ XPCOMUtils.defineLazyModuleGetters(this, {
|
|||
verifyBundleSignedState: "resource://gre/modules/addons/XPIInstall.jsm",
|
||||
});
|
||||
|
||||
const {nsIBlocklistService} = Ci;
|
||||
|
||||
XPCOMUtils.defineLazyServiceGetter(this, "aomStartup",
|
||||
"@mozilla.org/addons/addon-manager-startup;1",
|
||||
"amIAddonManagerStartup");
|
||||
|
@ -56,7 +54,6 @@ const PREF_EM_STARTUP_SCAN_SCOPES = "extensions.startupScanScopes";
|
|||
const PREF_EM_SHOW_MISMATCH_UI = "extensions.showMismatchUI";
|
||||
// xpinstall.signatures.required only supported in dev builds
|
||||
const PREF_XPI_SIGNATURES_REQUIRED = "xpinstall.signatures.required";
|
||||
const PREF_XPI_SIGNATURES_DEV_ROOT = "xpinstall.signatures.dev-root";
|
||||
const PREF_LANGPACK_SIGNATURES = "extensions.langpacks.signatures.required";
|
||||
const PREF_XPI_PERMISSIONS_BRANCH = "xpinstall.";
|
||||
const PREF_INSTALL_DISTRO_ADDONS = "extensions.installDistroAddons";
|
||||
|
@ -168,10 +165,6 @@ const SIGNED_TYPES = new Set([
|
|||
"webextension-theme",
|
||||
]);
|
||||
|
||||
const LEGACY_TYPES = new Set([
|
||||
"extension",
|
||||
]);
|
||||
|
||||
const ALL_EXTERNAL_TYPES = new Set([
|
||||
"dictionary",
|
||||
"extension",
|
||||
|
@ -179,18 +172,6 @@ const ALL_EXTERNAL_TYPES = new Set([
|
|||
"theme",
|
||||
]);
|
||||
|
||||
// Whether add-on signing is required.
|
||||
function mustSign(aType) {
|
||||
if (!SIGNED_TYPES.has(aType))
|
||||
return false;
|
||||
|
||||
if (aType == "webextension-langpack") {
|
||||
return AddonSettings.LANGPACKS_REQUIRE_SIGNING;
|
||||
}
|
||||
|
||||
return AddonSettings.REQUIRE_SIGNING;
|
||||
}
|
||||
|
||||
// Keep track of where we are in startup for telemetry
|
||||
// event happened during XPIDatabase.startup()
|
||||
const XPI_STARTING = "XPIStarting";
|
||||
|
@ -397,98 +378,6 @@ function canRunInSafeMode(aAddon) {
|
|||
return location.isSystem;
|
||||
}
|
||||
|
||||
/**
|
||||
* Determine if this addon should be disabled due to being legacy
|
||||
*
|
||||
* @param {Addon} addon The addon to check
|
||||
*
|
||||
* @returns {boolean} Whether the addon should be disabled for being legacy
|
||||
*/
|
||||
function isDisabledLegacy(addon) {
|
||||
return (!AddonSettings.ALLOW_LEGACY_EXTENSIONS &&
|
||||
LEGACY_TYPES.has(addon.type) &&
|
||||
|
||||
// Legacy add-ons are allowed in the system location.
|
||||
!addon._installLocation.isSystem &&
|
||||
|
||||
// Legacy extensions may be installed temporarily in
|
||||
// non-release builds.
|
||||
!(AppConstants.MOZ_ALLOW_LEGACY_EXTENSIONS &&
|
||||
addon._installLocation.name == KEY_APP_TEMPORARY) &&
|
||||
|
||||
// Properly signed legacy extensions are allowed.
|
||||
addon.signedState !== AddonManager.SIGNEDSTATE_PRIVILEGED);
|
||||
}
|
||||
|
||||
/**
|
||||
* Calculates whether an add-on should be appDisabled or not.
|
||||
*
|
||||
* @param {AddonInternal} aAddon
|
||||
* The add-on to check
|
||||
* @returns {boolean}
|
||||
* True if the add-on should not be appDisabled
|
||||
*/
|
||||
function isUsableAddon(aAddon) {
|
||||
if (mustSign(aAddon.type) && !aAddon.isCorrectlySigned) {
|
||||
logger.warn(`Add-on ${aAddon.id} is not correctly signed.`);
|
||||
if (Services.prefs.getBoolPref(PREF_XPI_SIGNATURES_DEV_ROOT, false)) {
|
||||
logger.warn(`Preference ${PREF_XPI_SIGNATURES_DEV_ROOT} is set.`);
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
if (aAddon.blocklistState == nsIBlocklistService.STATE_BLOCKED) {
|
||||
logger.warn(`Add-on ${aAddon.id} is blocklisted.`);
|
||||
return false;
|
||||
}
|
||||
|
||||
// If we can't read it, it's not usable:
|
||||
if (aAddon.brokenManifest) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (AddonManager.checkUpdateSecurity && !aAddon.providesUpdatesSecurely) {
|
||||
logger.warn(`Updates for add-on ${aAddon.id} must be provided over HTTPS.`);
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
if (!aAddon.isPlatformCompatible) {
|
||||
logger.warn(`Add-on ${aAddon.id} is not compatible with platform.`);
|
||||
return false;
|
||||
}
|
||||
|
||||
if (aAddon.dependencies.length) {
|
||||
let isActive = id => {
|
||||
let active = XPIProvider.activeAddons.get(id);
|
||||
return active && !active.disable;
|
||||
};
|
||||
|
||||
if (aAddon.dependencies.some(id => !isActive(id)))
|
||||
return false;
|
||||
}
|
||||
|
||||
if (isDisabledLegacy(aAddon)) {
|
||||
logger.warn(`disabling legacy extension ${aAddon.id}`);
|
||||
return false;
|
||||
}
|
||||
|
||||
if (AddonManager.checkCompatibility) {
|
||||
if (!aAddon.isCompatible) {
|
||||
logger.warn(`Add-on ${aAddon.id} is not compatible with application version.`);
|
||||
return false;
|
||||
}
|
||||
} else {
|
||||
let app = aAddon.matchingTargetApplication;
|
||||
if (!app) {
|
||||
logger.warn(`Add-on ${aAddon.id} is not compatible with target application.`);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Converts an internal add-on type to the type presented through the API.
|
||||
*
|
||||
|
@ -3055,7 +2944,7 @@ var XPIProvider = {
|
|||
if (aSoftDisabled === undefined || aUserDisabled)
|
||||
aSoftDisabled = aAddon.softDisabled;
|
||||
|
||||
let appDisabled = !isUsableAddon(aAddon);
|
||||
let appDisabled = !XPIDatabase.isUsableAddon(aAddon);
|
||||
// No change means nothing to do here
|
||||
if (aAddon.userDisabled == aUserDisabled &&
|
||||
aAddon.appDisabled == appDisabled &&
|
||||
|
@ -3684,9 +3573,7 @@ var XPIInternal = {
|
|||
getExternalType,
|
||||
getURIForResourceInFile,
|
||||
isTheme,
|
||||
isUsableAddon,
|
||||
isWebExtension,
|
||||
mustSign,
|
||||
};
|
||||
|
||||
var addonTypes = [
|
||||
|
|
Загрузка…
Ссылка в новой задаче