diff options
Diffstat (limited to '')
-rw-r--r-- | netwerk/cookie/test/unit/test_baseDomain_publicsuffix.js | 107 | ||||
-rw-r--r-- | netwerk/cookie/test/unit/test_bug1155169.js | 93 | ||||
-rw-r--r-- | netwerk/cookie/test/unit/test_bug1321912.js | 101 | ||||
-rw-r--r-- | netwerk/cookie/test/unit/test_bug643051.js | 41 | ||||
-rw-r--r-- | netwerk/cookie/test/unit/test_eviction.js | 212 | ||||
-rw-r--r-- | netwerk/cookie/test/unit/test_getCookieSince.js | 72 | ||||
-rw-r--r-- | netwerk/cookie/test/unit/test_parser_0001.js | 33 | ||||
-rw-r--r-- | netwerk/cookie/test/unit/test_parser_0019.js | 33 | ||||
-rw-r--r-- | netwerk/cookie/test/unit/test_rawSameSite.js | 126 | ||||
-rw-r--r-- | netwerk/cookie/test/unit/test_schemeMap.js | 287 | ||||
-rw-r--r-- | netwerk/cookie/test/unit/xpcshell.ini | 13 |
11 files changed, 1118 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..9d58c06695 --- /dev/null +++ b/netwerk/cookie/test/unit/test_baseDomain_publicsuffix.js @@ -0,0 +1,107 @@ +"use strict"; + +const { Services } = ChromeUtils.import("resource://gre/modules/Services.jsm"); + +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..4bccac6d1d --- /dev/null +++ b/netwerk/cookie/test/unit/test_bug1155169.js @@ -0,0 +1,93 @@ +const { NetUtil } = ChromeUtils.import("resource://gre/modules/NetUtil.jsm"); +const { Services } = ChromeUtils.import("resource://gre/modules/Services.jsm"); + +const URI = Services.io.newURI("http://example.org/"); + +const cs = Cc["@mozilla.org/cookieService;1"].getService(Ci.nsICookieService); + +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, + }); + + cs.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..46c9bf4a9f --- /dev/null +++ b/netwerk/cookie/test/unit/test_bug1321912.js @@ -0,0 +1,101 @@ +const { Services } = ChromeUtils.import("resource://gre/modules/Services.jsm"); + +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 +const cookies = 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..3aab640773 --- /dev/null +++ b/netwerk/cookie/test/unit/test_bug643051.js @@ -0,0 +1,41 @@ +const { NetUtil } = ChromeUtils.import("resource://gre/modules/NetUtil.jsm"); +const { Services } = ChromeUtils.import("resource://gre/modules/Services.jsm"); +const { CookieXPCShellUtils } = ChromeUtils.import( + "resource://testing-common/CookieXPCShellUtils.jsm" +); + +CookieXPCShellUtils.init(this); +CookieXPCShellUtils.createServer({ hosts: ["example.net"] }); + +add_task(async () => { + // Allow all cookies. + Services.prefs.setIntPref("network.cookie.cookieBehavior", 0); + Services.prefs.setBoolPref( + "network.cookieJarSettings.unblocked_for_testing", + true + ); + + let cs = Cc["@mozilla.org/cookieService;1"].getService(Ci.nsICookieService); + + 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"; + cs.setCookieStringFromHttp(uri, set, channel); + + let actual = cs.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); +}); diff --git a/netwerk/cookie/test/unit/test_eviction.js b/netwerk/cookie/test/unit/test_eviction.js new file mode 100644 index 0000000000..30634d7818 --- /dev/null +++ b/netwerk/cookie/test/unit/test_eviction.js @@ -0,0 +1,212 @@ +const { NetUtil } = ChromeUtils.import("resource://gre/modules/NetUtil.jsm"); +const { Services } = ChromeUtils.import("resource://gre/modules/Services.jsm"); + +var { XPCOMUtils } = ChromeUtils.import( + "resource://gre/modules/XPCOMUtils.jsm" +); + +const BASE_HOST = "example.org"; +const BASE_HOSTNAMES = ["example.org", "example.co.uk"]; +const SUBDOMAINS = ["", "pub.", "www.", "other."]; + +const { CookieXPCShellUtils } = ChromeUtils.import( + "resource://testing-common/CookieXPCShellUtils.jsm" +); + +CookieXPCShellUtils.init(this); +CookieXPCShellUtils.createServer({ hosts: ["example.org"] }); + +XPCOMUtils.defineLazyServiceGetter( + this, + "cm", + "@mozilla.org/cookiemanager;1", + "nsICookieManager" +); + +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 + ); + + cm.removeAll(); +}); + +// Verify that the given cookie names exist, and are ordered from least to most recently accessed +function verifyCookies(names, uri) { + Assert.equal(cm.countCookiesFromHost(uri.host), names.length); + let actual_cookies = []; + for (let cookie of cm.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, + }); + + const cs = Cc["@mozilla.org/cookieService;1"].getService(Ci.nsICookieService); + cs.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..d807cb548c --- /dev/null +++ b/netwerk/cookie/test/unit/test_getCookieSince.js @@ -0,0 +1,72 @@ +const { NetUtil } = ChromeUtils.import("resource://gre/modules/NetUtil.jsm"); +const { Services } = ChromeUtils.import("resource://gre/modules/Services.jsm"); + +const cs = Cc["@mozilla.org/cookieService;1"].getService(Ci.nsICookieService); +const cm = cs.QueryInterface(Ci.nsICookieManager); + +function setCookie(name, url) { + let value = `${name}=${Math.random()}; Path=/; Max-Age=1000; sameSite=none`; + info(`Setting cookie ${value} for ${url.spec}`); + + let channel = NetUtil.newChannel({ + uri: url, + loadUsingSystemPrincipal: true, + contentPolicyType: Ci.nsIContentPolicy.TYPE_DOCUMENT, + }); + + cs.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(cm.cookies.length, 4, "Cookie check"); + + const cookies = cm.getCookiesSince(0); + Assert.equal(cookies.length, 4, "We retrieve all the 4 cookies"); + checkSorting(cookies); + + let someCookies = cm.getCookiesSince(cookies[0].creationTime + 1); + Assert.equal(someCookies.length, 3, "We retrieve some cookies"); + checkSorting(someCookies); + + someCookies = cm.getCookiesSince(cookies[1].creationTime + 1); + Assert.equal(someCookies.length, 2, "We retrieve some cookies"); + checkSorting(someCookies); + + someCookies = cm.getCookiesSince(cookies[2].creationTime + 1); + Assert.equal(someCookies.length, 1, "We retrieve some cookies"); + checkSorting(someCookies); + + someCookies = cm.getCookiesSince(cookies[3].creationTime + 1); + Assert.equal(someCookies.length, 0, "We retrieve some 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..9b9f10613f --- /dev/null +++ b/netwerk/cookie/test/unit/test_parser_0001.js @@ -0,0 +1,33 @@ +const { NetUtil } = ChromeUtils.import("resource://gre/modules/NetUtil.jsm"); +const { Services } = ChromeUtils.import("resource://gre/modules/Services.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 cs = Cc["@mozilla.org/cookieService;1"].getService(Ci.nsICookieService); + + let uri = NetUtil.newURI("http://example.org/"); + let channel = NetUtil.newChannel({ + uri, + loadUsingSystemPrincipal: true, + contentPolicyType: Ci.nsIContentPolicy.TYPE_DOCUMENT, + }); + + let set = "foo=bar"; + cs.setCookieStringFromHttp(uri, set, channel); + + let expected = "foo=bar"; + let actual = cs.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..acf68d6b78 --- /dev/null +++ b/netwerk/cookie/test/unit/test_parser_0019.js @@ -0,0 +1,33 @@ +const { NetUtil } = ChromeUtils.import("resource://gre/modules/NetUtil.jsm"); +const { Services } = ChromeUtils.import("resource://gre/modules/Services.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 cs = Cc["@mozilla.org/cookieService;1"].getService(Ci.nsICookieService); + + 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=/"; + cs.setCookieStringFromHttp(uri, set, channel); + + let expected = "foo=b"; + let actual = cs.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..b8f833b7da --- /dev/null +++ b/netwerk/cookie/test/unit/test_rawSameSite.js @@ -0,0 +1,126 @@ +const { NetUtil } = ChromeUtils.import("resource://gre/modules/NetUtil.jsm"); +const { Services } = ChromeUtils.import("resource://gre/modules/Services.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 cs = Cc["@mozilla.org/cookieService;1"].getService(Ci.nsICookieService); + + 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"); + }); + + cs.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..e0ab8f6385 --- /dev/null +++ b/netwerk/cookie/test/unit/test_schemeMap.js @@ -0,0 +1,287 @@ +const { NetUtil } = ChromeUtils.import("resource://gre/modules/NetUtil.jsm"); +const { Services } = ChromeUtils.import("resource://gre/modules/Services.jsm"); + +var { XPCOMUtils } = ChromeUtils.import( + "resource://gre/modules/XPCOMUtils.jsm" +); + +XPCOMUtils.defineLazyServiceGetter( + Services, + "cookiemgr", + "@mozilla.org/cookiemanager;1", + "nsICookieManager" +); + +function inChildProcess() { + return Services.appinfo.processType != Ci.nsIXULRuntime.PROCESS_TYPE_DEFAULT; +} + +const { CookieXPCShellUtils } = ChromeUtils.import( + "resource://testing-common/CookieXPCShellUtils.jsm" +); + +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 + ); + } + + let cs = Cc["@mozilla.org/cookieService;1"].getService(Ci.nsICookieService); + + 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, + }); + + cs.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, + }); + + cs.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(); + + 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 + ); + } + + let cs = Cc["@mozilla.org/cookieService;1"].getService(Ci.nsICookieService); + + info("Let's set a cookie from HTTP example.org"); + + let uri = NetUtil.newURI("https://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, + }); + + cs.setCookieStringFromHttp(uri, "a=b; sameSite=lax", channel); + + let cookies = Services.cookies.getCookieStringFromHttp(uri, channel); + Assert.equal(cookies, "a=b", "Cookies match"); + + uri = NetUtil.newURI("http://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, + }); + + cookies = Services.cookies.getCookieStringFromHttp(uri, channel); + if (schemefulComparison) { + Assert.equal(cookies, "", "No cookie for different scheme!"); + } else { + Assert.equal(cookies, "a=b", "Cookie even for different scheme!"); + } + + cookies = await CookieXPCShellUtils.getCookieStringFromDocument(uri.spec); + if (schemefulComparison) { + Assert.equal(cookies, "", "No cookie for different scheme!"); + } else { + Assert.equal(cookies, "a=b", "Cookie even for different scheme!"); + } + + Services.cookies.removeAll(); + }); +}); + +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 without scheme"); + Services.cookiemgr.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(); +}); + +[ + { + prefValue: true, + consoleMessage: `Cookie “a” has been treated as cross-site against “http://example.org/” because the scheme does not match.`, + }, + { + prefValue: false, + consoleMessage: `Cookie “a” will be soon treated as cross-site cookie against “http://example.org/” because the scheme does not match.`, + }, +].forEach(test => { + add_task(async () => { + do_get_profile(); + + maybeInitializeCookieXPCShellUtils(); + + // Allow all cookies if the pref service is available in this process. + if (!inChildProcess()) { + Services.prefs.setBoolPref( + "network.cookie.sameSite.schemeful", + test.prefValue + ); + Services.prefs.setIntPref("network.cookie.cookieBehavior", 0); + Services.prefs.setBoolPref( + "network.cookieJarSettings.unblocked_for_testing", + true + ); + } + + let cs = Cc["@mozilla.org/cookieService;1"].getService(Ci.nsICookieService); + + info("Let's set a cookie from HTTPS example.org"); + + let uri = NetUtil.newURI("https://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, + }); + + cs.setCookieStringFromHttp(uri, "a=b; sameSite=lax", channel); + + // Create a console listener. + let consolePromise = new Promise(resolve => { + let listener = { + observe(message) { + // Ignore unexpected messages. + if (!(message instanceof Ci.nsIConsoleMessage)) { + return; + } + + if (message.message.includes(test.consoleMessage)) { + Services.console.unregisterListener(listener); + resolve(); + } + }, + }; + + Services.console.registerListener(listener); + }); + + const contentPage = await CookieXPCShellUtils.loadContentPage( + "http://example.org/" + ); + await contentPage.close(); + + await consolePromise; + Services.cookies.removeAll(); + }); +}); diff --git a/netwerk/cookie/test/unit/xpcshell.ini b/netwerk/cookie/test/unit/xpcshell.ini new file mode 100644 index 0000000000..3320111637 --- /dev/null +++ b/netwerk/cookie/test/unit/xpcshell.ini @@ -0,0 +1,13 @@ +[DEFAULT] +head = + +[test_baseDomain_publicsuffix.js] +[test_bug643051.js] +[test_bug1155169.js] +[test_bug1321912.js] +[test_parser_0001.js] +[test_parser_0019.js] +[test_eviction.js] +[test_rawSameSite.js] +[test_getCookieSince.js] +[test_schemeMap.js] |