mirror of
https://github.com/mozilla/gecko-dev.git
synced 2024-10-14 22:05:44 +00:00
Bug 284086: "Sanitize on shutdown" fails if the last closed window is not a browser window, patch by Giorgio Maone <g.maone@informaction.com>, r=mconnor
This commit is contained in:
parent
bb1236dbc0
commit
a3d66492fa
@ -19,6 +19,7 @@
|
||||
#
|
||||
# Contributor(s):
|
||||
# Ben Goodger <ben@mozilla.org>
|
||||
# Giorgio Maone <g.maone@informaction.com>
|
||||
#
|
||||
# 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
|
||||
@ -36,6 +37,7 @@
|
||||
|
||||
function Sanitizer() {}
|
||||
Sanitizer.prototype = {
|
||||
// warning to the caller: this one may raise an exception (e.g. bug #265028)
|
||||
clearItem: function (aItemName)
|
||||
{
|
||||
if (this.items[aItemName].canClear)
|
||||
@ -53,26 +55,90 @@ Sanitizer.prototype = {
|
||||
return aPreferenceName.substr(this._prefDomain.length);
|
||||
},
|
||||
|
||||
/**
|
||||
* Deletes privacy sensitive data in a batch, according to user preferences
|
||||
*
|
||||
* @returns null if everything's fine; an object in the form
|
||||
* { itemName: error, ... } on (partial) failure
|
||||
*/
|
||||
sanitize: function ()
|
||||
{
|
||||
var psvc = Components.classes["@mozilla.org/preferences-service;1"]
|
||||
.getService(Components.interfaces.nsIPrefService);
|
||||
var branch = psvc.getBranch(this._prefDomain);
|
||||
var errors = null;
|
||||
for (var itemName in this.items) {
|
||||
var item = this.items[itemName];
|
||||
if ("clear" in item && item.canClear && branch.getBoolPref(itemName))
|
||||
item.clear();
|
||||
if ("clear" in item && item.canClear && branch.getBoolPref(itemName)) {
|
||||
// Some of these clear() may raise exceptions (see bug #265028)
|
||||
// to sanitize as much as possible, we catch and store them,
|
||||
// rather than fail fast.
|
||||
// Callers should check returned errors and give user feedback
|
||||
// about items that could not be sanitized
|
||||
try {
|
||||
item.clear();
|
||||
} catch(er) {
|
||||
if (!errors)
|
||||
errors = {};
|
||||
errors[itemName] = er;
|
||||
dump("Error sanitizing " + itemName + ": " + er + "\n");
|
||||
}
|
||||
}
|
||||
}
|
||||
return errors;
|
||||
},
|
||||
|
||||
items: {
|
||||
cache: {
|
||||
clear: function ()
|
||||
{
|
||||
var cacheService = Components.classes["@mozilla.org/network/cache-service;1"]
|
||||
.getService(Components.interfaces.nsICacheService);
|
||||
cacheService.evictEntries(Components.interfaces.nsICache.STORE_ON_DISK);
|
||||
cacheService.evictEntries(Components.interfaces.nsICache.STORE_IN_MEMORY);
|
||||
const cc = Components.classes;
|
||||
const ci = Components.interfaces;
|
||||
var cacheService = cc["@mozilla.org/network/cache-service;1"]
|
||||
.getService(ci.nsICacheService);
|
||||
|
||||
// Here we play dirty, trying to brutally wipe out all the cache files
|
||||
// even if the disk cache device has gone away (if it is still with us,
|
||||
// our removal attempt will fail because the directory is locked,
|
||||
// and we fall back to the "nice" way below)
|
||||
|
||||
var cacheDir;
|
||||
// Look at nsCacheProfilePrefObserver::ReadPrefs()
|
||||
// and nsDiskCacheDevice::SetCacheParentDirectory()
|
||||
// for details on how we guess the cache directory
|
||||
try {
|
||||
cacheDir = cc["@mozilla.org/preferences-service;1"]
|
||||
.getService(ci.nsIBranch)
|
||||
.getComplexValue("browser.cache.disk.parent_directory",
|
||||
ci.nsILocalFile);
|
||||
} catch(er) {
|
||||
const dirServ = cc["@mozilla.org/file/directory_service;1"]
|
||||
.getService(ci.nsIProperties);
|
||||
try {
|
||||
cacheDir = dirServ.get("cachePDir",ci.nsILocalFile);
|
||||
} catch(er) {
|
||||
cacheDir = dirServ.get("ProfLD",ci.nsILocalFile);
|
||||
}
|
||||
}
|
||||
|
||||
if (cacheDir) {
|
||||
// Here we try to prevent the "phantom Cache.Trash" issue
|
||||
// reported in bug #296256
|
||||
cacheDir.append("Cache.Trash");
|
||||
try {
|
||||
cacheDir.remove(true);
|
||||
} catch(er) {}
|
||||
cacheDir = cacheDir.parent;
|
||||
cacheDir.append("Cache");
|
||||
try {
|
||||
cacheDir.remove(true);
|
||||
} catch(er) {}
|
||||
}
|
||||
|
||||
// The "nice" way
|
||||
cacheService.evictEntries(ci.nsICache.STORE_ON_DISK);
|
||||
cacheService.evictEntries(ci.nsICache.STORE_IN_MEMORY);
|
||||
|
||||
},
|
||||
|
||||
get canClear()
|
||||
@ -88,8 +154,9 @@ Sanitizer.prototype = {
|
||||
.getService(Components.interfaces.nsICookieManager);
|
||||
var e = cookieMgr.enumerator;
|
||||
var cookies = [];
|
||||
var cookie;
|
||||
while (e.hasMoreElements()) {
|
||||
var cookie = e.getNext().QueryInterface(Components.interfaces.nsICookie);
|
||||
cookie = e.getNext().QueryInterface(Components.interfaces.nsICookie);
|
||||
cookies.push(cookie);
|
||||
}
|
||||
|
||||
@ -113,7 +180,8 @@ Sanitizer.prototype = {
|
||||
globalHistory.removeAllPages();
|
||||
|
||||
try {
|
||||
var os = Components.classes["@mozilla.org/observer-service;1"].getService(Components.interfaces.nsIObserverService);
|
||||
var os = Components.classes["@mozilla.org/observer-service;1"]
|
||||
.getService(Components.interfaces.nsIObserverService);
|
||||
os.notifyObservers(null, "browser:purge-session-history", "");
|
||||
}
|
||||
catch (e) { }
|
||||
@ -205,3 +273,74 @@ Sanitizer.prototype = {
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
|
||||
// "Static" members
|
||||
Sanitizer.prefDomain = "privacy.sanitize.";
|
||||
Sanitizer.prefPrompt = "promptOnSanitize";
|
||||
Sanitizer.prefShutdown = "sanitizeOnShutdown";
|
||||
Sanitizer.prefDidShutdown = "didShutdownSanitize";
|
||||
|
||||
Sanitizer._prefs = null;
|
||||
Sanitizer.__defineGetter__("prefs", function()
|
||||
{
|
||||
return Sanitizer._prefs ? Sanitizer._prefs
|
||||
: Sanitizer._prefs = Components.classes["@mozilla.org/preferences-service;1"]
|
||||
.getService(Components.interfaces.nsIPrefService)
|
||||
.getBranch(Sanitizer.prefDomain);
|
||||
});
|
||||
|
||||
// Shows sanitization UI
|
||||
Sanitizer.showUI = function(aParentWindow)
|
||||
{
|
||||
var ww = Components.classes["@mozilla.org/embedcomp/window-watcher;1"]
|
||||
.getService(Components.interfaces.nsIWindowWatcher);
|
||||
ww.openWindow(aParentWindow,
|
||||
"chrome://browser/content/sanitize.xul",
|
||||
"Sanitize",
|
||||
"chrome,titlebar,centerscreen,modal",
|
||||
null);
|
||||
};
|
||||
|
||||
/**
|
||||
* Deletes privacy sensitive data in a batch, optionally showing the
|
||||
* sanitize UI, according to user preferences
|
||||
*
|
||||
* @returns null if everything's fine (no error or displayed UI, which
|
||||
* should handle errors);
|
||||
* an object in the form { itemName: error, ... } on (partial) failure
|
||||
*/
|
||||
Sanitizer.sanitize = function(aParentWindow)
|
||||
{
|
||||
if (Sanitizer.prefs.getBoolPref(Sanitizer.prefPrompt)) {
|
||||
Sanitizer.showUI(aParentWindow);
|
||||
return null;
|
||||
}
|
||||
return new Sanitizer().sanitize();
|
||||
};
|
||||
|
||||
Sanitizer.onStartup = function()
|
||||
{
|
||||
// we check for unclean exit with pending sanitization
|
||||
Sanitizer._checkAndSanitize();
|
||||
};
|
||||
|
||||
Sanitizer.onShutdown = function()
|
||||
{
|
||||
// we check if sanitization is needed and perform it
|
||||
Sanitizer._checkAndSanitize();
|
||||
};
|
||||
|
||||
// this is called on startup and shutdown, to perform pending sanitizations
|
||||
Sanitizer._checkAndSanitize = function()
|
||||
{
|
||||
const prefs = Sanitizer.prefs;
|
||||
if (prefs.getBoolPref(Sanitizer.prefShutdown) &&
|
||||
!prefs.prefHasUserValue(Sanitizer.prefDidShutdown)) {
|
||||
// this is a shutdown or a startup after an unclean exit
|
||||
Sanitizer.sanitize(null) || // sanitize() returns null on full success
|
||||
prefs.setBoolPref(Sanitizer.prefDidShutdown, true);
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user