зеркало из https://github.com/mozilla/gecko-dev.git
Back out 2 changesets (bug 1238183) for leaks from browser_forgetaboutsite.js
Backed out changeset 1207df32d737 (bug 1238183) Backed out changeset 663a083774f4 (bug 1238183)
This commit is contained in:
Родитель
0a5cac2ffc
Коммит
38f200f8da
|
@ -4,13 +4,11 @@ support-files =
|
|||
empty_file.html
|
||||
file_reflect_cookie_into_title.html
|
||||
favicon-normal32.png
|
||||
file_set_storages.html
|
||||
serviceworker.html
|
||||
worker.js
|
||||
|
||||
[browser_aboutURLs.js]
|
||||
[browser_favicon.js]
|
||||
[browser_forgetaboutsite.js]
|
||||
[browser_usercontext.js]
|
||||
[browser_usercontextid_tabdrop.js]
|
||||
skip-if = os == "mac" || os == "win" # Intermittent failure - bug 1268276
|
||||
|
|
|
@ -1,353 +0,0 @@
|
|||
/*
|
||||
* Bug 1238183 - Test cases for forgetAboutSite with userContextId.
|
||||
*/
|
||||
|
||||
const { classes: Cc, Constructor: CC, interfaces: Ci, utils: Cu } = Components;
|
||||
|
||||
Cu.import("resource://gre/modules/ForgetAboutSite.jsm");
|
||||
Cu.import("resource://gre/modules/Services.jsm");
|
||||
let {HttpServer} = Cu.import("resource://testing-common/httpd.js", {});
|
||||
let LoadContextInfo = Cc["@mozilla.org/load-context-info-factory;1"]
|
||||
.getService(Ci.nsILoadContextInfoFactory);
|
||||
let css = Cc["@mozilla.org/netwerk/cache-storage-service;1"]
|
||||
.getService(Ci.nsICacheStorageService);
|
||||
|
||||
const USER_CONTEXTS = [
|
||||
"default",
|
||||
"personal",
|
||||
"work",
|
||||
];
|
||||
const TEST_HOST = "example.com";
|
||||
const TEST_URL = "http://" + TEST_HOST + "/browser/browser/components/contextualidentity/test/browser/";
|
||||
const COOKIE_NAME = "userContextId";
|
||||
|
||||
// Counter for image load hits.
|
||||
let gHits = 0;
|
||||
|
||||
let gHttpServer = null;
|
||||
|
||||
function imageHandler(metadata, response) {
|
||||
// A 1x1 PNG image.
|
||||
// Source: https://commons.wikimedia.org/wiki/File:1x1.png (Public Domain)
|
||||
const IMAGE = atob("iVBORw0KGgoAAAANSUhEUgAAAAEAAAABAQMAAAAl21bKAAAAA1BMVEUAA" +
|
||||
"ACnej3aAAAAAXRSTlMAQObYZgAAAApJREFUCNdjYAAAAAIAAeIhvDMAAAAASUVORK5CYII=");
|
||||
gHits++;
|
||||
response.setHeader("Cache-Control", "max-age=10000", false);
|
||||
response.setStatusLine(metadata.httpVersion, 200, "OK");
|
||||
response.setHeader("Content-Type", "image/png", false);
|
||||
response.write(IMAGE);
|
||||
}
|
||||
|
||||
function loadImagePageHandler(metadata, response) {
|
||||
response.setHeader("Cache-Control", "max-age=10000", false);
|
||||
response.setStatusLine(metadata.httpVersion, 200, "Ok");
|
||||
response.setHeader("Content-Type", "text/html", false);
|
||||
let body = "<!DOCTYPE HTML>\
|
||||
<html>\
|
||||
<head>\
|
||||
<meta charset='utf-8'>\
|
||||
<title>Load Image</title>\
|
||||
</head>\
|
||||
<body>\
|
||||
<img src='image.png'>\
|
||||
</body>\
|
||||
</html>";
|
||||
response.bodyOutputStream.write(body, body.length);
|
||||
}
|
||||
|
||||
function* openTabInUserContext(uri, userContextId) {
|
||||
// Open the tab in the correct userContextId.
|
||||
let tab = gBrowser.addTab(uri, {userContextId});
|
||||
|
||||
// Select tab and make sure its browser is focused.
|
||||
gBrowser.selectedTab = tab;
|
||||
tab.ownerDocument.defaultView.focus();
|
||||
|
||||
let browser = gBrowser.getBrowserForTab(tab);
|
||||
yield BrowserTestUtils.browserLoaded(browser);
|
||||
return {tab, browser};
|
||||
}
|
||||
|
||||
function getCookiesForOA(host, userContextId) {
|
||||
return Services.cookies.getCookiesFromHost(host, {userContextId});
|
||||
}
|
||||
|
||||
function createURI(uri)
|
||||
{
|
||||
let ioServ = Cc["@mozilla.org/network/io-service;1"]
|
||||
.getService(Components.interfaces.nsIIOService);
|
||||
return ioServ.newURI(uri, null, null);
|
||||
}
|
||||
|
||||
function getCacheStorage(where, lci, appcache)
|
||||
{
|
||||
if (!lci) lci = LoadContextInfo.default;
|
||||
switch (where) {
|
||||
case "disk": return css.diskCacheStorage(lci, false);
|
||||
case "memory": return css.memoryCacheStorage(lci);
|
||||
case "appcache": return css.appCacheStorage(lci, appcache);
|
||||
case "pin": return css.pinningCacheStorage(lci);
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
function OpenCacheEntry(key, where, flags, lci)
|
||||
{
|
||||
return new Promise(resolve => {
|
||||
key = createURI(key);
|
||||
function CacheListener() { }
|
||||
CacheListener.prototype = {
|
||||
_appCache: null,
|
||||
|
||||
QueryInterface: function (iid) {
|
||||
if (iid.equals(Components.interfaces.nsICacheEntryOpenCallback) ||
|
||||
iid.equals(Components.interfaces.nsISupports))
|
||||
return this;
|
||||
throw Components.results.NS_ERROR_NO_INTERFACE;
|
||||
},
|
||||
|
||||
onCacheEntryCheck: function(entry, appCache) {
|
||||
return Ci.nsICacheEntryOpenCallback.ENTRY_WANTED;
|
||||
},
|
||||
|
||||
onCacheEntryAvailable: function (entry, isnew, appCache, status) {
|
||||
resolve();
|
||||
},
|
||||
|
||||
run: function () {
|
||||
let storage = getCacheStorage(where, lci, this._appCache);
|
||||
storage.asyncOpenURI(key, "", flags, this);
|
||||
}
|
||||
};
|
||||
|
||||
(new CacheListener()).run();
|
||||
});
|
||||
}
|
||||
|
||||
//
|
||||
// Test functions.
|
||||
//
|
||||
|
||||
// Cookies
|
||||
function* test_cookie_cleared() {
|
||||
let tabs = [];
|
||||
|
||||
for (let userContextId of Object.keys(USER_CONTEXTS)) {
|
||||
// Load the page in 3 different contexts and set a cookie
|
||||
// which should only be visible in that context.
|
||||
let value = USER_CONTEXTS[userContextId];
|
||||
|
||||
// Open our tab in the given user context.
|
||||
tabs[userContextId] = yield* openTabInUserContext(TEST_URL+ "file_set_storages.html?" + value, userContextId);
|
||||
}
|
||||
// Check that cookies have been set properly.
|
||||
for (let userContextId of Object.keys(USER_CONTEXTS)) {
|
||||
let enumerator = getCookiesForOA(TEST_HOST, userContextId);
|
||||
ok(enumerator.hasMoreElements(), "Cookies available");
|
||||
|
||||
let foundCookie = enumerator.getNext().QueryInterface(Ci.nsICookie2);
|
||||
Assert.equal(foundCookie["name"], COOKIE_NAME, "Check cookie name");
|
||||
Assert.equal(foundCookie["value"], USER_CONTEXTS[userContextId], "Check cookie value");
|
||||
}
|
||||
|
||||
// Forget the site.
|
||||
ForgetAboutSite.removeDataFromDomain(TEST_HOST);
|
||||
|
||||
// Check that whether cookies has been cleared or not.
|
||||
for (let userContextId of Object.keys(USER_CONTEXTS)) {
|
||||
let enumerator = getCookiesForOA(TEST_HOST, userContextId);
|
||||
ok(!enumerator.hasMoreElements(), "No Cookie should be here");
|
||||
}
|
||||
|
||||
// Clear Tabs
|
||||
for (let userContextId of Object.keys(USER_CONTEXTS)) {
|
||||
yield BrowserTestUtils.removeTab(tabs[userContextId].tab);
|
||||
}
|
||||
}
|
||||
|
||||
// Cache
|
||||
function* test_cache_cleared() {
|
||||
// First, add some caches.
|
||||
for (let userContextId of Object.keys(USER_CONTEXTS)) {
|
||||
yield OpenCacheEntry("http://" + TEST_HOST + "/",
|
||||
"disk",
|
||||
Ci.nsICacheStorage.OPEN_NORMALLY,
|
||||
LoadContextInfo.custom(false, false, {userContextId}));
|
||||
|
||||
yield OpenCacheEntry("http://" + TEST_HOST + "/",
|
||||
"memory",
|
||||
Ci.nsICacheStorage.OPEN_NORMALLY,
|
||||
LoadContextInfo.custom(false, false, {userContextId}));
|
||||
}
|
||||
|
||||
|
||||
// Check that caches have been set correctly.
|
||||
for (let userContextId of Object.keys(USER_CONTEXTS)) {
|
||||
let mem = getCacheStorage("memory");
|
||||
let disk = getCacheStorage("disk");
|
||||
|
||||
Assert.ok(mem.exists(createURI("http://" + TEST_HOST + "/"), ""), "The memory cache has been set correctly");
|
||||
Assert.ok(disk.exists(createURI("http://" + TEST_HOST + "/"), ""), "The disk cache has been set correctly");
|
||||
}
|
||||
|
||||
// Forget the site.
|
||||
ForgetAboutSite.removeDataFromDomain(TEST_HOST);
|
||||
|
||||
// Check that do caches be removed or not?
|
||||
for (let userContextId of Object.keys(USER_CONTEXTS)) {
|
||||
let mem = getCacheStorage("memory");
|
||||
let disk = getCacheStorage("disk");
|
||||
|
||||
Assert.ok(!mem.exists(createURI("http://" + TEST_HOST + "/"), ""), "The memory cache is cleared");
|
||||
Assert.ok(!disk.exists(createURI("http://" + TEST_HOST + "/"), ""), "The disk cache is cleared");
|
||||
}
|
||||
}
|
||||
|
||||
// Image Cache
|
||||
function* test_image_cache_cleared() {
|
||||
let tabs = [];
|
||||
|
||||
for (let userContextId of Object.keys(USER_CONTEXTS)) {
|
||||
// Open our tab in the given user context to cache image.
|
||||
tabs[userContextId] = yield* openTabInUserContext('http://localhost:' + gHttpServer.identity.primaryPort + '/loadImage.html',
|
||||
userContextId);
|
||||
yield BrowserTestUtils.removeTab(tabs[userContextId].tab);
|
||||
}
|
||||
|
||||
// Check that image cache works with the userContextId.
|
||||
todo_is(gHits, 3, "The image should be loaded three times. This test should be enabled after the bug 1270680 landed");
|
||||
|
||||
// Reset the cache count.
|
||||
gHits = 0;
|
||||
|
||||
// Forget the site.
|
||||
ForgetAboutSite.removeDataFromDomain("localhost:" + gHttpServer.identity.primaryPort + "/");
|
||||
|
||||
// Load again.
|
||||
for (let userContextId of Object.keys(USER_CONTEXTS)) {
|
||||
// Open our tab in the given user context to cache image.
|
||||
tabs[userContextId] = yield* openTabInUserContext('http://localhost:' + gHttpServer.identity.primaryPort + '/loadImage.html',
|
||||
userContextId);
|
||||
yield BrowserTestUtils.removeTab(tabs[userContextId].tab);
|
||||
}
|
||||
|
||||
// Check that image cache was cleared and the server gets another three hits.
|
||||
todo_is(gHits, 3, "The image should be loaded three times. This test should be enabled after the bug 1270680 landed");
|
||||
}
|
||||
|
||||
// Offline Storage
|
||||
function* test_storage_cleared() {
|
||||
for (let userContextId of Object.keys(USER_CONTEXTS)) {
|
||||
// Load the page in 3 different contexts and set the local storage
|
||||
// which should only be visible in that context.
|
||||
let value = USER_CONTEXTS[userContextId];
|
||||
|
||||
// Open our tab in the given user context.
|
||||
let tabInfo = yield* openTabInUserContext(TEST_URL+ "file_set_storages.html?" + value, userContextId);
|
||||
|
||||
// Check that the local storage has been set correctly.
|
||||
let win = tabInfo.browser.contentWindow;
|
||||
Assert.equal(win.localStorage.getItem("userContext"), USER_CONTEXTS[userContextId], "Check the local storage value");
|
||||
|
||||
// Check that the session storage has been set correctly.
|
||||
Assert.equal(win.sessionStorage.getItem("userContext"), USER_CONTEXTS[userContextId], "Check the session storage value");
|
||||
|
||||
// Check that the indexedDB has been set correctly.
|
||||
yield ContentTask.spawn(tabInfo.browser, { userContext: USER_CONTEXTS[userContextId] }, function* (arg) {
|
||||
let request = content.indexedDB.open("idb", 1);
|
||||
|
||||
let db = yield new Promise(done => {
|
||||
request.onsuccess = event => {
|
||||
done(event.target.result);
|
||||
};
|
||||
});
|
||||
|
||||
let transaction = db.transaction(["obj"], "readonly");
|
||||
let store = transaction.objectStore("obj");
|
||||
let storeRequest = store.get(1);
|
||||
|
||||
yield new Promise(done => {
|
||||
storeRequest.onsuccess = event => {
|
||||
let res = storeRequest.result;
|
||||
Assert.equal(res.userContext, arg.userContext, "Check the indexedDB value");
|
||||
done();
|
||||
};
|
||||
});
|
||||
});
|
||||
|
||||
// Close this tab.
|
||||
yield BrowserTestUtils.removeTab(tabInfo.tab);
|
||||
}
|
||||
|
||||
// Forget the site.
|
||||
ForgetAboutSite.removeDataFromDomain(TEST_HOST);
|
||||
|
||||
// Open the tab again without setting the localStorage and check that the
|
||||
// local storage has been cleared or not.
|
||||
for (let userContextId of Object.keys(USER_CONTEXTS)) {
|
||||
// Open our tab in the given user context without setting local storage.
|
||||
let tabInfo = yield* openTabInUserContext(TEST_URL+ "file_set_storages.html", userContextId);
|
||||
let win = tabInfo.browser.contentWindow;
|
||||
|
||||
// Check that does the local storage be cleared or not.
|
||||
Assert.ok(!win.localStorage.getItem("userContext"), "The local storage has been cleared");
|
||||
|
||||
// Check that does the session storage be cleared or not.
|
||||
Assert.ok(!win.sessionStorage.getItem("userContext"), "The session storage has been cleared");
|
||||
|
||||
// Check that does the indexedDB be cleared or not.
|
||||
yield ContentTask.spawn(tabInfo.browser, null, function* () {
|
||||
let request = content.indexedDB.open("idb", 1);
|
||||
|
||||
let db = yield new Promise(done => {
|
||||
request.onsuccess = event => {
|
||||
done(event.target.result);
|
||||
};
|
||||
});
|
||||
try {
|
||||
let transaction = db.transaction(["obj"], "readonly");
|
||||
Assert.ok(false, "The indexedDB should not exist");
|
||||
} catch (e) {
|
||||
Assert.equal(e.name, "NotFoundError", "The indexedDB does not exist as expected");
|
||||
}
|
||||
});
|
||||
|
||||
// Close the tab.
|
||||
yield BrowserTestUtils.removeTab(tabInfo.tab);
|
||||
}
|
||||
}
|
||||
|
||||
add_task(function* setup() {
|
||||
// Make sure userContext is enabled.
|
||||
yield new Promise(resolve => {
|
||||
SpecialPowers.pushPrefEnv({"set": [
|
||||
["privacy.userContext.enabled", true]
|
||||
]}, resolve);
|
||||
});
|
||||
|
||||
// Create a http server for the image cache test.
|
||||
if (!gHttpServer) {
|
||||
gHttpServer = new HttpServer();
|
||||
gHttpServer.registerPathHandler('/image.png', imageHandler);
|
||||
gHttpServer.registerPathHandler('/loadImage.html', loadImagePageHandler);
|
||||
gHttpServer.start(-1);
|
||||
}
|
||||
});
|
||||
|
||||
let tests = [
|
||||
test_cookie_cleared,
|
||||
test_cache_cleared,
|
||||
test_image_cache_cleared,
|
||||
test_storage_cleared,
|
||||
];
|
||||
|
||||
add_task(function* test() {
|
||||
for (let i = 0; i < tests.length; i++)
|
||||
add_task(tests[i]);
|
||||
});
|
||||
|
||||
registerCleanupFunction(() => {
|
||||
gHttpServer.stop(() => {
|
||||
gHttpServer = null;
|
||||
});
|
||||
});
|
|
@ -1,42 +0,0 @@
|
|||
<html>
|
||||
<head>
|
||||
<meta charset="UTF-8">
|
||||
<title>Bug 1238183</title>
|
||||
</head>
|
||||
<body>
|
||||
<script type="application/javascript;version=1.7">
|
||||
"use strict";
|
||||
|
||||
// if we have a query string, use it to set storages
|
||||
if (window.location.search.length > 0) {
|
||||
let context_name = window.location.search.substr(1);
|
||||
document.cookie = "userContextId=" + context_name;
|
||||
localStorage.setItem("userContext", context_name);
|
||||
sessionStorage.setItem("userContext", context_name);
|
||||
|
||||
let request = indexedDB.open("idb", 1);
|
||||
|
||||
request.onerror = function() {
|
||||
throw new Error("error opening db connection");
|
||||
};
|
||||
|
||||
request.onupgradeneeded = event => {
|
||||
let db = event.target.result;
|
||||
let store = db.createObjectStore("obj", { keyPath: "id" });
|
||||
store.createIndex("userContext", "userContext", { unique: false });
|
||||
};
|
||||
|
||||
request.onsuccess = event => {
|
||||
let db = request.result;
|
||||
let transaction = db.transaction(["obj"], "readwrite");
|
||||
let store = transaction.objectStore("obj");
|
||||
store.add({id: 1, userContext: context_name});
|
||||
|
||||
transaction.oncomplete = () => {
|
||||
db.close();
|
||||
};
|
||||
};
|
||||
}
|
||||
</script>
|
||||
</body>
|
||||
</html>
|
|
@ -1,7 +1,6 @@
|
|||
[DEFAULT]
|
||||
head = head.js head-http2.js
|
||||
tail =
|
||||
firefox-appdir = browser
|
||||
# Push notifications and alarms are currently disabled on Android.
|
||||
skip-if = toolkit == 'android'
|
||||
|
||||
|
|
|
@ -12,8 +12,6 @@ XPCOMUtils.defineLazyModuleGetter(this, "PlacesUtils",
|
|||
"resource://gre/modules/PlacesUtils.jsm");
|
||||
XPCOMUtils.defineLazyModuleGetter(this, "Downloads",
|
||||
"resource://gre/modules/Downloads.jsm");
|
||||
XPCOMUtils.defineLazyModuleGetter(this, "ContextualIdentityService",
|
||||
"resource:///modules/ContextualIdentityService.jsm");
|
||||
|
||||
this.EXPORTED_SYMBOLS = ["ForgetAboutSite"];
|
||||
|
||||
|
@ -49,14 +47,6 @@ const Cu = Components.utils;
|
|||
this.ForgetAboutSite = {
|
||||
removeDataFromDomain: function CRH_removeDataFromDomain(aDomain)
|
||||
{
|
||||
// Get all userContextId from the ContextualIdentityService and create
|
||||
// all originAttributes.
|
||||
let oaList = [ {} ]; // init the list with the default originAttributes.
|
||||
|
||||
for (let identity of ContextualIdentityService.getIdentities()) {
|
||||
oaList.push({ userContextId: identity.userContextId});
|
||||
}
|
||||
|
||||
PlacesUtils.history.removePagesFromHost(aDomain, true);
|
||||
|
||||
// Cache
|
||||
|
@ -84,13 +74,10 @@ this.ForgetAboutSite = {
|
|||
// Cookies
|
||||
let cm = Cc["@mozilla.org/cookiemanager;1"].
|
||||
getService(Ci.nsICookieManager2);
|
||||
let enumerator;
|
||||
for (let originAttributes of oaList) {
|
||||
enumerator = cm.getCookiesFromHost(aDomain, originAttributes);
|
||||
while (enumerator.hasMoreElements()) {
|
||||
let cookie = enumerator.getNext().QueryInterface(Ci.nsICookie);
|
||||
cm.remove(cookie.host, cookie.name, cookie.path, false, cookie.originAttributes);
|
||||
}
|
||||
let enumerator = cm.getCookiesFromHost(aDomain, {});
|
||||
while (enumerator.hasMoreElements()) {
|
||||
let cookie = enumerator.getNext().QueryInterface(Ci.nsICookie);
|
||||
cm.remove(cookie.host, cookie.name, cookie.path, false, cookie.originAttributes);
|
||||
}
|
||||
|
||||
// EME
|
||||
|
@ -177,14 +164,10 @@ this.ForgetAboutSite = {
|
|||
caUtils);
|
||||
let httpURI = caUtils.makeURI("http://" + aDomain);
|
||||
let httpsURI = caUtils.makeURI("https://" + aDomain);
|
||||
for (let originAttributes of oaList) {
|
||||
let httpPrincipal = Services.scriptSecurityManager
|
||||
.createCodebasePrincipal(httpURI, originAttributes);
|
||||
let httpsPrincipal = Services.scriptSecurityManager
|
||||
.createCodebasePrincipal(httpsURI, originAttributes);
|
||||
qms.clearStoragesForPrincipal(httpPrincipal);
|
||||
qms.clearStoragesForPrincipal(httpsPrincipal);
|
||||
}
|
||||
let httpPrincipal = Services.scriptSecurityManager.createCodebasePrincipal(httpURI, {});
|
||||
let httpsPrincipal = Services.scriptSecurityManager.createCodebasePrincipal(httpsURI, {});
|
||||
qms.clearStoragesForPrincipal(httpPrincipal);
|
||||
qms.clearStoragesForPrincipal(httpsPrincipal);
|
||||
|
||||
function onContentPrefsRemovalFinished() {
|
||||
// Everybody else (including extensions)
|
||||
|
|
|
@ -1,7 +1,6 @@
|
|||
[DEFAULT]
|
||||
head = head_forgetaboutsite.js ../../../../dom/push/test/xpcshell/head.js
|
||||
tail =
|
||||
firefox-appdir = browser
|
||||
skip-if = toolkit == 'android' || toolkit == 'gonk'
|
||||
support-files =
|
||||
!/dom/push/test/xpcshell/head.js
|
||||
|
|
Загрузка…
Ссылка в новой задаче