Backed out changeset 6c93b2419ee5 (bug 1649606) for causing xpcshell failures on test_corrupt.js. CLOSED TREE
authorCosmin Sabou <csabou@mozilla.com>
Wed, 07 Apr 2021 03:50:00 +0300
changeset 574670 e06c2941cdfc56de10e6b4fdd0ddfaff800e6b56
parent 574669 6c261a59cd920c54119820cf627ec0d07a932b7d
child 574671 b25b1aaa1ed0b9c2eb095bbed173552fcb85ab54
push id140298
push usercsabou@mozilla.com
push dateWed, 07 Apr 2021 00:50:25 +0000
treeherderautoland@e06c2941cdfc [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
bugs1649606
milestone89.0a1
backs out6c93b2419ee50246d8f81ad30419d35289491cd9
first release with
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
last release without
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
Backed out changeset 6c93b2419ee5 (bug 1649606) for causing xpcshell failures on test_corrupt.js. CLOSED TREE
toolkit/mozapps/extensions/internal/XPIDatabase.jsm
--- a/toolkit/mozapps/extensions/internal/XPIDatabase.jsm
+++ b/toolkit/mozapps/extensions/internal/XPIDatabase.jsm
@@ -23,16 +23,17 @@ const { XPCOMUtils } = ChromeUtils.impor
 XPCOMUtils.defineLazyModuleGetters(this, {
   AddonManager: "resource://gre/modules/AddonManager.jsm",
   AddonManagerPrivate: "resource://gre/modules/AddonManager.jsm",
   AddonRepository: "resource://gre/modules/addons/AddonRepository.jsm",
   AddonSettings: "resource://gre/modules/addons/AddonSettings.jsm",
   DeferredTask: "resource://gre/modules/DeferredTask.jsm",
   ExtensionUtils: "resource://gre/modules/ExtensionUtils.jsm",
   FileUtils: "resource://gre/modules/FileUtils.jsm",
+  OS: "resource://gre/modules/osfile.jsm",
   PermissionsUtils: "resource://gre/modules/PermissionsUtils.jsm",
   Services: "resource://gre/modules/Services.jsm",
 
   Blocklist: "resource://gre/modules/Blocklist.jsm",
   UpdateChecker: "resource://gre/modules/addons/XPIInstall.jsm",
   XPIInstall: "resource://gre/modules/addons/XPIInstall.jsm",
   XPIInternal: "resource://gre/modules/addons/XPIProvider.jsm",
   XPIProvider: "resource://gre/modules/addons/XPIProvider.jsm",
@@ -1545,18 +1546,19 @@ this.XPIDatabase = {
     if (this._saveError) {
       return this._saveError;
     }
     return null;
   },
 
   async _saveNow() {
     try {
+      let json = JSON.stringify(this);
       let path = this.jsonFile.path;
-      await IOUtils.writeJSON(path, this, { tmpPath: `${path}.tmp` });
+      await OS.File.writeAtomic(path, json, { tmpPath: `${path}.tmp` });
 
       if (!this._schemaVersionSet) {
         // Update the XPIDB schema version preference the first time we
         // successfully save the database.
         logger.debug(
           "XPI Database saved, setting schema version preference to " +
             DB_SCHEMA
         );
@@ -1564,20 +1566,17 @@ this.XPIDatabase = {
         this._schemaVersionSet = true;
 
         // Reading the DB worked once, so we don't need the load error
         this._loadError = null;
       }
     } catch (error) {
       logger.warn("Failed to save XPI database", error);
       this._saveError = error;
-
-      if (!(error instanceof DOMException) || error.name !== "AbortError") {
-        throw error;
-      }
+      throw error;
     }
   },
 
   /**
    * Mark the current stored data dirty, and schedule a flush to disk
    */
   saveChanges() {
     if (!this.initialized) {
@@ -1661,54 +1660,53 @@ this.XPIDatabase = {
 
   _recordStartupError(reason) {
     AddonManagerPrivate.recordSimpleMeasure("XPIDB_startupError", reason);
   },
 
   /**
    * Parse loaded data, reconstructing the database if the loaded data is not valid
    *
-   * @param {object} aInputAddons
-   *        The add-on JSON to parse.
+   * @param {string} aData
+   *        The stringified add-on JSON to parse.
    * @param {boolean} aRebuildOnError
    *        If true, synchronously reconstruct the database from installed add-ons
    */
-  async parseDB(aInputAddons, aRebuildOnError) {
+  async parseDB(aData, aRebuildOnError) {
     try {
       let parseTimer = AddonManagerPrivate.simpleTimer("XPIDB_parseDB_MS");
-
-      if (!("schemaVersion" in aInputAddons) || !("addons" in aInputAddons)) {
+      let inputAddons = JSON.parse(aData);
+
+      if (!("schemaVersion" in inputAddons) || !("addons" in inputAddons)) {
         let error = new Error("Bad JSON file contents");
         error.rebuildReason = "XPIDB_rebuildBadJSON_MS";
         throw error;
       }
 
-      if (aInputAddons.schemaVersion <= 27) {
+      if (inputAddons.schemaVersion <= 27) {
         // Types were translated in bug 857456.
-        for (let addon of aInputAddons.addons) {
+        for (let addon of inputAddons.addons) {
           migrateAddonLoader(addon);
         }
-      } else if (aInputAddons.schemaVersion != DB_SCHEMA) {
+      } else if (inputAddons.schemaVersion != DB_SCHEMA) {
         // For now, we assume compatibility for JSON data with a
         // mismatched schema version, though we throw away any fields we
         // don't know about (bug 902956)
-        this._recordStartupError(
-          `schemaMismatch-${aInputAddons.schemaVersion}`
-        );
+        this._recordStartupError(`schemaMismatch-${inputAddons.schemaVersion}`);
         logger.debug(
-          `JSON schema mismatch: expected ${DB_SCHEMA}, actual ${aInputAddons.schemaVersion}`
+          `JSON schema mismatch: expected ${DB_SCHEMA}, actual ${inputAddons.schemaVersion}`
         );
       }
 
       let forEach = this.syncLoadingDB ? arrayForEach : idleForEach;
 
       // If we got here, we probably have good data
       // Make AddonInternal instances from the loaded data and save them
       let addonDB = new Map();
-      await forEach(aInputAddons.addons, loadedAddon => {
+      await forEach(inputAddons.addons, loadedAddon => {
         if (loadedAddon.path) {
           try {
             loadedAddon._sourceBundle = new nsIFile(loadedAddon.path);
           } catch (e) {
             // We can fail here when the path is invalid, usually from the
             // wrong OS
             logger.warn(
               "Could not find source bundle for add-on " + loadedAddon.id,
@@ -1769,23 +1767,26 @@ this.XPIDatabase = {
     // Already started (and possibly finished) loading
     if (this._dbPromise) {
       return this._dbPromise;
     }
 
     logger.debug(`Starting async load of XPI database ${this.jsonFile.path}`);
     this._dbPromise = (async () => {
       try {
-        let json = await IOUtils.readJSON(this.jsonFile.path);
+        let byteArray = await OS.File.read(this.jsonFile.path, null);
 
         logger.debug("Finished async read of XPI database, parsing...");
         await this.maybeIdleDispatch();
-        await this.parseDB(json, true);
+        let text = new TextDecoder().decode(byteArray);
+
+        await this.maybeIdleDispatch();
+        await this.parseDB(text, true);
       } catch (error) {
-        if (error instanceof DOMException && error.name === "NotFoundError") {
+        if (error.becauseNoSuchFile) {
           if (Services.prefs.getIntPref(PREF_DB_SCHEMA, 0)) {
             this._recordStartupError("dbMissing");
           }
         } else {
           logger.warn(
             `Extensions database ${this.jsonFile.path} exists but is not readable; rebuilding`,
             error
           );