diff options
Diffstat (limited to 'toolkit/components/extensions/test/xpcshell/test_ext_browsingData_cookies_cache.js')
-rw-r--r-- | toolkit/components/extensions/test/xpcshell/test_ext_browsingData_cookies_cache.js | 456 |
1 files changed, 456 insertions, 0 deletions
diff --git a/toolkit/components/extensions/test/xpcshell/test_ext_browsingData_cookies_cache.js b/toolkit/components/extensions/test/xpcshell/test_ext_browsingData_cookies_cache.js new file mode 100644 index 0000000000..577d727a49 --- /dev/null +++ b/toolkit/components/extensions/test/xpcshell/test_ext_browsingData_cookies_cache.js @@ -0,0 +1,456 @@ +/* -*- Mode: indent-tabs-mode: nil; js-indent-level: 2 -*- */ +/* vim: set sts=2 sw=2 et tw=80: */ +/* eslint-disable mozilla/no-arbitrary-setTimeout */ +"use strict"; + +const { SiteDataTestUtils } = ChromeUtils.importESModule( + "resource://testing-common/SiteDataTestUtils.sys.mjs" +); + +const COOKIE = { + host: "example.com", + name: "test_cookie", + path: "/", +}; +const COOKIE_NET = { + host: "example.net", + name: "test_cookie", + path: "/", +}; +const COOKIE_ORG = { + host: "example.org", + name: "test_cookie", + path: "/", +}; +let since, oldCookie; + +function addCookie(cookie) { + Services.cookies.add( + cookie.host, + cookie.path, + cookie.name, + "test", + false, + false, + false, + Date.now() / 1000 + 10000, + {}, + Ci.nsICookie.SAMESITE_NONE, + Ci.nsICookie.SCHEME_HTTPS + ); + ok( + Services.cookies.cookieExists(cookie.host, cookie.path, cookie.name, {}), + `Cookie ${cookie.name} was created.` + ); +} + +async function setUpCookies() { + Services.cookies.removeAll(); + + // Add a cookie which will end up with an older creationTime. + oldCookie = Object.assign({}, COOKIE, { name: Date.now() }); + addCookie(oldCookie); + await new Promise(resolve => setTimeout(resolve, 10)); + since = Date.now(); + await new Promise(resolve => setTimeout(resolve, 10)); + + // Add a cookie which will end up with a more recent creationTime. + addCookie(COOKIE); + + // Add cookies for different domains. + addCookie(COOKIE_NET); + addCookie(COOKIE_ORG); +} + +async function setUpCache() { + Services.cache2.clear(); + + // Add cache entries for different domains. + for (const domain of ["example.net", "example.org", "example.com"]) { + await SiteDataTestUtils.addCacheEntry(`http://${domain}/`, "disk"); + await SiteDataTestUtils.addCacheEntry(`http://${domain}/`, "memory"); + } +} + +function hasCacheEntry(domain) { + const disk = SiteDataTestUtils.hasCacheEntry(`http://${domain}/`, "disk"); + const memory = SiteDataTestUtils.hasCacheEntry(`http://${domain}/`, "memory"); + + equal( + disk, + memory, + `For ${domain} either either both or neither caches need to exists.` + ); + return disk; +} + +add_task(async function testCache() { + function background() { + browser.test.onMessage.addListener(async msg => { + if (msg == "removeCache") { + await browser.browsingData.removeCache({}); + } else { + await browser.browsingData.remove({}, { cache: true }); + } + browser.test.sendMessage("cacheRemoved"); + }); + } + + let extension = ExtensionTestUtils.loadExtension({ + background, + manifest: { + permissions: ["browsingData"], + }, + }); + + async function testRemovalMethod(method) { + await setUpCache(); + + extension.sendMessage(method); + await extension.awaitMessage("cacheRemoved"); + + ok(!hasCacheEntry("example.net"), "example.net cache was removed"); + ok(!hasCacheEntry("example.org"), "example.org cache was removed"); + ok(!hasCacheEntry("example.com"), "example.com cache was removed"); + } + + await extension.startup(); + + await testRemovalMethod("removeCache"); + await testRemovalMethod("remove"); + + await extension.unload(); +}); + +add_task(async function testCookies() { + // Above in setUpCookies we create an 'old' cookies, wait 10ms, then log a timestamp. + // Here we ask the browser to delete all cookies after the timestamp, with the intention + // that the 'old' cookie is not removed. The issue arises when the timer precision is + // low enough such that the timestamp that gets logged is the same as the 'old' cookie. + // We hardcode a precision value to ensure that there is time between the 'old' cookie + // and the timestamp generation. + Services.prefs.setBoolPref("privacy.reduceTimerPrecision", true); + Services.prefs.setIntPref( + "privacy.resistFingerprinting.reduceTimerPrecision.microseconds", + 2000 + ); + + registerCleanupFunction(function () { + Services.prefs.clearUserPref("privacy.reduceTimerPrecision"); + Services.prefs.clearUserPref( + "privacy.resistFingerprinting.reduceTimerPrecision.microseconds" + ); + }); + + function background() { + browser.test.onMessage.addListener(async (msg, options) => { + if (msg == "removeCookies") { + await browser.browsingData.removeCookies(options); + } else { + await browser.browsingData.remove(options, { cookies: true }); + } + browser.test.sendMessage("cookiesRemoved"); + }); + } + + let extension = ExtensionTestUtils.loadExtension({ + background, + manifest: { + permissions: ["browsingData"], + }, + }); + + async function testRemovalMethod(method) { + // Clear cookies with a recent since value. + await setUpCookies(); + extension.sendMessage(method, { since }); + await extension.awaitMessage("cookiesRemoved"); + + ok( + Services.cookies.cookieExists( + oldCookie.host, + oldCookie.path, + oldCookie.name, + {} + ), + "Old cookie was not removed." + ); + ok( + !Services.cookies.cookieExists(COOKIE.host, COOKIE.path, COOKIE.name, {}), + "Recent cookie was removed." + ); + + // Clear cookies with an old since value. + await setUpCookies(); + addCookie(COOKIE); + extension.sendMessage(method, { since: since - 100000 }); + await extension.awaitMessage("cookiesRemoved"); + + ok( + !Services.cookies.cookieExists( + oldCookie.host, + oldCookie.path, + oldCookie.name, + {} + ), + "Old cookie was removed." + ); + ok( + !Services.cookies.cookieExists(COOKIE.host, COOKIE.path, COOKIE.name, {}), + "Recent cookie was removed." + ); + + // Clear cookies with no since value and valid originTypes. + await setUpCookies(); + extension.sendMessage(method, { + originTypes: { unprotectedWeb: true, protectedWeb: false }, + }); + await extension.awaitMessage("cookiesRemoved"); + + ok( + !Services.cookies.cookieExists(COOKIE.host, COOKIE.path, COOKIE.name, {}), + `Cookie ${COOKIE.name} was removed.` + ); + ok( + !Services.cookies.cookieExists( + oldCookie.host, + oldCookie.path, + oldCookie.name, + {} + ), + `Cookie ${oldCookie.name} was removed.` + ); + } + + await extension.startup(); + + await testRemovalMethod("removeCookies"); + await testRemovalMethod("remove"); + + await extension.unload(); +}); + +add_task(async function testCacheAndCookies() { + function background() { + browser.test.onMessage.addListener(async options => { + await browser.browsingData.remove(options, { + cache: true, + cookies: true, + }); + browser.test.sendMessage("cacheAndCookiesRemoved"); + }); + } + + let extension = ExtensionTestUtils.loadExtension({ + background, + manifest: { + permissions: ["browsingData"], + }, + }); + + await extension.startup(); + + // Clear cache and cookies with a recent since value. + await setUpCookies(); + await setUpCache(); + extension.sendMessage({ since }); + await extension.awaitMessage("cacheAndCookiesRemoved"); + + ok( + Services.cookies.cookieExists( + oldCookie.host, + oldCookie.path, + oldCookie.name, + {} + ), + "Old cookie was not removed." + ); + ok( + !Services.cookies.cookieExists(COOKIE.host, COOKIE.path, COOKIE.name, {}), + "Recent cookie was removed." + ); + + // Cache does not support |since| and deletes everything! + ok(!hasCacheEntry("example.net"), "example.net cache was removed"); + ok(!hasCacheEntry("example.org"), "example.org cache was removed"); + ok(!hasCacheEntry("example.com"), "example.com cache was removed"); + + // Clear cache and cookies with an old since value. + await setUpCookies(); + await setUpCache(); + extension.sendMessage({ since: since - 100000 }); + await extension.awaitMessage("cacheAndCookiesRemoved"); + + // Cache does not support |since| and deletes everything! + ok(!hasCacheEntry("example.net"), "example.net cache was removed"); + ok(!hasCacheEntry("example.org"), "example.org cache was removed"); + ok(!hasCacheEntry("example.com"), "example.com cache was removed"); + + ok( + !Services.cookies.cookieExists( + oldCookie.host, + oldCookie.path, + oldCookie.name, + {} + ), + "Old cookie was removed." + ); + ok( + !Services.cookies.cookieExists(COOKIE.host, COOKIE.path, COOKIE.name, {}), + "Recent cookie was removed." + ); + + // Clear cache and cookies with hostnames value. + await setUpCookies(); + await setUpCache(); + extension.sendMessage({ + hostnames: ["example.net", "example.org", "unknown.com"], + }); + await extension.awaitMessage("cacheAndCookiesRemoved"); + + ok( + Services.cookies.cookieExists(COOKIE.host, COOKIE.path, COOKIE.name, {}), + `Cookie ${COOKIE.name} was not removed.` + ); + ok( + !Services.cookies.cookieExists( + COOKIE_NET.host, + COOKIE_NET.path, + COOKIE_NET.name, + {} + ), + `Cookie ${COOKIE_NET.name} was removed.` + ); + ok( + !Services.cookies.cookieExists( + COOKIE_ORG.host, + COOKIE_ORG.path, + COOKIE_ORG.name, + {} + ), + `Cookie ${COOKIE_ORG.name} was removed.` + ); + + ok(!hasCacheEntry("example.net"), "example.net cache was removed"); + ok(!hasCacheEntry("example.org"), "example.org cache was removed"); + ok(hasCacheEntry("example.com"), "example.com cache was not removed"); + + // Clear cache and cookies with (empty) hostnames value. + await setUpCookies(); + await setUpCache(); + extension.sendMessage({ hostnames: [] }); + await extension.awaitMessage("cacheAndCookiesRemoved"); + + ok( + Services.cookies.cookieExists(COOKIE.host, COOKIE.path, COOKIE.name, {}), + `Cookie ${COOKIE.name} was not removed.` + ); + ok( + Services.cookies.cookieExists( + COOKIE_NET.host, + COOKIE_NET.path, + COOKIE_NET.name, + {} + ), + `Cookie ${COOKIE_NET.name} was not removed.` + ); + ok( + Services.cookies.cookieExists( + COOKIE_ORG.host, + COOKIE_ORG.path, + COOKIE_ORG.name, + {} + ), + `Cookie ${COOKIE_ORG.name} was not removed.` + ); + + ok(hasCacheEntry("example.net"), "example.net cache was not removed"); + ok(hasCacheEntry("example.org"), "example.org cache was not removed"); + ok(hasCacheEntry("example.com"), "example.com cache was not removed"); + + // Clear cache and cookies with both hostnames and since values. + await setUpCache(); + await setUpCookies(); + extension.sendMessage({ hostnames: ["example.com"], since }); + await extension.awaitMessage("cacheAndCookiesRemoved"); + + ok( + Services.cookies.cookieExists( + oldCookie.host, + oldCookie.path, + oldCookie.name, + {} + ), + "Old cookie was not removed." + ); + ok( + !Services.cookies.cookieExists(COOKIE.host, COOKIE.path, COOKIE.name, {}), + "Recent cookie was removed." + ); + ok( + Services.cookies.cookieExists( + COOKIE_NET.host, + COOKIE_NET.path, + COOKIE_NET.name, + {} + ), + "Cookie with different hostname was not removed" + ); + ok( + Services.cookies.cookieExists( + COOKIE_ORG.host, + COOKIE_ORG.path, + COOKIE_ORG.name, + {} + ), + "Cookie with different hostname was not removed" + ); + + ok(hasCacheEntry("example.net"), "example.net cache was not removed"); + ok(hasCacheEntry("example.org"), "example.org cache was not removed"); + ok(!hasCacheEntry("example.com"), "example.com cache was removed"); + + // Clear cache and cookies with no since or hostnames value. + await setUpCache(); + await setUpCookies(); + extension.sendMessage({}); + await extension.awaitMessage("cacheAndCookiesRemoved"); + + ok( + !Services.cookies.cookieExists(COOKIE.host, COOKIE.path, COOKIE.name, {}), + `Cookie ${COOKIE.name} was removed.` + ); + ok( + !Services.cookies.cookieExists( + oldCookie.host, + oldCookie.path, + oldCookie.name, + {} + ), + `Cookie ${oldCookie.name} was removed.` + ); + ok( + !Services.cookies.cookieExists( + COOKIE_NET.host, + COOKIE_NET.path, + COOKIE_NET.name, + {} + ), + `Cookie ${COOKIE_NET.name} was removed.` + ); + ok( + !Services.cookies.cookieExists( + COOKIE_ORG.host, + COOKIE_ORG.path, + COOKIE_ORG.name, + {} + ), + `Cookie ${COOKIE_ORG.name} was removed.` + ); + + ok(!hasCacheEntry("example.net"), "example.net cache was removed"); + ok(!hasCacheEntry("example.org"), "example.org cache was removed"); + ok(!hasCacheEntry("example.com"), "example.com cache was removed"); + + await extension.unload(); +}); |