diff options
author | Daniel Baumann <daniel.baumann@progress-linux.org> | 2024-04-19 00:47:55 +0000 |
---|---|---|
committer | Daniel Baumann <daniel.baumann@progress-linux.org> | 2024-04-19 00:47:55 +0000 |
commit | 26a029d407be480d791972afb5975cf62c9360a6 (patch) | |
tree | f435a8308119effd964b339f76abb83a57c29483 /netwerk/test/unit/test_cookies_sync_failure.js | |
parent | Initial commit. (diff) | |
download | firefox-26a029d407be480d791972afb5975cf62c9360a6.tar.xz firefox-26a029d407be480d791972afb5975cf62c9360a6.zip |
Adding upstream version 124.0.1.upstream/124.0.1
Signed-off-by: Daniel Baumann <daniel.baumann@progress-linux.org>
Diffstat (limited to 'netwerk/test/unit/test_cookies_sync_failure.js')
-rw-r--r-- | netwerk/test/unit/test_cookies_sync_failure.js | 344 |
1 files changed, 344 insertions, 0 deletions
diff --git a/netwerk/test/unit/test_cookies_sync_failure.js b/netwerk/test/unit/test_cookies_sync_failure.js new file mode 100644 index 0000000000..6c420d1cb0 --- /dev/null +++ b/netwerk/test/unit/test_cookies_sync_failure.js @@ -0,0 +1,344 @@ +/* Any copyright is dedicated to the Public Domain. + http://creativecommons.org/publicdomain/zero/1.0/ */ + +// Test the various ways opening a cookie database can fail in a synchronous +// (i.e. immediate) manner, and that the database is renamed and recreated +// under each circumstance. These circumstances are, in no particular order: +// +// 1) A corrupt database, such that opening the connection fails. +// 2) The 'moz_cookies' table doesn't exist. +// 3) Not all of the expected columns exist, and statement creation fails when: +// a) The schema version is larger than the current version. +// b) The schema version is less than or equal to the current version. +// 4) Migration fails. This will have different modes depending on the initial +// version: +// a) Schema 1: the 'lastAccessed' column already exists. +// b) Schema 2: the 'baseDomain' column already exists; or 'baseDomain' +// cannot be computed for a particular host. +// c) Schema 3: the 'creationTime' column already exists; or the +// 'moz_uniqueid' index already exists. + +"use strict"; + +let profile; +let cookieFile; +let backupFile; +let sub_generator; +let now; +let futureExpiry; +let cookie; + +var COOKIE_DATABASE_SCHEMA_CURRENT = 13; + +var test_generator = do_run_test(); + +function run_test() { + do_test_pending(); + do_run_generator(test_generator); +} + +function finish_test() { + executeSoon(function () { + test_generator.return(); + do_test_finished(); + }); +} + +function* do_run_test() { + // Set up a profile. + profile = do_get_profile(); + + // Allow all cookies. + Services.prefs.setIntPref("network.cookie.cookieBehavior", 0); + Services.prefs.setBoolPref( + "network.cookieJarSettings.unblocked_for_testing", + true + ); + + // Get the cookie file and the backup file. + cookieFile = profile.clone(); + cookieFile.append("cookies.sqlite"); + backupFile = profile.clone(); + backupFile.append("cookies.sqlite.bak"); + Assert.ok(!cookieFile.exists()); + Assert.ok(!backupFile.exists()); + + // Create a cookie object for testing. + now = Date.now() * 1000; + futureExpiry = Math.round(now / 1e6 + 1000); + cookie = new Cookie( + "oh", + "hai", + "bar.com", + "/", + futureExpiry, + now, + now, + false, + false, + false + ); + + sub_generator = run_test_1(test_generator); + sub_generator.next(); + yield; + + sub_generator = run_test_2(test_generator); + sub_generator.next(); + yield; + + sub_generator = run_test_3(test_generator, 99); + sub_generator.next(); + yield; + + sub_generator = run_test_3(test_generator, COOKIE_DATABASE_SCHEMA_CURRENT); + sub_generator.next(); + yield; + + sub_generator = run_test_3(test_generator, 4); + sub_generator.next(); + yield; + + sub_generator = run_test_3(test_generator, 3); + sub_generator.next(); + yield; + + sub_generator = run_test_4_exists( + test_generator, + 1, + "ALTER TABLE moz_cookies ADD lastAccessed INTEGER" + ); + sub_generator.next(); + yield; + + sub_generator = run_test_4_exists( + test_generator, + 2, + "ALTER TABLE moz_cookies ADD baseDomain TEXT" + ); + sub_generator.next(); + yield; + + sub_generator = run_test_4_baseDomain(test_generator); + sub_generator.next(); + yield; + + sub_generator = run_test_4_exists( + test_generator, + 3, + "ALTER TABLE moz_cookies ADD creationTime INTEGER" + ); + sub_generator.next(); + yield; + + sub_generator = run_test_4_exists( + test_generator, + 3, + "CREATE UNIQUE INDEX moz_uniqueid ON moz_cookies (name, host, path)" + ); + sub_generator.next(); + yield; + + finish_test(); +} + +const garbage = "hello thar!"; + +function create_garbage_file(file) { + // Create an empty database file. + file.create(Ci.nsIFile.NORMAL_FILE_TYPE, -1); + Assert.ok(file.exists()); + Assert.equal(file.fileSize, 0); + + // Write some garbage to it. + let ostream = Cc["@mozilla.org/network/file-output-stream;1"].createInstance( + Ci.nsIFileOutputStream + ); + ostream.init(file, -1, -1, 0); + ostream.write(garbage, garbage.length); + ostream.flush(); + ostream.close(); + + file = file.clone(); // Windows maintains a stat cache. It's lame. + Assert.equal(file.fileSize, garbage.length); +} + +function check_garbage_file(file) { + Assert.ok(file.exists()); + Assert.equal(file.fileSize, garbage.length); + file.remove(false); + Assert.ok(!file.exists()); +} + +function* run_test_1(generator) { + // Create a garbage database file. + create_garbage_file(cookieFile); + + let uri = NetUtil.newURI("http://foo.com/"); + const channel = NetUtil.newChannel({ + uri, + loadUsingSystemPrincipal: true, + contentPolicyType: Ci.nsIContentPolicy.TYPE_DOCUMENT, + }); + + // Load the profile and populate it. + Services.cookies.setCookieStringFromHttp( + uri, + "oh=hai; max-age=1000", + channel + ); + + // Fake a profile change. + do_close_profile(sub_generator); + yield; + do_load_profile(); + + // Check that the new database contains the cookie, and the old file was + // renamed. + Assert.equal(do_count_cookies(), 1); + check_garbage_file(backupFile); + + // Close the profile. + do_close_profile(sub_generator); + yield; + + // Clean up. + cookieFile.remove(false); + Assert.ok(!cookieFile.exists()); + do_run_generator(generator); +} + +function* run_test_2(generator) { + // Load the profile and populate it. + do_load_profile(); + let uri = NetUtil.newURI("http://foo.com/"); + const channel = NetUtil.newChannel({ + uri, + loadUsingSystemPrincipal: true, + contentPolicyType: Ci.nsIContentPolicy.TYPE_DOCUMENT, + }); + Services.cookies.setCookieStringFromHttp( + uri, + "oh=hai; max-age=1000", + channel + ); + + // Fake a profile change. + do_close_profile(sub_generator); + yield; + + // Drop the table. + let db = Services.storage.openDatabase(cookieFile); + db.executeSimpleSQL("DROP TABLE moz_cookies"); + db.close(); + + // Load the profile and check that the table is recreated in-place. + do_load_profile(); + Assert.equal(do_count_cookies(), 0); + Assert.ok(!backupFile.exists()); + + // Close the profile. + do_close_profile(sub_generator); + yield; + + // Clean up. + cookieFile.remove(false); + Assert.ok(!cookieFile.exists()); + do_run_generator(generator); +} + +function* run_test_3(generator, schema) { + // Manually create a schema 2 database, populate it, and set the schema + // version to the desired number. + let schema2db = new CookieDatabaseConnection(do_get_cookie_file(profile), 2); + schema2db.insertCookie(cookie); + schema2db.db.schemaVersion = schema; + schema2db.close(); + + // Load the profile and check that the column existence test fails. + do_load_profile(); + Assert.equal(do_count_cookies(), 0); + + // Close the profile. + do_close_profile(sub_generator); + yield; + + // Check that the schema version has been reset. + let db = Services.storage.openDatabase(cookieFile); + Assert.equal(db.schemaVersion, COOKIE_DATABASE_SCHEMA_CURRENT); + db.close(); + + // Clean up. + cookieFile.remove(false); + Assert.ok(!cookieFile.exists()); + do_run_generator(generator); +} + +function* run_test_4_exists(generator, schema, stmt) { + // Manually create a database, populate it, and add the desired column. + let db = new CookieDatabaseConnection(do_get_cookie_file(profile), schema); + db.insertCookie(cookie); + db.db.executeSimpleSQL(stmt); + db.close(); + + // Load the profile and check that migration fails. + do_load_profile(); + Assert.equal(do_count_cookies(), 0); + + // Close the profile. + do_close_profile(sub_generator); + yield; + + // Check that the schema version has been reset and the backup file exists. + db = Services.storage.openDatabase(cookieFile); + Assert.equal(db.schemaVersion, COOKIE_DATABASE_SCHEMA_CURRENT); + db.close(); + Assert.ok(backupFile.exists()); + + // Clean up. + cookieFile.remove(false); + backupFile.remove(false); + Assert.ok(!cookieFile.exists()); + Assert.ok(!backupFile.exists()); + do_run_generator(generator); +} + +function* run_test_4_baseDomain(generator) { + // Manually create a database and populate it with a bad host. + let db = new CookieDatabaseConnection(do_get_cookie_file(profile), 2); + let badCookie = new Cookie( + "oh", + "hai", + ".", + "/", + futureExpiry, + now, + now, + false, + false, + false + ); + db.insertCookie(badCookie); + db.close(); + + // Load the profile and check that migration fails. + do_load_profile(); + Assert.equal(do_count_cookies(), 0); + + // Close the profile. + do_close_profile(sub_generator); + yield; + + // Check that the schema version has been reset and the backup file exists. + db = Services.storage.openDatabase(cookieFile); + Assert.equal(db.schemaVersion, COOKIE_DATABASE_SCHEMA_CURRENT); + db.close(); + Assert.ok(backupFile.exists()); + + // Clean up. + cookieFile.remove(false); + backupFile.remove(false); + Assert.ok(!cookieFile.exists()); + Assert.ok(!backupFile.exists()); + do_run_generator(generator); +} |