зеркало из https://github.com/mozilla/gecko-dev.git
Bug 1324760 - Expose a function that clears plugin data in sanitize.js, r=mak
MozReview-Commit-ID: A8AxhyzyEwk --HG-- extra : rebase_source : 6c3c2c09fa011f36f38549d442bd6c85c880b281
This commit is contained in:
Родитель
9e010f1049
Коммит
526630bfba
|
@ -278,79 +278,16 @@ Sanitizer.prototype = {
|
|||
}
|
||||
|
||||
// Clear plugin data.
|
||||
// As evidenced in bug 1253204, clearing plugin data can sometimes be
|
||||
// very, very long, for mysterious reasons. Unfortunately, this is not
|
||||
// something actionable by Mozilla, so crashing here serves no purpose.
|
||||
//
|
||||
// For this reason, instead of waiting for sanitization to always
|
||||
// complete, we introduce a soft timeout. Once this timeout has
|
||||
// elapsed, we proceed with the shutdown of Firefox.
|
||||
let promiseClearPluginCookies;
|
||||
try {
|
||||
// We don't want to wait for this operation to complete...
|
||||
promiseClearPluginCookies = this.promiseClearPluginCookies(range);
|
||||
|
||||
// ... at least, not for more than 10 seconds.
|
||||
yield Promise.race([
|
||||
promiseClearPluginCookies,
|
||||
new Promise(resolve => setTimeout(resolve, 10000 /* 10 seconds */))
|
||||
]);
|
||||
yield Sanitizer.clearPluginData(range);
|
||||
} catch (ex) {
|
||||
seenException = ex;
|
||||
}
|
||||
|
||||
// Detach waiting for plugin cookies to be cleared.
|
||||
promiseClearPluginCookies.catch(() => {
|
||||
// If this exception is raised before the soft timeout, it
|
||||
// will appear in `seenException`. Otherwise, it's too late
|
||||
// to do anything about it.
|
||||
});
|
||||
|
||||
if (seenException) {
|
||||
throw seenException;
|
||||
}
|
||||
}),
|
||||
|
||||
promiseClearPluginCookies: Task.async(function* (range) {
|
||||
const FLAG_CLEAR_ALL = Ci.nsIPluginHost.FLAG_CLEAR_ALL;
|
||||
let ph = Cc["@mozilla.org/plugin/host;1"].getService(Ci.nsIPluginHost);
|
||||
|
||||
// Determine age range in seconds. (-1 means clear all.) We don't know
|
||||
// that range[1] is actually now, so we compute age range based
|
||||
// on the lower bound. If range results in a negative age, do nothing.
|
||||
let age = range ? (Date.now() / 1000 - range[0] / 1000000) : -1;
|
||||
if (!range || age >= 0) {
|
||||
let tags = ph.getPluginTags();
|
||||
for (let tag of tags) {
|
||||
let refObj = {};
|
||||
let probe = "";
|
||||
if (/\bFlash\b/.test(tag.name)) {
|
||||
probe = tag.loaded ? "FX_SANITIZE_LOADED_FLASH"
|
||||
: "FX_SANITIZE_UNLOADED_FLASH";
|
||||
TelemetryStopwatch.start(probe, refObj);
|
||||
}
|
||||
try {
|
||||
let rv = yield new Promise(resolve =>
|
||||
ph.clearSiteData(tag, null, FLAG_CLEAR_ALL, age, resolve)
|
||||
);
|
||||
// If the plugin doesn't support clearing by age, clear everything.
|
||||
if (rv == Components.results.NS_ERROR_PLUGIN_TIME_RANGE_NOT_SUPPORTED) {
|
||||
yield new Promise(resolve =>
|
||||
ph.clearSiteData(tag, null, FLAG_CLEAR_ALL, -1, resolve)
|
||||
);
|
||||
}
|
||||
if (probe) {
|
||||
TelemetryStopwatch.finish(probe, refObj);
|
||||
}
|
||||
} catch (ex) {
|
||||
// Ignore errors from plug-ins
|
||||
if (probe) {
|
||||
TelemetryStopwatch.cancel(probe, refObj);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
})
|
||||
},
|
||||
|
||||
offlineApps: {
|
||||
|
@ -705,6 +642,12 @@ Sanitizer.prototype = {
|
|||
yield promiseReady;
|
||||
})
|
||||
},
|
||||
|
||||
pluginData: {
|
||||
clear: Task.async(function* (range) {
|
||||
yield Sanitizer.clearPluginData(range);
|
||||
}),
|
||||
},
|
||||
}
|
||||
};
|
||||
|
||||
|
@ -774,6 +717,83 @@ Sanitizer.getClearRange = function(ts) {
|
|||
return [startDate, endDate];
|
||||
};
|
||||
|
||||
Sanitizer.clearPluginData = Task.async(function* (range) {
|
||||
// Clear plugin data.
|
||||
// As evidenced in bug 1253204, clearing plugin data can sometimes be
|
||||
// very, very long, for mysterious reasons. Unfortunately, this is not
|
||||
// something actionable by Mozilla, so crashing here serves no purpose.
|
||||
//
|
||||
// For this reason, instead of waiting for sanitization to always
|
||||
// complete, we introduce a soft timeout. Once this timeout has
|
||||
// elapsed, we proceed with the shutdown of Firefox.
|
||||
let seenException;
|
||||
|
||||
let promiseClearPluginData = Task.async(function* () {
|
||||
const FLAG_CLEAR_ALL = Ci.nsIPluginHost.FLAG_CLEAR_ALL;
|
||||
let ph = Cc["@mozilla.org/plugin/host;1"].getService(Ci.nsIPluginHost);
|
||||
|
||||
// Determine age range in seconds. (-1 means clear all.) We don't know
|
||||
// that range[1] is actually now, so we compute age range based
|
||||
// on the lower bound. If range results in a negative age, do nothing.
|
||||
let age = range ? (Date.now() / 1000 - range[0] / 1000000) : -1;
|
||||
if (!range || age >= 0) {
|
||||
let tags = ph.getPluginTags();
|
||||
for (let tag of tags) {
|
||||
let refObj = {};
|
||||
let probe = "";
|
||||
if (/\bFlash\b/.test(tag.name)) {
|
||||
probe = tag.loaded ? "FX_SANITIZE_LOADED_FLASH"
|
||||
: "FX_SANITIZE_UNLOADED_FLASH";
|
||||
TelemetryStopwatch.start(probe, refObj);
|
||||
}
|
||||
try {
|
||||
let rv = yield new Promise(resolve =>
|
||||
ph.clearSiteData(tag, null, FLAG_CLEAR_ALL, age, resolve)
|
||||
);
|
||||
// If the plugin doesn't support clearing by age, clear everything.
|
||||
if (rv == Components.results.NS_ERROR_PLUGIN_TIME_RANGE_NOT_SUPPORTED) {
|
||||
yield new Promise(resolve =>
|
||||
ph.clearSiteData(tag, null, FLAG_CLEAR_ALL, -1, resolve)
|
||||
);
|
||||
}
|
||||
if (probe) {
|
||||
TelemetryStopwatch.finish(probe, refObj);
|
||||
}
|
||||
} catch (ex) {
|
||||
// Ignore errors from plug-ins
|
||||
if (probe) {
|
||||
TelemetryStopwatch.cancel(probe, refObj);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
try {
|
||||
// We don't want to wait for this operation to complete...
|
||||
promiseClearPluginData = promiseClearPluginData(range);
|
||||
|
||||
// ... at least, not for more than 10 seconds.
|
||||
yield Promise.race([
|
||||
promiseClearPluginData,
|
||||
new Promise(resolve => setTimeout(resolve, 10000 /* 10 seconds */))
|
||||
]);
|
||||
} catch (ex) {
|
||||
seenException = ex;
|
||||
}
|
||||
|
||||
// Detach waiting for plugin data to be cleared.
|
||||
promiseClearPluginData.catch(() => {
|
||||
// If this exception is raised before the soft timeout, it
|
||||
// will appear in `seenException`. Otherwise, it's too late
|
||||
// to do anything about it.
|
||||
});
|
||||
|
||||
if (seenException) {
|
||||
throw seenException;
|
||||
}
|
||||
});
|
||||
|
||||
Sanitizer._prefs = null;
|
||||
Sanitizer.__defineGetter__("prefs", function()
|
||||
{
|
||||
|
|
|
@ -46,14 +46,14 @@ add_task(function* () {
|
|||
window.focus();
|
||||
gTestBrowser = null;
|
||||
});
|
||||
});
|
||||
|
||||
add_task(function* () {
|
||||
Services.prefs.setBoolPref("plugins.click_to_play", true);
|
||||
|
||||
setTestPluginEnabledState(Ci.nsIPluginTag.STATE_ENABLED, "Test Plug-in");
|
||||
setTestPluginEnabledState(Ci.nsIPluginTag.STATE_ENABLED, "Second Test Plug-in");
|
||||
});
|
||||
|
||||
function* setPrefs(cookies, pluginData) {
|
||||
sanitizer = new Sanitizer();
|
||||
sanitizer.ignoreTimespan = false;
|
||||
sanitizer.prefDomain = "privacy.cpd.";
|
||||
|
@ -61,67 +61,59 @@ add_task(function* () {
|
|||
itemPrefs.setBoolPref("history", false);
|
||||
itemPrefs.setBoolPref("downloads", false);
|
||||
itemPrefs.setBoolPref("cache", false);
|
||||
itemPrefs.setBoolPref("cookies", true); // plugin data
|
||||
itemPrefs.setBoolPref("cookies", cookies);
|
||||
itemPrefs.setBoolPref("formdata", false);
|
||||
itemPrefs.setBoolPref("offlineApps", false);
|
||||
itemPrefs.setBoolPref("passwords", false);
|
||||
itemPrefs.setBoolPref("sessions", false);
|
||||
itemPrefs.setBoolPref("siteSettings", false);
|
||||
});
|
||||
itemPrefs.setBoolPref("pluginData", pluginData);
|
||||
}
|
||||
|
||||
add_task(function* () {
|
||||
function* testClearingData(url) {
|
||||
// Load page to set data for the plugin.
|
||||
gBrowser.selectedTab = gBrowser.addTab();
|
||||
gTestBrowser = gBrowser.selectedBrowser;
|
||||
|
||||
yield promiseTabLoadEvent(gBrowser.selectedTab, testURL1);
|
||||
yield promiseTabLoadEvent(gBrowser.selectedTab, url);
|
||||
|
||||
yield promiseUpdatePluginBindings(gTestBrowser);
|
||||
|
||||
ok(stored(["foo.com", "bar.com", "baz.com", "qux.com"]),
|
||||
"Data stored for sites");
|
||||
|
||||
// Clear 20 seconds ago
|
||||
let now_uSec = Date.now() * 1000;
|
||||
sanitizer.range = [now_uSec - 20 * 1000000, now_uSec];
|
||||
yield sanitizer.sanitize();
|
||||
|
||||
ok(stored(["bar.com", "qux.com"]), "Data stored for sites");
|
||||
ok(!stored(["foo.com"]), "Data cleared for foo.com");
|
||||
ok(!stored(["baz.com"]), "Data cleared for baz.com");
|
||||
|
||||
// Clear everything
|
||||
sanitizer.range = null;
|
||||
yield sanitizer.sanitize();
|
||||
|
||||
ok(!stored(null), "All data cleared");
|
||||
|
||||
gBrowser.removeCurrentTab();
|
||||
gTestBrowser = null;
|
||||
});
|
||||
|
||||
add_task(function* () {
|
||||
// Load page to set data for the plugin.
|
||||
gBrowser.selectedTab = gBrowser.addTab();
|
||||
gTestBrowser = gBrowser.selectedBrowser;
|
||||
|
||||
yield promiseTabLoadEvent(gBrowser.selectedTab, testURL2);
|
||||
|
||||
yield promiseUpdatePluginBindings(gTestBrowser);
|
||||
|
||||
ok(stored(["foo.com", "bar.com", "baz.com", "qux.com"]),
|
||||
"Data stored for sites");
|
||||
|
||||
// Attempt to clear 20 seconds ago. The plugin will throw
|
||||
// Clear 20 seconds ago.
|
||||
// In the case of testURL2 the plugin will throw
|
||||
// NS_ERROR_PLUGIN_TIME_RANGE_NOT_SUPPORTED, which should result in us
|
||||
// clearing all data regardless of age.
|
||||
let now_uSec = Date.now() * 1000;
|
||||
sanitizer.range = [now_uSec - 20 * 1000000, now_uSec];
|
||||
yield sanitizer.sanitize();
|
||||
|
||||
if (url == testURL1) {
|
||||
ok(stored(["bar.com", "qux.com"]), "Data stored for sites");
|
||||
ok(!stored(["foo.com"]), "Data cleared for foo.com");
|
||||
ok(!stored(["baz.com"]), "Data cleared for baz.com");
|
||||
|
||||
// Clear everything.
|
||||
sanitizer.range = null;
|
||||
yield sanitizer.sanitize();
|
||||
}
|
||||
|
||||
ok(!stored(null), "All data cleared");
|
||||
|
||||
gBrowser.removeCurrentTab();
|
||||
gTestBrowser = null;
|
||||
});
|
||||
}
|
||||
|
||||
add_task(function* () {
|
||||
// Test when santizing cookies.
|
||||
yield setPrefs(true, false);
|
||||
yield testClearingData(testURL1);
|
||||
yield testClearingData(testURL2);
|
||||
|
||||
// Test when santizing pluginData.
|
||||
yield setPrefs(false, true);
|
||||
yield testClearingData(testURL1);
|
||||
yield testClearingData(testURL2);
|
||||
});
|
||||
|
|
Загрузка…
Ссылка в новой задаче