Bug 1249786 - Sanitize on startup prefs are broken. r=yoric
MozReview-Commit-ID: LDmK7G1BhGP
--- a/browser/base/content/sanitize.js
+++ b/browser/base/content/sanitize.js
@@ -672,20 +672,28 @@ Sanitizer.prototype = {
}
newWindow.focus();
yield promiseReady;
})
},
}
};
-// "Static" members
+// The preferences branch for the sanitizer.
Sanitizer.PREF_DOMAIN = "privacy.sanitize.";
+// Whether we should sanitize on shutdown.
Sanitizer.PREF_SANITIZE_ON_SHUTDOWN = "privacy.sanitize.sanitizeOnShutdown";
+// During a sanitization this is set to a json containing the array of items
+// being sanitized, then cleared once the sanitization is complete.
+// This allows to retry a sanitization on startup in case it was interrupted
+// by a crash.
Sanitizer.PREF_SANITIZE_IN_PROGRESS = "privacy.sanitize.sanitizeInProgress";
+// Whether the previous shutdown sanitization completed successfully.
+// Note that PREF_SANITIZE_IN_PROGRESS would be enough to detect an interrupted
+// sanitization, but this is still supported for backwards compatibility.
Sanitizer.PREF_SANITIZE_DID_SHUTDOWN = "privacy.sanitize.didShutdownSanitize";
// Time span constants corresponding to values of the privacy.sanitize.timeSpan
// pref. Used to determine how much history to clear, for various items
Sanitizer.TIMESPAN_EVERYTHING = 0;
Sanitizer.TIMESPAN_HOUR = 1;
Sanitizer.TIMESPAN_2HOURS = 2;
Sanitizer.TIMESPAN_4HOURS = 3;
@@ -761,16 +769,26 @@ Sanitizer.showUI = function(aParentWindo
* sanitize UI, according to user preferences
*/
Sanitizer.sanitize = function(aParentWindow)
{
Sanitizer.showUI(aParentWindow);
};
Sanitizer.onStartup = Task.async(function*() {
+ // Check if we were interrupted during the last shutdown sanitization.
+ let shutownSanitizationWasInterrupted =
+ Preferences.get(Sanitizer.PREF_SANITIZE_ON_SHUTDOWN, false) &&
+ !Preferences.has(Sanitizer.PREF_SANITIZE_DID_SHUTDOWN);
+ // Regardless, reset the pref, since we will check it again at the next start.
+ Preferences.reset(Sanitizer.PREF_SANITIZE_DID_SHUTDOWN);
+ // Ensure the pref is stored, if we crash during this sanitization we may
+ // enter a never ending crash loop.
+ Services.prefs.savePrefFile(null);
+
// Make sure that we are triggered during shutdown, at the right time,
// and only once.
let placesClient = Cc["@mozilla.org/browser/nav-history-service;1"]
.getService(Ci.nsPIPlacesDatabase)
.shutdownClient
.jsclient;
let deferredSanitization = PromiseUtils.defer();
@@ -781,34 +799,38 @@ Sanitizer.onStartup = Task.async(functio
Sanitizer.onShutdown().catch(er => {Promise.reject(er) /* Do not return rejected promise */;}).then(() =>
deferredSanitization.resolve()
);
}
return deferredSanitization.promise;
}
placesClient.addBlocker("sanitize.js: Sanitize on shutdown", doSanitize);
- // Handle incomplete sanitizations
- if (Preferences.has(Sanitizer.PREF_SANITIZE_IN_PROGRESS)) {
- // Firefox crashed during sanitization.
+ // Check if Firefox crashed before completing a sanitization.
+ let lastInterruptedSanitization = Preferences.get(Sanitizer.PREF_SANITIZE_IN_PROGRESS, "");
+ if (lastInterruptedSanitization) {
let s = new Sanitizer();
- let json = Preferences.get(Sanitizer.PREF_SANITIZE_IN_PROGRESS);
- let itemsToClear = JSON.parse(json);
+ // If the json is invalid this will just throw and reject the Task.
+ let itemsToClear = JSON.parse(lastInterruptedSanitization);
yield s.sanitize(itemsToClear);
- }
- if (Preferences.has(Sanitizer.PREF_SANITIZE_DID_SHUTDOWN)) {
- // Firefox crashed before having a chance to sanitize during shutdown.
- // (note that if Firefox crashed during shutdown sanitization, we
- // will hit both `if` so we will run a second double-sanitization).
+ } else if (shutownSanitizationWasInterrupted) {
+ // Ideally lastInterruptedSanitization should always be set when a
+ // sanitization is interrupted, but some add-ons or Firefox previous
+ // versions may not set the pref.
+ // In such a case, we can still detect an interrupted shutdown sanitization,
+ // and just redo it.
yield Sanitizer.onShutdown();
}
});
Sanitizer.onShutdown = Task.async(function*() {
if (!Preferences.get(Sanitizer.PREF_SANITIZE_ON_SHUTDOWN)) {
return;
}
// Need to sanitize upon shutdown
let s = new Sanitizer();
s.prefDomain = "privacy.clearOnShutdown.";
yield s.sanitize();
+ // We didn't crash during shutdown sanitization, so annotate it to avoid
+ // sanitizing again on startup.
Preferences.set(Sanitizer.PREF_SANITIZE_DID_SHUTDOWN, true);
+ Services.prefs.savePrefFile(null);
});