summaryrefslogtreecommitdiffstats
path: root/netwerk/cookie/test/unit
diff options
context:
space:
mode:
Diffstat (limited to '')
-rw-r--r--netwerk/cookie/test/unit/test_baseDomain_publicsuffix.js105
-rw-r--r--netwerk/cookie/test/unit/test_bug1155169.js90
-rw-r--r--netwerk/cookie/test/unit/test_bug1321912.js99
-rw-r--r--netwerk/cookie/test/unit/test_bug643051.js41
-rw-r--r--netwerk/cookie/test/unit/test_eviction.js197
-rw-r--r--netwerk/cookie/test/unit/test_getCookieSince.js70
-rw-r--r--netwerk/cookie/test/unit/test_migrateCookieLifetimePref.js65
-rw-r--r--netwerk/cookie/test/unit/test_parser_0001.js30
-rw-r--r--netwerk/cookie/test/unit/test_parser_0019.js30
-rw-r--r--netwerk/cookie/test/unit/test_rawSameSite.js123
-rw-r--r--netwerk/cookie/test/unit/test_schemeMap.js214
-rw-r--r--netwerk/cookie/test/unit/test_timestamp_fixup.js137
-rw-r--r--netwerk/cookie/test/unit/xpcshell.ini15
13 files changed, 1216 insertions, 0 deletions
diff --git a/netwerk/cookie/test/unit/test_baseDomain_publicsuffix.js b/netwerk/cookie/test/unit/test_baseDomain_publicsuffix.js
new file mode 100644
index 0000000000..94f01b778e
--- /dev/null
+++ b/netwerk/cookie/test/unit/test_baseDomain_publicsuffix.js
@@ -0,0 +1,105 @@
+"use strict";
+
+add_task(async () => {
+ const HOST = "www.bbc.co.uk";
+ Assert.equal(
+ Services.eTLD.getBaseDomainFromHost(HOST),
+ "bbc.co.uk",
+ "Sanity check: HOST is an eTLD + 1 with subdomain"
+ );
+
+ const tests = [
+ {
+ // Correct baseDomain: eTLD + 1.
+ baseDomain: "bbc.co.uk",
+ name: "originally_bbc_co_uk",
+ },
+ {
+ // Incorrect baseDomain: Part of public suffix list.
+ baseDomain: "uk",
+ name: "originally_uk",
+ },
+ {
+ // Incorrect baseDomain: Part of public suffix list.
+ baseDomain: "co.uk",
+ name: "originally_co_uk",
+ },
+ {
+ // Incorrect baseDomain: eTLD + 2.
+ baseDomain: "www.bbc.co.uk",
+ name: "originally_www_bbc_co_uk",
+ },
+ ];
+
+ do_get_profile();
+
+ let dbFile = Services.dirsvc.get("ProfD", Ci.nsIFile);
+ dbFile.append("cookies.sqlite");
+ let conn = Services.storage.openDatabase(dbFile);
+
+ conn.schemaVersion = 10;
+ conn.executeSimpleSQL("DROP TABLE IF EXISTS moz_cookies");
+ conn.executeSimpleSQL(
+ "CREATE TABLE moz_cookies (" +
+ "id INTEGER PRIMARY KEY, " +
+ "baseDomain TEXT, " +
+ "originAttributes TEXT NOT NULL DEFAULT '', " +
+ "name TEXT, " +
+ "value TEXT, " +
+ "host TEXT, " +
+ "path TEXT, " +
+ "expiry INTEGER, " +
+ "lastAccessed INTEGER, " +
+ "creationTime INTEGER, " +
+ "isSecure INTEGER, " +
+ "isHttpOnly INTEGER, " +
+ "inBrowserElement INTEGER DEFAULT 0, " +
+ "sameSite INTEGER DEFAULT 0, " +
+ "rawSameSite INTEGER DEFAULT 0, " +
+ "CONSTRAINT moz_uniqueid UNIQUE (name, host, path, originAttributes)" +
+ ")"
+ );
+
+ function addCookie(baseDomain, host, name) {
+ conn.executeSimpleSQL(
+ "INSERT INTO moz_cookies(" +
+ "baseDomain, host, name, value, path, expiry, " +
+ "lastAccessed, creationTime, isSecure, isHttpOnly) VALUES (" +
+ `'${baseDomain}', '${host}', '${name}', 'thevalue', '/', ` +
+ (Date.now() + 3600000) +
+ "," +
+ Date.now() +
+ "," +
+ Date.now() +
+ ", 1, 1)"
+ );
+ }
+
+ // Prepare the database.
+ for (let { baseDomain, name } of tests) {
+ addCookie(baseDomain, HOST, name);
+ }
+ // Domain cookies are not supported for IP addresses.
+ addCookie("127.0.0.1", ".127.0.0.1", "invalid_host");
+ conn.close();
+
+ let cs = Services.cookies;
+
+ // Count excludes the invalid_host cookie.
+ Assert.equal(cs.cookies.length, tests.length, "Expected number of cookies");
+
+ // Check whether the database has the expected value,
+ // despite the incorrect baseDomain.
+ for (let { name } of tests) {
+ Assert.ok(
+ cs.cookieExists(HOST, "/", name, {}),
+ "Should find cookie with name: " + name
+ );
+ }
+
+ Assert.equal(
+ cs.cookieExists("127.0.0.1", "/", "invalid_host", {}),
+ false,
+ "Should ignore database row with invalid host name"
+ );
+});
diff --git a/netwerk/cookie/test/unit/test_bug1155169.js b/netwerk/cookie/test/unit/test_bug1155169.js
new file mode 100644
index 0000000000..de2cd50ab6
--- /dev/null
+++ b/netwerk/cookie/test/unit/test_bug1155169.js
@@ -0,0 +1,90 @@
+const { NetUtil } = ChromeUtils.import("resource://gre/modules/NetUtil.jsm");
+
+const URI = Services.io.newURI("http://example.org/");
+
+function run_test() {
+ // Allow all cookies.
+ Services.prefs.setIntPref("network.cookie.cookieBehavior", 0);
+
+ // Clear cookies.
+ Services.cookies.removeAll();
+
+ // Add a new cookie.
+ setCookie("foo=bar", {
+ type: "added",
+ isSession: true,
+ isSecure: false,
+ isHttpOnly: false,
+ });
+
+ // Update cookie with isHttpOnly=true.
+ setCookie("foo=bar; HttpOnly", {
+ type: "changed",
+ isSession: true,
+ isSecure: false,
+ isHttpOnly: true,
+ });
+
+ // Update cookie with isSecure=true.
+ setCookie("foo=bar; Secure", {
+ type: "changed",
+ isSession: true,
+ isSecure: true,
+ isHttpOnly: false,
+ });
+
+ // Update cookie with isSession=false.
+ let expiry = new Date();
+ expiry.setUTCFullYear(expiry.getUTCFullYear() + 2);
+ setCookie(`foo=bar; Expires=${expiry.toGMTString()}`, {
+ type: "changed",
+ isSession: false,
+ isSecure: false,
+ isHttpOnly: false,
+ });
+
+ // Reset cookie.
+ setCookie("foo=bar", {
+ type: "changed",
+ isSession: true,
+ isSecure: false,
+ isHttpOnly: false,
+ });
+}
+
+function setCookie(value, expected) {
+ function setCookieInternal(valueInternal, expectedInternal = null) {
+ function observer(subject, topic, data) {
+ if (!expectedInternal) {
+ do_throw("no notification expected");
+ return;
+ }
+
+ // Check we saw the right notification.
+ Assert.equal(data, expectedInternal.type);
+
+ // Check cookie details.
+ let cookie = subject.QueryInterface(Ci.nsICookie);
+ Assert.equal(cookie.isSession, expectedInternal.isSession);
+ Assert.equal(cookie.isSecure, expectedInternal.isSecure);
+ Assert.equal(cookie.isHttpOnly, expectedInternal.isHttpOnly);
+ }
+
+ Services.obs.addObserver(observer, "cookie-changed");
+
+ let channel = NetUtil.newChannel({
+ uri: URI,
+ loadUsingSystemPrincipal: true,
+ contentPolicyType: Ci.nsIContentPolicy.TYPE_DOCUMENT,
+ });
+
+ Services.cookies.setCookieStringFromHttp(URI, valueInternal, channel);
+ Services.obs.removeObserver(observer, "cookie-changed");
+ }
+
+ // Check that updating/inserting the cookie works.
+ setCookieInternal(value, expected);
+
+ // Check that we ignore identical cookies.
+ setCookieInternal(value);
+}
diff --git a/netwerk/cookie/test/unit/test_bug1321912.js b/netwerk/cookie/test/unit/test_bug1321912.js
new file mode 100644
index 0000000000..5b4bf8fcc8
--- /dev/null
+++ b/netwerk/cookie/test/unit/test_bug1321912.js
@@ -0,0 +1,99 @@
+do_get_profile();
+const dirSvc = Services.dirsvc;
+
+let dbFile = dirSvc.get("ProfD", Ci.nsIFile);
+dbFile.append("cookies.sqlite");
+
+let storage = Services.storage;
+let properties = Cc["@mozilla.org/hash-property-bag;1"].createInstance(
+ Ci.nsIWritablePropertyBag
+);
+properties.setProperty("shared", true);
+let conn = storage.openDatabase(dbFile);
+
+// Write the schema v7 to the database.
+conn.schemaVersion = 7;
+conn.executeSimpleSQL(
+ "CREATE TABLE moz_cookies (" +
+ "id INTEGER PRIMARY KEY, " +
+ "baseDomain TEXT, " +
+ "originAttributes TEXT NOT NULL DEFAULT '', " +
+ "name TEXT, " +
+ "value TEXT, " +
+ "host TEXT, " +
+ "path TEXT, " +
+ "expiry INTEGER, " +
+ "lastAccessed INTEGER, " +
+ "creationTime INTEGER, " +
+ "isSecure INTEGER, " +
+ "isHttpOnly INTEGER, " +
+ "appId INTEGER DEFAULT 0, " +
+ "inBrowserElement INTEGER DEFAULT 0, " +
+ "CONSTRAINT moz_uniqueid UNIQUE (name, host, path, originAttributes)" +
+ ")"
+);
+conn.executeSimpleSQL(
+ "CREATE INDEX moz_basedomain ON moz_cookies (baseDomain, " +
+ "originAttributes)"
+);
+
+conn.executeSimpleSQL("PRAGMA synchronous = OFF");
+conn.executeSimpleSQL("PRAGMA journal_mode = WAL");
+conn.executeSimpleSQL("PRAGMA wal_autocheckpoint = 16");
+
+let now = Date.now();
+conn.executeSimpleSQL(
+ "INSERT INTO moz_cookies(" +
+ "baseDomain, host, name, value, path, expiry, " +
+ "lastAccessed, creationTime, isSecure, isHttpOnly) VALUES (" +
+ "'foo.com', '.foo.com', 'foo', 'bar=baz', '/', " +
+ now +
+ ", " +
+ now +
+ ", " +
+ now +
+ ", 1, 1)"
+);
+
+// Now start the cookie service, and then check the fields in the table.
+// Get sessionCookies to wait for the initialization in cookie thread
+Services.cookies.sessionCookies;
+
+Assert.equal(conn.schemaVersion, 12);
+let stmt = conn.createStatement(
+ "SELECT sql FROM sqlite_master " +
+ "WHERE type = 'table' AND " +
+ " name = 'moz_cookies'"
+);
+try {
+ Assert.ok(stmt.executeStep());
+ let sql = stmt.getString(0);
+ Assert.equal(sql.indexOf("appId"), -1);
+} finally {
+ stmt.finalize();
+}
+
+stmt = conn.createStatement(
+ "SELECT * FROM moz_cookies " +
+ "WHERE host = '.foo.com' AND " +
+ " name = 'foo' AND " +
+ " value = 'bar=baz' AND " +
+ " path = '/' AND " +
+ " expiry = " +
+ now +
+ " AND " +
+ " lastAccessed = " +
+ now +
+ " AND " +
+ " creationTime = " +
+ now +
+ " AND " +
+ " isSecure = 1 AND " +
+ " isHttpOnly = 1"
+);
+try {
+ Assert.ok(stmt.executeStep());
+} finally {
+ stmt.finalize();
+}
+conn.close();
diff --git a/netwerk/cookie/test/unit/test_bug643051.js b/netwerk/cookie/test/unit/test_bug643051.js
new file mode 100644
index 0000000000..d06f375877
--- /dev/null
+++ b/netwerk/cookie/test/unit/test_bug643051.js
@@ -0,0 +1,41 @@
+const { NetUtil } = ChromeUtils.import("resource://gre/modules/NetUtil.jsm");
+const { CookieXPCShellUtils } = ChromeUtils.importESModule(
+ "resource://testing-common/CookieXPCShellUtils.sys.mjs"
+);
+
+CookieXPCShellUtils.init(this);
+CookieXPCShellUtils.createServer({ hosts: ["example.net"] });
+
+add_task(async () => {
+ Services.prefs.setBoolPref("dom.security.https_first", false);
+
+ // Allow all cookies.
+ Services.prefs.setIntPref("network.cookie.cookieBehavior", 0);
+ Services.prefs.setBoolPref(
+ "network.cookieJarSettings.unblocked_for_testing",
+ true
+ );
+
+ let uri = NetUtil.newURI("http://example.org/");
+ let channel = NetUtil.newChannel({
+ uri,
+ loadUsingSystemPrincipal: true,
+ contentPolicyType: Ci.nsIContentPolicy.TYPE_DOCUMENT,
+ });
+
+ let set = "foo=bar\nbaz=foo";
+ let expected = "foo=bar; baz=foo";
+ Services.cookies.setCookieStringFromHttp(uri, set, channel);
+
+ let actual = Services.cookies.getCookieStringFromHttp(uri, channel);
+ Assert.equal(actual, expected);
+
+ await CookieXPCShellUtils.setCookieToDocument("http://example.net/", set);
+ actual = await CookieXPCShellUtils.getCookieStringFromDocument(
+ "http://example.net/"
+ );
+
+ expected = "foo=bar";
+ Assert.equal(actual, expected);
+ Services.prefs.clearUserPref("dom.security.https_first");
+});
diff --git a/netwerk/cookie/test/unit/test_eviction.js b/netwerk/cookie/test/unit/test_eviction.js
new file mode 100644
index 0000000000..f694cc80aa
--- /dev/null
+++ b/netwerk/cookie/test/unit/test_eviction.js
@@ -0,0 +1,197 @@
+const { NetUtil } = ChromeUtils.import("resource://gre/modules/NetUtil.jsm");
+
+const BASE_HOST = "example.org";
+
+const { CookieXPCShellUtils } = ChromeUtils.importESModule(
+ "resource://testing-common/CookieXPCShellUtils.sys.mjs"
+);
+
+CookieXPCShellUtils.init(this);
+CookieXPCShellUtils.createServer({ hosts: ["example.org"] });
+
+add_task(async function test_basic_eviction() {
+ do_get_profile();
+
+ Services.prefs.setIntPref("network.cookie.staleThreshold", 0);
+ Services.prefs.setIntPref("network.cookie.quotaPerHost", 2);
+ Services.prefs.setIntPref("network.cookie.maxPerHost", 5);
+
+ // We don't want to have CookieJarSettings blocking this test.
+ Services.prefs.setBoolPref(
+ "network.cookieJarSettings.unblocked_for_testing",
+ true
+ );
+
+ const BASE_URI = Services.io.newURI("http://" + BASE_HOST);
+ const FOO_PATH = Services.io.newURI("http://" + BASE_HOST + "/foo/");
+ const BAR_PATH = Services.io.newURI("http://" + BASE_HOST + "/bar/");
+
+ await setCookie("session_foo_path_1", null, "/foo", null, FOO_PATH);
+ await setCookie("session_foo_path_2", null, "/foo", null, FOO_PATH);
+ await setCookie("session_foo_path_3", null, "/foo", null, FOO_PATH);
+ await setCookie("session_foo_path_4", null, "/foo", null, FOO_PATH);
+ await setCookie("session_foo_path_5", null, "/foo", null, FOO_PATH);
+ verifyCookies(
+ [
+ "session_foo_path_1",
+ "session_foo_path_2",
+ "session_foo_path_3",
+ "session_foo_path_4",
+ "session_foo_path_5",
+ ],
+ BASE_URI
+ );
+
+ // Check if cookies are evicted by creation time.
+ await setCookie("session_foo_path_6", null, "/foo", null, FOO_PATH);
+ verifyCookies(
+ ["session_foo_path_4", "session_foo_path_5", "session_foo_path_6"],
+ BASE_URI
+ );
+
+ await setCookie("session_bar_path_1", null, "/bar", null, BAR_PATH);
+ await setCookie("session_bar_path_2", null, "/bar", null, BAR_PATH);
+
+ verifyCookies(
+ [
+ "session_foo_path_4",
+ "session_foo_path_5",
+ "session_foo_path_6",
+ "session_bar_path_1",
+ "session_bar_path_2",
+ ],
+ BASE_URI
+ );
+
+ // Check if cookies are evicted by last accessed time.
+ await CookieXPCShellUtils.getCookieStringFromDocument(FOO_PATH.spec);
+
+ await setCookie("session_foo_path_7", null, "/foo", null, FOO_PATH);
+ verifyCookies(
+ ["session_foo_path_5", "session_foo_path_6", "session_foo_path_7"],
+ BASE_URI
+ );
+
+ const EXPIRED_TIME = 3;
+
+ await setCookie(
+ "non_session_expired_foo_path_1",
+ null,
+ "/foo",
+ EXPIRED_TIME,
+ FOO_PATH
+ );
+ await setCookie(
+ "non_session_expired_foo_path_2",
+ null,
+ "/foo",
+ EXPIRED_TIME,
+ FOO_PATH
+ );
+ verifyCookies(
+ [
+ "session_foo_path_5",
+ "session_foo_path_6",
+ "session_foo_path_7",
+ "non_session_expired_foo_path_1",
+ "non_session_expired_foo_path_2",
+ ],
+ BASE_URI
+ );
+
+ // Check if expired cookies are evicted first.
+ await new Promise(resolve => do_timeout(EXPIRED_TIME * 1000, resolve));
+ await setCookie("session_foo_path_8", null, "/foo", null, FOO_PATH);
+ verifyCookies(
+ ["session_foo_path_6", "session_foo_path_7", "session_foo_path_8"],
+ BASE_URI
+ );
+
+ Services.cookies.removeAll();
+});
+
+// Verify that the given cookie names exist, and are ordered from least to most recently accessed
+function verifyCookies(names, uri) {
+ Assert.equal(Services.cookies.countCookiesFromHost(uri.host), names.length);
+ let actual_cookies = [];
+ for (let cookie of Services.cookies.getCookiesFromHost(uri.host, {})) {
+ actual_cookies.push(cookie);
+ }
+ if (names.length != actual_cookies.length) {
+ let left = names.filter(function (n) {
+ return (
+ actual_cookies.findIndex(function (c) {
+ return c.name == n;
+ }) == -1
+ );
+ });
+ let right = actual_cookies
+ .filter(function (c) {
+ return (
+ names.findIndex(function (n) {
+ return c.name == n;
+ }) == -1
+ );
+ })
+ .map(function (c) {
+ return c.name;
+ });
+ if (left.length) {
+ info("unexpected cookies: " + left);
+ }
+ if (right.length) {
+ info("expected cookies: " + right);
+ }
+ }
+ Assert.equal(names.length, actual_cookies.length);
+ actual_cookies.sort(function (a, b) {
+ if (a.lastAccessed < b.lastAccessed) {
+ return -1;
+ }
+ if (a.lastAccessed > b.lastAccessed) {
+ return 1;
+ }
+ return 0;
+ });
+ for (var i = 0; i < names.length; i++) {
+ Assert.equal(names[i], actual_cookies[i].name);
+ Assert.equal(names[i].startsWith("session"), actual_cookies[i].isSession);
+ }
+}
+
+var lastValue = 0;
+function setCookie(name, domain, path, maxAge, url) {
+ let value = name + "=" + ++lastValue;
+ var s = "setting cookie " + value;
+ if (domain) {
+ value += "; Domain=" + domain;
+ s += " (d=" + domain + ")";
+ }
+ if (path) {
+ value += "; Path=" + path;
+ s += " (p=" + path + ")";
+ }
+ if (maxAge) {
+ value += "; Max-Age=" + maxAge;
+ s += " (non-session)";
+ } else {
+ s += " (session)";
+ }
+ s += " for " + url.spec;
+ info(s);
+
+ let channel = NetUtil.newChannel({
+ uri: url,
+ loadUsingSystemPrincipal: true,
+ contentPolicyType: Ci.nsIContentPolicy.TYPE_DOCUMENT,
+ });
+
+ Services.cookies.setCookieStringFromHttp(url, value, channel);
+
+ return new Promise(function (resolve) {
+ // Windows XP has low precision timestamps that cause our cookie eviction
+ // algorithm to produce different results from other platforms. We work around
+ // this by ensuring that there's a clear gap between each cookie update.
+ do_timeout(10, resolve);
+ });
+}
diff --git a/netwerk/cookie/test/unit/test_getCookieSince.js b/netwerk/cookie/test/unit/test_getCookieSince.js
new file mode 100644
index 0000000000..6d419860ed
--- /dev/null
+++ b/netwerk/cookie/test/unit/test_getCookieSince.js
@@ -0,0 +1,70 @@
+const { NetUtil } = ChromeUtils.import("resource://gre/modules/NetUtil.jsm");
+
+function setCookie(name, url) {
+ let value = `${name}=${Math.random()}; Path=/; Max-Age=1000; sameSite=none; Secure`;
+ info(`Setting cookie ${value} for ${url.spec}`);
+
+ let channel = NetUtil.newChannel({
+ uri: url,
+ loadUsingSystemPrincipal: true,
+ contentPolicyType: Ci.nsIContentPolicy.TYPE_DOCUMENT,
+ });
+
+ Services.cookies.setCookieStringFromHttp(url, value, channel);
+}
+
+async function sleep() {
+ await new Promise(resolve => do_timeout(1000, resolve));
+}
+
+function checkSorting(cookies) {
+ for (let i = 1; i < cookies.length; ++i) {
+ Assert.greater(
+ cookies[i].creationTime,
+ cookies[i - 1].creationTime,
+ "Cookie " + cookies[i].name
+ );
+ }
+}
+
+add_task(async function () {
+ Services.prefs.setBoolPref(
+ "network.cookieJarSettings.unblocked_for_testing",
+ true
+ );
+
+ await setCookie("A", Services.io.newURI("https://example.com/A/"));
+ await sleep();
+
+ await setCookie("B", Services.io.newURI("https://foo.bar/B/"));
+ await sleep();
+
+ await setCookie("C", Services.io.newURI("https://example.org/C/"));
+ await sleep();
+
+ await setCookie("D", Services.io.newURI("https://example.com/D/"));
+ await sleep();
+
+ Assert.equal(Services.cookies.cookies.length, 4, "Cookie check");
+
+ const cookies = Services.cookies.getCookiesSince(0);
+ Assert.equal(cookies.length, 4, "We retrieve all the 4 cookies");
+ checkSorting(cookies);
+
+ let someCookies = Services.cookies.getCookiesSince(
+ cookies[0].creationTime + 1
+ );
+ Assert.equal(someCookies.length, 3, "We retrieve some cookies");
+ checkSorting(someCookies);
+
+ someCookies = Services.cookies.getCookiesSince(cookies[1].creationTime + 1);
+ Assert.equal(someCookies.length, 2, "We retrieve some cookies");
+ checkSorting(someCookies);
+
+ someCookies = Services.cookies.getCookiesSince(cookies[2].creationTime + 1);
+ Assert.equal(someCookies.length, 1, "We retrieve some cookies");
+ checkSorting(someCookies);
+
+ someCookies = Services.cookies.getCookiesSince(cookies[3].creationTime + 1);
+ Assert.equal(someCookies.length, 0, "We retrieve some cookies");
+});
diff --git a/netwerk/cookie/test/unit/test_migrateCookieLifetimePref.js b/netwerk/cookie/test/unit/test_migrateCookieLifetimePref.js
new file mode 100644
index 0000000000..088a909709
--- /dev/null
+++ b/netwerk/cookie/test/unit/test_migrateCookieLifetimePref.js
@@ -0,0 +1,65 @@
+/* Any copyright is dedicated to the Public Domain.
+ * http://creativecommons.org/publicdomain/zero/1.0/ */
+
+/*
+ Tests that
+ - the migration code runs,
+ - the sanitize on shutdown prefs for profiles with the network.cookie.lifetimePolicy enabled are set to true,
+ - the previous settings for clearOnShutdown prefs will not be applied due to sanitizeOnShutdown being disabled
+ - the network.cookie.lifetimePolicy is disabled afterwards.
+*/
+add_task(async function migrateSanitizationPrefsClearCleaningPrefs() {
+ // Former network.cookie.lifetimePolicy values ACCEPT_SESSION/ACCEPT_NORMALLY are not available anymore
+ // 2 = ACCEPT_SESSION
+ Services.prefs.setIntPref("network.cookie.lifetimePolicy", 2);
+ Services.prefs.setBoolPref("privacy.sanitize.sanitizeOnShutdown", false);
+ Services.prefs.setBoolPref("privacy.clearOnShutdown.cache", false);
+ Services.prefs.setBoolPref("privacy.clearOnShutdown.cookies", false);
+ Services.prefs.setBoolPref("privacy.clearOnShutdown.offlineApps", false);
+ Services.prefs.setBoolPref("privacy.clearOnShutdown.downloads", true);
+ Services.prefs.setBoolPref("privacy.clearOnShutdown.sessions", true);
+
+ // The migration code is called in cookieService::Init
+ Services.cookies;
+
+ // Former network.cookie.lifetimePolicy values ACCEPT_SESSION/ACCEPT_NORMALLY are not available anymore
+ // 0 = ACCEPT_NORMALLY
+ Assert.equal(
+ Services.prefs.getIntPref("network.cookie.lifetimePolicy", 0),
+ 0,
+ "Cookie lifetime policy is off"
+ );
+
+ Assert.ok(
+ Services.prefs.getBoolPref("privacy.sanitize.sanitizeOnShutdown"),
+ "Sanitize on shutdown is set"
+ );
+
+ Assert.ok(
+ Services.prefs.getBoolPref("privacy.clearOnShutdown.cookies"),
+ "Clearing cookies on shutdown is selected"
+ );
+
+ Assert.ok(
+ Services.prefs.getBoolPref("privacy.clearOnShutdown.cache"),
+ "Clearing cache on shutdown is still selected"
+ );
+
+ Assert.ok(
+ Services.prefs.getBoolPref("privacy.clearOnShutdown.offlineApps"),
+ "Clearing offline apps on shutdown is selected"
+ );
+
+ Assert.ok(
+ !Services.prefs.getBoolPref("privacy.clearOnShutdown.downloads"),
+ "Clearing downloads on shutdown is not set anymore"
+ );
+ Assert.ok(
+ !Services.prefs.getBoolPref("privacy.clearOnShutdown.sessions"),
+ "Clearing active logins on shutdown is not set anymore"
+ );
+
+ Services.prefs.resetPrefs();
+
+ delete Services.cookies;
+});
diff --git a/netwerk/cookie/test/unit/test_parser_0001.js b/netwerk/cookie/test/unit/test_parser_0001.js
new file mode 100644
index 0000000000..60a65b9718
--- /dev/null
+++ b/netwerk/cookie/test/unit/test_parser_0001.js
@@ -0,0 +1,30 @@
+const { NetUtil } = ChromeUtils.import("resource://gre/modules/NetUtil.jsm");
+
+function inChildProcess() {
+ return Services.appinfo.processType != Ci.nsIXULRuntime.PROCESS_TYPE_DEFAULT;
+}
+
+function run_test() {
+ // Allow all cookies if the pref service is available in this process.
+ if (!inChildProcess()) {
+ Services.prefs.setIntPref("network.cookie.cookieBehavior", 0);
+ Services.prefs.setBoolPref(
+ "network.cookieJarSettings.unblocked_for_testing",
+ true
+ );
+ }
+
+ let uri = NetUtil.newURI("http://example.org/");
+ let channel = NetUtil.newChannel({
+ uri,
+ loadUsingSystemPrincipal: true,
+ contentPolicyType: Ci.nsIContentPolicy.TYPE_DOCUMENT,
+ });
+
+ let set = "foo=bar";
+ Services.cookies.setCookieStringFromHttp(uri, set, channel);
+
+ let expected = "foo=bar";
+ let actual = Services.cookies.getCookieStringFromHttp(uri, channel);
+ Assert.equal(actual, expected);
+}
diff --git a/netwerk/cookie/test/unit/test_parser_0019.js b/netwerk/cookie/test/unit/test_parser_0019.js
new file mode 100644
index 0000000000..f2c883cb32
--- /dev/null
+++ b/netwerk/cookie/test/unit/test_parser_0019.js
@@ -0,0 +1,30 @@
+const { NetUtil } = ChromeUtils.import("resource://gre/modules/NetUtil.jsm");
+
+function inChildProcess() {
+ return Services.appinfo.processType != Ci.nsIXULRuntime.PROCESS_TYPE_DEFAULT;
+}
+
+function run_test() {
+ // Allow all cookies if the pref service is available in this process.
+ if (!inChildProcess()) {
+ Services.prefs.setIntPref("network.cookie.cookieBehavior", 0);
+ Services.prefs.setBoolPref(
+ "network.cookieJarSettings.unblocked_for_testing",
+ true
+ );
+ }
+
+ let uri = NetUtil.newURI("http://example.org/");
+ let channel = NetUtil.newChannel({
+ uri,
+ loadUsingSystemPrincipal: true,
+ contentPolicyType: Ci.nsIContentPolicy.TYPE_DOCUMENT,
+ });
+
+ let set = "foo=b;max-age=3600, c=d;path=/";
+ Services.cookies.setCookieStringFromHttp(uri, set, channel);
+
+ let expected = "foo=b";
+ let actual = Services.cookies.getCookieStringFromHttp(uri, channel);
+ Assert.equal(actual, expected);
+}
diff --git a/netwerk/cookie/test/unit/test_rawSameSite.js b/netwerk/cookie/test/unit/test_rawSameSite.js
new file mode 100644
index 0000000000..7cf10d5440
--- /dev/null
+++ b/netwerk/cookie/test/unit/test_rawSameSite.js
@@ -0,0 +1,123 @@
+const { NetUtil } = ChromeUtils.import("resource://gre/modules/NetUtil.jsm");
+
+function inChildProcess() {
+ return Services.appinfo.processType != Ci.nsIXULRuntime.PROCESS_TYPE_DEFAULT;
+}
+
+add_task(async _ => {
+ do_get_profile();
+
+ let dbFile = Services.dirsvc.get("ProfD", Ci.nsIFile);
+ dbFile.append("cookies.sqlite");
+
+ let storage = Services.storage;
+ let properties = Cc["@mozilla.org/hash-property-bag;1"].createInstance(
+ Ci.nsIWritablePropertyBag
+ );
+ properties.setProperty("shared", true);
+ let conn = storage.openDatabase(dbFile);
+
+ conn.schemaVersion = 9;
+ conn.executeSimpleSQL("DROP TABLE IF EXISTS moz_cookies");
+ conn.executeSimpleSQL(
+ "CREATE TABLE moz_cookies (" +
+ "id INTEGER PRIMARY KEY, " +
+ "baseDomain TEXT, " +
+ "originAttributes TEXT NOT NULL DEFAULT '', " +
+ "name TEXT, " +
+ "value TEXT, " +
+ "host TEXT, " +
+ "path TEXT, " +
+ "expiry INTEGER, " +
+ "lastAccessed INTEGER, " +
+ "creationTime INTEGER, " +
+ "isSecure INTEGER, " +
+ "isHttpOnly INTEGER, " +
+ "inBrowserElement INTEGER DEFAULT 0, " +
+ "sameSite INTEGER DEFAULT 0, " +
+ "CONSTRAINT moz_uniqueid UNIQUE (name, host, path, originAttributes)" +
+ ")"
+ );
+ conn.close();
+
+ // Allow all cookies if the pref service is available in this process.
+ if (!inChildProcess()) {
+ Services.prefs.setIntPref("network.cookie.cookieBehavior", 0);
+ Services.prefs.setBoolPref(
+ "network.cookieJarSettings.unblocked_for_testing",
+ true
+ );
+ Services.prefs.setBoolPref("network.cookie.sameSite.laxByDefault", true);
+ Services.prefs.setBoolPref(
+ "network.cookie.sameSite.noneRequiresSecure",
+ true
+ );
+ }
+
+ let uri = NetUtil.newURI("http://example.org/");
+
+ let principal = Services.scriptSecurityManager.createContentPrincipal(
+ uri,
+ {}
+ );
+
+ let channel = NetUtil.newChannel({
+ uri,
+ loadingPrincipal: principal,
+ securityFlags: Ci.nsILoadInfo.SEC_ALLOW_CROSS_ORIGIN_SEC_CONTEXT_IS_NULL,
+ contentPolicyType: Ci.nsIContentPolicy.TYPE_OTHER,
+ });
+
+ let tests = [
+ {
+ cookie: "foo=b;max-age=3600, c=d;path=/; sameSite=strict",
+ sameSite: 2,
+ rawSameSite: 2,
+ },
+ {
+ cookie: "foo=b;max-age=3600, c=d;path=/; sameSite=lax",
+ sameSite: 1,
+ rawSameSite: 1,
+ },
+ { cookie: "foo=b;max-age=3600, c=d;path=/", sameSite: 1, rawSameSite: 0 },
+ ];
+
+ for (let i = 0; i < tests.length; ++i) {
+ let test = tests[i];
+
+ let promise = new Promise(resolve => {
+ function observer(subject, topic, data) {
+ Services.obs.removeObserver(observer, "cookie-saved-on-disk");
+ resolve();
+ }
+
+ Services.obs.addObserver(observer, "cookie-saved-on-disk");
+ });
+
+ Services.cookies.setCookieStringFromHttp(uri, test.cookie, channel);
+
+ await promise;
+
+ conn = storage.openDatabase(dbFile);
+ Assert.equal(conn.schemaVersion, 12);
+
+ let stmt = conn.createStatement(
+ "SELECT sameSite, rawSameSite FROM moz_cookies"
+ );
+
+ let success = stmt.executeStep();
+ Assert.ok(success);
+
+ let sameSite = stmt.getInt32(0);
+ let rawSameSite = stmt.getInt32(1);
+ stmt.finalize();
+
+ Assert.equal(sameSite, test.sameSite);
+ Assert.equal(rawSameSite, test.rawSameSite);
+
+ Services.cookies.removeAll();
+
+ stmt.finalize();
+ conn.close();
+ }
+});
diff --git a/netwerk/cookie/test/unit/test_schemeMap.js b/netwerk/cookie/test/unit/test_schemeMap.js
new file mode 100644
index 0000000000..8802fd7e1f
--- /dev/null
+++ b/netwerk/cookie/test/unit/test_schemeMap.js
@@ -0,0 +1,214 @@
+const { NetUtil } = ChromeUtils.import("resource://gre/modules/NetUtil.jsm");
+
+function inChildProcess() {
+ return Services.appinfo.processType != Ci.nsIXULRuntime.PROCESS_TYPE_DEFAULT;
+}
+
+const { CookieXPCShellUtils } = ChromeUtils.importESModule(
+ "resource://testing-common/CookieXPCShellUtils.sys.mjs"
+);
+
+let CookieXPCShellUtilsInitialized = false;
+function maybeInitializeCookieXPCShellUtils() {
+ if (!CookieXPCShellUtilsInitialized) {
+ CookieXPCShellUtilsInitialized = true;
+ CookieXPCShellUtils.init(this);
+
+ CookieXPCShellUtils.createServer({ hosts: ["example.org"] });
+ }
+}
+
+// Don't pick up default permissions from profile.
+Services.prefs.setCharPref("permissions.manager.defaultsUrl", "");
+
+add_task(async _ => {
+ do_get_profile();
+
+ // Allow all cookies if the pref service is available in this process.
+ if (!inChildProcess()) {
+ Services.prefs.setIntPref("network.cookie.cookieBehavior", 0);
+ Services.prefs.setBoolPref(
+ "network.cookieJarSettings.unblocked_for_testing",
+ true
+ );
+ }
+
+ info("Let's set a cookie from HTTP example.org");
+
+ let uri = NetUtil.newURI("http://example.org/");
+ let principal = Services.scriptSecurityManager.createContentPrincipal(
+ uri,
+ {}
+ );
+ let channel = NetUtil.newChannel({
+ uri,
+ loadingPrincipal: principal,
+ securityFlags: Ci.nsILoadInfo.SEC_ALLOW_CROSS_ORIGIN_SEC_CONTEXT_IS_NULL,
+ contentPolicyType: Ci.nsIContentPolicy.TYPE_OTHER,
+ });
+
+ Services.cookies.setCookieStringFromHttp(uri, "a=b; sameSite=lax", channel);
+
+ let cookies = Services.cookies.getCookiesFromHost("example.org", {});
+ Assert.equal(cookies.length, 1, "We expect 1 cookie only");
+
+ Assert.equal(cookies[0].schemeMap, Ci.nsICookie.SCHEME_HTTP, "HTTP Scheme");
+
+ info("Let's set a cookie from HTTPS example.org");
+
+ uri = NetUtil.newURI("https://example.org/");
+ principal = Services.scriptSecurityManager.createContentPrincipal(uri, {});
+ channel = NetUtil.newChannel({
+ uri,
+ loadingPrincipal: principal,
+ securityFlags: Ci.nsILoadInfo.SEC_ALLOW_CROSS_ORIGIN_SEC_CONTEXT_IS_NULL,
+ contentPolicyType: Ci.nsIContentPolicy.TYPE_OTHER,
+ });
+
+ Services.cookies.setCookieStringFromHttp(uri, "a=b; sameSite=lax", channel);
+
+ cookies = Services.cookies.getCookiesFromHost("example.org", {});
+ Assert.equal(cookies.length, 1, "We expect 1 cookie only");
+
+ Assert.equal(
+ cookies[0].schemeMap,
+ Ci.nsICookie.SCHEME_HTTP | Ci.nsICookie.SCHEME_HTTPS,
+ "HTTP + HTTPS Schemes"
+ );
+
+ Services.cookies.removeAll();
+});
+
+[true, false].forEach(schemefulComparison => {
+ add_task(async () => {
+ do_get_profile();
+ Services.prefs.setBoolPref("dom.security.https_first", false);
+
+ maybeInitializeCookieXPCShellUtils();
+
+ // Allow all cookies if the pref service is available in this process.
+ if (!inChildProcess()) {
+ Services.prefs.setBoolPref(
+ "network.cookie.sameSite.schemeful",
+ schemefulComparison
+ );
+ Services.prefs.setIntPref("network.cookie.cookieBehavior", 0);
+ Services.prefs.setBoolPref(
+ "network.cookieJarSettings.unblocked_for_testing",
+ true
+ );
+ }
+
+ info(
+ `Testing schemefulSameSite=${schemefulComparison}. Let's set a cookie from HTTPS example.org`
+ );
+
+ let https_uri = NetUtil.newURI("https://example.org/");
+ let https_principal = Services.scriptSecurityManager.createContentPrincipal(
+ https_uri,
+ {}
+ );
+ let same_site_channel = NetUtil.newChannel({
+ uri: https_uri,
+ loadingPrincipal: https_principal,
+ securityFlags: Ci.nsILoadInfo.SEC_ALLOW_CROSS_ORIGIN_SEC_CONTEXT_IS_NULL,
+ contentPolicyType: Ci.nsIContentPolicy.TYPE_OTHER,
+ });
+
+ Services.cookies.setCookieStringFromHttp(
+ https_uri,
+ "a=b; sameSite=lax",
+ same_site_channel
+ );
+
+ let cookies = Services.cookies.getCookieStringFromHttp(
+ https_uri,
+ same_site_channel
+ );
+ Assert.equal(cookies, "a=b", "Cookies match");
+
+ let http_uri = NetUtil.newURI("http://example.org/");
+ let http_principal = Services.scriptSecurityManager.createContentPrincipal(
+ http_uri,
+ {}
+ );
+ let cross_site_channel = NetUtil.newChannel({
+ uri: https_uri,
+ loadingPrincipal: http_principal,
+ securityFlags: Ci.nsILoadInfo.SEC_ALLOW_CROSS_ORIGIN_SEC_CONTEXT_IS_NULL,
+ contentPolicyType: Ci.nsIContentPolicy.TYPE_OTHER,
+ });
+
+ cookies = Services.cookies.getCookieStringFromHttp(
+ http_uri,
+ cross_site_channel
+ );
+ if (schemefulComparison) {
+ Assert.equal(cookies, "", "No http(s) cookie for different scheme!");
+ } else {
+ Assert.equal(cookies, "a=b", "http(s) Cookie even for differentscheme!");
+ }
+
+ // SameSite cookies are included via document.domain
+ cookies = await CookieXPCShellUtils.getCookieStringFromDocument(
+ http_uri.spec
+ );
+ Assert.equal(cookies, "a=b", "document.cookie even for different scheme!");
+
+ Services.cookies.removeAll();
+ Services.prefs.clearUserPref("dom.security.https_first");
+ });
+});
+
+add_task(async _ => {
+ do_get_profile();
+ Services.prefs.setBoolPref("dom.security.https_first", false);
+
+ // Allow all cookies if the pref service is available in this process.
+ if (!inChildProcess()) {
+ Services.prefs.setIntPref("network.cookie.cookieBehavior", 0);
+ Services.prefs.setBoolPref(
+ "network.cookieJarSettings.unblocked_for_testing",
+ true
+ );
+ }
+
+ info("Let's set a cookie without scheme");
+ Services.cookies.add(
+ "example.org",
+ "/",
+ "a",
+ "b",
+ false,
+ false,
+ false,
+ Math.floor(Date.now() / 1000 + 1000),
+ {},
+ Ci.nsICookie.SAMESITE_LAX,
+ Ci.nsICookie.SCHEME_UNSET
+ );
+
+ let cookies = Services.cookies.getCookiesFromHost("example.org", {});
+ Assert.equal(cookies.length, 1, "We expect 1 cookie only");
+ Assert.equal(cookies[0].schemeMap, Ci.nsICookie.SCHEME_UNSET, "Unset scheme");
+
+ ["https", "http"].forEach(scheme => {
+ let uri = NetUtil.newURI(scheme + "://example.org/");
+ let principal = Services.scriptSecurityManager.createContentPrincipal(
+ uri,
+ {}
+ );
+ let channel = NetUtil.newChannel({
+ uri,
+ loadingPrincipal: principal,
+ securityFlags: Ci.nsILoadInfo.SEC_ALLOW_CROSS_ORIGIN_SEC_CONTEXT_IS_NULL,
+ contentPolicyType: Ci.nsIContentPolicy.TYPE_OTHER,
+ });
+
+ cookies = Services.cookies.getCookieStringFromHttp(uri, channel);
+ Assert.equal(cookies, "a=b", "Cookie for unset scheme");
+ });
+
+ Services.cookies.removeAll();
+ Services.prefs.clearUserPref("dom.security.https_first");
+});
diff --git a/netwerk/cookie/test/unit/test_timestamp_fixup.js b/netwerk/cookie/test/unit/test_timestamp_fixup.js
new file mode 100644
index 0000000000..961241cc97
--- /dev/null
+++ b/netwerk/cookie/test/unit/test_timestamp_fixup.js
@@ -0,0 +1,137 @@
+/* Any copyright is dedicated to the Public Domain.
+ * http://creativecommons.org/publicdomain/zero/1.0/ */
+
+const { AppConstants } = ChromeUtils.importESModule(
+ "resource://gre/modules/AppConstants.sys.mjs"
+);
+
+const USEC_PER_SEC = 1000 * 1000;
+const ONE_DAY = 60 * 60 * 24 * USEC_PER_SEC;
+const ONE_YEAR = ONE_DAY * 365;
+const LAST_ACCESSED_DIFF = 10 * ONE_YEAR;
+const CREATION_DIFF = 100 * ONE_YEAR;
+
+function initDB(conn, now) {
+ // Write the schema v7 to the database.
+ conn.schemaVersion = 7;
+ conn.executeSimpleSQL(
+ "CREATE TABLE moz_cookies (" +
+ "id INTEGER PRIMARY KEY, " +
+ "baseDomain TEXT, " +
+ "originAttributes TEXT NOT NULL DEFAULT '', " +
+ "name TEXT, " +
+ "value TEXT, " +
+ "host TEXT, " +
+ "path TEXT, " +
+ "expiry INTEGER, " +
+ "lastAccessed INTEGER, " +
+ "creationTime INTEGER, " +
+ "isSecure INTEGER, " +
+ "isHttpOnly INTEGER, " +
+ "appId INTEGER DEFAULT 0, " +
+ "inBrowserElement INTEGER DEFAULT 0, " +
+ "CONSTRAINT moz_uniqueid UNIQUE (name, host, path, originAttributes)" +
+ ")"
+ );
+ conn.executeSimpleSQL(
+ "CREATE INDEX moz_basedomain ON moz_cookies (baseDomain, " +
+ "originAttributes)"
+ );
+
+ conn.executeSimpleSQL("PRAGMA synchronous = OFF");
+ conn.executeSimpleSQL("PRAGMA journal_mode = WAL");
+ conn.executeSimpleSQL("PRAGMA wal_autocheckpoint = 16");
+
+ conn.executeSimpleSQL(
+ `INSERT INTO moz_cookies(baseDomain, host, name, value, path, expiry, lastAccessed, creationTime, isSecure, isHttpOnly)
+ VALUES ('foo.com', '.foo.com', 'foo', 'bar=baz', '/',
+ ${now + ONE_DAY}, ${now + LAST_ACCESSED_DIFF} , ${
+ now + CREATION_DIFF
+ } , 1, 1)`
+ );
+}
+
+add_task(async function test_timestamp_fixup() {
+ let now = Date.now() * 1000; // date in microseconds
+ Services.prefs.setBoolPref("network.cookie.fixup_on_db_load", true);
+ do_get_profile();
+ let dbFile = Services.dirsvc.get("ProfD", Ci.nsIFile);
+ dbFile.append("cookies.sqlite");
+ let conn = Services.storage.openDatabase(dbFile);
+ initDB(conn, now);
+
+ if (AppConstants.platform != "android") {
+ Services.fog.initializeFOG();
+ Services.fog.testResetFOG();
+ }
+
+ // Now start the cookie service, and then check the fields in the table.
+ // Get sessionCookies to wait for the initialization in cookie thread
+ Assert.lessOrEqual(
+ Math.floor(Services.cookies.cookies[0].creationTime / 1000),
+ now
+ );
+ Assert.equal(conn.schemaVersion, 12);
+
+ // Testing telemetry is disabled until we can fix
+ // Bug 1752139 - Support `TestResetFOG` on Android
+ if (AppConstants.platform == "android") {
+ conn.close();
+ return;
+ }
+
+ Assert.equal(
+ await Glean.networking.cookieTimestampFixedCount.creationTime.testGetValue(),
+ 1,
+ "One fixup of creation time"
+ );
+ Assert.equal(
+ await Glean.networking.cookieTimestampFixedCount.lastAccessed.testGetValue(),
+ 1,
+ "One fixup of lastAccessed"
+ );
+ {
+ let { values } =
+ await Glean.networking.cookieCreationFixupDiff.testGetValue();
+ info(JSON.stringify(values));
+ let keys = Object.keys(values).splice(-2, 2);
+ Assert.equal(keys.length, 2, "There should be two entries in telemetry");
+ Assert.equal(values[keys[0]], 1, "First entry should have value 1");
+ Assert.equal(values[keys[1]], 0, "Second entry should have value 0");
+ const creationDiffInSeconds = CREATION_DIFF / USEC_PER_SEC;
+ Assert.lessOrEqual(
+ parseInt(keys[0]),
+ creationDiffInSeconds,
+ "The bucket should be smaller than time diff"
+ );
+ Assert.lessOrEqual(
+ creationDiffInSeconds,
+ parseInt(keys[1]),
+ "The next bucket should be larger than time diff"
+ );
+ }
+
+ {
+ let { values } =
+ await Glean.networking.cookieAccessFixupDiff.testGetValue();
+ info(JSON.stringify(values));
+ let keys = Object.keys(values).splice(-2, 2);
+ Assert.equal(keys.length, 2, "There should be two entries in telemetry");
+ Assert.equal(values[keys[0]], 1, "First entry should have value 1");
+ Assert.equal(values[keys[1]], 0, "Second entry should have value 0");
+ info(now);
+ const lastAccessedDiffInSeconds = LAST_ACCESSED_DIFF / USEC_PER_SEC;
+ Assert.lessOrEqual(
+ parseInt(keys[0]),
+ lastAccessedDiffInSeconds,
+ "The bucket should be smaller than time diff"
+ );
+ Assert.lessOrEqual(
+ lastAccessedDiffInSeconds,
+ parseInt(keys[1]),
+ "The next bucket should be larger than time diff"
+ );
+ }
+
+ conn.close();
+});
diff --git a/netwerk/cookie/test/unit/xpcshell.ini b/netwerk/cookie/test/unit/xpcshell.ini
new file mode 100644
index 0000000000..0147643a89
--- /dev/null
+++ b/netwerk/cookie/test/unit/xpcshell.ini
@@ -0,0 +1,15 @@
+[DEFAULT]
+head =
+
+[test_baseDomain_publicsuffix.js]
+[test_bug643051.js]
+[test_bug1155169.js]
+[test_bug1321912.js]
+[test_eviction.js]
+[test_getCookieSince.js]
+[test_migrateCookieLifetimePref.js]
+[test_parser_0001.js]
+[test_parser_0019.js]
+[test_rawSameSite.js]
+[test_schemeMap.js]
+[test_timestamp_fixup.js]