Bug 1286785 - treat a corrupt addons.json as though it was missing. r?rhelmer draft
authorMark Hammond <mhammond@skippinet.com.au>
Mon, 18 Jul 2016 09:55:00 +1000
changeset 388794 fa13b530e96a5590c66096e92792a330382fa712
parent 387451 31cab0ba8bbf1d88b08abeae45bcdf317645355a
child 525600 6e37e014983427442f0c39b324e779028fe93241
push id23235
push userbmo:markh@mozilla.com
push dateMon, 18 Jul 2016 00:04:21 +0000
reviewersrhelmer
bugs1286785
milestone50.0a1
Bug 1286785 - treat a corrupt addons.json as though it was missing. r?rhelmer MozReview-Commit-ID: 3CmGaQ2MxPg
toolkit/mozapps/extensions/internal/AddonRepository.jsm
--- a/toolkit/mozapps/extensions/internal/AddonRepository.jsm
+++ b/toolkit/mozapps/extensions/internal/AddonRepository.jsm
@@ -474,23 +474,16 @@ AddonSearchResult.prototype = {
  * that are compatible with the current application and are not already
  * installed.
  */
 this.AddonRepository = {
   /**
    * Whether caching is currently enabled
    */
   get cacheEnabled() {
-    // Act as though caching is disabled if there was an unrecoverable error
-    // openning the database.
-    if (!AddonDatabase.databaseOk) {
-      logger.warn("Cache is disabled because database is not OK");
-      return false;
-    }
-
     let preference = PREF_GETADDONS_CACHE_ENABLED;
     let enabled = false;
     try {
       enabled = Services.prefs.getBoolPref(preference);
     } catch(e) {
       logger.warn("cacheEnabled: Couldn't get pref: " + preference);
     }
 
@@ -1556,19 +1549,16 @@ this.AddonRepository = {
   },
 
   flush: function() {
     return AddonDatabase.flush();
   }
 };
 
 var AddonDatabase = {
-  // false if there was an unrecoverable error opening the database
-  databaseOk: true,
-
   connectionPromise: null,
   // the in-memory database
   DB: BLANK_DB(),
 
   /**
    * A getter to retrieve the path to the DB
    */
   get jsonFile() {
@@ -1604,41 +1594,40 @@ var AddonDatabase = {
 
          if (!Number.isInteger(schema) ||
              schema < DB_MIN_JSON_SCHEMA) {
            throw new Error("Invalid schema value.");
          }
        } catch (e) {
          if (e instanceof OS.File.Error && e.becauseNoSuchFile) {
            logger.debug("No " + FILE_DATABASE + " found.");
-
-           // Create a blank addons.json file
-           this._saveDBToDisk();
+         } else {
+           logger.error(`Malformed ${FILE_DATABASE}: ${e} - resetting to empty`);
+         }
 
-           let dbSchema = 0;
-           try {
-             dbSchema = Services.prefs.getIntPref(PREF_GETADDONS_DB_SCHEMA);
-           } catch (e) {}
+         // Create a blank addons.json file
+         this._saveDBToDisk();
 
-           if (dbSchema < DB_MIN_JSON_SCHEMA) {
-             let results = yield new Promise((resolve, reject) => {
-               AddonRepository_SQLiteMigrator.migrate(resolve);
-             });
+         let dbSchema = 0;
+         try {
+           dbSchema = Services.prefs.getIntPref(PREF_GETADDONS_DB_SCHEMA);
+         } catch (e) {}
 
-             if (results.length) {
-               yield this._insertAddons(results);
-             }
+         if (dbSchema < DB_MIN_JSON_SCHEMA) {
+           let results = yield new Promise((resolve, reject) => {
+             AddonRepository_SQLiteMigrator.migrate(resolve);
+           });
 
+           if (results.length) {
+             yield this._insertAddons(results);
            }
 
-           Services.prefs.setIntPref(PREF_GETADDONS_DB_SCHEMA, DB_SCHEMA);
-         } else {
-           logger.error("Malformed " + FILE_DATABASE + ": " + e);
-           this.databaseOk = false;
          }
+
+         Services.prefs.setIntPref(PREF_GETADDONS_DB_SCHEMA, DB_SCHEMA);
          return this.DB;
        }
 
        Services.prefs.setIntPref(PREF_GETADDONS_DB_SCHEMA, DB_SCHEMA);
 
        // We use _insertAddon manually instead of calling
        // insertAddons to avoid the write to disk which would
        // be a waste since this is the data that was just read.
@@ -1666,18 +1655,16 @@ var AddonDatabase = {
    *
    * @param  aCallback
    *         An optional callback to call once complete
    * @param  aSkipFlush
    *         An optional boolean to skip flushing data to disk. Useful
    *         when the database is going to be deleted afterwards.
    */
   shutdown: function(aSkipFlush) {
-    this.databaseOk = true;
-
     if (!this.connectionPromise) {
       return Promise.resolve();
     }
 
     this.connectionPromise = null;
 
     if (aSkipFlush) {
       return Promise.resolve();