summaryrefslogtreecommitdiffstats
path: root/toolkit/mozapps/extensions/nsBlocklistService.js
diff options
context:
space:
mode:
Diffstat (limited to 'toolkit/mozapps/extensions/nsBlocklistService.js')
-rw-r--r--toolkit/mozapps/extensions/nsBlocklistService.js519
1 files changed, 165 insertions, 354 deletions
diff --git a/toolkit/mozapps/extensions/nsBlocklistService.js b/toolkit/mozapps/extensions/nsBlocklistService.js
index 0af90430c..936c9d1b5 100644
--- a/toolkit/mozapps/extensions/nsBlocklistService.js
+++ b/toolkit/mozapps/extensions/nsBlocklistService.js
@@ -12,29 +12,25 @@ const Cr = Components.results;
Components.utils.import("resource://gre/modules/XPCOMUtils.jsm");
Components.utils.import("resource://gre/modules/Services.jsm");
-Components.utils.import("resource://gre/modules/AppConstants.jsm");
try {
// AddonManager.jsm doesn't allow itself to be imported in the child
// process. We're used in the child process (for now), so guard against
// this.
Components.utils.import("resource://gre/modules/AddonManager.jsm");
- /* globals AddonManagerPrivate*/
} catch (e) {
}
XPCOMUtils.defineLazyModuleGetter(this, "FileUtils",
"resource://gre/modules/FileUtils.jsm");
-XPCOMUtils.defineLazyModuleGetter(this, "UpdateUtils",
- "resource://gre/modules/UpdateUtils.jsm");
+XPCOMUtils.defineLazyModuleGetter(this, "UpdateChannel",
+ "resource://gre/modules/UpdateChannel.jsm");
XPCOMUtils.defineLazyModuleGetter(this, "OS",
"resource://gre/modules/osfile.jsm");
-XPCOMUtils.defineLazyModuleGetter(this, "ServiceRequest",
- "resource://gre/modules/ServiceRequest.jsm");
XPCOMUtils.defineLazyModuleGetter(this, "Task",
"resource://gre/modules/Task.jsm");
-const TOOLKIT_ID = "toolkit@mozilla.org";
+const TOOLKIT_ID = "toolkit@mozilla.org"
const KEY_PROFILEDIR = "ProfD";
const KEY_APPDIR = "XCurProcD";
const FILE_BLOCKLIST = "blocklist.xml";
@@ -47,8 +43,7 @@ const PREF_BLOCKLIST_LEVEL = "extensions.blocklist.level";
const PREF_BLOCKLIST_PINGCOUNTTOTAL = "extensions.blocklist.pingCountTotal";
const PREF_BLOCKLIST_PINGCOUNTVERSION = "extensions.blocklist.pingCountVersion";
const PREF_BLOCKLIST_SUPPRESSUI = "extensions.blocklist.suppressUI";
-const PREF_ONECRL_VIA_AMO = "security.onecrl.via.amo";
-const PREF_BLOCKLIST_UPDATE_ENABLED = "services.blocklist.update_enabled";
+const PREF_PLUGINS_NOTIFYUSER = "plugins.update.notifyUser";
const PREF_GENERAL_USERAGENT_LOCALE = "general.useragent.locale";
const PREF_APP_DISTRIBUTION = "distribution.id";
const PREF_APP_DISTRIBUTION_VERSION = "distribution.version";
@@ -83,30 +78,17 @@ XPCOMUtils.defineLazyServiceGetter(this, "gCertBlocklistService",
"@mozilla.org/security/certblocklist;1",
"nsICertBlocklist");
-XPCOMUtils.defineLazyGetter(this, "gPref", function() {
+XPCOMUtils.defineLazyGetter(this, "gPref", function bls_gPref() {
return Cc["@mozilla.org/preferences-service;1"].getService(Ci.nsIPrefService).
QueryInterface(Ci.nsIPrefBranch);
});
-// From appinfo in Services.jsm. It is not possible to use the one in
-// Services.jsm since it will not successfully QueryInterface nsIXULAppInfo in
-// xpcshell tests due to other code calling Services.appinfo before the
-// nsIXULAppInfo is created by the tests.
-XPCOMUtils.defineLazyGetter(this, "gApp", function() {
- let appinfo = Cc["@mozilla.org/xre/app-info;1"]
- .getService(Ci.nsIXULRuntime);
- try {
- appinfo.QueryInterface(Ci.nsIXULAppInfo);
- } catch (ex) {
- // Not all applications implement nsIXULAppInfo (e.g. xpcshell doesn't).
- if (!(ex instanceof Components.Exception) ||
- ex.result != Cr.NS_NOINTERFACE)
- throw ex;
- }
- return appinfo;
+XPCOMUtils.defineLazyGetter(this, "gApp", function bls_gApp() {
+ return Cc["@mozilla.org/xre/app-info;1"].getService(Ci.nsIXULAppInfo).
+ QueryInterface(Ci.nsIXULRuntime);
});
-XPCOMUtils.defineLazyGetter(this, "gABI", function() {
+XPCOMUtils.defineLazyGetter(this, "gABI", function bls_gABI() {
let abi = null;
try {
abi = gApp.XPCOMABI;
@@ -114,20 +96,19 @@ XPCOMUtils.defineLazyGetter(this, "gABI", function() {
catch (e) {
LOG("BlockList Global gABI: XPCOM ABI unknown.");
}
-
- if (AppConstants.platform == "macosx") {
- // Mac universal build should report a different ABI than either macppc
- // or mactel.
- let macutils = Cc["@mozilla.org/xpcom/mac-utils;1"].
- getService(Ci.nsIMacUtils);
-
- if (macutils.isUniversalBinary)
- abi += "-u-" + macutils.architecturesInBinary;
- }
+#ifdef XP_MACOSX
+ // Mac universal build should report a different ABI than either macppc
+ // or mactel.
+ let macutils = Cc["@mozilla.org/xpcom/mac-utils;1"].
+ getService(Ci.nsIMacUtils);
+
+ if (macutils.isUniversalBinary)
+ abi += "-u-" + macutils.architecturesInBinary;
+#endif
return abi;
});
-XPCOMUtils.defineLazyGetter(this, "gOSVersion", function() {
+XPCOMUtils.defineLazyGetter(this, "gOSVersion", function bls_gOSVersion() {
let osVersion;
let sysInfo = Cc["@mozilla.org/system-info;1"].
getService(Ci.nsIPropertyBag2);
@@ -151,7 +132,7 @@ XPCOMUtils.defineLazyGetter(this, "gOSVersion", function() {
});
// shared code for suppressing bad cert dialogs
-XPCOMUtils.defineLazyGetter(this, "gCertUtils", function() {
+XPCOMUtils.defineLazyGetter(this, "gCertUtils", function bls_gCertUtils() {
let temp = { };
Components.utils.import("resource://gre/modules/CertUtils.jsm", temp);
return temp;
@@ -289,6 +270,26 @@ function parseRegExp(aStr) {
}
/**
+ * Helper function to test if the blockEntry matches with the plugin.
+ *
+ * @param blockEntry
+ * The plugin blocklist entries to compare against.
+ * @param plugin
+ * The nsIPluginTag to get the blocklist state for.
+ * @returns True if the blockEntry matches the plugin, false otherwise.
+ */
+function matchesAllPluginNames(blockEntry, plugin) {
+ for (let name in blockEntry.matches) {
+ if (!(name in plugin) ||
+ typeof(plugin[name]) != "string" ||
+ !blockEntry.matches[name].test(plugin[name])) {
+ return false;
+ }
+ }
+ return true;
+}
+
+/**
* Manages the Blocklist. The Blocklist is a representation of the contents of
* blocklist.xml and allows us to remotely disable / re-enable blocklisted
* items managed by the Extension Manager with an item's appDisabled property.
@@ -305,9 +306,6 @@ function Blocklist() {
gPref.addObserver("extensions.blocklist.", this, false);
gPref.addObserver(PREF_EM_LOGGING_ENABLED, this, false);
this.wrappedJSObject = this;
- // requests from child processes come in here, see receiveMessage.
- Services.ppmm.addMessageListener("Blocklist:getPluginBlocklistState", this);
- Services.ppmm.addMessageListener("Blocklist:content-blocklist-updated", this);
}
Blocklist.prototype = {
@@ -327,21 +325,14 @@ Blocklist.prototype = {
* (default = *)
*/
_addonEntries: null,
- _gfxEntries: null,
_pluginEntries: null,
- shutdown: function() {
- Services.obs.removeObserver(this, "xpcom-shutdown");
- Services.ppmm.removeMessageListener("Blocklist:getPluginBlocklistState", this);
- Services.ppmm.removeMessageListener("Blocklist:content-blocklist-updated", this);
- gPref.removeObserver("extensions.blocklist.", this);
- gPref.removeObserver(PREF_EM_LOGGING_ENABLED, this);
- },
-
- observe: function(aSubject, aTopic, aData) {
+ observe: function Blocklist_observe(aSubject, aTopic, aData) {
switch (aTopic) {
case "xpcom-shutdown":
- this.shutdown();
+ Services.obs.removeObserver(this, "xpcom-shutdown");
+ gPref.removeObserver("extensions.blocklist.", this);
+ gPref.removeObserver(PREF_EM_LOGGING_ENABLED, this);
break;
case "nsPref:changed":
switch (aData) {
@@ -367,30 +358,14 @@ Blocklist.prototype = {
}
},
- // Message manager message handlers
- receiveMessage: function(aMsg) {
- switch (aMsg.name) {
- case "Blocklist:getPluginBlocklistState":
- return this.getPluginBlocklistState(aMsg.data.addonData,
- aMsg.data.appVersion,
- aMsg.data.toolkitVersion);
- case "Blocklist:content-blocklist-updated":
- Services.obs.notifyObservers(null, "content-blocklist-updated", null);
- break;
- default:
- throw new Error("Unknown blocklist message received from content: " + aMsg.name);
- }
- return undefined;
- },
-
/* See nsIBlocklistService */
- isAddonBlocklisted: function(addon, appVersion, toolkitVersion) {
+ isAddonBlocklisted: function Blocklist_isAddonBlocklisted(addon, appVersion, toolkitVersion) {
return this.getAddonBlocklistState(addon, appVersion, toolkitVersion) ==
Ci.nsIBlocklistService.STATE_BLOCKED;
},
/* See nsIBlocklistService */
- getAddonBlocklistState: function(addon, appVersion, toolkitVersion) {
+ getAddonBlocklistState: function Blocklist_getAddonBlocklistState(addon, appVersion, toolkitVersion) {
if (!this._isBlocklistLoaded())
this._loadBlocklist();
return this._getAddonBlocklistState(addon, this._addonEntries,
@@ -416,14 +391,11 @@ Blocklist.prototype = {
* @returns The blocklist state for the item, one of the STATE constants as
* defined in nsIBlocklistService.
*/
- _getAddonBlocklistState: function(addon, addonEntries, appVersion, toolkitVersion) {
+ _getAddonBlocklistState: function Blocklist_getAddonBlocklistStateCall(addon,
+ addonEntries, appVersion, toolkitVersion) {
if (!gBlocklistEnabled)
return Ci.nsIBlocklistService.STATE_NOT_BLOCKED;
- // Not all applications implement nsIXULAppInfo (e.g. xpcshell doesn't).
- if (!appVersion && !gApp.version)
- return Ci.nsIBlocklistService.STATE_NOT_BLOCKED;
-
if (!appVersion)
appVersion = gApp.version;
if (!toolkitVersion)
@@ -447,12 +419,13 @@ Blocklist.prototype = {
* @param addon
* The add-on whose to-be-reset prefs are to be found.
*/
- _getAddonPrefs: function(addon) {
+ _getAddonPrefs: function Blocklist_getAddonPrefs(addon) {
let entry = this._findMatchingAddonEntry(this._addonEntries, addon);
return entry.prefs.slice(0);
},
- _findMatchingAddonEntry: function(aAddonEntries, aAddon) {
+ _findMatchingAddonEntry: function Blocklist_findMatchingAddonEntry(aAddonEntries,
+ aAddon) {
if (!aAddon)
return null;
// Returns true if the params object passes the constraints set by entry.
@@ -492,7 +465,7 @@ Blocklist.prototype = {
},
/* See nsIBlocklistService */
- getAddonBlocklistURL: function(addon, appVersion, toolkitVersion) {
+ getAddonBlocklistURL: function Blocklist_getAddonBlocklistURL(addon, appVersion, toolkitVersion) {
if (!gBlocklistEnabled)
return "";
@@ -506,14 +479,14 @@ Blocklist.prototype = {
return this._createBlocklistURL(blItem.blockID);
},
- _createBlocklistURL: function(id) {
+ _createBlocklistURL: function Blocklist_createBlocklistURL(id) {
let url = Services.urlFormatter.formatURLPref(PREF_BLOCKLIST_ITEM_URL);
url = url.replace(/%blockID%/g, id);
return url;
},
- notify: function(aTimer) {
+ notify: function Blocklist_notify(aTimer) {
if (!gBlocklistEnabled)
return;
@@ -556,18 +529,14 @@ Blocklist.prototype = {
pingCountTotal = 1;
dsURI = dsURI.replace(/%APP_ID%/g, gApp.ID);
- // Not all applications implement nsIXULAppInfo (e.g. xpcshell doesn't).
- if (gApp.version)
- dsURI = dsURI.replace(/%APP_VERSION%/g, gApp.version);
+ dsURI = dsURI.replace(/%APP_VERSION%/g, gApp.version);
dsURI = dsURI.replace(/%PRODUCT%/g, gApp.name);
- // Not all applications implement nsIXULAppInfo (e.g. xpcshell doesn't).
- if (gApp.version)
- dsURI = dsURI.replace(/%VERSION%/g, gApp.version);
+ dsURI = dsURI.replace(/%VERSION%/g, gApp.version);
dsURI = dsURI.replace(/%BUILD_ID%/g, gApp.appBuildID);
dsURI = dsURI.replace(/%BUILD_TARGET%/g, gApp.OS + "_" + gABI);
dsURI = dsURI.replace(/%OS_VERSION%/g, gOSVersion);
dsURI = dsURI.replace(/%LOCALE%/g, getLocale());
- dsURI = dsURI.replace(/%CHANNEL%/g, UpdateUtils.UpdateChannel);
+ dsURI = dsURI.replace(/%CHANNEL%/g, UpdateChannel.get());
dsURI = dsURI.replace(/%PLATFORM_VERSION%/g, gApp.platformVersion);
dsURI = dsURI.replace(/%DISTRIBUTION%/g,
getDistributionPrefValue(PREF_APP_DISTRIBUTION));
@@ -612,15 +581,19 @@ Blocklist.prototype = {
}
LOG("Blocklist::notify: Requesting " + uri.spec);
- let request = new ServiceRequest();
+ var request = Cc["@mozilla.org/xmlextras/xmlhttprequest;1"].
+ createInstance(Ci.nsIXMLHttpRequest);
request.open("GET", uri.spec, true);
request.channel.notificationCallbacks = new gCertUtils.BadCertHandler();
request.overrideMimeType("text/xml");
request.setRequestHeader("Cache-Control", "no-cache");
request.QueryInterface(Components.interfaces.nsIJSXMLHttpRequest);
- request.addEventListener("error", event => this.onXMLError(event), false);
- request.addEventListener("load", event => this.onXMLLoad(event), false);
+ var self = this;
+ request.addEventListener("error", function errorEventListener(event) {
+ self.onXMLError(event); }, false);
+ request.addEventListener("load", function loadEventListener(event) {
+ self.onXMLLoad(event); }, false);
request.send(null);
// When the blocklist loads we need to compare it to the current copy so
@@ -629,7 +602,7 @@ Blocklist.prototype = {
this._loadBlocklist();
},
- onXMLLoad: Task.async(function*(aEvent) {
+ onXMLLoad: Task.async(function* (aEvent) {
let request = aEvent.target;
try {
gCertUtils.checkCert(request.channel);
@@ -648,12 +621,9 @@ Blocklist.prototype = {
var oldAddonEntries = this._addonEntries;
var oldPluginEntries = this._pluginEntries;
this._addonEntries = [];
- this._gfxEntries = [];
this._pluginEntries = [];
this._loadBlocklistFromString(request.responseText);
- // We don't inform the users when the graphics blocklist changed at runtime.
- // However addons and plugins blocking status is refreshed.
this._blocklistUpdated(oldAddonEntries, oldPluginEntries);
try {
@@ -664,7 +634,7 @@ Blocklist.prototype = {
}
}),
- onXMLError: function(aEvent) {
+ onXMLError: function Blocklist_onXMLError(aEvent) {
try {
var request = aEvent.target;
// the following may throw (e.g. a local file or timeout)
@@ -690,9 +660,8 @@ Blocklist.prototype = {
* Finds the newest blocklist file from the application and the profile and
* load it or does nothing if neither exist.
*/
- _loadBlocklist: function() {
+ _loadBlocklist: function Blocklist_loadBlocklist() {
this._addonEntries = [];
- this._gfxEntries = [];
this._pluginEntries = [];
var profFile = FileUtils.getFile(KEY_PROFILEDIR, [FILE_BLOCKLIST]);
if (profFile.exists()) {
@@ -718,7 +687,7 @@ Blocklist.prototype = {
# <pref>accessibility.blockautorefresh</pref>
# </prefs>
# <versionRange minVersion="1.0" maxVersion="2.0.*">
-# <targetApplication id="{ec8030f7-c20a-464f-9b0e-13a3a9e97384}">
+# <targetApplication id="{8de7fcbb-c55c-4fbe-bfc5-fc555c87dbc4}">
# <versionRange minVersion="1.5" maxVersion="1.5.*"/>
# <versionRange minVersion="1.7" maxVersion="1.7.*"/>
# </targetApplication>
@@ -727,7 +696,7 @@ Blocklist.prototype = {
# </targetApplication>
# </versionRange>
# <versionRange minVersion="3.0" maxVersion="3.0.*">
-# <targetApplication id="{ec8030f7-c20a-464f-9b0e-13a3a9e97384}">
+# <targetApplication id="{8de7fcbb-c55c-4fbe-bfc5-fc555c87dbc4}">
# <versionRange minVersion="1.5" maxVersion="1.5.*"/>
# </targetApplication>
# <targetApplication id="toolkit@mozilla.org">
@@ -740,7 +709,7 @@ Blocklist.prototype = {
# </emItem>
# <emItem id="item_3@domain">
# <versionRange>
-# <targetApplication id="{ec8030f7-c20a-464f-9b0e-13a3a9e97384}">
+# <targetApplication id="{8de7fcbb-c55c-4fbe-bfc5-fc555c87dbc4}">
# <versionRange minVersion="1.5" maxVersion="1.5.*"/>
# </targetApplication>
# </versionRange>
@@ -766,14 +735,11 @@ Blocklist.prototype = {
# <!-- ... as is the serial number DER data -->
# <serialNumber>AkHVNA==</serialNumber>
# </certItem>
-# <!-- subject is the DER subject name data base64 encoded... -->
-# <certItem subject="MA0xCzAJBgNVBAMMAmNh" pubKeyHash="/xeHA5s+i9/z9d8qy6JEuE1xGoRYIwgJuTE/lmaGJ7M=">
-# </certItem>
# </certItems>
# </blocklist>
*/
- _loadBlocklistFromFile: function(file) {
+ _loadBlocklistFromFile: function Blocklist_loadBlocklistFromFile(file) {
if (!gBlocklistEnabled) {
LOG("Blocklist::_loadBlocklistFromFile: blocklist is disabled");
return;
@@ -829,7 +795,7 @@ Blocklist.prototype = {
},
_isBlocklistLoaded: function() {
- return this._addonEntries != null && this._gfxEntries != null && this._pluginEntries != null;
+ return this._addonEntries != null && this._pluginEntries != null;
},
_isBlocklistPreloaded: function() {
@@ -839,7 +805,6 @@ Blocklist.prototype = {
/* Used for testing */
_clear: function() {
this._addonEntries = null;
- this._gfxEntries = null;
this._pluginEntries = null;
this._preloadedBlocklistContent = null;
},
@@ -854,7 +819,7 @@ Blocklist.prototype = {
}
var appFile = FileUtils.getFile(KEY_APPDIR, [FILE_BLOCKLIST]);
- try {
+ try{
yield this._preloadBlocklistFile(appFile.path);
return;
} catch (e) {
@@ -864,7 +829,7 @@ Blocklist.prototype = {
LOG("Blocklist::_preloadBlocklist: no XML File found");
}),
- _preloadBlocklistFile: Task.async(function*(path) {
+ _preloadBlocklistFile: Task.async(function* (path){
if (this._addonEntries) {
// The file has been already loaded.
return;
@@ -883,7 +848,7 @@ Blocklist.prototype = {
}
}),
- _loadBlocklistFromString : function(text) {
+ _loadBlocklistFromString : function Blocklist_loadBlocklistFromString(text) {
try {
var parser = Cc["@mozilla.org/xmlextras/domparser;1"].
createInstance(Ci.nsIDOMParser);
@@ -895,46 +860,30 @@ Blocklist.prototype = {
return;
}
- var populateCertBlocklist = getPref("getBoolPref", PREF_ONECRL_VIA_AMO, true);
-
var childNodes = doc.documentElement.childNodes;
for (let element of childNodes) {
if (!(element instanceof Ci.nsIDOMElement))
continue;
switch (element.localName) {
case "emItems":
- this._addonEntries = this._processItemNodes(element.childNodes, "emItem",
+ this._addonEntries = this._processItemNodes(element.childNodes, "em",
this._handleEmItemNode);
break;
case "pluginItems":
- // We don't support plugins on b2g.
- if (AppConstants.MOZ_B2G) {
- return;
- }
- this._pluginEntries = this._processItemNodes(element.childNodes, "pluginItem",
+ this._pluginEntries = this._processItemNodes(element.childNodes, "plugin",
this._handlePluginItemNode);
break;
case "certItems":
- if (populateCertBlocklist) {
- this._processItemNodes(element.childNodes, "certItem",
- this._handleCertItemNode.bind(this));
- }
- break;
- case "gfxItems":
- // Parse as simple list of objects.
- this._gfxEntries = this._processItemNodes(element.childNodes, "gfxBlacklistEntry",
- this._handleGfxBlacklistNode);
+ this._processItemNodes(element.childNodes, "cert",
+ this._handleCertItemNode.bind(this));
break;
default:
- LOG("Blocklist::_loadBlocklistFromString: ignored entries " + element.localName);
+ Services.obs.notifyObservers(element,
+ "blocklist-data-" + element.localName,
+ null);
}
}
- if (populateCertBlocklist) {
- gCertBlocklistService.saveEntries();
- }
- if (this._gfxEntries.length > 0) {
- this._notifyObserversBlocklistGFX();
- }
+ gCertBlocklistService.saveEntries();
}
catch (e) {
LOG("Blocklist::_loadBlocklistFromFile: Error constructing blocklist " + e);
@@ -942,8 +891,9 @@ Blocklist.prototype = {
}
},
- _processItemNodes: function(itemNodes, itemName, handler) {
+ _processItemNodes: function Blocklist_processItemNodes(itemNodes, prefix, handler) {
var result = [];
+ var itemName = prefix + "Item";
for (var i = 0; i < itemNodes.length; ++i) {
var blocklistElement = itemNodes.item(i);
if (!(blocklistElement instanceof Ci.nsIDOMElement) ||
@@ -955,34 +905,21 @@ Blocklist.prototype = {
return result;
},
- _handleCertItemNode: function(blocklistElement, result) {
+ _handleCertItemNode: function Blocklist_handleCertItemNode(blocklistElement,
+ result) {
let issuer = blocklistElement.getAttribute("issuerName");
- if (issuer) {
- for (let snElement of blocklistElement.children) {
- try {
- gCertBlocklistService.revokeCertByIssuerAndSerial(issuer, snElement.textContent);
- } catch (e) {
- // we want to keep trying other elements since missing all items
- // is worse than missing one
- LOG("Blocklist::_handleCertItemNode: Error adding revoked cert by Issuer and Serial" + e);
- }
- }
- return;
- }
-
- let pubKeyHash = blocklistElement.getAttribute("pubKeyHash");
- let subject = blocklistElement.getAttribute("subject");
-
- if (pubKeyHash && subject) {
+ for (let snElement of blocklistElement.children) {
try {
- gCertBlocklistService.revokeCertBySubjectAndPubKey(subject, pubKeyHash);
+ gCertBlocklistService.addRevokedCert(issuer, snElement.textContent);
} catch (e) {
- LOG("Blocklist::_handleCertItemNode: Error adding revoked cert by Subject and PubKey" + e);
+ // we want to keep trying other elements since missing all items
+ // is worse than missing one
+ LOG("Blocklist::_handleCertItemNode: Error adding revoked cert " + e);
}
}
},
- _handleEmItemNode: function(blocklistElement, result) {
+ _handleEmItemNode: function Blocklist_handleEmItemNode(blocklistElement, result) {
if (!matchesOSABI(blocklistElement))
return;
@@ -1035,7 +972,7 @@ Blocklist.prototype = {
result.push(blockEntry);
},
- _handlePluginItemNode: function(blocklistElement, result) {
+ _handlePluginItemNode: function Blocklist_handlePluginItemNode(blocklistElement, result) {
if (!matchesOSABI(blocklistElement))
return;
@@ -1080,81 +1017,9 @@ Blocklist.prototype = {
result.push(blockEntry);
},
- // <gfxBlacklistEntry blockID="g60">
- // <os>WINNT 6.0</os>
- // <osversion>14</osversion> currently only used for Android
- // <versionRange minVersion="42.0" maxVersion="13.0b2"/>
- // <vendor>0x8086</vendor>
- // <devices>
- // <device>0x2582</device>
- // <device>0x2782</device>
- // </devices>
- // <feature> DIRECT3D_10_LAYERS </feature>
- // <featureStatus> BLOCKED_DRIVER_VERSION </featureStatus>
- // <driverVersion> 8.52.322.2202 </driverVersion>
- // <driverVersionMax> 8.52.322.2202 </driverVersionMax>
- // <driverVersionComparator> LESS_THAN_OR_EQUAL </driverVersionComparator>
- // <model>foo</model>
- // <product>foo</product>
- // <manufacturer>foo</manufacturer>
- // <hardware>foo</hardware>
- // </gfxBlacklistEntry>
- _handleGfxBlacklistNode: function (blocklistElement, result) {
- const blockEntry = {};
-
- // The blockID attribute is always present in the actual data produced on server
- // (see https://github.com/mozilla/addons-server/blob/2016.05.05/src/olympia/blocklist/templates/blocklist/blocklist.xml#L74)
- // But it is sometimes missing in test fixtures.
- if (blocklistElement.hasAttribute("blockID")) {
- blockEntry.blockID = blocklistElement.getAttribute("blockID");
- }
-
- // Trim helper (spaces, tabs, no-break spaces..)
- const trim = (s) => (s || '').replace(/(^[\s\uFEFF\xA0]+)|([\s\uFEFF\xA0]+$)/g, "");
-
- for (let i = 0; i < blocklistElement.childNodes.length; ++i) {
- var matchElement = blocklistElement.childNodes.item(i);
- if (!(matchElement instanceof Ci.nsIDOMElement))
- continue;
-
- let value;
- if (matchElement.localName == "devices") {
- value = [];
- for (let j = 0; j < matchElement.childNodes.length; j++) {
- const childElement = matchElement.childNodes.item(j);
- const childValue = trim(childElement.textContent);
- // Make sure no empty value is added.
- if (childValue) {
- if (/,/.test(childValue)) {
- // Devices can't contain comma.
- // (c.f serialization in _notifyObserversBlocklistGFX)
- const e = new Error(`Unsupported device name ${childValue}`);
- Components.utils.reportError(e);
- }
- else {
- value.push(childValue);
- }
- }
- }
- } else if (matchElement.localName == "versionRange") {
- value = {minVersion: trim(matchElement.getAttribute("minVersion")) || "0",
- maxVersion: trim(matchElement.getAttribute("maxVersion")) || "*"};
- } else {
- value = trim(matchElement.textContent);
- }
- if (value) {
- blockEntry[matchElement.localName] = value;
- }
- }
- result.push(blockEntry);
- },
-
/* See nsIBlocklistService */
- getPluginBlocklistState: function(plugin, appVersion, toolkitVersion) {
- if (AppConstants.platform == "android" ||
- AppConstants.MOZ_B2G) {
- return Ci.nsIBlocklistService.STATE_NOT_BLOCKED;
- }
+ getPluginBlocklistState: function Blocklist_getPluginBlocklistState(plugin,
+ appVersion, toolkitVersion) {
if (!this._isBlocklistLoaded())
this._loadBlocklist();
return this._getPluginBlocklistState(plugin, this._pluginEntries,
@@ -1162,8 +1027,8 @@ Blocklist.prototype = {
},
/**
- * Private helper to get the blocklist entry for a plugin given a set of
- * blocklist entries and versions.
+ * Private version of getPluginBlocklistState that allows the caller to pass in
+ * the plugin blocklist entries.
*
* @param plugin
* The nsIPluginTag to get the blocklist state for.
@@ -1175,15 +1040,12 @@ Blocklist.prototype = {
* @param toolkitVersion
* The toolkit version to compare to, will use the current version if
* null.
- * @returns {entry: blocklistEntry, version: blocklistEntryVersion},
- * or null if there is no matching entry.
+ * @returns The blocklist state for the item, one of the STATE constants as
+ * defined in nsIBlocklistService.
*/
- _getPluginBlocklistEntry: function(plugin, pluginEntries, appVersion, toolkitVersion) {
+ _getPluginBlocklistState: function Blocklist_getPluginBlocklistState(plugin,
+ pluginEntries, appVersion, toolkitVersion) {
if (!gBlocklistEnabled)
- return null;
-
- // Not all applications implement nsIXULAppInfo (e.g. xpcshell doesn't).
- if (!appVersion && !gApp.version)
return Ci.nsIBlocklistService.STATE_NOT_BLOCKED;
if (!appVersion)
@@ -1191,7 +1053,7 @@ Blocklist.prototype = {
if (!toolkitVersion)
toolkitVersion = gApp.platformVersion;
- for (var blockEntry of pluginEntries) {
+ for each (var blockEntry in pluginEntries) {
var matchFailed = false;
for (var name in blockEntry.matches) {
if (!(name in plugin) ||
@@ -1207,66 +1069,52 @@ Blocklist.prototype = {
for (let blockEntryVersion of blockEntry.versions) {
if (blockEntryVersion.includesItem(plugin.version, appVersion,
- toolkitVersion)) {
- return {entry: blockEntry, version: blockEntryVersion};
+ toolkitVersion)) {
+ if (blockEntryVersion.severity >= gBlocklistLevel)
+ return Ci.nsIBlocklistService.STATE_BLOCKED;
+ if (blockEntryVersion.severity == SEVERITY_OUTDATED) {
+ let vulnerabilityStatus = blockEntryVersion.vulnerabilityStatus;
+ if (vulnerabilityStatus == VULNERABILITYSTATUS_UPDATE_AVAILABLE)
+ return Ci.nsIBlocklistService.STATE_VULNERABLE_UPDATE_AVAILABLE;
+ if (vulnerabilityStatus == VULNERABILITYSTATUS_NO_UPDATE)
+ return Ci.nsIBlocklistService.STATE_VULNERABLE_NO_UPDATE;
+ return Ci.nsIBlocklistService.STATE_OUTDATED;
+ }
+ return Ci.nsIBlocklistService.STATE_SOFTBLOCKED;
}
}
}
- return null;
+ return Ci.nsIBlocklistService.STATE_NOT_BLOCKED;
},
/**
- * Private version of getPluginBlocklistState that allows the caller to pass in
- * the plugin blocklist entries.
- *
- * @param plugin
- * The nsIPluginTag to get the blocklist state for.
- * @param pluginEntries
- * The plugin blocklist entries to compare against.
- * @param appVersion
- * The application version to compare to, will use the current
- * version if null.
- * @param toolkitVersion
- * The toolkit version to compare to, will use the current version if
- * null.
- * @returns The blocklist state for the item, one of the STATE constants as
- * defined in nsIBlocklistService.
+ * Get the matching blocklist entry for the passed plugin, if
+ * available.
+ * @param plugin The plugin to find the block entry for.
+ * @returns The block entry which matches the passed plugin, null
+ * otherwise.
*/
- _getPluginBlocklistState: function(plugin, pluginEntries, appVersion, toolkitVersion) {
+ _getPluginBlockEntry: function (plugin) {
+ if (!gBlocklistEnabled)
+ return null;
- let r = this._getPluginBlocklistEntry(plugin, pluginEntries,
- appVersion, toolkitVersion);
- if (!r) {
- return Ci.nsIBlocklistService.STATE_NOT_BLOCKED;
- }
+ if (!this._isBlocklistLoaded())
+ this._loadBlocklist();
- let {entry: blockEntry, version: blockEntryVersion} = r;
-
- if (blockEntryVersion.severity >= gBlocklistLevel)
- return Ci.nsIBlocklistService.STATE_BLOCKED;
- if (blockEntryVersion.severity == SEVERITY_OUTDATED) {
- let vulnerabilityStatus = blockEntryVersion.vulnerabilityStatus;
- if (vulnerabilityStatus == VULNERABILITYSTATUS_UPDATE_AVAILABLE)
- return Ci.nsIBlocklistService.STATE_VULNERABLE_UPDATE_AVAILABLE;
- if (vulnerabilityStatus == VULNERABILITYSTATUS_NO_UPDATE)
- return Ci.nsIBlocklistService.STATE_VULNERABLE_NO_UPDATE;
- return Ci.nsIBlocklistService.STATE_OUTDATED;
+ for each (let blockEntry in this._pluginEntries) {
+ if (matchesAllPluginNames(blockEntry, plugin)) {
+ return blockEntry;
+ }
}
- return Ci.nsIBlocklistService.STATE_SOFTBLOCKED;
+
+ return null;
},
/* See nsIBlocklistService */
- getPluginBlocklistURL: function(plugin) {
- if (!this._isBlocklistLoaded())
- this._loadBlocklist();
-
- let r = this._getPluginBlocklistEntry(plugin, this._pluginEntries);
- if (!r) {
- return null;
- }
- let {entry: blockEntry, version: blockEntryVersion} = r;
- if (!blockEntry.blockID) {
+ getPluginBlocklistURL: function Blocklist_getPluginBlocklistURL(plugin) {
+ let blockEntry = this._getPluginBlockEntry(plugin);
+ if (!blockEntry || !blockEntry.blockID) {
return null;
}
@@ -1274,50 +1122,16 @@ Blocklist.prototype = {
},
/* See nsIBlocklistService */
- getPluginInfoURL: function(plugin) {
- if (!this._isBlocklistLoaded())
- this._loadBlocklist();
-
- let r = this._getPluginBlocklistEntry(plugin, this._pluginEntries);
- if (!r) {
- return null;
- }
- let {entry: blockEntry, version: blockEntryVersion} = r;
- if (!blockEntry.blockID) {
+ getPluginInfoURL: function (plugin) {
+ let blockEntry = this._getPluginBlockEntry(plugin);
+ if (!blockEntry || !blockEntry.blockID) {
return null;
}
return blockEntry.infoURL;
},
- _notifyObserversBlocklistGFX: function () {
- // Notify `GfxInfoBase`, by passing a string serialization.
- // This way we avoid spreading XML structure logics there.
- const payload = this._gfxEntries.map((r) => {
- return Object.keys(r).sort().filter((k) => !/id|last_modified/.test(k)).map((key) => {
- let value = r[key];
- if (Array.isArray(value)) {
- value = value.join(",");
- } else if (value.hasOwnProperty("minVersion")) {
- // When XML is parsed, both minVersion and maxVersion are set.
- value = `${value.minVersion},${value.maxVersion}`;
- }
- return `${key}:${value}`;
- }).join("\t");
- }).join("\n");
- Services.obs.notifyObservers(null, "blocklist-data-gfxItems", payload);
- },
-
- _notifyObserversBlocklistUpdated: function() {
- Services.obs.notifyObservers(this, "blocklist-updated", "");
- Services.ppmm.broadcastAsyncMessage("Blocklist:blocklistInvalidated", {});
- },
-
- _blocklistUpdated: function(oldAddonEntries, oldPluginEntries) {
- if (AppConstants.MOZ_B2G) {
- return;
- }
-
+ _blocklistUpdated: function Blocklist_blocklistUpdated(oldAddonEntries, oldPluginEntries) {
var addonList = [];
// A helper function that reverts the prefs passed to default values.
@@ -1325,13 +1139,15 @@ Blocklist.prototype = {
for (let pref of prefs)
gPref.clearUserPref(pref);
}
+ var self = this;
const types = ["extension", "theme", "locale", "dictionary", "service"];
- AddonManager.getAddonsByTypes(types, addons => {
+ AddonManager.getAddonsByTypes(types, function blocklistUpdated_getAddonsByTypes(addons) {
+
for (let addon of addons) {
let oldState = Ci.nsIBlocklistService.STATE_NOTBLOCKED;
if (oldAddonEntries)
- oldState = this._getAddonBlocklistState(addon, oldAddonEntries);
- let state = this.getAddonBlocklistState(addon);
+ oldState = self._getAddonBlocklistState(addon, oldAddonEntries);
+ let state = self.getAddonBlocklistState(addon);
LOG("Blocklist state for " + addon.id + " changed from " +
oldState + " to " + state);
@@ -1342,7 +1158,7 @@ Blocklist.prototype = {
if (state === Ci.nsIBlocklistService.STATE_BLOCKED) {
// It's a hard block. We must reset certain preferences.
- let prefs = this._getAddonPrefs(addon);
+ let prefs = self._getAddonPrefs(addon);
resetPrefs(prefs);
}
@@ -1364,15 +1180,8 @@ Blocklist.prototype = {
// If the add-on is already disabled for some reason then don't warn
// about it
- if (!addon.isActive) {
- // But mark it as softblocked if necessary. Note that we avoid setting
- // softDisabled at the same time as userDisabled to make it clear
- // which was the original cause of the add-on becoming disabled in a
- // way that the user can change.
- if (state == Ci.nsIBlocklistService.STATE_SOFTBLOCKED && !addon.userDisabled)
- addon.softDisabled = true;
+ if (!addon.isActive)
continue;
- }
addonList.push({
name: addon.name,
@@ -1381,7 +1190,7 @@ Blocklist.prototype = {
disable: false,
blocked: state == Ci.nsIBlocklistService.STATE_BLOCKED,
item: addon,
- url: this.getAddonBlocklistURL(addon),
+ url: self.getAddonBlocklistURL(addon),
});
}
@@ -1394,8 +1203,8 @@ Blocklist.prototype = {
for (let plugin of plugins) {
let oldState = -1;
if (oldPluginEntries)
- oldState = this._getPluginBlocklistState(plugin, oldPluginEntries);
- let state = this.getPluginBlocklistState(plugin);
+ oldState = self._getPluginBlocklistState(plugin, oldPluginEntries);
+ let state = self.getPluginBlocklistState(plugin);
LOG("Blocklist state for " + plugin.name + " changed from " +
oldState + " to " + state);
// We don't want to re-warn about items
@@ -1407,9 +1216,11 @@ Blocklist.prototype = {
plugin.enabledState = Ci.nsIPluginTag.STATE_DISABLED;
}
else if (!plugin.disabled && state != Ci.nsIBlocklistService.STATE_NOT_BLOCKED) {
- if (state != Ci.nsIBlocklistService.STATE_OUTDATED &&
- state != Ci.nsIBlocklistService.STATE_VULNERABLE_UPDATE_AVAILABLE &&
- state != Ci.nsIBlocklistService.STATE_VULNERABLE_NO_UPDATE) {
+ if (state == Ci.nsIBlocklistService.STATE_OUTDATED) {
+ gPref.setBoolPref(PREF_PLUGINS_NOTIFYUSER, true);
+ }
+ else if (state != Ci.nsIBlocklistService.STATE_VULNERABLE_UPDATE_AVAILABLE &&
+ state != Ci.nsIBlocklistService.STATE_VULNERABLE_NO_UPDATE) {
addonList.push({
name: plugin.name,
version: plugin.version,
@@ -1417,14 +1228,14 @@ Blocklist.prototype = {
disable: false,
blocked: state == Ci.nsIBlocklistService.STATE_BLOCKED,
item: plugin,
- url: this.getPluginBlocklistURL(plugin),
+ url: self.getPluginBlocklistURL(plugin),
});
}
}
}
if (addonList.length == 0) {
- this._notifyObserversBlocklistUpdated();
+ Services.obs.notifyObservers(self, "blocklist-updated", "");
return;
}
@@ -1436,7 +1247,7 @@ Blocklist.prototype = {
} catch (e) {
LOG(e);
}
- this._notifyObserversBlocklistUpdated();
+ Services.obs.notifyObservers(self, "blocklist-updated", "");
return;
}
@@ -1451,7 +1262,7 @@ Blocklist.prototype = {
Some tests run without UI, so the async code listens to a message
that can be sent programatically
*/
- let applyBlocklistChanges = () => {
+ let applyBlocklistChanges = function blocklistUpdated_applyBlocklistChanges() {
for (let addon of addonList) {
if (!addon.disable)
continue;
@@ -1462,7 +1273,7 @@ Blocklist.prototype = {
// This add-on is softblocked.
addon.item.softDisabled = true;
// We must revert certain prefs.
- let prefs = this._getAddonPrefs(addon.item);
+ let prefs = self._getAddonPrefs(addon.item);
resetPrefs(prefs);
}
}
@@ -1470,7 +1281,7 @@ Blocklist.prototype = {
if (args.restart)
restartApp();
- this._notifyObserversBlocklistUpdated();
+ Services.obs.notifyObservers(self, "blocklist-updated", "");
Services.obs.removeObserver(applyBlocklistChanges, "addon-blocklist-closed");
}
@@ -1552,7 +1363,7 @@ BlocklistItemData.prototype = {
* @returns True if the version range covers the item version and application
* or toolkit version.
*/
- includesItem: function(version, appVersion, toolkitVersion) {
+ includesItem: function BlocklistItemData_includesItem(version, appVersion, toolkitVersion) {
// Some platforms have no version for plugins, these don't match if there
// was a min/maxVersion provided
if (!version && (this.minVersion || this.maxVersion))
@@ -1582,7 +1393,7 @@ BlocklistItemData.prototype = {
* The maximum version. If null it is assumed that version is always
* smaller.
*/
- matchesRange: function(version, minVersion, maxVersion) {
+ matchesRange: function BlocklistItemData_matchesRange(version, minVersion, maxVersion) {
if (minVersion && gVersionChecker.compare(version, minVersion) < 0)
return false;
if (maxVersion && gVersionChecker.compare(version, maxVersion) > 0)
@@ -1599,7 +1410,7 @@ BlocklistItemData.prototype = {
* The version of the application to test for.
* @returns True if this version range covers the application version given.
*/
- matchesTargetRange: function(appID, appVersion) {
+ matchesTargetRange: function BlocklistItemData_matchesTargetRange(appID, appVersion) {
var blTargetApp = this.targetApps[appID];
if (!blTargetApp)
return false;
@@ -1621,7 +1432,7 @@ BlocklistItemData.prototype = {
* "minVersion" The minimum version in a version range (default = null).
* "maxVersion" The maximum version in a version range (default = null).
*/
- getBlocklistAppVersions: function(targetAppElement) {
+ getBlocklistAppVersions: function BlocklistItemData_getBlocklistAppVersions(targetAppElement) {
var appVersions = [ ];
if (targetAppElement) {
@@ -1649,7 +1460,7 @@ BlocklistItemData.prototype = {
* "minVersion" The minimum version in a version range (default = null).
* "maxVersion" The maximum version in a version range (default = null).
*/
- getBlocklistVersionRange: function(versionRangeElement) {
+ getBlocklistVersionRange: function BlocklistItemData_getBlocklistVersionRange(versionRangeElement) {
var minVersion = null;
var maxVersion = null;
if (!versionRangeElement)