--- a/browser/installer/unix/packages-static
+++ b/browser/installer/unix/packages-static
@@ -213,16 +213,17 @@ bin/components/nsHelperAppDlg.js
bin/components/nsInterfaceInfoToIDL.js
; bin/components/nsProgressDialog.js not needed for firefox
bin/components/nsProxyAutoConfig.js
; bin/components/nsResetPref.js not needed for firefox
bin/components/nsSidebar.js
; bin/components/nsUpdateNotifier.js not needed for firefox
bin/components/nsXmlRpcClient.js
bin/components/nsExtensionManager.js
+bin/components/nsBlocklistService.js
bin/components/nsUpdateService.js
bin/components/pluginGlue.js
bin/components/extensions.xpt
bin/components/update.xpt
bin/components/nsSessionStartup.js
bin/components/nsSessionStore.js
bin/components/sessionstore.xpt
bin/components/nsURLFormatter.js
--- a/browser/installer/windows/packages-static
+++ b/browser/installer/windows/packages-static
@@ -206,16 +206,17 @@ bin\components\nsTryToClose.js
bin\components\nsDictionary.js
bin\components\nsHelperAppDlg.js
bin\components\nsProxyAutoConfig.js
bin\components\nsSearchService.js
bin\components\nsSearchSuggestions.js
bin\components\nsSidebar.js
bin\components\nsXmlRpcClient.js
bin\components\nsExtensionManager.js
+bin\components\nsBlocklistService.js
bin\components\nsUpdateService.js
bin\components\nsMicrosummaryService.js
bin\components\nsPlacesTransactionsService.js
bin\components\nsPostUpdateWin.js
bin\components\nsLoginInfo.js
bin\components\nsLoginManager.js
bin\components\nsLoginManagerPrompter.js
bin\components\storage-Legacy.js
--- a/toolkit/mozapps/extensions/public/Makefile.in
+++ b/toolkit/mozapps/extensions/public/Makefile.in
@@ -39,12 +39,12 @@ topsrcdir = @top_srcdir@
srcdir = @srcdir@
VPATH = @srcdir@
include $(DEPTH)/config/autoconf.mk
MODULE = extensions
XPIDL_MODULE = extensions
-XPIDLSRCS = nsIExtensionManager.idl
+XPIDLSRCS = nsIExtensionManager.idl nsIBlocklistService.idl
include $(topsrcdir)/config/rules.mk
new file mode 100644
--- /dev/null
+++ b/toolkit/mozapps/extensions/public/nsIBlocklistService.idl
@@ -0,0 +1,64 @@
+/* -*- Mode: IDL; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
+/* ***** BEGIN LICENSE BLOCK *****
+ * Version: MPL 1.1/GPL 2.0/LGPL 2.1
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is the Blocklist Service.
+ *
+ * The Initial Developer of the Original Code is
+ * Mozilla Corporation
+ * Portions created by the Initial Developer are Copyright (C) 2007
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s):
+ * Michael Wu <flamingice@sourmilk.net> (original author)
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * either the GNU General Public License Version 2 or later (the "GPL"), or
+ * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+ * in which case the provisions of the GPL or the LGPL are applicable instead
+ * of those above. If you wish to allow use of your version of this file only
+ * under the terms of either the GPL or the LGPL, and not to allow others to
+ * use your version of this file under the terms of the MPL, indicate your
+ * decision by deleting the provisions above and replace them with the notice
+ * and other provisions required by the GPL or the LGPL. If you do not delete
+ * the provisions above, a recipient may use your version of this file under
+ * the terms of any one of the MPL, the GPL or the LGPL.
+ *
+ * ***** END LICENSE BLOCK ***** */
+
+
+#include "nsISupports.idl"
+
+[scriptable, uuid(0c3fe697-d50d-4f42-b747-0c5855cfc60e)]
+interface nsIBlocklistService : nsISupports
+{
+ /**
+ * Determine if an item is blocklisted
+ * @param id
+ * The GUID of the item.
+ * @param version
+ * The item's version.
+ * @param appVersion
+ * The version of the application we are checking in the blocklist.
+ * If this parameter is undefined, the version of the running
+ * application is used.
+ * @param toolkitVersion
+ * The version of the toolkit we are checking in the blocklist.
+ * If this parameter is undefined, the version of the running
+ * toolkit is used.
+ * @returns true if the item is compatible with this version of the
+ * application or this version of the toolkit, false, otherwise.
+ */
+ boolean isAddonBlocklisted(in AString id, in AString version,
+ in AString appVersion, in AString toolkitVersion);
+};
--- a/toolkit/mozapps/extensions/src/Makefile.in
+++ b/toolkit/mozapps/extensions/src/Makefile.in
@@ -40,15 +40,16 @@ topsrcdir = @top_srcdir@
srcdir = @srcdir@
VPATH = @srcdir@
include $(DEPTH)/config/autoconf.mk
MODULE = extensions
EXTRA_COMPONENTS = nsExtensionManager.js
+EXTRA_PP_COMPONENTS = nsBlocklistService.js
GARBAGE += nsExtensionManager.js
include $(topsrcdir)/config/rules.mk
nsExtensionManager.js: nsExtensionManager.js.in
$(PYTHON) $(MOZILLA_DIR)/config/Preprocessor.py $(DEFINES) $(ACDEFINES) $^ > $@
new file mode 100644
--- /dev/null
+++ b/toolkit/mozapps/extensions/src/nsBlocklistService.js
@@ -0,0 +1,696 @@
+/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
+/*
+ # ***** BEGIN LICENSE BLOCK *****
+ # Version: MPL 1.1/GPL 2.0/LGPL 2.1
+ #
+ # The contents of this file are subject to the Mozilla Public License Version
+ # 1.1 (the "License"); you may not use this file except in compliance with
+ # the License. You may obtain a copy of the License at
+ # http://www.mozilla.org/MPL/
+ #
+ # Software distributed under the License is distributed on an "AS IS" basis,
+ # WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ # for the specific language governing rights and limitations under the
+ # License.
+ #
+ # The Original Code is the Blocklist Service.
+ #
+ # The Initial Developer of the Original Code is
+ # Mozilla Corporation.
+ # Portions created by the Initial Developer are Copyright (C) 2007
+ # the Initial Developer. All Rights Reserved.
+ #
+ # Contributor(s):
+ # Robert Strong <robert.bugzilla@gmail.com>
+ # Michael Wu <flamingice@sourmilk.net>
+ #
+ # Alternatively, the contents of this file may be used under the terms of
+ # either the GNU General Public License Version 2 or later (the "GPL"), or
+ # the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+ # in which case the provisions of the GPL or the LGPL are applicable instead
+ # of those above. If you wish to allow use of your version of this file only
+ # under the terms of either the GPL or the LGPL, and not to allow others to
+ # use your version of this file under the terms of the MPL, indicate your
+ # decision by deleting the provisions above and replace them with the notice
+ # and other provisions required by the GPL or the LGPL. If you do not delete
+ # the provisions above, a recipient may use your version of this file under
+ # the terms of any one of the MPL, the GPL or the LGPL.
+ #
+ # ***** END LICENSE BLOCK *****
+ */
+
+const Cc = Components.classes;
+const Ci = Components.interfaces;
+const Cr = Components.results;
+
+const kELEMENT_NODE = Ci.nsIDOMNode.ELEMENT_NODE;
+const TOOLKIT_ID = "toolkit@mozilla.org"
+const KEY_PROFILEDIR = "ProfD";
+const FILE_BLOCKLIST = "blocklist.xml";
+const PREF_BLOCKLIST_URL = "extensions.blocklist.url";
+const PREF_BLOCKLIST_ENABLED = "extensions.blocklist.enabled";
+const PREF_BLOCKLIST_INTERVAL = "extensions.blocklist.interval";
+const PREF_EM_LOGGING_ENABLED = "extensions.logging.enabled";
+const XMLURI_BLOCKLIST = "http://www.mozilla.org/2006/addons-blocklist";
+const XMLURI_PARSE_ERROR = "http://www.mozilla.org/newlayout/xml/parsererror.xml"
+
+const MODE_RDONLY = 0x01;
+const MODE_WRONLY = 0x02;
+const MODE_CREATE = 0x08;
+const MODE_APPEND = 0x10;
+const MODE_TRUNCATE = 0x20;
+
+const PERMS_FILE = 0644;
+const PERMS_DIRECTORY = 0755;
+
+const CID = Components.ID("{66354bc9-7ed1-4692-ae1d-8da97d6b205e}");
+const CONTRACT_ID = "@mozilla.org/extensions/blocklist;1"
+const CLASS_NAME = "Blocklist Service";
+
+var gApp = null;
+var gPref = null;
+var gOS = null;
+var gConsole = null;
+var gVersionChecker = null;
+var gLoggingEnabled = null;
+
+// shared code for suppressing bad cert dialogs
+#include ../../shared/src/badCertHandler.js
+
+/**
+ * Logs a string to the error console.
+ * @param string
+ * The string to write to the error console..
+ */
+function LOG(string) {
+ if (gLoggingEnabled) {
+ dump("*** " + string + "\n");
+ gConsole.logStringMessage(string);
+ }
+}
+
+/**
+ * Gets a preference value, handling the case where there is no default.
+ * @param func
+ * The name of the preference function to call, on nsIPrefBranch
+ * @param preference
+ * The name of the preference
+ * @param defaultValue
+ * The default value to return in the event the preference has
+ * no setting
+ * @returns The value of the preference, or undefined if there was no
+ * user or default value.
+ */
+function getPref(func, preference, defaultValue) {
+ try {
+ return gPref[func](preference);
+ }
+ catch (e) {
+ }
+ return defaultValue;
+}
+
+/**
+ * Gets the file at the specified hierarchy under a Directory Service key.
+ * @param key
+ * The Directory Service Key to start from
+ * @param pathArray
+ * An array of path components to locate beneath the directory
+ * specified by |key|. The last item in this array must be the
+ * leaf name of a file.
+ * @return nsIFile object for the file specified. The file is NOT created
+ * if it does not exist, however all required directories along
+ * the way are.
+ */
+function getFile(key, pathArray) {
+ var fileLocator = Cc["@mozilla.org/file/directory_service;1"].
+ getService(Ci.nsIProperties);
+ var file = fileLocator.get(key, Ci.nsILocalFile);
+ for (var i = 0; i < pathArray.length - 1; ++i) {
+ file.append(pathArray[i]);
+ if (!file.exists())
+ file.create(Ci.nsILocalFile.DIRECTORY_TYPE, PERMS_DIRECTORY);
+ }
+ file.followLinks = false;
+ file.append(pathArray[pathArray.length - 1]);
+ return file;
+}
+
+/**
+ * Opens a safe file output stream for writing.
+ * @param file
+ * The file to write to.
+ * @param modeFlags
+ * (optional) File open flags. Can be undefined.
+ * @returns nsIFileOutputStream to write to.
+ */
+function openSafeFileOutputStream(file, modeFlags) {
+ var fos = Cc["@mozilla.org/network/safe-file-output-stream;1"].
+ createInstance(Ci.nsIFileOutputStream);
+ if (modeFlags === undefined)
+ modeFlags = MODE_WRONLY | MODE_CREATE | MODE_TRUNCATE;
+ if (!file.exists())
+ file.create(Ci.nsILocalFile.NORMAL_FILE_TYPE, PERMS_FILE);
+ fos.init(file, modeFlags, PERMS_FILE, 0);
+ return fos;
+}
+
+/**
+ * Closes a safe file output stream.
+ * @param stream
+ * The stream to close.
+ */
+function closeSafeFileOutputStream(stream) {
+ if (stream instanceof Ci.nsISafeOutputStream)
+ stream.finish();
+ else
+ stream.close();
+}
+
+/**
+ * Constructs a URI to a spec.
+ * @param spec
+ * The spec to construct a URI to
+ * @returns The nsIURI constructed.
+ */
+function newURI(spec) {
+ var ioServ = Cc["@mozilla.org/network/io-service;1"].
+ getService(Ci.nsIIOService);
+ return ioServ.newURI(spec, null, null);
+}
+
+/**
+ * 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.
+ * It also blocklists plugins with data from blocklist.xml.
+ */
+
+function Blocklist() {
+ gApp = Cc["@mozilla.org/xre/app-info;1"].getService(Ci.nsIXULAppInfo);
+ gApp.QueryInterface(Ci.nsIXULRuntime);
+ gPref = Cc["@mozilla.org/preferences-service;1"].
+ getService(Ci.nsIPrefBranch2);
+ gVersionChecker = Cc["@mozilla.org/xpcom/version-comparator;1"].
+ getService(Ci.nsIVersionComparator);
+ gConsole = Cc["@mozilla.org/consoleservice;1"].
+ getService(Ci.nsIConsoleService);
+
+ gOS = Cc["@mozilla.org/observer-service;1"].
+ getService(Ci.nsIObserverService);
+ gOS.addObserver(this, "xpcom-shutdown", false);
+}
+
+Blocklist.prototype = {
+ /**
+ * Extension ID -> array of Version Ranges
+ * Each value in the version range array is a JS Object that has the
+ * following properties:
+ * "minVersion" The minimum version in a version range (default = 0)
+ * "maxVersion" The maximum version in a version range (default = *)
+ * "targetApps" Application ID -> array of Version Ranges
+ * (default = current application ID)
+ * Each value in the version range array is a JS Object that
+ * has the following properties:
+ * "minVersion" The minimum version in a version range
+ * (default = 0)
+ * "maxVersion" The maximum version in a version range
+ * (default = *)
+ */
+ _addonEntries: null,
+ _pluginEntries: null,
+
+ observe: function (aSubject, aTopic, aData) {
+ switch (aTopic) {
+ case "app-startup":
+ gOS.addObserver(this, "plugins-list-updated", false);
+ gOS.addObserver(this, "profile-after-change", false);
+ break;
+ case "profile-after-change":
+ gLoggingEnabled = getPref("getBoolPref", PREF_EM_LOGGING_ENABLED, false);
+ var tm = Cc["@mozilla.org/updates/timer-manager;1"].
+ getService(Ci.nsIUpdateTimerManager);
+ var interval = getPref("getIntPref", PREF_BLOCKLIST_INTERVAL, 86400);
+ tm.registerTimer("blocklist-background-update-timer", this, interval);
+ break;
+ case "plugins-list-updated":
+ this._checkPluginsList();
+ break;
+ case "xpcom-shutdown":
+ gOS.removeObserver(this, "xpcom-shutdown");
+ gOS.removeObserver(this, "profile-after-change");
+ gOS.removeObserver(this, "plugins-list-updated");
+ gOS = null;
+ gPref = null;
+ gConsole = null;
+ gVersionChecker = null;
+ gApp = null;
+ break;
+ }
+ },
+
+ isAddonBlocklisted: function(id, version, appVersion, toolkitVersion) {
+ if (!this._addonEntries)
+ this._loadBlocklistFromFile(getFile(KEY_PROFILEDIR, [FILE_BLOCKLIST]));
+ if (appVersion === undefined)
+ appVersion = gApp.version;
+ if (toolkitVersion === undefined)
+ toolkitVersion = gApp.platformVersion;
+
+ var blItem = this._addonEntries[id];
+ if (!blItem)
+ return false;
+
+ for (var i = 0; i < blItem.length; ++i) {
+ if (gVersionChecker.compare(version, blItem[i].minVersion) < 0 ||
+ gVersionChecker.compare(version, blItem[i].maxVersion) > 0)
+ continue;
+
+ var blTargetApp = blItem[i].targetApps[gApp.ID];
+ if (blTargetApp) {
+ for (var x = 0; x < blTargetApp.length; ++x) {
+ if (gVersionChecker.compare(appVersion, blTargetApp[x].minVersion) < 0 ||
+ gVersionChecker.compare(appVersion, blTargetApp[x].maxVersion) > 0)
+ continue;
+ return true;
+ }
+ }
+
+ blTargetApp = blItem[i].targetApps[TOOLKIT_ID];
+ if (!blTargetApp)
+ return false;
+ for (x = 0; x < blTargetApp.length; ++x) {
+ if (gVersionChecker.compare(toolkitVersion, blTargetApp[x].minVersion) < 0 ||
+ gVersionChecker.compare(toolkitVersion, blTargetApp[x].maxVersion) > 0)
+ continue;
+ return true;
+ }
+ }
+ return false;
+ },
+
+ notify: function(aTimer) {
+ if (getPref("getBoolPref", PREF_BLOCKLIST_ENABLED, true) == false)
+ return;
+
+ try {
+ var dsURI = gPref.getCharPref(PREF_BLOCKLIST_URL);
+ }
+ catch (e) {
+ LOG("Blocklist::notify: The " + PREF_BLOCKLIST_URL + " preference" +
+ " is missing!");
+ return;
+ }
+
+ dsURI = dsURI.replace(/%APP_ID%/g, gApp.ID);
+ dsURI = dsURI.replace(/%APP_VERSION%/g, gApp.version);
+ // Verify that the URI is valid
+ try {
+ var uri = newURI(dsURI);
+ }
+ catch (e) {
+ LOG("Blocklist::notify: There was an error creating the blocklist URI\r\n" +
+ "for: " + dsURI + ", error: " + e);
+ return;
+ }
+
+ var request = Cc["@mozilla.org/xmlextras/xmlhttprequest;1"].
+ createInstance(Ci.nsIXMLHttpRequest);
+ request.open("GET", uri.spec, true);
+ request.channel.notificationCallbacks = new BadCertHandler();
+ request.overrideMimeType("text/xml");
+ request.setRequestHeader("Cache-Control", "no-cache");
+ request.QueryInterface(Components.interfaces.nsIJSXMLHttpRequest);
+
+ var self = this;
+ request.onerror = function(event) { self.onXMLError(event); };
+ request.onload = function(event) { self.onXMLLoad(event); };
+ request.send(null);
+ },
+
+ onXMLLoad: function(aEvent) {
+ var request = aEvent.target;
+ try {
+ checkCert(request.channel);
+ }
+ catch (e) {
+ LOG("Blocklist::onXMLLoad: " + e);
+ return;
+ }
+ var responseXML = request.responseXML;
+ if (!responseXML || responseXML.documentElement.namespaceURI == XMLURI_PARSE_ERROR ||
+ (request.status != 200 && request.status != 0)) {
+ LOG("Blocklist::onXMLLoad: there was an error during load");
+ return;
+ }
+ var blocklistFile = getFile(KEY_PROFILEDIR, [FILE_BLOCKLIST]);
+ if (blocklistFile.exists())
+ blocklistFile.remove(false);
+ var fos = openSafeFileOutputStream(blocklistFile);
+ fos.write(request.responseText, request.responseText.length);
+ closeSafeFileOutputStream(fos);
+ this._loadBlocklistFromFile(getFile(KEY_PROFILEDIR, [FILE_BLOCKLIST]));
+ var em = Cc["@mozilla.org/extensions/manager;1"].
+ getService(Ci.nsIExtensionManager);
+ em.checkForBlocklistChanges();
+ this._checkPluginsList();
+ },
+
+ onXMLError: function(aEvent) {
+ try {
+ var request = aEvent.target;
+ // the following may throw (e.g. a local file or timeout)
+ var status = request.status;
+ }
+ catch (e) {
+ request = aEvent.target.channel.QueryInterface(Ci.nsIRequest);
+ status = request.status;
+ }
+ var statusText = request.statusText;
+ // When status is 0 we don't have a valid channel.
+ if (status == 0)
+ statusText = "nsIXMLHttpRequest channel unavailable";
+ LOG("Blocklist:onError: There was an error loading the blocklist file\r\n" +
+ statusText);
+ },
+
+ /**
+ # The blocklist XML file looks something like this:
+ #
+ # <blocklist xmlns="http://www.mozilla.org/2006/addons-blocklist">
+ # <emItems>
+ # <emItem id="item_1@domain">
+ # <versionRange minVersion="1.0" maxVersion="2.0.*">
+ # <targetApplication id="{ec8030f7-c20a-464f-9b0e-13a3a9e97384}">
+ # <versionRange minVersion="1.5" maxVersion="1.5.*"/>
+ # <versionRange minVersion="1.7" maxVersion="1.7.*"/>
+ # </targetApplication>
+ # <targetApplication id="toolkit@mozilla.org">
+ # <versionRange minVersion="1.8" maxVersion="1.8.*"/>
+ # </targetApplication>
+ # </versionRange>
+ # <versionRange minVersion="3.0" maxVersion="3.0.*">
+ # <targetApplication id="{ec8030f7-c20a-464f-9b0e-13a3a9e97384}">
+ # <versionRange minVersion="1.5" maxVersion="1.5.*"/>
+ # </targetApplication>
+ # <targetApplication id="toolkit@mozilla.org">
+ # <versionRange minVersion="1.8" maxVersion="1.8.*"/>
+ # </targetApplication>
+ # </versionRange>
+ # </emItem>
+ # <emItem id="item_2@domain">
+ # <versionRange minVersion="3.1" maxVersion="4.*"/>
+ # </emItem>
+ # <emItem id="item_3@domain">
+ # <versionRange>
+ # <targetApplication id="{ec8030f7-c20a-464f-9b0e-13a3a9e97384}">
+ # <versionRange minVersion="1.5" maxVersion="1.5.*"/>
+ # </targetApplication>
+ # </versionRange>
+ # </emItem>
+ # <emItem id="item_4@domain">
+ # <versionRange>
+ # <targetApplication>
+ # <versionRange minVersion="1.5" maxVersion="1.5.*"/>
+ # </targetApplication>
+ # </versionRange>
+ # <emItem id="item_5@domain"/>
+ # </emItems>
+ # <pluginItems>
+ # <pluginItem>
+ # <!-- All match tags must match a plugin to blocklist a plugin -->
+ # <match name="name" exp="some plugin"/>
+ # <match name="description" exp="1[.]2[.]3"/>
+ # </pluginItem>
+ # </pluginItems>
+ # </blocklist>
+ */
+
+ _loadBlocklistFromFile: function(file) {
+ this._addonEntries = { };
+ this._pluginEntries = { };
+ if (getPref("getBoolPref", PREF_BLOCKLIST_ENABLED, true) == false) {
+ LOG("Blocklist::_loadBlocklistFromFile: blocklist is disabled");
+ return;
+ }
+
+ if (!file.exists()) {
+ LOG("Blocklist::_loadBlocklistFromFile: XML File does not exist");
+ return;
+ }
+
+ var fileStream = Components.classes["@mozilla.org/network/file-input-stream;1"]
+ .createInstance(Components.interfaces.nsIFileInputStream);
+ fileStream.init(file, MODE_RDONLY, PERMS_FILE, 0);
+ try {
+ var parser = Cc["@mozilla.org/xmlextras/domparser;1"].
+ createInstance(Ci.nsIDOMParser);
+ var doc = parser.parseFromStream(fileStream, "UTF-8", file.fileSize, "text/xml");
+ if (doc.documentElement.namespaceURI != XMLURI_BLOCKLIST) {
+ LOG("Blocklist::_loadBlocklistFromFile: aborting due to incorrect " +
+ "XML Namespace.\r\nExpected: " + XMLURI_BLOCKLIST + "\r\n" +
+ "Received: " + doc.documentElement.namespaceURI);
+ return;
+ }
+
+ var childNodes = doc.documentElement.childNodes;
+ this._addonEntries = this._processItemNodes(childNodes, "em",
+ this._handleEmItemNode);
+ this._pluginEntries = this._processItemNodes(childNodes, "plugin",
+ this._handlePluginItemNode);
+ }
+ catch (e) {
+ LOG("Blocklist::_loadBlocklistFromFile: Error constructing blocklist " + e);
+ return;
+ }
+ fileStream.close();
+ },
+
+ _processItemNodes: function(deChildNodes, prefix, handler) {
+ var result = [];
+ var itemNodes;
+ var containerName = prefix + "Items";
+ for (var i = 0; i < deChildNodes.length; ++i) {
+ var emItemsElement = deChildNodes[i];
+ if (emItemsElement.nodeType == kELEMENT_NODE &&
+ emItemsElement.localName == containerName) {
+ itemNodes = emItemsElement.childNodes;
+ break;
+ }
+ }
+ if (!itemNodes)
+ return result;
+
+ var itemName = prefix + "Item";
+ for (var i = 0; i < itemNodes.length; ++i) {
+ var blocklistElement = itemNodes[i];
+ if (blocklistElement.nodeType != kELEMENT_NODE ||
+ blocklistElement.localName != itemName)
+ continue;
+
+ blocklistElement.QueryInterface(Ci.nsIDOMElement);
+ handler(blocklistElement, result);
+ }
+ return result;
+ },
+
+ _handleEmItemNode: function(blocklistElement, result) {
+ var versionNodes = blocklistElement.childNodes;
+ var id = blocklistElement.getAttribute("id");
+ result[id] = [];
+ for (var x = 0; x < versionNodes.length; ++x) {
+ var versionRangeElement = versionNodes[x];
+ if (versionRangeElement.nodeType != kELEMENT_NODE ||
+ versionRangeElement.localName != "versionRange")
+ continue;
+
+ result[id].push(new BlocklistItemData(versionRangeElement));
+ }
+ // if only the extension ID is specified block all versions of the
+ // extension for the current application.
+ if (result[id].length == 0)
+ result[id].push(new BlocklistItemData(null));
+ },
+
+ _handlePluginItemNode: function(blocklistElement, result) {
+ var matchNodes = blocklistElement.childNodes;
+ var matchList;
+ for (var x = 0; x < matchNodes.length; ++x) {
+ var matchElement = matchNodes[x];
+ if (matchElement.nodeType != kELEMENT_NODE ||
+ matchElement.localName != "match")
+ continue;
+
+ var name = matchElement.getAttribute("name");
+ var exp = matchElement.getAttribute("exp");
+ if (!matchList)
+ matchList = { };
+ matchList[name] = new RegExp(exp, "m");
+ }
+ if (matchList)
+ result.push(matchList);
+ },
+
+ _checkPlugin: function(plugin) {
+ for each (var matchList in this._pluginEntries) {
+ var matchFailed = false;
+ for (var name in matchList) {
+ if (typeof(plugin[name]) != "string" ||
+ !matchList[name].test(plugin[name])) {
+ matchFailed = true;
+ break;
+ }
+ }
+
+ if (!matchFailed) {
+ plugin.blocklisted = true;
+ return;
+ }
+ }
+ plugin.blocklisted = false;
+ },
+
+ _checkPluginsList: function() {
+ if (!this._addonEntries)
+ this._loadBlocklistFromFile(getFile(KEY_PROFILEDIR, [FILE_BLOCKLIST]));
+ var phs = Cc["@mozilla.org/plugin/host;1"].
+ getService(Ci.nsIPluginHost);
+ phs.getPluginTags({ }).forEach(this._checkPlugin, this);
+ },
+
+ QueryInterface: function(aIID) {
+ if (!aIID.equals(Ci.nsIObserver) &&
+ !aIID.equals(Ci.nsIBlocklistService) &&
+ !aIID.equals(Ci.nsITimerCallback) &&
+ !aIID.equals(Ci.nsISupports))
+ throw Cr.NS_ERROR_NO_INTERFACE;
+ return this;
+ }
+};
+
+/**
+ * Helper for constructing a blocklist.
+ */
+function BlocklistItemData(versionRangeElement) {
+ var versionRange = this.getBlocklistVersionRange(versionRangeElement);
+ this.minVersion = versionRange.minVersion;
+ this.maxVersion = versionRange.maxVersion;
+ this.targetApps = { };
+ var found = false;
+
+ if (versionRangeElement) {
+ for (var i = 0; i < versionRangeElement.childNodes.length; ++i) {
+ var targetAppElement = versionRangeElement.childNodes[i];
+ if (targetAppElement.nodeType != Ci.nsIDOMNode.ELEMENT_NODE ||
+ targetAppElement.localName != "targetApplication")
+ continue;
+ found = true;
+ // default to the current application if id is not provided.
+ var appID = targetAppElement.hasAttribute("id") ? targetAppElement.getAttribute("id") : gApp.ID;
+ this.targetApps[appID] = this.getBlocklistAppVersions(targetAppElement);
+ }
+ }
+ // Default to all versions of the extension and the current application when
+ // versionRange is not defined.
+ if (!found)
+ this.targetApps[gApp.ID] = this.getBlocklistAppVersions(null);
+}
+
+BlocklistItemData.prototype = {
+/**
+ * Retrieves a version range (e.g. minVersion and maxVersion) for a
+ * blocklist item's targetApplication element.
+ * @param targetAppElement
+ * A targetApplication blocklist element.
+ * @returns An array of JS objects with the following properties:
+ * "minVersion" The minimum version in a version range (default = 0).
+ * "maxVersion" The maximum version in a version range (default = *).
+ */
+ getBlocklistAppVersions: function(targetAppElement) {
+ var appVersions = [ ];
+ var found = false;
+
+ if (targetAppElement) {
+ for (var i = 0; i < targetAppElement.childNodes.length; ++i) {
+ var versionRangeElement = targetAppElement.childNodes[i];
+ if (versionRangeElement.nodeType != Ci.nsIDOMNode.ELEMENT_NODE ||
+ versionRangeElement.localName != "versionRange")
+ continue;
+ found = true;
+ appVersions.push(this.getBlocklistVersionRange(versionRangeElement));
+ }
+ }
+ // return minVersion = 0 and maxVersion = * if not available
+ if (!found)
+ return [ this.getBlocklistVersionRange(null) ];
+ return appVersions;
+ },
+
+/**
+ * Retrieves a version range (e.g. minVersion and maxVersion) for a blocklist
+ * versionRange element.
+ * @param versionRangeElement
+ * The versionRange blocklist element.
+ * @returns A JS object with the following properties:
+ * "minVersion" The minimum version in a version range (default = 0).
+ * "maxVersion" The maximum version in a version range (default = *).
+ */
+ getBlocklistVersionRange: function(versionRangeElement) {
+ var minVersion = "0";
+ var maxVersion = "*";
+ if (!versionRangeElement)
+ return { minVersion: minVersion, maxVersion: maxVersion };
+
+ if (versionRangeElement.hasAttribute("minVersion"))
+ minVersion = versionRangeElement.getAttribute("minVersion");
+ if (versionRangeElement.hasAttribute("maxVersion"))
+ maxVersion = versionRangeElement.getAttribute("maxVersion");
+
+ return { minVersion: minVersion, maxVersion: maxVersion };
+ }
+};
+
+const BlocklistFactory = {
+ createInstance: function(aOuter, aIID) {
+ if (aOuter != null)
+ throw Cr.NS_ERROR_NO_AGGREGATION;
+
+ return (new Blocklist()).QueryInterface(aIID);
+ }
+};
+
+const gModule = {
+ registerSelf: function(aCompMgr, aFileSpec, aLocation, aType) {
+ aCompMgr.QueryInterface(Ci.nsIComponentRegistrar);
+ aCompMgr.registerFactoryLocation(CID, CLASS_NAME, CONTRACT_ID,
+ aFileSpec, aLocation, aType);
+
+ var catMan = Cc["@mozilla.org/categorymanager;1"].
+ getService(Ci.nsICategoryManager);
+ catMan.addCategoryEntry("app-startup", CLASS_NAME, "service," + CONTRACT_ID, true, true);
+ },
+
+ unregisterSelf: function(aCompMgr, aLocation, aType) {
+ aCompMgr.QueryInterface(Ci.nsIComponentRegistrar);
+ aCompMgr.unregisterFactoryLocation(CID, aLocation);
+
+ var catMan = Cc["@mozilla.org/categorymanager;1"].
+ getService(Ci.nsICategoryManager);
+ catMan.deleteCategoryEntry("app-startup", "service," + CONTRACT_ID, true);
+ },
+
+ getClassObject: function(aCompMgr, aCID, aIID) {
+ if (aCID.equals(CID))
+ return BlocklistFactory;
+
+ throw Cr.NS_ERROR_NOT_REGISTERED;
+ },
+
+ canUnload: function(aCompMgr) {
+ return true;
+ }
+};
+
+function NSGetModule(aCompMgr, aFileSpec) {
+ return gModule;
+}
--- a/toolkit/mozapps/extensions/src/nsExtensionManager.js.in
+++ b/toolkit/mozapps/extensions/src/nsExtensionManager.js.in
@@ -68,35 +68,30 @@ const PREF_EM_ITEM_UPDATE_ENABLED =
const PREF_EM_UPDATE_ENABLED = "extensions.update.enabled";
const PREF_EM_ITEM_UPDATE_URL = "extensions.%UUID%.update.url";
const PREF_EM_DSS_ENABLED = "extensions.dss.enabled";
const PREF_DSS_SWITCHPENDING = "extensions.dss.switchPending";
const PREF_DSS_SKIN_TO_SELECT = "extensions.lastSelectedSkin";
const PREF_GENERAL_SKINS_SELECTEDSKIN = "general.skins.selectedSkin";
const PREF_EM_LOGGING_ENABLED = "extensions.logging.enabled";
const PREF_EM_UPDATE_INTERVAL = "extensions.update.interval";
-const PREF_BLOCKLIST_URL = "extensions.blocklist.url";
-const PREF_BLOCKLIST_DETAILS_URL = "extensions.blocklist.detailsURL";
-const PREF_BLOCKLIST_ENABLED = "extensions.blocklist.enabled";
-const PREF_BLOCKLIST_INTERVAL = "extensions.blocklist.interval";
const PREF_UPDATE_NOTIFYUSER = "extensions.update.notifyUser";
const PREF_MATCH_OS_LOCALE = "intl.locale.matchOS";
const PREF_SELECTED_LOCALE = "general.useragent.locale";
const DIR_EXTENSIONS = "extensions";
const DIR_CHROME = "chrome";
const DIR_STAGE = "staged-xpis";
const FILE_EXTENSIONS = "extensions.rdf";
const FILE_EXTENSION_MANIFEST = "extensions.ini";
const FILE_EXTENSIONS_STARTUP_CACHE = "extensions.cache";
const FILE_AUTOREG = ".autoreg";
const FILE_INSTALL_MANIFEST = "install.rdf";
const FILE_CONTENTS_MANIFEST = "contents.rdf";
const FILE_CHROME_MANIFEST = "chrome.manifest";
-const FILE_BLOCKLIST = "blocklist.xml";
const UNKNOWN_XPCOM_ABI = "unknownABI";
const FILE_LOGFILE = "extensionmanager.log";
const FILE_DEFAULT_THEME_JAR = "classic.jar";
const TOOLKIT_ID = "toolkit@mozilla.org"
@@ -130,17 +125,16 @@ const PREFIX_NS_EM =
const PREFIX_NS_CHROME = "http://www.mozilla.org/rdf/chrome#";
const PREFIX_ITEM_URI = "urn:mozilla:item:";
const PREFIX_EXTENSION = "urn:mozilla:extension:";
const PREFIX_THEME = "urn:mozilla:theme:";
const RDFURI_INSTALL_MANIFEST_ROOT = "urn:mozilla:install-manifest";
const RDFURI_ITEM_ROOT = "urn:mozilla:item:root"
const RDFURI_DEFAULT_THEME = "urn:mozilla:item:{972ce4c6-7e08-4474-a285-3208198ce6fd}";
const XMLURI_PARSE_ERROR = "http://www.mozilla.org/newlayout/xml/parsererror.xml"
-const XMLURI_BLOCKLIST = "http://www.mozilla.org/2006/addons-blocklist";
const URI_GENERIC_ICON_XPINSTALL = "chrome://mozapps/skin/xpinstall/xpinstallItemGeneric.png";
const URI_GENERIC_ICON_THEME = "chrome://mozapps/skin/extensions/themeGeneric.png";
const URI_XPINSTALL_CONFIRM_DIALOG = "chrome://mozapps/content/xpinstall/xpinstallConfirm.xul";
const URI_FINALIZE_DIALOG = "chrome://mozapps/content/extensions/finalize.xul";
const URI_EXTENSIONS_PROPERTIES = "chrome://mozapps/locale/extensions/extensions.properties";
const URI_BRAND_PROPERTIES = "chrome://branding/locale/brand.properties";
const URI_DOWNLOADS_PROPERTIES = "chrome://mozapps/locale/downloads/downloads.properties";
@@ -163,16 +157,17 @@ const MODE_TRUNCATE = 0x20;
const PERMS_FILE = 0644;
const PERMS_DIRECTORY = 0755;
var gApp = null;
var gPref = null;
var gRDF = null;
var gOS = null;
+var gBlocklist = null;
var gXPCOMABI = null;
var gOSTarget = null;
var gConsole = null;
var gInstallManifestRoot = null;
var gVersionChecker = null;
var gLoggingEnabled = null;
var gCheckCompatibility = true;
var gLocale = "en-US";
@@ -2299,328 +2294,16 @@ var StartupCache = {
}
}
}
closeSafeFileOutputStream(fos);
}
};
/**
- * 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.
- */
-var Blocklist = {
- /**
- * Extension ID -> array of Version Ranges
- * Each value in the version range array is a JS Object that has the
- * following properties:
- * "minVersion" The minimum version in a version range (default = 0)
- * "maxVersion" The maximum version in a version range (default = *)
- * "targetApps" Application ID -> array of Version Ranges
- * (default = current application ID)
- * Each value in the version range array is a JS Object that
- * has the following properties:
- * "minVersion" The minimum version in a version range
- * (default = 0)
- * "maxVersion" The maximum version in a version range
- * (default = *)
- */
- entries: null,
-
- notify: function() {
- if (getPref("getBoolPref", PREF_BLOCKLIST_ENABLED, true) == false)
- return;
-
- try {
- var dsURI = gPref.getCharPref(PREF_BLOCKLIST_URL);
- }
- catch (e) {
- LOG("Blocklist::notify: The " + PREF_BLOCKLIST_URL + " preference" +
- " is missing!");
- return;
- }
-
- dsURI = dsURI.replace(/%APP_ID%/g, gApp.ID);
- dsURI = dsURI.replace(/%APP_VERSION%/g, gApp.version);
- // Verify that the URI is valid
- try {
- var uri = newURI(dsURI);
- }
- catch (e) {
- LOG("Blocklist::notify: There was an error creating the blocklist URI\r\n" +
- "for: " + dsURI + ", error: " + e);
- return;
- }
-
- var request = Components.classes["@mozilla.org/xmlextras/xmlhttprequest;1"]
- .createInstance(Components.interfaces.nsIXMLHttpRequest);
- request.open("GET", uri.spec, true);
- request.channel.notificationCallbacks = new BadCertHandler();
- request.overrideMimeType("text/xml");
- request.setRequestHeader("Cache-Control", "no-cache");
- request.QueryInterface(Components.interfaces.nsIJSXMLHttpRequest);
-
- var self = this;
- request.onerror = function(event) { self.onXMLError(event); };
- request.onload = function(event) { self.onXMLLoad(event); };
- request.send(null);
- },
-
- onXMLLoad: function(aEvent) {
- var request = aEvent.target;
- try {
- checkCert(request.channel);
- }
- catch (e) {
- LOG("Blocklist::onXMLLoad: " + e);
- return;
- }
- var responseXML = request.responseXML;
- if (!responseXML || responseXML.documentElement.namespaceURI == XMLURI_PARSE_ERROR ||
- (request.status != 200 && request.status != 0)) {
- LOG("Blocklist::onXMLLoad: there was an error during load");
- return;
- }
- var blocklistFile = getFile(KEY_PROFILEDIR, [FILE_BLOCKLIST]);
- if (blocklistFile.exists())
- blocklistFile.remove(false);
- var fos = openSafeFileOutputStream(blocklistFile);
- fos.write(request.responseText, request.responseText.length);
- closeSafeFileOutputStream(fos);
- this.entries = this._loadBlocklistFromFile(getFile(KEY_PROFILEDIR,
- [FILE_BLOCKLIST]));
- var em = Components.classes["@mozilla.org/extensions/manager;1"]
- .getService(Components.interfaces.nsIExtensionManager);
- em.checkForBlocklistChanges();
- },
-
- onXMLError: function(aEvent) {
- try {
- var request = aEvent.target;
- // the following may throw (e.g. a local file or timeout)
- var status = request.status;
- }
- catch (e) {
- request = aEvent.target.channel.QueryInterface(Components.interfaces.nsIRequest);
- status = request.status;
- }
- var statusText = request.statusText;
- // When status is 0 we don't have a valid channel.
- if (status == 0)
- statusText = "nsIXMLHttpRequest channel unavailable";
- LOG("Blocklist:onError: There was an error loading the blocklist file\r\n" +
- statusText);
- },
-
- /**
- * The blocklist XML file looks something like this:
- *
- * <blocklist xmlns="http://www.mozilla.org/2006/addons-blocklist">
- * <emItems>
- * <emItem id="item_1@domain">
- * <versionRange minVersion="1.0" maxVersion="2.0.*">
- * <targetApplication id="{ec8030f7-c20a-464f-9b0e-13a3a9e97384}">
- * <versionRange minVersion="1.5" maxVersion="1.5.*"/>
- * <versionRange minVersion="1.7" maxVersion="1.7.*"/>
- * </targetApplication>
- * <targetApplication id="toolkit@mozilla.org">
- * <versionRange minVersion="1.8" maxVersion="1.8.*"/>
- * </targetApplication>
- * </versionRange>
- * <versionRange minVersion="3.0" maxVersion="3.0.*">
- * <targetApplication id="{ec8030f7-c20a-464f-9b0e-13a3a9e97384}">
- * <versionRange minVersion="1.5" maxVersion="1.5.*"/>
- * </targetApplication>
- * <targetApplication id="toolkit@mozilla.org">
- * <versionRange minVersion="1.8" maxVersion="1.8.*"/>
- * </targetApplication>
- * </versionRange>
- * </emItem>
- * <emItem id="item_2@domain">
- * <versionRange minVersion="3.1" maxVersion="4.*"/>
- * </emItem>
- * <emItem id="item_3@domain">
- * <versionRange>
- * <targetApplication id="{ec8030f7-c20a-464f-9b0e-13a3a9e97384}">
- * <versionRange minVersion="1.5" maxVersion="1.5.*"/>
- * </targetApplication>
- * </versionRange>
- * </emItem>
- * <emItem id="item_4@domain">
- * <versionRange>
- * <targetApplication>
- * <versionRange minVersion="1.5" maxVersion="1.5.*"/>
- * </targetApplication>
- * </versionRange>
- * <emItem id="item_5@domain"/>
- * </emItems>
- * </blocklist>
- */
- _loadBlocklistFromFile: function(file) {
- if (getPref("getBoolPref", PREF_BLOCKLIST_ENABLED, true) == false) {
- LOG("Blocklist::_loadBlocklistFromFile: blocklist is disabled");
- return { };
- }
-
- if (!file.exists()) {
- LOG("Blocklist::_loadBlocklistFromFile: XML File does not exist");
- return { };
- }
-
- var result = { };
- var fileStream = Components.classes["@mozilla.org/network/file-input-stream;1"]
- .createInstance(Components.interfaces.nsIFileInputStream);
- fileStream.init(file, MODE_RDONLY, PERMS_FILE, 0);
- try {
- var parser = Components.classes["@mozilla.org/xmlextras/domparser;1"]
- .createInstance(Components.interfaces.nsIDOMParser);
- var doc = parser.parseFromStream(fileStream, "UTF-8", file.fileSize, "text/xml");
- if (doc.documentElement.namespaceURI != XMLURI_BLOCKLIST) {
- LOG("Blocklist::_loadBlocklistFromFile: aborting due to incorrect " +
- "XML Namespace.\r\nExpected: " + XMLURI_BLOCKLIST + "\r\n" +
- "Received: " + doc.documentElement.namespaceURI);
- return { };
- }
-
- const kELEMENT_NODE = Components.interfaces.nsIDOMNode.ELEMENT_NODE;
- var itemNodes = this._getItemNodes(doc.documentElement.childNodes);
- for (var i = 0; i < itemNodes.length; ++i) {
- var blocklistElement = itemNodes[i];
- if (blocklistElement.nodeType != kELEMENT_NODE ||
- blocklistElement.localName != "emItem")
- continue;
-
- blocklistElement.QueryInterface(Components.interfaces.nsIDOMElement);
- var versionNodes = blocklistElement.childNodes;
- var id = blocklistElement.getAttribute("id");
- result[id] = [];
- for (var x = 0; x < versionNodes.length; ++x) {
- var versionRangeElement = versionNodes[x];
- if (versionRangeElement.nodeType != kELEMENT_NODE ||
- versionRangeElement.localName != "versionRange")
- continue;
-
- result[id].push(new BlocklistItemData(versionRangeElement));
- }
- // if only the extension ID is specified block all versions of the
- // extension for the current application.
- if (result[id].length == 0)
- result[id].push(new BlocklistItemData(null));
- }
- }
- catch (e) {
- LOG("Blocklist::_loadBlocklistFromFile: Error constructing blocklist " + e);
- return { };
- }
- fileStream.close();
- return result;
- },
-
- _getItemNodes: function(deChildNodes) {
- const kELEMENT_NODE = Components.interfaces.nsIDOMNode.ELEMENT_NODE;
- for (var i = 0; i < deChildNodes.length; ++i) {
- var emItemsElement = deChildNodes[i];
- if (emItemsElement.nodeType == kELEMENT_NODE &&
- emItemsElement.localName == "emItems")
- return emItemsElement.childNodes;
- }
- return [ ];
- },
-
- _ensureBlocklist: function() {
- if (!this.entries)
- this.entries = this._loadBlocklistFromFile(getFile(KEY_PROFILEDIR,
- [FILE_BLOCKLIST]));
- }
-};
-
-/**
- * Helper for constructing a blocklist.
- */
-function BlocklistItemData(versionRangeElement) {
- var versionRange = this.getBlocklistVersionRange(versionRangeElement);
- this.minVersion = versionRange.minVersion;
- this.maxVersion = versionRange.maxVersion;
- this.targetApps = { };
- var found = false;
-
- if (versionRangeElement) {
- for (var i = 0; i < versionRangeElement.childNodes.length; ++i) {
- var targetAppElement = versionRangeElement.childNodes[i];
- if (targetAppElement.nodeType != Components.interfaces.nsIDOMNode.ELEMENT_NODE ||
- targetAppElement.localName != "targetApplication")
- continue;
- found = true;
- // default to the current application if id is not provided.
- var appID = targetAppElement.hasAttribute("id") ? targetAppElement.getAttribute("id") : gApp.ID;
- this.targetApps[appID] = this.getBlocklistAppVersions(targetAppElement);
- }
- }
- // Default to all versions of the extension and the current application when
- // versionRange is not defined.
- if (!found)
- this.targetApps[gApp.ID] = this.getBlocklistAppVersions(null);
-}
-
-BlocklistItemData.prototype = {
-/**
- * Retrieves a version range (e.g. minVersion and maxVersion) for a
- * blocklist item's targetApplication element.
- * @param targetAppElement
- * A targetApplication blocklist element.
- * @returns An array of JS objects with the following properties:
- * "minVersion" The minimum version in a version range (default = 0).
- * "maxVersion" The maximum version in a version range (default = *).
- */
- getBlocklistAppVersions: function(targetAppElement) {
- var appVersions = [ ];
- var found = false;
-
- if (targetAppElement) {
- for (var i = 0; i < targetAppElement.childNodes.length; ++i) {
- var versionRangeElement = targetAppElement.childNodes[i];
- if (versionRangeElement.nodeType != Components.interfaces.nsIDOMNode.ELEMENT_NODE ||
- versionRangeElement.localName != "versionRange")
- continue;
- found = true;
- appVersions.push(this.getBlocklistVersionRange(versionRangeElement));
- }
- }
- // return minVersion = 0 and maxVersion = * if not available
- if (!found)
- return [ this.getBlocklistVersionRange(null) ];
- return appVersions;
- },
-
-/**
- * Retrieves a version range (e.g. minVersion and maxVersion) for a blocklist
- * versionRange element.
- * @param versionRangeElement
- * The versionRange blocklist element.
- * @returns A JS object with the following properties:
- * "minVersion" The minimum version in a version range (default = 0).
- * "maxVersion" The maximum version in a version range (default = *).
- */
- getBlocklistVersionRange: function(versionRangeElement) {
- var minVersion = "0";
- var maxVersion = "*";
- if (!versionRangeElement)
- return { minVersion: minVersion, maxVersion: maxVersion };
-
- if (versionRangeElement.hasAttribute("minVersion"))
- minVersion = versionRangeElement.getAttribute("minVersion");
- if (versionRangeElement.hasAttribute("maxVersion"))
- maxVersion = versionRangeElement.getAttribute("maxVersion");
-
- return { minVersion: minVersion, maxVersion: maxVersion };
- }
-};
-
-/**
* Installs, manages and tracks compatibility for Extensions and Themes
* @constructor
*/
function ExtensionManager() {
gApp = Components.classes["@mozilla.org/xre/app-info;1"]
.getService(Components.interfaces.nsIXULAppInfo)
.QueryInterface(Components.interfaces.nsIXULRuntime);
gOSTarget = gApp.OS;
@@ -2927,19 +2610,16 @@ ExtensionManager.prototype = {
*/
_startTimers: function() {
// Register a background update check timer
var tm =
Components.classes["@mozilla.org/updates/timer-manager;1"]
.getService(Components.interfaces.nsIUpdateTimerManager);
var interval = getPref("getIntPref", PREF_EM_UPDATE_INTERVAL, 86400);
tm.registerTimer("addon-background-update-timer", this, interval);
-
- interval = getPref("getIntPref", PREF_BLOCKLIST_INTERVAL, 86400);
- tm.registerTimer("blocklist-background-update-timer", Blocklist, interval);
},
/**
* Notified when a timer fires
* @param timer
* The timer that fired
*/
notify: function(timer) {
@@ -4236,17 +3916,20 @@ ExtensionManager.prototype = {
}
// Check the target application range specified by the extension metadata.
if (gCheckCompatibility &&
!this.datasource.isCompatible(installManifest, gInstallManifestRoot, undefined))
installData.error = INSTALLERROR_INCOMPATIBLE_VERSION;
// Check if the item is blocklisted.
- if (this.datasource.isBlocklisted(installData.id, installData.version,
+ if (!gBlocklist)
+ gBlocklist = Components.classes["@mozilla.org/extensions/blocklist;1"]
+ .getService(Components.interfaces.nsIBlocklistService);
+ if (gBlocklist.isAddonBlocklisted(installData.id, installData.version,
undefined, undefined))
installData.error = INSTALLERROR_BLOCKLISTED;
return installData;
},
/**
* Installs an item from a XPI/JAR file.
@@ -6066,18 +5749,21 @@ ExtensionItemUpdater.prototype = {
gVersionChecker.compare(appExtensionsVersion, aMinAppVersion) < 0)
return false;
// Check if the update will only run on an older version of Firefox.
if (aMaxAppVersion &&
gVersionChecker.compare(appExtensionsVersion, aMaxAppVersion) > 0)
return false;
- if (this._emDS.isBlocklisted(aLocalItem.id, aVersion,
- undefined, undefined))
+ if (!gBlocklist)
+ gBlocklist = Components.classes["@mozilla.org/extensions/blocklist;1"]
+ .getService(Components.interfaces.nsIBlocklistService);
+ if (gBlocklist.isAddonBlocklisted(aLocalItem.id, aVersion,
+ undefined, undefined))
return false;
return true;
},
checkForDone: function(item, status) {
if (this._background &&
status == nsIAddonUpdateCheckListener.STATUS_UPDATE) {
@@ -6668,72 +6354,16 @@ ExtensionsDataSource.prototype = {
return ((versionChecker.compare(version, minVersion) >= 0) &&
(versionChecker.compare(version, maxVersion) <= 0));
}
}
return false;
},
/**
- * Determine if an item is blocklisted
- * @param id
- * The id of the item to check.
- * @param extVersion
- * The item's version.
- * @param appVersion
- * The version of the application we are checking in the blocklist.
- * If this parameter is undefined, the version of the running
- * application is used.
- * @param toolkitVersion
- * The version of the toolkit we are checking in the blocklist.
- * If this parameter is undefined, the version of the running
- * toolkit is used.
- * @returns true if the item is compatible with this version of the
- * application, false, otherwise.
- */
- isBlocklisted: function(id, extVersion, appVersion, toolkitVersion) {
- if (appVersion === undefined)
- appVersion = gApp.version;
- if (toolkitVersion === undefined)
- toolkitVersion = gApp.platformVersion;
-
- var blItem = Blocklist.entries[id];
- if (!blItem)
- return false;
-
- var versionChecker = getVersionChecker();
- for (var i = 0; i < blItem.length; ++i) {
- if (versionChecker.compare(extVersion, blItem[i].minVersion) < 0 ||
- versionChecker.compare(extVersion, blItem[i].maxVersion) > 0)
- continue;
-
- var blTargetApp = blItem[i].targetApps[gApp.ID];
- if (blTargetApp) {
- for (var x = 0; x < blTargetApp.length; ++x) {
- if (versionChecker.compare(appVersion, blTargetApp[x].minVersion) < 0 ||
- versionChecker.compare(appVersion, blTargetApp[x].maxVersion) > 0)
- continue;
- return true;
- }
- }
-
- blTargetApp = blItem[i].targetApps[TOOLKIT_ID];
- if (!blTargetApp)
- return false;
- for (x = 0; x < blTargetApp.length; ++x) {
- if (versionChecker.compare(toolkitVersion, blTargetApp[x].minVersion) < 0 ||
- versionChecker.compare(toolkitVersion, blTargetApp[x].maxVersion) > 0)
- continue;
- return true;
- }
- }
- return false;
- },
-
- /**
* Gets a list of items that are incompatible with a specific application version.
* @param appID
* The ID of the application - XXXben unused?
* @param appVersion
* The Version of the application to check for incompatibility against.
* @param desiredType
* The nsIUpdateItem type of items to look for
* @param includeDisabled
@@ -6784,32 +6414,35 @@ ExtensionsDataSource.prototype = {
* @param includeAppDisabled
* Whether or not items that are or are already set to be disabled
* by the app on next restart should be included in the set returned
* @returns An array of nsIUpdateItems that are blocklisted with the application
* or toolkit version supplied.
*/
getBlocklistedItemList: function(appVersion, toolkitVersion, desiredType,
includeAppDisabled) {
+ if (!gBlocklist)
+ gBlocklist = Components.classes["@mozilla.org/extensions/blocklist;1"]
+ .getService(Components.interfaces.nsIBlocklistService);
var items = [];
var ctr = getContainer(this._inner, this._itemRoot);
var elements = ctr.GetElements();
while (elements.hasMoreElements()) {
var item = elements.getNext().QueryInterface(Components.interfaces.nsIRDFResource);
var id = stripPrefix(item.Value, PREFIX_ITEM_URI);
var type = this.getItemProperty(id, "type");
if (!includeAppDisabled &&
(this.getItemProperty(id, "appDisabled") == "true" ||
this.getItemProperty(id, "appDisabled") == OP_NEEDS_DISABLE))
continue;
- var extVersion = this.getItemProperty(id, "version");
+ var version = this.getItemProperty(id, "version");
if (type != -1 && (type & desiredType) &&
- this.isBlocklisted(id, extVersion, appVersion, toolkitVersion))
+ gBlocklist.isAddonBlocklisted(id, version, appVersion, toolkitVersion))
items.push(this.getItemForID(id));
}
return items;
},
/**
* Gets a list of items of a specific type
* @param desiredType
@@ -7732,17 +7365,16 @@ ExtensionsDataSource.prototype = {
else
this.visibleItems[id] = locationKey;
},
/**
* Load the Extensions Datasource from disk.
*/
loadExtensions: function() {
- Blocklist._ensureBlocklist();
var extensionsFile = getFile(KEY_PROFILEDIR, [FILE_EXTENSIONS]);
try {
this._inner = gRDF.GetDataSourceBlocking(getURLSpecFromFile(extensionsFile));
}
catch (e) {
LOG("Datasource::loadExtensions: removing corrupted extensions datasource " +
" file = " + extensionsFile.path + ", exception = " + e + "\n");
extensionsFile.remove(false);
@@ -7924,50 +7556,25 @@ ExtensionsDataSource.prototype = {
}
return EM_L("true");
},
/**
* Get the em:blocklisted property (whether or not this item is blocklisted)
*/
_rdfGet_blocklisted: function(item, property) {
- Blocklist._ensureBlocklist();
var id = stripPrefix(item.Value, PREFIX_ITEM_URI);
- var blItem = Blocklist.entries[id];
- if (!blItem)
- return EM_L("false");
-
- getVersionChecker();
var version = this.getItemProperty(id, "version");
- var appVersion = gApp.version;
- for (var i = 0; i < blItem.length; ++i) {
- if (gVersionChecker.compare(version, blItem[i].minVersion) < 0 ||
- gVersionChecker.compare(version, blItem[i].maxVersion) > 0)
- continue;
-
- var blTargetApp = blItem[i].targetApps[gApp.ID];
- if (blTargetApp) {
- for (var x = 0; x < blTargetApp.length; ++x) {
- if (gVersionChecker.compare(appVersion, blTargetApp[x].minVersion) < 0 ||
- gVersionChecker.compare(appVersion, blTargetApp[x].maxVersion) > 0)
- continue;
- return EM_L("true");
- }
- }
-
- blTargetApp = blItem[i].targetApps[TOOLKIT_ID];
- if (!blTargetApp)
- return EM_L("false");
- for (x = 0; x < blTargetApp.length; ++x) {
- if (gVersionChecker.compare(gApp.platformVersion, blTargetApp[x].minVersion) < 0 ||
- gVersionChecker.compare(gApp.platformVersion, blTargetApp[x].maxVersion) > 0)
- continue;
- return EM_L("true");
- }
- }
+ if (!gBlocklist)
+ gBlocklist = Components.classes["@mozilla.org/extensions/blocklist;1"]
+ .getService(Components.interfaces.nsIBlocklistService);
+ if (gBlocklist.isAddonBlocklisted(id, version,
+ undefined, undefined))
+ return EM_L("true");
+
return EM_L("false");
},
/**
* Get the em:state property (represents the current phase of an install).
*/
_rdfGet_state: function(item, property) {
var id = item.Value;