summaryrefslogtreecommitdiffstats
path: root/netwerk/test/unit/head_cookies.js
diff options
context:
space:
mode:
Diffstat (limited to 'netwerk/test/unit/head_cookies.js')
-rw-r--r--netwerk/test/unit/head_cookies.js955
1 files changed, 955 insertions, 0 deletions
diff --git a/netwerk/test/unit/head_cookies.js b/netwerk/test/unit/head_cookies.js
new file mode 100644
index 0000000000..223ea90120
--- /dev/null
+++ b/netwerk/test/unit/head_cookies.js
@@ -0,0 +1,955 @@
+/* Any copyright is dedicated to the Public Domain.
+ * http://creativecommons.org/publicdomain/zero/1.0/
+ */
+
+/* import-globals-from head_cache.js */
+
+"use strict";
+
+const { NetUtil } = ChromeUtils.import("resource://gre/modules/NetUtil.jsm");
+const { CookieXPCShellUtils } = ChromeUtils.importESModule(
+ "resource://testing-common/CookieXPCShellUtils.sys.mjs"
+);
+
+// Don't pick up default permissions from profile.
+Services.prefs.setCharPref("permissions.manager.defaultsUrl", "");
+
+CookieXPCShellUtils.init(this);
+
+function do_check_throws(f, result, stack) {
+ if (!stack) {
+ stack = Components.stack.caller;
+ }
+
+ try {
+ f();
+ } catch (exc) {
+ if (exc.result == result) {
+ return;
+ }
+ do_throw("expected result " + result + ", caught " + exc, stack);
+ }
+ do_throw("expected result " + result + ", none thrown", stack);
+}
+
+// Helper to step a generator function and catch a StopIteration exception.
+function do_run_generator(generator) {
+ try {
+ generator.next();
+ } catch (e) {
+ do_throw("caught exception " + e, Components.stack.caller);
+ }
+}
+
+// Helper to finish a generator function test.
+function do_finish_generator_test(generator) {
+ executeSoon(function () {
+ generator.return();
+ do_test_finished();
+ });
+}
+
+function _observer(generator, topic) {
+ Services.obs.addObserver(this, topic);
+
+ this.generator = generator;
+ this.topic = topic;
+}
+
+_observer.prototype = {
+ observe(subject, topic, data) {
+ Assert.equal(this.topic, topic);
+
+ Services.obs.removeObserver(this, this.topic);
+
+ // Continue executing the generator function.
+ if (this.generator) {
+ do_run_generator(this.generator);
+ }
+
+ this.generator = null;
+ this.topic = null;
+ },
+};
+
+// Close the cookie database. If a generator is supplied, it will be invoked
+// once the close is complete.
+function do_close_profile(generator) {
+ // Register an observer for db close.
+ new _observer(generator, "cookie-db-closed");
+
+ // Close the db.
+ let service = Services.cookies.QueryInterface(Ci.nsIObserver);
+ service.observe(null, "profile-before-change", null);
+}
+
+function _promise_observer(topic) {
+ Services.obs.addObserver(this, topic);
+
+ this.topic = topic;
+ return new Promise(resolve => (this.resolve = resolve));
+}
+
+_promise_observer.prototype = {
+ observe(subject, topic, data) {
+ Assert.equal(this.topic, topic);
+
+ Services.obs.removeObserver(this, this.topic);
+ if (this.resolve) {
+ this.resolve();
+ }
+
+ this.resolve = null;
+ this.topic = null;
+ },
+};
+
+// Close the cookie database. And resolve a promise.
+function promise_close_profile() {
+ // Register an observer for db close.
+ let promise = new _promise_observer("cookie-db-closed");
+
+ // Close the db.
+ let service = Services.cookies.QueryInterface(Ci.nsIObserver);
+ service.observe(null, "profile-before-change", null);
+
+ return promise;
+}
+
+// Load the cookie database.
+function promise_load_profile() {
+ // Register an observer for read completion.
+ let promise = new _promise_observer("cookie-db-read");
+
+ // Load the profile.
+ let service = Services.cookies.QueryInterface(Ci.nsIObserver);
+ service.observe(null, "profile-do-change", "");
+
+ return promise;
+}
+
+// Load the cookie database. If a generator is supplied, it will be invoked
+// once the load is complete.
+function do_load_profile(generator) {
+ // Register an observer for read completion.
+ new _observer(generator, "cookie-db-read");
+
+ // Load the profile.
+ let service = Services.cookies.QueryInterface(Ci.nsIObserver);
+ service.observe(null, "profile-do-change", "");
+}
+
+// Set a single session cookie using http and test the cookie count
+// against 'expected'
+function do_set_single_http_cookie(uri, channel, expected) {
+ Services.cookies.setCookieStringFromHttp(uri, "foo=bar", channel);
+ Assert.equal(Services.cookies.countCookiesFromHost(uri.host), expected);
+}
+
+// Set two cookies; via document.channel and via http request.
+async function do_set_cookies(uri, channel, session, expected) {
+ let suffix = session ? "" : "; max-age=1000";
+
+ // via document.cookie
+ const thirdPartyUrl = "http://third.com/";
+ const contentPage = await CookieXPCShellUtils.loadContentPage(thirdPartyUrl);
+ await contentPage.spawn(
+ [
+ {
+ cookie: "can=has" + suffix,
+ url: uri.spec,
+ },
+ ],
+ async obj => {
+ // eslint-disable-next-line no-undef
+ await new content.Promise(resolve => {
+ // eslint-disable-next-line no-undef
+ const ifr = content.document.createElement("iframe");
+ // eslint-disable-next-line no-undef
+ content.document.body.appendChild(ifr);
+ ifr.src = obj.url;
+ ifr.onload = () => {
+ ifr.contentDocument.cookie = obj.cookie;
+ resolve();
+ };
+ });
+ }
+ );
+ await contentPage.close();
+
+ Assert.equal(Services.cookies.countCookiesFromHost(uri.host), expected[0]);
+
+ // via http request
+ Services.cookies.setCookieStringFromHttp(uri, "hot=dog" + suffix, channel);
+ Assert.equal(Services.cookies.countCookiesFromHost(uri.host), expected[1]);
+}
+
+function do_count_cookies() {
+ return Services.cookies.cookies.length;
+}
+
+// Helper object to store cookie data.
+function Cookie(
+ name,
+ value,
+ host,
+ path,
+ expiry,
+ lastAccessed,
+ creationTime,
+ isSession,
+ isSecure,
+ isHttpOnly,
+ inBrowserElement = false,
+ originAttributes = {},
+ sameSite = Ci.nsICookie.SAMESITE_NONE,
+ rawSameSite = Ci.nsICookie.SAMESITE_NONE,
+ schemeMap = Ci.nsICookie.SCHEME_UNSET
+) {
+ this.name = name;
+ this.value = value;
+ this.host = host;
+ this.path = path;
+ this.expiry = expiry;
+ this.lastAccessed = lastAccessed;
+ this.creationTime = creationTime;
+ this.isSession = isSession;
+ this.isSecure = isSecure;
+ this.isHttpOnly = isHttpOnly;
+ this.inBrowserElement = inBrowserElement;
+ this.originAttributes = originAttributes;
+ this.sameSite = sameSite;
+ this.rawSameSite = rawSameSite;
+ this.schemeMap = schemeMap;
+
+ let strippedHost = host.charAt(0) == "." ? host.slice(1) : host;
+
+ try {
+ this.baseDomain = Services.eTLD.getBaseDomainFromHost(strippedHost);
+ } catch (e) {
+ if (
+ e.result == Cr.NS_ERROR_HOST_IS_IP_ADDRESS ||
+ e.result == Cr.NS_ERROR_INSUFFICIENT_DOMAIN_LEVELS
+ ) {
+ this.baseDomain = strippedHost;
+ }
+ }
+}
+
+// Object representing a database connection and associated statements. The
+// implementation varies depending on schema version.
+function CookieDatabaseConnection(file, schema) {
+ // Manually generate a cookies.sqlite file with appropriate rows, columns,
+ // and schema version. If it already exists, just set up our statements.
+ let exists = file.exists();
+
+ this.db = Services.storage.openDatabase(file);
+ this.schema = schema;
+ if (!exists) {
+ this.db.schemaVersion = schema;
+ }
+
+ switch (schema) {
+ case 1: {
+ if (!exists) {
+ this.db.executeSimpleSQL(
+ "CREATE TABLE moz_cookies ( \
+ id INTEGER PRIMARY KEY, \
+ name TEXT, \
+ value TEXT, \
+ host TEXT, \
+ path TEXT, \
+ expiry INTEGER, \
+ isSecure INTEGER, \
+ isHttpOnly INTEGER)"
+ );
+ }
+
+ this.stmtInsert = this.db.createStatement(
+ "INSERT INTO moz_cookies ( \
+ id, \
+ name, \
+ value, \
+ host, \
+ path, \
+ expiry, \
+ isSecure, \
+ isHttpOnly) \
+ VALUES ( \
+ :id, \
+ :name, \
+ :value, \
+ :host, \
+ :path, \
+ :expiry, \
+ :isSecure, \
+ :isHttpOnly)"
+ );
+
+ this.stmtDelete = this.db.createStatement(
+ "DELETE FROM moz_cookies WHERE id = :id"
+ );
+
+ break;
+ }
+
+ case 2: {
+ if (!exists) {
+ this.db.executeSimpleSQL(
+ "CREATE TABLE moz_cookies ( \
+ id INTEGER PRIMARY KEY, \
+ name TEXT, \
+ value TEXT, \
+ host TEXT, \
+ path TEXT, \
+ expiry INTEGER, \
+ lastAccessed INTEGER, \
+ isSecure INTEGER, \
+ isHttpOnly INTEGER)"
+ );
+ }
+
+ this.stmtInsert = this.db.createStatement(
+ "INSERT OR REPLACE INTO moz_cookies ( \
+ id, \
+ name, \
+ value, \
+ host, \
+ path, \
+ expiry, \
+ lastAccessed, \
+ isSecure, \
+ isHttpOnly) \
+ VALUES ( \
+ :id, \
+ :name, \
+ :value, \
+ :host, \
+ :path, \
+ :expiry, \
+ :lastAccessed, \
+ :isSecure, \
+ :isHttpOnly)"
+ );
+
+ this.stmtDelete = this.db.createStatement(
+ "DELETE FROM moz_cookies WHERE id = :id"
+ );
+
+ this.stmtUpdate = this.db.createStatement(
+ "UPDATE moz_cookies SET lastAccessed = :lastAccessed WHERE id = :id"
+ );
+
+ break;
+ }
+
+ case 3: {
+ if (!exists) {
+ this.db.executeSimpleSQL(
+ "CREATE TABLE moz_cookies ( \
+ id INTEGER PRIMARY KEY, \
+ baseDomain TEXT, \
+ name TEXT, \
+ value TEXT, \
+ host TEXT, \
+ path TEXT, \
+ expiry INTEGER, \
+ lastAccessed INTEGER, \
+ isSecure INTEGER, \
+ isHttpOnly INTEGER)"
+ );
+
+ this.db.executeSimpleSQL(
+ "CREATE INDEX moz_basedomain ON moz_cookies (baseDomain)"
+ );
+ }
+
+ this.stmtInsert = this.db.createStatement(
+ "INSERT INTO moz_cookies ( \
+ id, \
+ baseDomain, \
+ name, \
+ value, \
+ host, \
+ path, \
+ expiry, \
+ lastAccessed, \
+ isSecure, \
+ isHttpOnly) \
+ VALUES ( \
+ :id, \
+ :baseDomain, \
+ :name, \
+ :value, \
+ :host, \
+ :path, \
+ :expiry, \
+ :lastAccessed, \
+ :isSecure, \
+ :isHttpOnly)"
+ );
+
+ this.stmtDelete = this.db.createStatement(
+ "DELETE FROM moz_cookies WHERE id = :id"
+ );
+
+ this.stmtUpdate = this.db.createStatement(
+ "UPDATE moz_cookies SET lastAccessed = :lastAccessed WHERE id = :id"
+ );
+
+ break;
+ }
+
+ case 4: {
+ if (!exists) {
+ this.db.executeSimpleSQL(
+ "CREATE TABLE moz_cookies ( \
+ id INTEGER PRIMARY KEY, \
+ baseDomain TEXT, \
+ name TEXT, \
+ value TEXT, \
+ host TEXT, \
+ path TEXT, \
+ expiry INTEGER, \
+ lastAccessed INTEGER, \
+ creationTime INTEGER, \
+ isSecure INTEGER, \
+ isHttpOnly INTEGER \
+ CONSTRAINT moz_uniqueid UNIQUE (name, host, path))"
+ );
+
+ this.db.executeSimpleSQL(
+ "CREATE INDEX moz_basedomain ON moz_cookies (baseDomain)"
+ );
+
+ this.db.executeSimpleSQL("PRAGMA journal_mode = WAL");
+ }
+
+ this.stmtInsert = this.db.createStatement(
+ "INSERT INTO moz_cookies ( \
+ baseDomain, \
+ name, \
+ value, \
+ host, \
+ path, \
+ expiry, \
+ lastAccessed, \
+ creationTime, \
+ isSecure, \
+ isHttpOnly) \
+ VALUES ( \
+ :baseDomain, \
+ :name, \
+ :value, \
+ :host, \
+ :path, \
+ :expiry, \
+ :lastAccessed, \
+ :creationTime, \
+ :isSecure, \
+ :isHttpOnly)"
+ );
+
+ this.stmtDelete = this.db.createStatement(
+ "DELETE FROM moz_cookies \
+ WHERE name = :name AND host = :host AND path = :path"
+ );
+
+ this.stmtUpdate = this.db.createStatement(
+ "UPDATE moz_cookies SET lastAccessed = :lastAccessed \
+ WHERE name = :name AND host = :host AND path = :path"
+ );
+
+ break;
+ }
+
+ case 10: {
+ if (!exists) {
+ this.db.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))"
+ );
+
+ this.db.executeSimpleSQL(
+ "CREATE INDEX moz_basedomain ON moz_cookies (baseDomain)"
+ );
+
+ this.db.executeSimpleSQL("PRAGMA journal_mode = WAL");
+ this.db.executeSimpleSQL("PRAGMA wal_autocheckpoint = 16");
+ }
+
+ this.stmtInsert = this.db.createStatement(
+ "INSERT INTO moz_cookies ( \
+ name, \
+ value, \
+ host, \
+ baseDomain, \
+ path, \
+ expiry, \
+ lastAccessed, \
+ creationTime, \
+ isSecure, \
+ isHttpOnly, \
+ inBrowserElement, \
+ originAttributes, \
+ sameSite, \
+ rawSameSite \
+ ) VALUES ( \
+ :name, \
+ :value, \
+ :host, \
+ :baseDomain, \
+ :path, \
+ :expiry, \
+ :lastAccessed, \
+ :creationTime, \
+ :isSecure, \
+ :isHttpOnly, \
+ :inBrowserElement, \
+ :originAttributes, \
+ :sameSite, \
+ :rawSameSite)"
+ );
+
+ this.stmtDelete = this.db.createStatement(
+ "DELETE FROM moz_cookies \
+ WHERE name = :name AND host = :host AND path = :path AND \
+ originAttributes = :originAttributes"
+ );
+
+ this.stmtUpdate = this.db.createStatement(
+ "UPDATE moz_cookies SET lastAccessed = :lastAccessed \
+ WHERE name = :name AND host = :host AND path = :path AND \
+ originAttributes = :originAttributes"
+ );
+
+ break;
+ }
+
+ case 11: {
+ if (!exists) {
+ this.db.executeSimpleSQL(
+ "CREATE TABLE moz_cookies ( \
+ id INTEGER PRIMARY KEY, \
+ 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))"
+ );
+
+ this.db.executeSimpleSQL("PRAGMA journal_mode = WAL");
+ this.db.executeSimpleSQL("PRAGMA wal_autocheckpoint = 16");
+ }
+
+ this.stmtInsert = this.db.createStatement(
+ "INSERT INTO moz_cookies ( \
+ name, \
+ value, \
+ host, \
+ path, \
+ expiry, \
+ lastAccessed, \
+ creationTime, \
+ isSecure, \
+ isHttpOnly, \
+ inBrowserElement, \
+ originAttributes, \
+ sameSite, \
+ rawSameSite \
+ ) VALUES ( \
+ :name, \
+ :value, \
+ :host, \
+ :path, \
+ :expiry, \
+ :lastAccessed, \
+ :creationTime, \
+ :isSecure, \
+ :isHttpOnly, \
+ :inBrowserElement, \
+ :originAttributes, \
+ :sameSite, \
+ :rawSameSite)"
+ );
+
+ this.stmtDelete = this.db.createStatement(
+ "DELETE FROM moz_cookies \
+ WHERE name = :name AND host = :host AND path = :path AND \
+ originAttributes = :originAttributes"
+ );
+
+ this.stmtUpdate = this.db.createStatement(
+ "UPDATE moz_cookies SET lastAccessed = :lastAccessed \
+ WHERE name = :name AND host = :host AND path = :path AND \
+ originAttributes = :originAttributes"
+ );
+
+ break;
+ }
+
+ case 12: {
+ if (!exists) {
+ this.db.executeSimpleSQL(
+ "CREATE TABLE moz_cookies ( \
+ id INTEGER PRIMARY KEY, \
+ 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, \
+ schemeMap INTEGER DEFAULT 0, \
+ CONSTRAINT moz_uniqueid UNIQUE (name, host, path, originAttributes))"
+ );
+
+ this.db.executeSimpleSQL("PRAGMA journal_mode = WAL");
+ this.db.executeSimpleSQL("PRAGMA wal_autocheckpoint = 16");
+ }
+
+ this.stmtInsert = this.db.createStatement(
+ "INSERT INTO moz_cookies ( \
+ name, \
+ value, \
+ host, \
+ path, \
+ expiry, \
+ lastAccessed, \
+ creationTime, \
+ isSecure, \
+ isHttpOnly, \
+ inBrowserElement, \
+ originAttributes, \
+ sameSite, \
+ rawSameSite, \
+ schemeMap \
+ ) VALUES ( \
+ :name, \
+ :value, \
+ :host, \
+ :path, \
+ :expiry, \
+ :lastAccessed, \
+ :creationTime, \
+ :isSecure, \
+ :isHttpOnly, \
+ :inBrowserElement, \
+ :originAttributes, \
+ :sameSite, \
+ :rawSameSite, \
+ :schemeMap)"
+ );
+
+ this.stmtDelete = this.db.createStatement(
+ "DELETE FROM moz_cookies \
+ WHERE name = :name AND host = :host AND path = :path AND \
+ originAttributes = :originAttributes"
+ );
+
+ this.stmtUpdate = this.db.createStatement(
+ "UPDATE moz_cookies SET lastAccessed = :lastAccessed \
+ WHERE name = :name AND host = :host AND path = :path AND \
+ originAttributes = :originAttributes"
+ );
+
+ break;
+ }
+
+ default:
+ do_throw("unrecognized schemaVersion!");
+ }
+}
+
+CookieDatabaseConnection.prototype = {
+ insertCookie(cookie) {
+ if (!(cookie instanceof Cookie)) {
+ do_throw("not a cookie");
+ }
+
+ switch (this.schema) {
+ case 1:
+ this.stmtInsert.bindByName("id", cookie.creationTime);
+ this.stmtInsert.bindByName("name", cookie.name);
+ this.stmtInsert.bindByName("value", cookie.value);
+ this.stmtInsert.bindByName("host", cookie.host);
+ this.stmtInsert.bindByName("path", cookie.path);
+ this.stmtInsert.bindByName("expiry", cookie.expiry);
+ this.stmtInsert.bindByName("isSecure", cookie.isSecure);
+ this.stmtInsert.bindByName("isHttpOnly", cookie.isHttpOnly);
+ break;
+
+ case 2:
+ this.stmtInsert.bindByName("id", cookie.creationTime);
+ this.stmtInsert.bindByName("name", cookie.name);
+ this.stmtInsert.bindByName("value", cookie.value);
+ this.stmtInsert.bindByName("host", cookie.host);
+ this.stmtInsert.bindByName("path", cookie.path);
+ this.stmtInsert.bindByName("expiry", cookie.expiry);
+ this.stmtInsert.bindByName("lastAccessed", cookie.lastAccessed);
+ this.stmtInsert.bindByName("isSecure", cookie.isSecure);
+ this.stmtInsert.bindByName("isHttpOnly", cookie.isHttpOnly);
+ break;
+
+ case 3:
+ this.stmtInsert.bindByName("id", cookie.creationTime);
+ this.stmtInsert.bindByName("baseDomain", cookie.baseDomain);
+ this.stmtInsert.bindByName("name", cookie.name);
+ this.stmtInsert.bindByName("value", cookie.value);
+ this.stmtInsert.bindByName("host", cookie.host);
+ this.stmtInsert.bindByName("path", cookie.path);
+ this.stmtInsert.bindByName("expiry", cookie.expiry);
+ this.stmtInsert.bindByName("lastAccessed", cookie.lastAccessed);
+ this.stmtInsert.bindByName("isSecure", cookie.isSecure);
+ this.stmtInsert.bindByName("isHttpOnly", cookie.isHttpOnly);
+ break;
+
+ case 4:
+ this.stmtInsert.bindByName("baseDomain", cookie.baseDomain);
+ this.stmtInsert.bindByName("name", cookie.name);
+ this.stmtInsert.bindByName("value", cookie.value);
+ this.stmtInsert.bindByName("host", cookie.host);
+ this.stmtInsert.bindByName("path", cookie.path);
+ this.stmtInsert.bindByName("expiry", cookie.expiry);
+ this.stmtInsert.bindByName("lastAccessed", cookie.lastAccessed);
+ this.stmtInsert.bindByName("creationTime", cookie.creationTime);
+ this.stmtInsert.bindByName("isSecure", cookie.isSecure);
+ this.stmtInsert.bindByName("isHttpOnly", cookie.isHttpOnly);
+ break;
+
+ case 10:
+ this.stmtInsert.bindByName("name", cookie.name);
+ this.stmtInsert.bindByName("value", cookie.value);
+ this.stmtInsert.bindByName("host", cookie.host);
+ this.stmtInsert.bindByName("baseDomain", cookie.baseDomain);
+ this.stmtInsert.bindByName("path", cookie.path);
+ this.stmtInsert.bindByName("expiry", cookie.expiry);
+ this.stmtInsert.bindByName("lastAccessed", cookie.lastAccessed);
+ this.stmtInsert.bindByName("creationTime", cookie.creationTime);
+ this.stmtInsert.bindByName("isSecure", cookie.isSecure);
+ this.stmtInsert.bindByName("isHttpOnly", cookie.isHttpOnly);
+ this.stmtInsert.bindByName("inBrowserElement", cookie.inBrowserElement);
+ this.stmtInsert.bindByName(
+ "originAttributes",
+ ChromeUtils.originAttributesToSuffix(cookie.originAttributes)
+ );
+ this.stmtInsert.bindByName("sameSite", cookie.sameSite);
+ this.stmtInsert.bindByName("rawSameSite", cookie.rawSameSite);
+ break;
+
+ case 11:
+ this.stmtInsert.bindByName("name", cookie.name);
+ this.stmtInsert.bindByName("value", cookie.value);
+ this.stmtInsert.bindByName("host", cookie.host);
+ this.stmtInsert.bindByName("path", cookie.path);
+ this.stmtInsert.bindByName("expiry", cookie.expiry);
+ this.stmtInsert.bindByName("lastAccessed", cookie.lastAccessed);
+ this.stmtInsert.bindByName("creationTime", cookie.creationTime);
+ this.stmtInsert.bindByName("isSecure", cookie.isSecure);
+ this.stmtInsert.bindByName("isHttpOnly", cookie.isHttpOnly);
+ this.stmtInsert.bindByName("inBrowserElement", cookie.inBrowserElement);
+ this.stmtInsert.bindByName(
+ "originAttributes",
+ ChromeUtils.originAttributesToSuffix(cookie.originAttributes)
+ );
+ this.stmtInsert.bindByName("sameSite", cookie.sameSite);
+ this.stmtInsert.bindByName("rawSameSite", cookie.rawSameSite);
+ break;
+
+ case 12:
+ this.stmtInsert.bindByName("name", cookie.name);
+ this.stmtInsert.bindByName("value", cookie.value);
+ this.stmtInsert.bindByName("host", cookie.host);
+ this.stmtInsert.bindByName("path", cookie.path);
+ this.stmtInsert.bindByName("expiry", cookie.expiry);
+ this.stmtInsert.bindByName("lastAccessed", cookie.lastAccessed);
+ this.stmtInsert.bindByName("creationTime", cookie.creationTime);
+ this.stmtInsert.bindByName("isSecure", cookie.isSecure);
+ this.stmtInsert.bindByName("isHttpOnly", cookie.isHttpOnly);
+ this.stmtInsert.bindByName("inBrowserElement", cookie.inBrowserElement);
+ this.stmtInsert.bindByName(
+ "originAttributes",
+ ChromeUtils.originAttributesToSuffix(cookie.originAttributes)
+ );
+ this.stmtInsert.bindByName("sameSite", cookie.sameSite);
+ this.stmtInsert.bindByName("rawSameSite", cookie.rawSameSite);
+ this.stmtInsert.bindByName("schemeMap", cookie.schemeMap);
+ break;
+
+ default:
+ do_throw("unrecognized schemaVersion!");
+ }
+
+ do_execute_stmt(this.stmtInsert);
+ },
+
+ deleteCookie(cookie) {
+ if (!(cookie instanceof Cookie)) {
+ do_throw("not a cookie");
+ }
+
+ switch (this.db.schemaVersion) {
+ case 1:
+ case 2:
+ case 3:
+ this.stmtDelete.bindByName("id", cookie.creationTime);
+ break;
+
+ case 4:
+ this.stmtDelete.bindByName("name", cookie.name);
+ this.stmtDelete.bindByName("host", cookie.host);
+ this.stmtDelete.bindByName("path", cookie.path);
+ break;
+
+ case 10:
+ case 11:
+ case 12:
+ this.stmtDelete.bindByName("name", cookie.name);
+ this.stmtDelete.bindByName("host", cookie.host);
+ this.stmtDelete.bindByName("path", cookie.path);
+ this.stmtDelete.bindByName(
+ "originAttributes",
+ ChromeUtils.originAttributesToSuffix(cookie.originAttributes)
+ );
+ break;
+
+ default:
+ do_throw("unrecognized schemaVersion!");
+ }
+
+ do_execute_stmt(this.stmtDelete);
+ },
+
+ updateCookie(cookie) {
+ if (!(cookie instanceof Cookie)) {
+ do_throw("not a cookie");
+ }
+
+ switch (this.db.schemaVersion) {
+ case 1:
+ do_throw("can't update a schema 1 cookie!");
+ break;
+ case 2:
+ case 3:
+ this.stmtUpdate.bindByName("id", cookie.creationTime);
+ this.stmtUpdate.bindByName("lastAccessed", cookie.lastAccessed);
+ break;
+
+ case 4:
+ this.stmtDelete.bindByName("name", cookie.name);
+ this.stmtDelete.bindByName("host", cookie.host);
+ this.stmtDelete.bindByName("path", cookie.path);
+ this.stmtUpdate.bindByName("name", cookie.name);
+ this.stmtUpdate.bindByName("host", cookie.host);
+ this.stmtUpdate.bindByName("path", cookie.path);
+ this.stmtUpdate.bindByName("lastAccessed", cookie.lastAccessed);
+ break;
+
+ case 10:
+ case 11:
+ case 12:
+ this.stmtDelete.bindByName("name", cookie.name);
+ this.stmtDelete.bindByName("host", cookie.host);
+ this.stmtDelete.bindByName("path", cookie.path);
+ this.stmtDelete.bindByName(
+ "originAttributes",
+ ChromeUtils.originAttributesToSuffix(cookie.originAttributes)
+ );
+ this.stmtUpdate.bindByName("name", cookie.name);
+ this.stmtUpdate.bindByName("host", cookie.host);
+ this.stmtUpdate.bindByName("path", cookie.path);
+ this.stmtUpdate.bindByName(
+ "originAttributes",
+ ChromeUtils.originAttributesToSuffix(cookie.originAttributes)
+ );
+ this.stmtUpdate.bindByName("lastAccessed", cookie.lastAccessed);
+ break;
+
+ default:
+ do_throw("unrecognized schemaVersion!");
+ }
+
+ do_execute_stmt(this.stmtUpdate);
+ },
+
+ close() {
+ this.stmtInsert.finalize();
+ this.stmtDelete.finalize();
+ if (this.stmtUpdate) {
+ this.stmtUpdate.finalize();
+ }
+ this.db.close();
+
+ this.stmtInsert = null;
+ this.stmtDelete = null;
+ this.stmtUpdate = null;
+ this.db = null;
+ },
+};
+
+function do_get_cookie_file(profile) {
+ let file = profile.clone();
+ file.append("cookies.sqlite");
+ return file;
+}
+
+// Count the cookies from 'host' in a database. If 'host' is null, count all
+// cookies.
+function do_count_cookies_in_db(connection, host) {
+ let select = null;
+ if (host) {
+ select = connection.createStatement(
+ "SELECT COUNT(1) FROM moz_cookies WHERE host = :host"
+ );
+ select.bindByName("host", host);
+ } else {
+ select = connection.createStatement("SELECT COUNT(1) FROM moz_cookies");
+ }
+
+ select.executeStep();
+ let result = select.getInt32(0);
+ select.reset();
+ select.finalize();
+ return result;
+}
+
+// Execute 'stmt', ensuring that we reset it if it throws.
+function do_execute_stmt(stmt) {
+ try {
+ stmt.executeStep();
+ stmt.reset();
+ } catch (e) {
+ stmt.reset();
+ throw e;
+ }
+}