Bug 470377: Overriding compatibility checking should not allow installing in different applications. r=robstrong
authorDave Townsend <dtownsend@oxymoronical.com>
Thu, 06 Aug 2009 15:24:52 +0100
changeset 31174 91db32e73fc0091998efc1852d60a94d1450fd43
parent 31173 5b5a412e9cd3dc5cf6f59a3d5f6390fe2ebd1029
child 31175 b61bc50678e77d7b03e8aa26ed1305b0af3d933c
push id8407
push userdtownsend@mozilla.com
push dateThu, 06 Aug 2009 14:25:54 +0000
treeherdermozilla-central@91db32e73fc0 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersrobstrong
bugs470377
milestone1.9.2a1pre
Bug 470377: Overriding compatibility checking should not allow installing in different applications. r=robstrong
toolkit/mozapps/extensions/src/nsExtensionManager.js.in
toolkit/mozapps/extensions/test/addons/test_bug470377_1/install.rdf
toolkit/mozapps/extensions/test/addons/test_bug470377_2/install.rdf
toolkit/mozapps/extensions/test/addons/test_bug470377_3/install.rdf
toolkit/mozapps/extensions/test/addons/test_bug470377_4/install.rdf
toolkit/mozapps/extensions/test/addons/test_bug470377_5/install.rdf
toolkit/mozapps/extensions/test/unit/data/test_bug470377/install_1.rdf
toolkit/mozapps/extensions/test/unit/data/test_bug470377/install_2.rdf
toolkit/mozapps/extensions/test/unit/data/test_bug470377/install_3.rdf
toolkit/mozapps/extensions/test/unit/data/test_bug470377/install_4.rdf
toolkit/mozapps/extensions/test/unit/data/test_bug470377/install_5.rdf
toolkit/mozapps/extensions/test/unit/data/test_bug470377/update_1.rdf
toolkit/mozapps/extensions/test/unit/data/test_bug470377/update_2.rdf
toolkit/mozapps/extensions/test/unit/data/test_bug470377/update_3.rdf
toolkit/mozapps/extensions/test/unit/data/test_bug470377/update_4.rdf
toolkit/mozapps/extensions/test/unit/data/test_bug470377/update_5.rdf
toolkit/mozapps/extensions/test/unit/test_bug470377_1.js
toolkit/mozapps/extensions/test/unit/test_bug470377_2.js
toolkit/mozapps/extensions/test/unit/test_bug470377_3.js
toolkit/mozapps/extensions/test/unit/test_bug470377_4.js
--- a/toolkit/mozapps/extensions/src/nsExtensionManager.js.in
+++ b/toolkit/mozapps/extensions/src/nsExtensionManager.js.in
@@ -3619,20 +3619,19 @@ ExtensionManager.prototype = {
     // Check that the add-on provides a secure update method.
     if (gCheckUpdateSecurity &&
         installData.updateURL &&
         installData.updateURL.substring(0, 6) != "https:" &&
         !installData.updateKey) {
       installData.error = INSTALLERROR_INSECURE_UPDATE;
       return installData;
     }
-      
-    // Check that the target application range allows compatibility with the app
-    if (gCheckCompatibility &&
-        !this.datasource.isCompatible(installManifest, gInstallManifestRoot, undefined)) {
+
+    // Check that the item is compatible with the application.
+    if (!this.datasource.isCompatible(installManifest, gInstallManifestRoot, false)) {
       installData.error = INSTALLERROR_INCOMPATIBLE_VERSION;
       return installData;
     }
     
     // Check if the item is blocklisted.
     if (!gBlocklist)
       gBlocklist = Cc["@mozilla.org/extensions/blocklist;1"].
                    getService(Ci.nsIBlocklistService);
@@ -4813,20 +4812,19 @@ ExtensionManager.prototype = {
 
   /**
    * Determines whether an item should be disabled by the application.
    * @param   id
    *          The ID of the item to check
    */
   _isUsableItem: function EM__isUsableItem(id) {
     var ds = this.datasource;
-    /* If we're not compatibility checking or if the item is compatible
-     * and if it isn't blocklisted and has all dependencies satisfied then
-     * proceed to the security check */
-    if ((!gCheckCompatibility || ds.getItemProperty(id, "compatible") == "true") &&
+    /* If the item is compatible and if it isn't blocklisted and has all
+     * dependencies satisfied then proceed to the security check */
+    if (ds.isCompatible(ds, getResourceForID(id), false) &&
         ds.getItemProperty(id, "blocklisted") == "false" &&
         ds.getItemProperty(id, "satisfiesDependencies") == "true") {
 
       // appManaged items aren't updated so no need to check update security.
       if (ds.getItemProperty(id, "appManaged") == "true")
         return true;
 
       /* If we are not ignoring update security then check that the item has
@@ -6583,30 +6581,40 @@ ExtensionsDataSource.prototype = {
 
   /**
    * Determine if an item is compatible
    * @param   datasource
    *          The datasource to inspect for compatibility - can be the main
    *          datasource or an Install Manifest.
    * @param   source
    *          The RDF Resource of the item to inspect for compatibility.
+   * @param   alwaysCheckVersion
+   *          Set to true to only obey the compatibility information in the
+   *          datasource. When false the compatibility range may be ignored
+   *          if compatibility checking is disabled.
    * @param   appVersion
    *          The version of the application we are checking for compatibility
    *          against. If this parameter is undefined, the version of the running
    *          application is used.
    * @param   platformVersion
    *          The version of the toolkit to check compatibility against
    * @returns true if the item is compatible with this version of the
    *          application, false, otherwise.
    */
-  isCompatible: function EMDS_isCompatible(datasource, source, appVersion, platformVersion) {
+  isCompatible: function EMDS_isCompatible(datasource, source, alwaysCheckVersion,
+                                           appVersion, platformVersion) {
     // The Default Theme is always compatible.
     if (source.EqualsNode(this._defaultTheme))
       return true;
 
+    // Items pending install have no target application info in the datasource
+    if (datasource === this &&
+        this._getItemProperty(source, "opType") == OP_NEEDS_INSTALL)
+      return true;
+
     var appID = gApp.ID;
     if (appVersion === undefined)
       appVersion = gApp.version;
     if (platformVersion === undefined)
       var platformVersion = gApp.platformVersion;
 
     var targets = datasource.GetTargets(source, EM_R("targetApplication"), true);
     var idRes = EM_R("id");
@@ -6615,22 +6623,26 @@ ExtensionsDataSource.prototype = {
     var versionChecker = getVersionChecker();
     var rv = false;
     while (targets.hasMoreElements()) {
       var targetApp = targets.getNext().QueryInterface(Ci.nsIRDFResource);
       var id          = stringData(datasource.GetTarget(targetApp, idRes, true));
       var minVersion  = stringData(datasource.GetTarget(targetApp, minVersionRes, true));
       var maxVersion  = stringData(datasource.GetTarget(targetApp, maxVersionRes, true));
       if (id == appID) {
+        if (!alwaysCheckVersion && !gCheckCompatibility)
+          return true;
         rv = (versionChecker.compare(appVersion, minVersion) >= 0) &&
              (versionChecker.compare(appVersion, maxVersion) <= 0);
         return rv; // App takes precedence over toolkit.
       }
 
       if (id == TOOLKIT_ID) {
+        if (!alwaysCheckVersion && !gCheckCompatibility)
+          return true;
         rv =  (versionChecker.compare(platformVersion, minVersion) >= 0) &&
               (versionChecker.compare(platformVersion, maxVersion) <= 0);
         // Keep looping, in case the app id is later.
       }
     }
     return rv;
   },
 
@@ -6670,17 +6682,17 @@ ExtensionsDataSource.prototype = {
       // it is always compatible with the next release of the application since
       // we will continue to support it.
       var locationKey = this.getItemProperty(id, "installLocation");
       var appManaged = this.getItemProperty(id, "appManaged") == "true";
       if (appManaged && locationKey == KEY_APP_GLOBAL)
         continue;
 
       if (type != -1 && (type & desiredType) &&
-          !this.isCompatible(this, item, appVersion, platformVersion))
+          !this.isCompatible(this, item, true, appVersion, platformVersion))
         items.push(this.getItemForID(id));
     }
     return items;
   },
 
   /**
    * Gets a list of items of a specific type
    * @param   desiredType
@@ -7805,33 +7817,18 @@ ExtensionsDataSource.prototype = {
       return EM_D(StartupCache.entries[key][id].mtime * 1000000);
     return null;
   },
 
   /**
    * Get the em:compatible property (whether or not this item is compatible)
    */
   _rdfGet_compatible: function EMDS__rdfGet_compatible(item, property) {
-    var id = stripPrefix(item.Value, PREFIX_ITEM_URI);
-    var targetAppInfo = this.getTargetApplicationInfo(id, this);
-    if (!targetAppInfo) {
-      // When installing a new addon targetAppInfo does not exist yet
-      if (this.getItemProperty(id, "opType") == OP_NEEDS_INSTALL)
-        return EM_L("true");
-      return EM_L("false");
-    }
-
-    getVersionChecker();
-    var appVersion = targetAppInfo.appID == TOOLKIT_ID ? gApp.platformVersion : gApp.version;
-    if (gVersionChecker.compare(targetAppInfo.maxVersion, appVersion) < 0 ||
-        gVersionChecker.compare(appVersion, targetAppInfo.minVersion) < 0) {
-      // OK, this item is incompatible.
-      return EM_L("false");
-    }
-    return EM_L("true");
+    var compatible = this.isCompatible(this, item, true);
+    return compatible ? EM_L("true") : EM_L("false");
   },
 
   /**
    * Get the providesUpdatesSecurely property (whether or not this item has a
    * secure update mechanism)
    */
   _rdfGet_providesUpdatesSecurely: function EMDS__rdfGet_providesUpdatesSecurely(item, property) {
     var id = stripPrefix(item.Value, PREFIX_ITEM_URI);
new file mode 100644
--- /dev/null
+++ b/toolkit/mozapps/extensions/test/addons/test_bug470377_1/install.rdf
@@ -0,0 +1,18 @@
+<?xml version="1.0"?>
+
+<RDF xmlns="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
+     xmlns:em="http://www.mozilla.org/2004/em-rdf#">
+  <Description about="urn:mozilla:install-manifest">
+    <em:id>bug470377_1@tests.mozilla.org</em:id>
+    <em:version>1</em:version>
+    <em:targetApplication>
+      <Description>
+        <em:id>unknown@tests.mozilla.org</em:id>
+        <em:minVersion>1</em:minVersion>
+        <em:maxVersion>1</em:maxVersion>
+      </Description>
+    </em:targetApplication>
+    <em:name>Test for Bug 470377</em:name>
+    <em:updateURL>http://localhost:4444/test_bug470377_1.rdf</em:updateURL>
+  </Description>
+</RDF>
new file mode 100644
--- /dev/null
+++ b/toolkit/mozapps/extensions/test/addons/test_bug470377_2/install.rdf
@@ -0,0 +1,18 @@
+<?xml version="1.0"?>
+
+<RDF xmlns="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
+     xmlns:em="http://www.mozilla.org/2004/em-rdf#">
+  <Description about="urn:mozilla:install-manifest">
+    <em:id>bug470377_2@tests.mozilla.org</em:id>
+    <em:version>1</em:version>
+    <em:targetApplication>
+      <Description>
+        <em:id>toolkit@mozilla.org</em:id>
+        <em:minVersion>1</em:minVersion>
+        <em:maxVersion>1</em:maxVersion>
+      </Description>
+    </em:targetApplication>
+    <em:name>Test for Bug 470377</em:name>
+    <em:updateURL>http://localhost:4444/test_bug470377_2.rdf</em:updateURL>
+  </Description>
+</RDF>
new file mode 100644
--- /dev/null
+++ b/toolkit/mozapps/extensions/test/addons/test_bug470377_3/install.rdf
@@ -0,0 +1,18 @@
+<?xml version="1.0"?>
+
+<RDF xmlns="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
+     xmlns:em="http://www.mozilla.org/2004/em-rdf#">
+  <Description about="urn:mozilla:install-manifest">
+    <em:id>bug470377_3@tests.mozilla.org</em:id>
+    <em:version>1</em:version>
+    <em:targetApplication>
+      <Description>
+        <em:id>xpcshell@tests.mozilla.org</em:id>
+        <em:minVersion>1</em:minVersion>
+        <em:maxVersion>1</em:maxVersion>
+      </Description>
+    </em:targetApplication>
+    <em:name>Test for Bug 470377</em:name>
+    <em:updateURL>http://localhost:4444/test_bug470377_3.rdf</em:updateURL>
+  </Description>
+</RDF>
new file mode 100644
--- /dev/null
+++ b/toolkit/mozapps/extensions/test/addons/test_bug470377_4/install.rdf
@@ -0,0 +1,18 @@
+<?xml version="1.0"?>
+
+<RDF xmlns="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
+     xmlns:em="http://www.mozilla.org/2004/em-rdf#">
+  <Description about="urn:mozilla:install-manifest">
+    <em:id>bug470377_4@tests.mozilla.org</em:id>
+    <em:version>1</em:version>
+    <em:targetApplication>
+      <Description>
+        <em:id>toolkit@mozilla.org</em:id>
+        <em:minVersion>1</em:minVersion>
+        <em:maxVersion>2</em:maxVersion>
+      </Description>
+    </em:targetApplication>
+    <em:name>Test for Bug 470377</em:name>
+    <em:updateURL>http://localhost:4444/test_bug470377_4.rdf</em:updateURL>
+  </Description>
+</RDF>
new file mode 100644
--- /dev/null
+++ b/toolkit/mozapps/extensions/test/addons/test_bug470377_5/install.rdf
@@ -0,0 +1,18 @@
+<?xml version="1.0"?>
+
+<RDF xmlns="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
+     xmlns:em="http://www.mozilla.org/2004/em-rdf#">
+  <Description about="urn:mozilla:install-manifest">
+    <em:id>bug470377_5@tests.mozilla.org</em:id>
+    <em:version>1</em:version>
+    <em:targetApplication>
+      <Description>
+        <em:id>xpcshell@tests.mozilla.org</em:id>
+        <em:minVersion>1</em:minVersion>
+        <em:maxVersion>2</em:maxVersion>
+      </Description>
+    </em:targetApplication>
+    <em:name>Test for Bug 470377</em:name>
+    <em:updateURL>http://localhost:4444/test_bug470377_5.rdf</em:updateURL>
+  </Description>
+</RDF>
new file mode 100644
--- /dev/null
+++ b/toolkit/mozapps/extensions/test/unit/data/test_bug470377/install_1.rdf
@@ -0,0 +1,17 @@
+<?xml version="1.0"?>
+
+<RDF xmlns="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
+     xmlns:em="http://www.mozilla.org/2004/em-rdf#">
+  <Description about="urn:mozilla:install-manifest">
+    <em:id>bug470377_1@tests.mozilla.org</em:id>
+    <em:version>1</em:version>
+    <em:targetApplication>
+      <Description>
+        <em:id>unknown@tests.mozilla.org</em:id>
+        <em:minVersion>1</em:minVersion>
+        <em:maxVersion>1</em:maxVersion>
+      </Description>
+    </em:targetApplication>
+    <em:name>Test for Bug 470377</em:name>
+  </Description>
+</RDF>
new file mode 100644
--- /dev/null
+++ b/toolkit/mozapps/extensions/test/unit/data/test_bug470377/install_2.rdf
@@ -0,0 +1,17 @@
+<?xml version="1.0"?>
+
+<RDF xmlns="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
+     xmlns:em="http://www.mozilla.org/2004/em-rdf#">
+  <Description about="urn:mozilla:install-manifest">
+    <em:id>bug470377_2@tests.mozilla.org</em:id>
+    <em:version>1</em:version>
+    <em:targetApplication>
+      <Description>
+        <em:id>toolkit@mozilla.org</em:id>
+        <em:minVersion>1</em:minVersion>
+        <em:maxVersion>1</em:maxVersion>
+      </Description>
+    </em:targetApplication>
+    <em:name>Test for Bug 470377</em:name>
+  </Description>
+</RDF>
new file mode 100644
--- /dev/null
+++ b/toolkit/mozapps/extensions/test/unit/data/test_bug470377/install_3.rdf
@@ -0,0 +1,17 @@
+<?xml version="1.0"?>
+
+<RDF xmlns="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
+     xmlns:em="http://www.mozilla.org/2004/em-rdf#">
+  <Description about="urn:mozilla:install-manifest">
+    <em:id>bug470377_3@tests.mozilla.org</em:id>
+    <em:version>1</em:version>
+    <em:targetApplication>
+      <Description>
+        <em:id>xpcshell@tests.mozilla.org</em:id>
+        <em:minVersion>1</em:minVersion>
+        <em:maxVersion>1</em:maxVersion>
+      </Description>
+    </em:targetApplication>
+    <em:name>Test for Bug 470377</em:name>
+  </Description>
+</RDF>
new file mode 100644
--- /dev/null
+++ b/toolkit/mozapps/extensions/test/unit/data/test_bug470377/install_4.rdf
@@ -0,0 +1,17 @@
+<?xml version="1.0"?>
+
+<RDF xmlns="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
+     xmlns:em="http://www.mozilla.org/2004/em-rdf#">
+  <Description about="urn:mozilla:install-manifest">
+    <em:id>bug470377_4@tests.mozilla.org</em:id>
+    <em:version>1</em:version>
+    <em:targetApplication>
+      <Description>
+        <em:id>toolkit@mozilla.org</em:id>
+        <em:minVersion>1</em:minVersion>
+        <em:maxVersion>2</em:maxVersion>
+      </Description>
+    </em:targetApplication>
+    <em:name>Test for Bug 470377</em:name>
+  </Description>
+</RDF>
new file mode 100644
--- /dev/null
+++ b/toolkit/mozapps/extensions/test/unit/data/test_bug470377/install_5.rdf
@@ -0,0 +1,17 @@
+<?xml version="1.0"?>
+
+<RDF xmlns="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
+     xmlns:em="http://www.mozilla.org/2004/em-rdf#">
+  <Description about="urn:mozilla:install-manifest">
+    <em:id>bug470377_5@tests.mozilla.org</em:id>
+    <em:version>1</em:version>
+    <em:targetApplication>
+      <Description>
+        <em:id>xpcshell@tests.mozilla.org</em:id>
+        <em:minVersion>1</em:minVersion>
+        <em:maxVersion>2</em:maxVersion>
+      </Description>
+    </em:targetApplication>
+    <em:name>Test for Bug 470377</em:name>
+  </Description>
+</RDF>
new file mode 100644
--- /dev/null
+++ b/toolkit/mozapps/extensions/test/unit/data/test_bug470377/update_1.rdf
@@ -0,0 +1,26 @@
+<?xml version="1.0" encoding="UTF-8"?>
+
+<RDF:RDF xmlns:RDF="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
+         xmlns:em="http://www.mozilla.org/2004/em-rdf#">
+
+  <RDF:Description about="urn:mozilla:extension:test_bug470377_1@tests.mozilla.org">
+    <em:updates>
+      <RDF:Seq>
+        <RDF:li>
+          <RDF:Description>
+            <em:version>1</em:version>
+            <em:targetApplication>
+              <RDF:Description>
+                <em:id>unknown@tests.mozilla.org</em:id>
+                <em:minVersion>1</em:minVersion>
+                <em:maxVersion>2</em:maxVersion>
+                <em:updateLink>http://localhost:4444/broken.xpi</em:updateLink>
+              </RDF:Description>
+            </em:targetApplication>
+          </RDF:Description>
+        </RDF:li>
+      </RDF:Seq>
+    </em:updates>
+  </RDF:Description>
+
+</RDF:RDF>
new file mode 100644
--- /dev/null
+++ b/toolkit/mozapps/extensions/test/unit/data/test_bug470377/update_2.rdf
@@ -0,0 +1,26 @@
+<?xml version="1.0" encoding="UTF-8"?>
+
+<RDF:RDF xmlns:RDF="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
+         xmlns:em="http://www.mozilla.org/2004/em-rdf#">
+
+  <RDF:Description about="urn:mozilla:extension:test_bug470377_2@tests.mozilla.org">
+    <em:updates>
+      <RDF:Seq>
+        <RDF:li>
+          <RDF:Description>
+            <em:version>1</em:version>
+            <em:targetApplication>
+              <RDF:Description>
+                <em:id>toolkit@mozilla.org</em:id>
+                <em:minVersion>1</em:minVersion>
+                <em:maxVersion>1</em:maxVersion>
+                <em:updateLink>http://localhost:4444/broken.xpi</em:updateLink>
+              </RDF:Description>
+            </em:targetApplication>
+          </RDF:Description>
+        </RDF:li>
+      </RDF:Seq>
+    </em:updates>
+  </RDF:Description>
+
+</RDF:RDF>
new file mode 100644
--- /dev/null
+++ b/toolkit/mozapps/extensions/test/unit/data/test_bug470377/update_3.rdf
@@ -0,0 +1,26 @@
+<?xml version="1.0" encoding="UTF-8"?>
+
+<RDF:RDF xmlns:RDF="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
+         xmlns:em="http://www.mozilla.org/2004/em-rdf#">
+
+  <RDF:Description about="urn:mozilla:extension:test_bug470377_3@tests.mozilla.org">
+    <em:updates>
+      <RDF:Seq>
+        <RDF:li>
+          <RDF:Description>
+            <em:version>1</em:version>
+            <em:targetApplication>
+              <RDF:Description>
+                <em:id>xpcshell@tests.mozilla.org</em:id>
+                <em:minVersion>1</em:minVersion>
+                <em:maxVersion>1</em:maxVersion>
+                <em:updateLink>http://localhost:4444/broken.xpi</em:updateLink>
+              </RDF:Description>
+            </em:targetApplication>
+          </RDF:Description>
+        </RDF:li>
+      </RDF:Seq>
+    </em:updates>
+  </RDF:Description>
+
+</RDF:RDF>
new file mode 100644
--- /dev/null
+++ b/toolkit/mozapps/extensions/test/unit/data/test_bug470377/update_4.rdf
@@ -0,0 +1,26 @@
+<?xml version="1.0" encoding="UTF-8"?>
+
+<RDF:RDF xmlns:RDF="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
+         xmlns:em="http://www.mozilla.org/2004/em-rdf#">
+
+  <RDF:Description about="urn:mozilla:extension:test_bug470377_4@tests.mozilla.org">
+    <em:updates>
+      <RDF:Seq>
+        <RDF:li>
+          <RDF:Description>
+            <em:version>1</em:version>
+            <em:targetApplication>
+              <RDF:Description>
+                <em:id>toolkit@mozilla.org</em:id>
+                <em:minVersion>1</em:minVersion>
+                <em:maxVersion>2</em:maxVersion>
+                <em:updateLink>http://localhost:4444/broken.xpi</em:updateLink>
+              </RDF:Description>
+            </em:targetApplication>
+          </RDF:Description>
+        </RDF:li>
+      </RDF:Seq>
+    </em:updates>
+  </RDF:Description>
+
+</RDF:RDF>
new file mode 100644
--- /dev/null
+++ b/toolkit/mozapps/extensions/test/unit/data/test_bug470377/update_5.rdf
@@ -0,0 +1,26 @@
+<?xml version="1.0" encoding="UTF-8"?>
+
+<RDF:RDF xmlns:RDF="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
+         xmlns:em="http://www.mozilla.org/2004/em-rdf#">
+
+  <RDF:Description about="urn:mozilla:extension:test_bug470377_5@tests.mozilla.org">
+    <em:updates>
+      <RDF:Seq>
+        <RDF:li>
+          <RDF:Description>
+            <em:version>1</em:version>
+            <em:targetApplication>
+              <RDF:Description>
+                <em:id>xpcshell@tests.mozilla.org</em:id>
+                <em:minVersion>1</em:minVersion>
+                <em:maxVersion>2</em:maxVersion>
+                <em:updateLink>http://localhost:4444/broken.xpi</em:updateLink>
+              </RDF:Description>
+            </em:targetApplication>
+          </RDF:Description>
+        </RDF:li>
+      </RDF:Seq>
+    </em:updates>
+  </RDF:Description>
+
+</RDF:RDF>
new file mode 100644
--- /dev/null
+++ b/toolkit/mozapps/extensions/test/unit/test_bug470377_1.js
@@ -0,0 +1,157 @@
+/* ***** 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 mozilla.org code.
+ *
+ * The Initial Developer of the Original Code is
+ * Dave Townsend <dtownsend@oxymoronical.com>.
+ *
+ * Portions created by the Initial Developer are Copyright (C) 2009
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s):
+ *
+ * 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 *****
+ */
+
+// Disables security checking our updates which haven't been signed
+gPrefs.setBoolPref("extensions.checkUpdateSecurity", false);
+
+// This allows the EM to attempt to display errors to the user without failing
+var promptService = {
+  alert: function(aParent, aDialogTitle, aText) {
+  },
+
+  alertCheck: function(aParent, aDialogTitle, aText, aCheckMsg, aCheckState) {
+  },
+
+  confirm: function(aParent, aDialogTitle, aText) {
+  },
+
+  confirmCheck: function(aParent, aDialogTitle, aText, aCheckMsg, aCheckState) {
+  },
+
+  confirmEx: function(aParent, aDialogTitle, aText, aButtonFlags, aButton0Title, aButton1Title, aButton2Title, aCheckMsg, aCheckState) {
+  },
+
+  prompt: function(aParent, aDialogTitle, aText, aValue, aCheckMsg, aCheckState) {
+  },
+
+  promptUsernameAndPassword: function(aParent, aDialogTitle, aText, aUsername, aPassword, aCheckMsg, aCheckState) {
+  },
+
+  promptPassword: function(aParent, aDialogTitle, aText, aPassword, aCheckMsg, aCheckState) {
+  },
+
+  select: function(aParent, aDialogTitle, aText, aCount, aSelectList, aOutSelection) {
+  },
+
+  QueryInterface: function(iid) {
+    if (iid.equals(Components.interfaces.nsIPromptService)
+     || iid.equals(Components.interfaces.nsISupports))
+      return this;
+
+    throw Components.results.NS_ERROR_NO_INTERFACE;
+  }
+};
+
+var PromptServiceFactory = {
+  createInstance: function (outer, iid) {
+    if (outer != null)
+      throw Components.results.NS_ERROR_NO_AGGREGATION;
+    return promptService.QueryInterface(iid);
+  }
+};
+var registrar = Components.manager.QueryInterface(Components.interfaces.nsIComponentRegistrar);
+registrar.registerFactory(Components.ID("{6cc9c9fe-bc0b-432b-a410-253ef8bcc699}"),
+                          "PromptService",
+                          "@mozilla.org/embedcomp/prompt-service;1", PromptServiceFactory);
+
+var ADDONS = [
+  "test_bug470377_1",
+  "test_bug470377_2",
+  "test_bug470377_3",
+  "test_bug470377_4",
+  "test_bug470377_5",
+];
+
+var InstallListener = {
+  onDownloadStarted: function(aAddon) {
+  },
+
+  onDownloadProgress: function onProgress(aAddon, aValue, aMaxValue) {
+  },
+
+  onDownloadEnded: function(aAddon) {
+  },
+
+  onInstallStarted: function(aAddon) {
+  },
+
+  onCompatibilityCheckStarted: function(aAddon) {
+    if (aAddon.id == "bug470377_1@tests.mozilla.org")
+      do_throw("Shouldn't perform a compatibility check for test_bug470377_1");
+  },
+
+  onCompatibilityCheckEnded: function(aAddon, aStatus) {
+  },
+
+  onInstallEnded: function(aAddon, aStatus) {
+  },
+
+  onInstallsCompleted: function() {
+    if (ADDONS.length == 0) {
+      do_execute_soon(check_test);
+      return;
+    }
+    gEM.installItemFromFile(do_get_addon(ADDONS.shift()), NS_INSTALL_LOCATION_APPPROFILE);
+  }
+};
+
+do_load_httpd_js();
+var server;
+
+function run_test() {
+  createAppInfo("xpcshell@tests.mozilla.org", "XPCShell", "2", "2");
+
+  server = new nsHttpServer();
+  server.registerDirectory("/", do_get_file("data/test_bug470377"));
+  server.start(4444);
+
+  do_test_pending();
+  startupEM();
+  gEM.addInstallListener(InstallListener);
+  gEM.installItemFromFile(do_get_addon(ADDONS.shift()), NS_INSTALL_LOCATION_APPPROFILE);
+}
+
+function check_test() {
+  restartEM();
+  do_check_eq(gEM.getItemForID("bug470377_1@tests.mozilla.org"), null);
+  do_check_eq(gEM.getItemForID("bug470377_2@tests.mozilla.org"), null);
+  do_check_eq(gEM.getItemForID("bug470377_3@tests.mozilla.org"), null);
+  do_check_neq(gEM.getItemForID("bug470377_4@tests.mozilla.org"), null);
+  do_check_neq(gEM.getItemForID("bug470377_5@tests.mozilla.org"), null);
+  do_test_finished();
+}
new file mode 100644
--- /dev/null
+++ b/toolkit/mozapps/extensions/test/unit/test_bug470377_2.js
@@ -0,0 +1,158 @@
+/* ***** 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 mozilla.org code.
+ *
+ * The Initial Developer of the Original Code is
+ * Dave Townsend <dtownsend@oxymoronical.com>.
+ *
+ * Portions created by the Initial Developer are Copyright (C) 2009
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s):
+ *
+ * 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 *****
+ */
+
+// Disables security checking our updates which haven't been signed
+gPrefs.setBoolPref("extensions.checkUpdateSecurity", false);
+// Disables compatibility checking
+gPrefs.setBoolPref("extensions.checkCompatibility", false);
+
+// This allows the EM to attempt to display errors to the user without failing
+var promptService = {
+  alert: function(aParent, aDialogTitle, aText) {
+  },
+
+  alertCheck: function(aParent, aDialogTitle, aText, aCheckMsg, aCheckState) {
+  },
+
+  confirm: function(aParent, aDialogTitle, aText) {
+  },
+
+  confirmCheck: function(aParent, aDialogTitle, aText, aCheckMsg, aCheckState) {
+  },
+
+  confirmEx: function(aParent, aDialogTitle, aText, aButtonFlags, aButton0Title, aButton1Title, aButton2Title, aCheckMsg, aCheckState) {
+  },
+
+  prompt: function(aParent, aDialogTitle, aText, aValue, aCheckMsg, aCheckState) {
+  },
+
+  promptUsernameAndPassword: function(aParent, aDialogTitle, aText, aUsername, aPassword, aCheckMsg, aCheckState) {
+  },
+
+  promptPassword: function(aParent, aDialogTitle, aText, aPassword, aCheckMsg, aCheckState) {
+  },
+
+  select: function(aParent, aDialogTitle, aText, aCount, aSelectList, aOutSelection) {
+  },
+
+  QueryInterface: function(iid) {
+    if (iid.equals(Components.interfaces.nsIPromptService)
+     || iid.equals(Components.interfaces.nsISupports))
+      return this;
+
+    throw Components.results.NS_ERROR_NO_INTERFACE;
+  }
+};
+
+var PromptServiceFactory = {
+  createInstance: function (outer, iid) {
+    if (outer != null)
+      throw Components.results.NS_ERROR_NO_AGGREGATION;
+    return promptService.QueryInterface(iid);
+  }
+};
+var registrar = Components.manager.QueryInterface(Components.interfaces.nsIComponentRegistrar);
+registrar.registerFactory(Components.ID("{6cc9c9fe-bc0b-432b-a410-253ef8bcc699}"),
+                          "PromptService",
+                          "@mozilla.org/embedcomp/prompt-service;1", PromptServiceFactory);
+
+var ADDONS = [
+  "test_bug470377_1",
+  "test_bug470377_2",
+  "test_bug470377_3",
+  "test_bug470377_4",
+  "test_bug470377_5",
+];
+
+var InstallListener = {
+  onDownloadStarted: function(aAddon) {
+  },
+
+  onDownloadProgress: function onProgress(aAddon, aValue, aMaxValue) {
+  },
+
+  onDownloadEnded: function(aAddon) {
+  },
+
+  onInstallStarted: function(aAddon) {
+  },
+
+  onCompatibilityCheckStarted: function(aAddon) {
+    do_throw("Shouldn't perform any compatibility checks but did for " + aAddon.id);
+  },
+
+  onCompatibilityCheckEnded: function(aAddon, aStatus) {
+  },
+
+  onInstallEnded: function(aAddon, aStatus) {
+  },
+
+  onInstallsCompleted: function() {
+    if (ADDONS.length == 0) {
+      do_execute_soon(check_test);
+      return;
+    }
+    gEM.installItemFromFile(do_get_addon(ADDONS.shift()), NS_INSTALL_LOCATION_APPPROFILE);
+  }
+};
+
+do_load_httpd_js();
+var server;
+
+function run_test() {
+  createAppInfo("xpcshell@tests.mozilla.org", "XPCShell", "2", "2");
+
+  server = new nsHttpServer();
+  server.registerDirectory("/", do_get_file("data/test_bug470377"));
+  server.start(4444);
+
+  do_test_pending();
+  startupEM();
+  gEM.addInstallListener(InstallListener);
+  gEM.installItemFromFile(do_get_addon(ADDONS.shift()), NS_INSTALL_LOCATION_APPPROFILE);
+}
+
+function check_test() {
+  restartEM();
+  do_check_eq(gEM.getItemForID("bug470377_1@tests.mozilla.org"), null);
+  do_check_neq(gEM.getItemForID("bug470377_2@tests.mozilla.org"), null);
+  do_check_neq(gEM.getItemForID("bug470377_3@tests.mozilla.org"), null);
+  do_check_neq(gEM.getItemForID("bug470377_4@tests.mozilla.org"), null);
+  do_check_neq(gEM.getItemForID("bug470377_5@tests.mozilla.org"), null);
+  do_test_finished();
+}
new file mode 100644
--- /dev/null
+++ b/toolkit/mozapps/extensions/test/unit/test_bug470377_3.js
@@ -0,0 +1,101 @@
+/* ***** 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 mozilla.org code.
+ *
+ * The Initial Developer of the Original Code is
+ * Dave Townsend <dtownsend@oxymoronical.com>.
+ *
+ * Portions created by the Initial Developer are Copyright (C) 2009
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s):
+ *
+ * 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 *****
+ */
+
+function run_test() {
+  createAppInfo("xpcshell@tests.mozilla.org", "XPCShell", "2", "2");
+
+  // inject the add-ons into the profile
+  var dest = gProfD.clone();
+  dest.append("extensions");
+  dest.append("bug470377_1@tests.mozilla.org");
+  dest.create(Components.interfaces.nsIFile.DIRECTORY_TYPE, 0755);
+  var source = do_get_file("data/test_bug470377/install_1.rdf");
+  source.copyTo(dest, "install.rdf");
+  dest = gProfD.clone();
+  dest.append("extensions");
+  dest.append("bug470377_2@tests.mozilla.org");
+  dest.create(Components.interfaces.nsIFile.DIRECTORY_TYPE, 0755);
+  source = do_get_file("data/test_bug470377/install_2.rdf");
+  source.copyTo(dest, "install.rdf");
+  dest = gProfD.clone();
+  dest.append("extensions");
+  dest.append("bug470377_3@tests.mozilla.org");
+  dest.create(Components.interfaces.nsIFile.DIRECTORY_TYPE, 0755);
+  source = do_get_file("data/test_bug470377/install_3.rdf");
+  source.copyTo(dest, "install.rdf");
+  dest = gProfD.clone();
+  dest.append("extensions");
+  dest.append("bug470377_4@tests.mozilla.org");
+  dest.create(Components.interfaces.nsIFile.DIRECTORY_TYPE, 0755);
+  source = do_get_file("data/test_bug470377/install_4.rdf");
+  source.copyTo(dest, "install.rdf");
+  dest = gProfD.clone();
+  dest.append("extensions");
+  dest.append("bug470377_5@tests.mozilla.org");
+  dest.create(Components.interfaces.nsIFile.DIRECTORY_TYPE, 0755);
+  source = do_get_file("data/test_bug470377/install_5.rdf");
+  source.copyTo(dest, "install.rdf");
+
+  startupEM();
+
+  do_check_neq(gEM.getItemForID("bug470377_1@tests.mozilla.org"), null);
+  do_check_eq(getManifestProperty("bug470377_1@tests.mozilla.org", "isDisabled"), "true");
+  do_check_neq(gEM.getItemForID("bug470377_2@tests.mozilla.org"), null);
+  do_check_eq(getManifestProperty("bug470377_2@tests.mozilla.org", "isDisabled"), "true");
+  do_check_neq(gEM.getItemForID("bug470377_3@tests.mozilla.org"), null);
+  do_check_eq(getManifestProperty("bug470377_3@tests.mozilla.org", "isDisabled"), "true");
+  do_check_neq(gEM.getItemForID("bug470377_4@tests.mozilla.org"), null);
+  do_check_eq(getManifestProperty("bug470377_4@tests.mozilla.org", "isDisabled"), "false");
+  do_check_neq(gEM.getItemForID("bug470377_5@tests.mozilla.org"), null);
+  do_check_eq(getManifestProperty("bug470377_5@tests.mozilla.org", "isDisabled"), "false");
+
+  // Disable compatibility checks
+  gPrefs.setBoolPref("extensions.checkCompatibility", false);
+  restartEM();
+
+  do_check_neq(gEM.getItemForID("bug470377_1@tests.mozilla.org"), null);
+  do_check_eq(getManifestProperty("bug470377_1@tests.mozilla.org", "isDisabled"), "true");
+  do_check_neq(gEM.getItemForID("bug470377_2@tests.mozilla.org"), null);
+  do_check_eq(getManifestProperty("bug470377_2@tests.mozilla.org", "isDisabled"), "false");
+  do_check_neq(gEM.getItemForID("bug470377_3@tests.mozilla.org"), null);
+  do_check_eq(getManifestProperty("bug470377_3@tests.mozilla.org", "isDisabled"), "false");
+  do_check_neq(gEM.getItemForID("bug470377_4@tests.mozilla.org"), null);
+  do_check_eq(getManifestProperty("bug470377_4@tests.mozilla.org", "isDisabled"), "false");
+  do_check_neq(gEM.getItemForID("bug470377_5@tests.mozilla.org"), null);
+  do_check_eq(getManifestProperty("bug470377_5@tests.mozilla.org", "isDisabled"), "false");
+}
new file mode 100644
--- /dev/null
+++ b/toolkit/mozapps/extensions/test/unit/test_bug470377_4.js
@@ -0,0 +1,103 @@
+/* ***** 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 mozilla.org code.
+ *
+ * The Initial Developer of the Original Code is
+ * Dave Townsend <dtownsend@oxymoronical.com>.
+ *
+ * Portions created by the Initial Developer are Copyright (C) 2009
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s):
+ *
+ * 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 *****
+ */
+
+function run_test() {
+  createAppInfo("xpcshell@tests.mozilla.org", "XPCShell", "2", "2");
+
+  // inject the add-ons into the profile
+  var dest = gProfD.clone();
+  dest.append("extensions");
+  dest.append("bug470377_1@tests.mozilla.org");
+  dest.create(Components.interfaces.nsIFile.DIRECTORY_TYPE, 0755);
+  var source = do_get_file("data/test_bug470377/install_1.rdf");
+  source.copyTo(dest, "install.rdf");
+  dest = gProfD.clone();
+  dest.append("extensions");
+  dest.append("bug470377_2@tests.mozilla.org");
+  dest.create(Components.interfaces.nsIFile.DIRECTORY_TYPE, 0755);
+  source = do_get_file("data/test_bug470377/install_2.rdf");
+  source.copyTo(dest, "install.rdf");
+  dest = gProfD.clone();
+  dest.append("extensions");
+  dest.append("bug470377_3@tests.mozilla.org");
+  dest.create(Components.interfaces.nsIFile.DIRECTORY_TYPE, 0755);
+  source = do_get_file("data/test_bug470377/install_3.rdf");
+  source.copyTo(dest, "install.rdf");
+  dest = gProfD.clone();
+  dest.append("extensions");
+  dest.append("bug470377_4@tests.mozilla.org");
+  dest.create(Components.interfaces.nsIFile.DIRECTORY_TYPE, 0755);
+  source = do_get_file("data/test_bug470377/install_4.rdf");
+  source.copyTo(dest, "install.rdf");
+  dest = gProfD.clone();
+  dest.append("extensions");
+  dest.append("bug470377_5@tests.mozilla.org");
+  dest.create(Components.interfaces.nsIFile.DIRECTORY_TYPE, 0755);
+  source = do_get_file("data/test_bug470377/install_5.rdf");
+  source.copyTo(dest, "install.rdf");
+
+  // Disable compatibility checks
+  gPrefs.setBoolPref("extensions.checkCompatibility", false);
+  startupEM();
+
+  do_check_neq(gEM.getItemForID("bug470377_1@tests.mozilla.org"), null);
+  do_check_eq(getManifestProperty("bug470377_1@tests.mozilla.org", "isDisabled"), "true");
+  do_check_neq(gEM.getItemForID("bug470377_2@tests.mozilla.org"), null);
+  do_check_eq(getManifestProperty("bug470377_2@tests.mozilla.org", "isDisabled"), "false");
+  do_check_neq(gEM.getItemForID("bug470377_3@tests.mozilla.org"), null);
+  do_check_eq(getManifestProperty("bug470377_3@tests.mozilla.org", "isDisabled"), "false");
+  do_check_neq(gEM.getItemForID("bug470377_4@tests.mozilla.org"), null);
+  do_check_eq(getManifestProperty("bug470377_4@tests.mozilla.org", "isDisabled"), "false");
+  do_check_neq(gEM.getItemForID("bug470377_5@tests.mozilla.org"), null);
+  do_check_eq(getManifestProperty("bug470377_5@tests.mozilla.org", "isDisabled"), "false");
+
+  // Enable compatibility checks
+  gPrefs.setBoolPref("extensions.checkCompatibility", true);
+  restartEM();
+
+  do_check_neq(gEM.getItemForID("bug470377_1@tests.mozilla.org"), null);
+  do_check_eq(getManifestProperty("bug470377_1@tests.mozilla.org", "isDisabled"), "true");
+  do_check_neq(gEM.getItemForID("bug470377_2@tests.mozilla.org"), null);
+  do_check_eq(getManifestProperty("bug470377_2@tests.mozilla.org", "isDisabled"), "true");
+  do_check_neq(gEM.getItemForID("bug470377_3@tests.mozilla.org"), null);
+  do_check_eq(getManifestProperty("bug470377_3@tests.mozilla.org", "isDisabled"), "true");
+  do_check_neq(gEM.getItemForID("bug470377_4@tests.mozilla.org"), null);
+  do_check_eq(getManifestProperty("bug470377_4@tests.mozilla.org", "isDisabled"), "false");
+  do_check_neq(gEM.getItemForID("bug470377_5@tests.mozilla.org"), null);
+  do_check_eq(getManifestProperty("bug470377_5@tests.mozilla.org", "isDisabled"), "false");
+}