diff options
Diffstat (limited to 'netwerk/cookie/test')
-rw-r--r-- | netwerk/cookie/test/browser/browser.ini | 5 | ||||
-rw-r--r-- | netwerk/cookie/test/browser/browser_originattributes.js | 113 | ||||
-rw-r--r-- | netwerk/cookie/test/browser/file_empty.html | 3 | ||||
-rw-r--r-- | netwerk/cookie/test/unit/test_bug1155169.js | 73 | ||||
-rw-r--r-- | netwerk/cookie/test/unit/test_bug1267910.js | 196 | ||||
-rw-r--r-- | netwerk/cookie/test/unit/test_bug643051.js | 29 | ||||
-rw-r--r-- | netwerk/cookie/test/unit/test_eviction.js | 296 | ||||
-rw-r--r-- | netwerk/cookie/test/unit/test_parser_0001.js | 29 | ||||
-rw-r--r-- | netwerk/cookie/test/unit/test_parser_0019.js | 29 | ||||
-rw-r--r-- | netwerk/cookie/test/unit/xpcshell.ini | 10 | ||||
-rw-r--r-- | netwerk/cookie/test/unit_ipc/test_ipc_parser_0001.js | 9 | ||||
-rw-r--r-- | netwerk/cookie/test/unit_ipc/test_ipc_parser_0019.js | 9 | ||||
-rw-r--r-- | netwerk/cookie/test/unit_ipc/xpcshell.ini | 10 |
13 files changed, 811 insertions, 0 deletions
diff --git a/netwerk/cookie/test/browser/browser.ini b/netwerk/cookie/test/browser/browser.ini new file mode 100644 index 000000000..342e14578 --- /dev/null +++ b/netwerk/cookie/test/browser/browser.ini @@ -0,0 +1,5 @@ +[DEFAULT] +support-files = + file_empty.html + +[browser_originattributes.js] diff --git a/netwerk/cookie/test/browser/browser_originattributes.js b/netwerk/cookie/test/browser/browser_originattributes.js new file mode 100644 index 000000000..617d52e35 --- /dev/null +++ b/netwerk/cookie/test/browser/browser_originattributes.js @@ -0,0 +1,113 @@ +/* Any copyright is dedicated to the Public Domain. + * http://creativecommons.org/publicdomain/zero/1.0/ */ + +let { classes: Cc, interfaces: Ci } = Components; + +const USER_CONTEXTS = ["default", "personal", "work"]; + +const COOKIE_NAMES = ["cookie0", "cookie1", "cookie2"]; + +const TEST_URL = + "http://example.com/browser/netwerk/cookie/test/browser/file_empty.html"; + +let cm = Cc["@mozilla.org/cookiemanager;1"].getService(Ci.nsICookieManager2); + +// opens `uri' in a new tab with the provided userContextId and focuses it. +// returns the newly opened tab +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); + // wait for tab load + yield BrowserTestUtils.browserLoaded(browser); + + return {tab, browser}; +} + +add_task(function* setup() { + // make sure userContext is enabled. + yield new Promise(resolve => { + SpecialPowers.pushPrefEnv({"set": [ + ["privacy.userContext.enabled", true] + ]}, resolve); + }); +}); + +add_task(function* test() { + // load the page in 3 different contexts and set a cookie + // which should only be visible in that context + for (let userContextId of Object.keys(USER_CONTEXTS)) { + // open our tab in the given user context + let {tab, browser} = yield* openTabInUserContext(TEST_URL, userContextId); + + yield ContentTask.spawn(browser, + {names: COOKIE_NAMES, value: USER_CONTEXTS[userContextId]}, + function(opts) { + for (let name of opts.names) { + content.document.cookie = name + "=" + opts.value; + } + }); + + // remove the tab + gBrowser.removeTab(tab); + } + + let expectedValues = USER_CONTEXTS.slice(0); + yield checkCookies(expectedValues, "before removal"); + + // remove cookies that belongs to user context id #1 + cm.removeCookiesWithOriginAttributes(JSON.stringify({userContextId: 1})); + + expectedValues[1] = undefined; + yield checkCookies(expectedValues, "after removal"); +}); + +function *checkCookies(expectedValues, time) { + for (let userContextId of Object.keys(expectedValues)) { + let cookiesFromTitle = yield* getCookiesFromJS(userContextId); + let cookiesFromManager = getCookiesFromManager(userContextId); + + let expectedValue = expectedValues[userContextId]; + for (let name of COOKIE_NAMES) { + is(cookiesFromTitle[name], expectedValue, + `User context ${userContextId}: ${name} should be correct from title ${time}`); + is(cookiesFromManager[name], expectedValue, + `User context ${userContextId}: ${name} should be correct from manager ${time}`); + } + + } +} + +function getCookiesFromManager(userContextId) { + let cookies = {}; + let enumerator = cm.getCookiesWithOriginAttributes(JSON.stringify({userContextId})); + while (enumerator.hasMoreElements()) { + let cookie = enumerator.getNext().QueryInterface(Ci.nsICookie); + cookies[cookie.name] = cookie.value; + } + return cookies; +} + +function* getCookiesFromJS(userContextId) { + let {tab, browser} = yield* openTabInUserContext(TEST_URL, userContextId); + + // get the cookies + let cookieString = yield ContentTask.spawn(browser, null, function() { + return content.document.cookie; + }); + + // check each item in the title and validate it meets expectatations + let cookies = {}; + for (let cookie of cookieString.split(";")) { + let [name, value] = cookie.trim().split("="); + cookies[name] = value; + } + + gBrowser.removeTab(tab); + return cookies; +} diff --git a/netwerk/cookie/test/browser/file_empty.html b/netwerk/cookie/test/browser/file_empty.html new file mode 100644 index 000000000..5a08c4205 --- /dev/null +++ b/netwerk/cookie/test/browser/file_empty.html @@ -0,0 +1,3 @@ +<html><body> +</body></html> + diff --git a/netwerk/cookie/test/unit/test_bug1155169.js b/netwerk/cookie/test/unit/test_bug1155169.js new file mode 100644 index 000000000..6806ffe6d --- /dev/null +++ b/netwerk/cookie/test/unit/test_bug1155169.js @@ -0,0 +1,73 @@ +var {utils: Cu, interfaces: Ci, classes: Cc} = Components; + +Cu.import("resource://gre/modules/Services.jsm"); + +const URI = Services.io.newURI("http://example.org/", null, null); + +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(value, expected = null) { + function observer(subject, topic, data) { + if (!expected) { + do_throw("no notification expected"); + return; + } + + // Check we saw the right notification. + do_check_eq(data, expected.type); + + // Check cookie details. + let cookie = subject.QueryInterface(Ci.nsICookie2); + do_check_eq(cookie.isSession, expected.isSession); + do_check_eq(cookie.isSecure, expected.isSecure); + do_check_eq(cookie.isHttpOnly, expected.isHttpOnly); + } + + Services.obs.addObserver(observer, "cookie-changed", false); + cs.setCookieStringFromHttp(URI, null, null, value, null, null); + 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_bug1267910.js b/netwerk/cookie/test/unit/test_bug1267910.js new file mode 100644 index 000000000..93ea5e132 --- /dev/null +++ b/netwerk/cookie/test/unit/test_bug1267910.js @@ -0,0 +1,196 @@ +/* + * Bug 1267910 - Add test cases for the backward compatiability and originAttributes + * of nsICookieManager2. + */ + +var {utils: Cu, interfaces: Ci, classes: Cc} = Components; + +Cu.import("resource://gre/modules/Services.jsm"); + +const BASE_URL = "http://example.org/"; + +const COOKIE = { + host: BASE_URL, + path: "/", + name: "test1", + value: "yes", + isSecure: false, + isHttpOnly: false, + isSession: true, + expiry: 2145934800, +}; + +const COOKIE_OA_DEFAULT = { + host: BASE_URL, + path: "/", + name: "test0", + value: "yes0", + isSecure: false, + isHttpOnly: false, + isSession: true, + expiry: 2145934800, + originAttributes: {}, +}; + +const COOKIE_OA_1 = { + host: BASE_URL, + path: "/", + name: "test1", + value: "yes1", + isSecure: false, + isHttpOnly: false, + isSession: true, + expiry: 2145934800, + originAttributes: {userContextId: 1}, +}; + +function checkCookie(cookie, cookieObj) { + for (let prop of Object.keys(cookieObj)) { + if (prop === "originAttributes") { + ok(ChromeUtils.isOriginAttributesEqual(cookie[prop], cookieObj[prop]), + "Check cookie: " + prop); + } else { + equal(cookie[prop], cookieObj[prop], "Check cookie: " + prop); + } + } +} + +function countCookies(enumerator) { + let cnt = 0; + + while (enumerator.hasMoreElements()) { + cnt++; + enumerator.getNext(); + } + + return cnt; +} + +function run_test() { + // Allow all cookies. + Services.prefs.setIntPref("network.cookie.cookieBehavior", 0); + + // Enable user context id + Services.prefs.setBoolPref("privacy.userContext.enabled", true); + + add_test(test_backward_compatiability); + add_test(test_originAttributes); + + + run_next_test(); +} + +/* + * Test for backward compatiablility that APIs works correctly without + * originAttributes. + */ +function test_backward_compatiability() { + // Clear cookies. + Services.cookies.removeAll(); + + // Call Add() to add a cookie without originAttributes + Services.cookies.add(COOKIE.host, + COOKIE.path, + COOKIE.name, + COOKIE.value, + COOKIE.isSecure, + COOKIE.isHttpOnly, + COOKIE.isSession, + COOKIE.expiry); + + // Call getCookiesFromHost() to get cookies without originAttributes + let enumerator = Services.cookies.getCookiesFromHost(BASE_URL); + + ok(enumerator.hasMoreElements(), "Cookies available"); + let foundCookie = enumerator.getNext().QueryInterface(Ci.nsICookie2); + + checkCookie(foundCookie, COOKIE); + + ok(!enumerator.hasMoreElements(), "We should get only one cookie"); + + run_next_test(); +} + +/* + * Test for originAttributes. + */ +function test_originAttributes() { + // Clear cookies. + Services.cookies.removeAll(); + + // Add a cookie for default originAttributes. + Services.cookies.add(COOKIE_OA_DEFAULT.host, + COOKIE_OA_DEFAULT.path, + COOKIE_OA_DEFAULT.name, + COOKIE_OA_DEFAULT.value, + COOKIE_OA_DEFAULT.isSecure, + COOKIE_OA_DEFAULT.isHttpOnly, + COOKIE_OA_DEFAULT.isSession, + COOKIE_OA_DEFAULT.expiry, + COOKIE_OA_DEFAULT.originAttributes); + + // Get cookies for default originAttributes. + let enumerator = Services.cookies.getCookiesFromHost(BASE_URL, COOKIE_OA_DEFAULT.originAttributes); + + // Check that do we get cookie correctly. + ok(enumerator.hasMoreElements(), "Cookies available"); + let foundCookie = enumerator.getNext().QueryInterface(Ci.nsICookie2); + checkCookie(foundCookie, COOKIE_OA_DEFAULT); + + // We should only get one cookie. + ok(!enumerator.hasMoreElements(), "We should get only one cookie"); + + // Get cookies for originAttributes with user context id 1. + enumerator = Services.cookies.getCookiesFromHost(BASE_URL, COOKIE_OA_1.originAttributes); + + // Check that we will not get cookies if the originAttributes is different. + ok(!enumerator.hasMoreElements(), "No cookie should be here"); + + // Add a cookie for originAttributes with user context id 1. + Services.cookies.add(COOKIE_OA_1.host, + COOKIE_OA_1.path, + COOKIE_OA_1.name, + COOKIE_OA_1.value, + COOKIE_OA_1.isSecure, + COOKIE_OA_1.isHttpOnly, + COOKIE_OA_1.isSession, + COOKIE_OA_1.expiry, + COOKIE_OA_1.originAttributes); + + // Get cookies for originAttributes with user context id 1. + enumerator = Services.cookies.getCookiesFromHost(BASE_URL, COOKIE_OA_1.originAttributes); + + // Check that do we get cookie correctly. + ok(enumerator.hasMoreElements(), "Cookies available"); + foundCookie = enumerator.getNext().QueryInterface(Ci.nsICookie2); + checkCookie(foundCookie, COOKIE_OA_1); + + // We should only get one cookie. + ok(!enumerator.hasMoreElements(), "We should get only one cookie"); + + // Check that add a cookie will not affect cookies in different originAttributes. + enumerator = Services.cookies.getCookiesFromHost(BASE_URL, COOKIE_OA_DEFAULT.originAttributes); + equal(countCookies(enumerator), 1, "We should get only one cookie for default originAttributes"); + + // Remove a cookie for originAttributes with user context id 1. + Services.cookies.remove(COOKIE_OA_1.host, COOKIE_OA_1.name, COOKIE_OA_1.path, + false, COOKIE_OA_1.originAttributes); + + // Check that remove will not affect cookies in default originAttributes. + enumerator = Services.cookies.getCookiesFromHost(BASE_URL, COOKIE_OA_DEFAULT.originAttributes); + equal(countCookies(enumerator), 1, "Get one cookie for default originAttributes."); + + // Check that should be no cookie for originAttributes with user context id 1. + enumerator = Services.cookies.getCookiesFromHost(BASE_URL, COOKIE_OA_1.originAttributes); + equal(countCookies(enumerator), 0, "No cookie shold be here"); + + // Remove a cookie for default originAttributes. + Services.cookies.remove(COOKIE_OA_DEFAULT.host, COOKIE_OA_DEFAULT.name, COOKIE_OA_DEFAULT.path, + false, COOKIE_OA_DEFAULT.originAttributes); + + // Check remove() works correctly for default originAttributes. + enumerator = Services.cookies.getCookiesFromHost(BASE_URL, COOKIE_OA_DEFAULT.originAttributes); + equal(countCookies(enumerator), 0, "No cookie shold be here"); + + run_next_test(); +} diff --git a/netwerk/cookie/test/unit/test_bug643051.js b/netwerk/cookie/test/unit/test_bug643051.js new file mode 100644 index 000000000..d6695054e --- /dev/null +++ b/netwerk/cookie/test/unit/test_bug643051.js @@ -0,0 +1,29 @@ +var Cc = Components.classes; +var Ci = Components.interfaces; + +Components.utils.import("resource://gre/modules/NetUtil.jsm"); +Components.utils.import("resource://gre/modules/Services.jsm"); + +function run_test() { + // Allow all cookies. + Services.prefs.setIntPref("network.cookie.cookieBehavior", 0); + + let cs = Cc["@mozilla.org/cookieService;1"].getService(Ci.nsICookieService); + + let uri = NetUtil.newURI("http://example.org/"); + + let set = "foo=bar\nbaz=foo"; + let expected = "foo=bar; baz=foo"; + cs.setCookieStringFromHttp(uri, null, null, set, null, null); + + let actual = cs.getCookieStringFromHttp(uri, null, null); + do_check_eq(actual, expected); + + uri = NetUtil.newURI("http://example.com/"); + cs.setCookieString(uri, null, set, null); + + expected = "foo=bar"; + actual = cs.getCookieString(uri, null, null); + do_check_eq(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 000000000..7f693ee94 --- /dev/null +++ b/netwerk/cookie/test/unit/test_eviction.js @@ -0,0 +1,296 @@ +var {utils: Cu, interfaces: Ci, classes: Cc} = Components; + +Cu.import("resource://gre/modules/Services.jsm"); + +const BASE_HOSTNAMES = ["example.org", "example.co.uk"]; +const SUBDOMAINS = ["", "pub.", "www.", "other."]; + +const cs = Cc["@mozilla.org/cookieService;1"].getService(Ci.nsICookieService); +const cm = cs.QueryInterface(Ci.nsICookieManager2); + +function run_test() { + var tests = []; + Services.prefs.setIntPref("network.cookie.staleThreshold", 0); + for (var host of BASE_HOSTNAMES) { + var base = SUBDOMAINS[0] + host; + var sub = SUBDOMAINS[1] + host; + var other = SUBDOMAINS[2] + host; + var another = SUBDOMAINS[3] + host; + tests.push([host, test_basic_eviction.bind(this, base, sub, other, another)]); + add_task(function* a() { + var t = tests.splice(0, 1)[0]; + do_print('testing with host ' + t[0]); + yield t[1](); + cm.removeAll(); + }); + tests.push([host, test_domain_or_path_matches_not_both.bind(this, base, sub, other, another)]); + add_task(function*() { + var t = tests.splice(0, 1)[0]; + do_print('testing with host ' + t[0]); + yield t[1](); + cm.removeAll(); + }); + } + add_task(function*() { + yield test_localdomain(); + cm.removeAll(); + }); + + add_task(function*() { + yield test_path_prefix(); + }); + + run_next_test(); +} + +// Verify that cookies that share a path prefix with the URI path are still considered +// candidates for eviction, since the paths do not actually match. +function* test_path_prefix() { + Services.prefs.setIntPref("network.cookie.maxPerHost", 2); + + const BASE_URI = Services.io.newURI("http://example.org/", null, null); + const BASE_BAR = Services.io.newURI("http://example.org/bar/", null, null); + const BASE_BARBAR = Services.io.newURI("http://example.org/barbar/", null, null); + + yield setCookie("session_first", null, null, null, BASE_URI); + yield setCookie("session_second", null, "/bar", null, BASE_BAR); + verifyCookies(['session_first', 'session_second'], BASE_URI); + + yield setCookie("session_third", null, "/barbar", null, BASE_BARBAR); + verifyCookies(['session_first', 'session_third'], BASE_URI); +} + +// Verify that subdomains of localhost are treated as separate hosts and aren't considered +// candidates for eviction. +function* test_localdomain() { + Services.prefs.setIntPref("network.cookie.maxPerHost", 2); + + const BASE_URI = Services.io.newURI("http://localhost", null, null); + const BASE_BAR = Services.io.newURI("http://localhost/bar", null, null); + const OTHER_URI = Services.io.newURI("http://other.localhost", null, null); + const OTHER_BAR = Services.io.newURI("http://other.localhost/bar", null, null); + + yield setCookie("session_no_path", null, null, null, BASE_URI); + yield setCookie("session_bar_path", null, "/bar", null, BASE_BAR); + + yield setCookie("session_no_path", null, null, null, OTHER_URI); + yield setCookie("session_bar_path", null, "/bar", null, OTHER_BAR); + + verifyCookies(['session_no_path', + 'session_bar_path'], BASE_URI); + verifyCookies(['session_no_path', + 'session_bar_path'], OTHER_URI); + + yield setCookie("session_another_no_path", null, null, null, BASE_URI); + verifyCookies(['session_no_path', + 'session_another_no_path'], BASE_URI); + + yield setCookie("session_another_no_path", null, null, null, OTHER_URI); + verifyCookies(['session_no_path', + 'session_another_no_path'], OTHER_URI); +} + +// Ensure that cookies are still considered candidates for eviction if either the domain +// or path matches, but not both. +function* test_domain_or_path_matches_not_both(base_host, + subdomain_host, + other_subdomain_host, + another_subdomain_host) { + Services.prefs.setIntPref("network.cookie.maxPerHost", 2); + + const BASE_URI = Services.io.newURI("http://" + base_host, null, null); + const PUB_FOO_PATH = Services.io.newURI("http://" + subdomain_host + "/foo/", null, null); + const WWW_BAR_PATH = Services.io.newURI("http://" + other_subdomain_host + "/bar/", null, null); + const OTHER_BAR_PATH = Services.io.newURI("http://" + another_subdomain_host + "/bar/", null, null); + const PUB_BAR_PATH = Services.io.newURI("http://" + subdomain_host + "/bar/", null, null); + const WWW_FOO_PATH = Services.io.newURI("http://" + other_subdomain_host + "/foo/", null, null); + + yield setCookie("session_pub_with_foo_path", subdomain_host, "/foo", null, PUB_FOO_PATH); + yield setCookie("session_www_with_bar_path", other_subdomain_host, "/bar", null, WWW_BAR_PATH); + verifyCookies(['session_pub_with_foo_path', + 'session_www_with_bar_path'], BASE_URI); + + yield setCookie("session_pub_with_bar_path", subdomain_host, "/bar", null, PUB_BAR_PATH); + verifyCookies(['session_www_with_bar_path', + 'session_pub_with_bar_path'], BASE_URI); + + yield setCookie("session_other_with_bar_path", another_subdomain_host, "/bar", null, OTHER_BAR_PATH); + verifyCookies(['session_pub_with_bar_path', + 'session_other_with_bar_path'], BASE_URI); +} + +function* test_basic_eviction(base_host, subdomain_host, other_subdomain_host) { + Services.prefs.setIntPref("network.cookie.maxPerHost", 5); + + const BASE_URI = Services.io.newURI("http://" + base_host, null, null); + const SUBDOMAIN_URI = Services.io.newURI("http://" + subdomain_host, null, null); + const OTHER_SUBDOMAIN_URI = Services.io.newURI("http://" + other_subdomain_host, null, null); + const FOO_PATH = Services.io.newURI("http://" + base_host + "/foo/", null, null); + const BAR_PATH = Services.io.newURI("http://" + base_host + "/bar/", null, null); + const ALL_SUBDOMAINS = '.' + base_host; + const OTHER_SUBDOMAIN = other_subdomain_host; + + // Initialize the set of cookies with a mix of non-session cookies with no path, + // and session cookies with explicit paths. Any subsequent cookies added will cause + // existing cookies to be evicted. + yield setCookie("non_session_non_path_non_domain", null, null, 100000, BASE_URI); + yield setCookie("non_session_non_path_subdomain", ALL_SUBDOMAINS, null, 100000, SUBDOMAIN_URI); + yield setCookie("session_non_path_pub_domain", OTHER_SUBDOMAIN, null, null, OTHER_SUBDOMAIN_URI); + yield setCookie("session_foo_path", null, "/foo", null, FOO_PATH); + yield setCookie("session_bar_path", null, "/bar", null, BAR_PATH); + verifyCookies(['non_session_non_path_non_domain', + 'non_session_non_path_subdomain', + 'session_non_path_pub_domain', + 'session_foo_path', + 'session_bar_path'], BASE_URI); + + // Ensure that cookies set for the / path appear more recent. + cs.getCookieString(OTHER_SUBDOMAIN_URI, null) + verifyCookies(['non_session_non_path_non_domain', + 'session_foo_path', + 'session_bar_path', + 'non_session_non_path_subdomain', + 'session_non_path_pub_domain'], BASE_URI); + + // Evict oldest session cookie that does not match example.org/foo (session_bar_path) + yield setCookie("session_foo_path_2", null, "/foo", null, FOO_PATH); + verifyCookies(['non_session_non_path_non_domain', + 'session_foo_path', + 'non_session_non_path_subdomain', + 'session_non_path_pub_domain', + 'session_foo_path_2'], BASE_URI); + + // Evict oldest session cookie that does not match example.org/bar (session_foo_path) + yield setCookie("session_bar_path_2", null, "/bar", null, BAR_PATH); + verifyCookies(['non_session_non_path_non_domain', + 'non_session_non_path_subdomain', + 'session_non_path_pub_domain', + 'session_foo_path_2', + 'session_bar_path_2'], BASE_URI); + + // Evict oldest session cookie that does not match example.org/ (session_non_path_pub_domain) + yield setCookie("non_session_non_path_non_domain_2", null, null, 100000, BASE_URI); + verifyCookies(['non_session_non_path_non_domain', + 'non_session_non_path_subdomain', + 'session_foo_path_2', + 'session_bar_path_2', + 'non_session_non_path_non_domain_2'], BASE_URI); + + // Evict oldest session cookie that does not match example.org/ (session_foo_path_2) + yield setCookie("session_non_path_non_domain_3", null, null, null, BASE_URI); + verifyCookies(['non_session_non_path_non_domain', + 'non_session_non_path_subdomain', + 'session_bar_path_2', + 'non_session_non_path_non_domain_2', + 'session_non_path_non_domain_3'], BASE_URI); + + // Evict oldest session cookie; all such cookies match example.org/bar (session_bar_path_2) + // note: this new cookie doesn't have an explicit path, but empty paths inherit the + // request's path + yield setCookie("non_session_bar_path_non_domain", null, null, 100000, BAR_PATH); + verifyCookies(['non_session_non_path_non_domain', + 'non_session_non_path_subdomain', + 'non_session_non_path_non_domain_2', + 'session_non_path_non_domain_3', + 'non_session_bar_path_non_domain'], BASE_URI); + + // Evict oldest session cookie, even though it matches pub.example.org (session_non_path_non_domain_3) + yield setCookie("non_session_non_path_pub_domain", null, null, 100000, OTHER_SUBDOMAIN_URI); + verifyCookies(['non_session_non_path_non_domain', + 'non_session_non_path_subdomain', + 'non_session_non_path_non_domain_2', + 'non_session_bar_path_non_domain', + 'non_session_non_path_pub_domain'], BASE_URI); + + // All session cookies have been evicted. + // Evict oldest non-session non-domain-matching cookie (non_session_non_path_pub_domain) + yield setCookie("non_session_bar_path_non_domain_2", null, '/bar', 100000, BAR_PATH); + verifyCookies(['non_session_non_path_non_domain', + 'non_session_non_path_subdomain', + 'non_session_non_path_non_domain_2', + 'non_session_bar_path_non_domain', + 'non_session_bar_path_non_domain_2'], BASE_URI); + + // Evict oldest non-session non-path-matching cookie (non_session_bar_path_non_domain) + yield setCookie("non_session_non_path_non_domain_4", null, null, 100000, BASE_URI); + verifyCookies(['non_session_non_path_non_domain', + 'non_session_non_path_subdomain', + 'non_session_non_path_non_domain_2', + 'non_session_bar_path_non_domain_2', + 'non_session_non_path_non_domain_4'], BASE_URI); + + // At this point all remaining cookies are non-session cookies, have a path of /, + // and either don't have a domain or have one that matches subdomains. + // They will therefore be evicted from oldest to newest if all new cookies added share + // similar characteristics. +} + +// Verify that the given cookie names exist, and are ordered from least to most recently accessed +function verifyCookies(names, uri) { + do_check_eq(cm.countCookiesFromHost(uri.host), names.length); + let cookies = cm.getCookiesFromHost(uri.host, {}); + let actual_cookies = []; + while (cookies.hasMoreElements()) { + let cookie = cookies.getNext().QueryInterface(Ci.nsICookie2); + 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) { + do_print("unexpected cookies: " + left); + } + if (right.length) { + do_print("expected cookies: " + right); + } + } + do_check_eq(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++) { + do_check_eq(names[i], actual_cookies[i].name); + do_check_eq(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; + do_print(s); + cs.setCookieStringFromHttp(url, null, null, value, null, null); + 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_parser_0001.js b/netwerk/cookie/test/unit/test_parser_0001.js new file mode 100644 index 000000000..f885972a0 --- /dev/null +++ b/netwerk/cookie/test/unit/test_parser_0001.js @@ -0,0 +1,29 @@ +var Cc = Components.classes; +var Ci = Components.interfaces; + +Components.utils.import("resource://gre/modules/NetUtil.jsm"); +Components.utils.import("resource://gre/modules/Services.jsm"); + +function inChildProcess() { + return Cc["@mozilla.org/xre/app-info;1"] + .getService(Ci.nsIXULRuntime) + .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); + + let cs = Cc["@mozilla.org/cookieService;1"].getService(Ci.nsICookieService); + + let uri = NetUtil.newURI("http://example.org/"); + + let set = "foo=bar"; + cs.setCookieStringFromHttp(uri, null, null, set, null, null); + + let expected = "foo=bar"; + let actual = cs.getCookieStringFromHttp(uri, null, null); + do_check_eq(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 000000000..7811b01fe --- /dev/null +++ b/netwerk/cookie/test/unit/test_parser_0019.js @@ -0,0 +1,29 @@ +var Cc = Components.classes; +var Ci = Components.interfaces; + +Components.utils.import("resource://gre/modules/NetUtil.jsm"); +Components.utils.import("resource://gre/modules/Services.jsm"); + +function inChildProcess() { + return Cc["@mozilla.org/xre/app-info;1"] + .getService(Ci.nsIXULRuntime) + .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); + + let cs = Cc["@mozilla.org/cookieService;1"].getService(Ci.nsICookieService); + + let uri = NetUtil.newURI("http://example.org/"); + + let set = "foo=b;max-age=3600, c=d;path=/"; + cs.setCookieStringFromHttp(uri, null, null, set, null, null); + + let expected = "foo=b"; + let actual = cs.getCookieStringFromHttp(uri, null, null); + do_check_eq(actual, expected); +} + diff --git a/netwerk/cookie/test/unit/xpcshell.ini b/netwerk/cookie/test/unit/xpcshell.ini new file mode 100644 index 000000000..f9c4093cf --- /dev/null +++ b/netwerk/cookie/test/unit/xpcshell.ini @@ -0,0 +1,10 @@ +[DEFAULT] +head = +tail = + +[test_bug643051.js] +[test_bug1155169.js] +[test_bug1267910.js] +[test_parser_0001.js] +[test_parser_0019.js] +[test_eviction.js]
\ No newline at end of file diff --git a/netwerk/cookie/test/unit_ipc/test_ipc_parser_0001.js b/netwerk/cookie/test/unit_ipc/test_ipc_parser_0001.js new file mode 100644 index 000000000..988c8d196 --- /dev/null +++ b/netwerk/cookie/test/unit_ipc/test_ipc_parser_0001.js @@ -0,0 +1,9 @@ +var Cu = Components.utils; + +Cu.import("resource://gre/modules/Services.jsm"); + +function run_test() { + // Allow all cookies. + Services.prefs.setIntPref("network.cookie.cookieBehavior", 0); + run_test_in_child("../unit/test_parser_0001.js"); +} diff --git a/netwerk/cookie/test/unit_ipc/test_ipc_parser_0019.js b/netwerk/cookie/test/unit_ipc/test_ipc_parser_0019.js new file mode 100644 index 000000000..535ac6e34 --- /dev/null +++ b/netwerk/cookie/test/unit_ipc/test_ipc_parser_0019.js @@ -0,0 +1,9 @@ +var Cu = Components.utils; + +Cu.import("resource://gre/modules/Services.jsm"); + +function run_test() { + // Allow all cookies. + Services.prefs.setIntPref("network.cookie.cookieBehavior", 0); + run_test_in_child("../unit/test_parser_0019.js"); +} diff --git a/netwerk/cookie/test/unit_ipc/xpcshell.ini b/netwerk/cookie/test/unit_ipc/xpcshell.ini new file mode 100644 index 000000000..922443490 --- /dev/null +++ b/netwerk/cookie/test/unit_ipc/xpcshell.ini @@ -0,0 +1,10 @@ +[DEFAULT] +head = +tail = +skip-if = toolkit == 'android' +support-files = + !/netwerk/cookie/test/unit/test_parser_0001.js + !/netwerk/cookie/test/unit/test_parser_0019.js + +[test_ipc_parser_0001.js] +[test_ipc_parser_0019.js] |