Source code

Revision control

Copy as Markdown

Other Tools

Test Info:

/* Any copyright is dedicated to the Public Domain.
add_setup(function test_setup() {
Services.prefs.setIntPref(
"network.cookie.cookieBehavior",
Ci.nsICookieService.BEHAVIOR_REJECT_TRACKER_AND_PARTITION_FOREIGN
);
Services.prefs.setBoolPref(
"network.cookieJarSettings.unblocked_for_testing",
true
);
Services.prefs.setBoolPref(
"network.cookie.cookieBehavior.optInPartitioning",
true
);
Services.prefs.setBoolPref("network.cookie.CHIPS.enabled", true);
Services.prefs.setBoolPref(
"network.cookie.chips.partitionLimitEnabled",
true
);
Services.prefs.setBoolPref(
"network.cookie.chips.partitionLimitDryRun",
false
);
Services.prefs.setIntPref(
"network.cookie.chips.partitionLimitByteCapacity",
24
);
});
registerCleanupFunction(() => {
Services.prefs.clearUserPref("network.cookie.cookieBehavior");
Services.prefs.clearUserPref(
"network.cookie.cookieBehavior.optInPartitioning"
);
Services.prefs.clearUserPref(
"network.cookieJarSettings.unblocked_for_testing"
);
Services.prefs.clearUserPref("network.cookie.CHIPS.enabled");
Services.prefs.clearUserPref("network.cookie.chips.partitionLimitEnabled");
Services.prefs.clearUserPref("network.cookie.chips.partitionLimitDryRun");
Services.prefs.clearUserPref(
"network.cookie.chips.partitionLimitByteCapacity"
);
Services.cookies.removeAll();
});
function addChipsCookie(
name,
value,
host,
expiry,
lastAccessed,
creationTime,
db
) {
let cookie = new Cookie(
name,
value,
host,
"/", // path
expiry,
lastAccessed,
creationTime,
false, // session
true, // secure
false, // http-only
false, // in browser element
{ partitionKey: "(https,example.com)" },
Ci.nsICookie.SAMESITE_UNSET,
Ci.nsICookie.SCHEME_UNSET,
true // isPartitioned
);
db.insertCookie(cookie);
}
add_task(async function test_purge_crash() {
let profile = do_get_profile();
let dbFile = do_get_cookie_file(profile);
Assert.ok(!dbFile.exists());
let schemaDb = new CookieDatabaseConnection(dbFile, 15);
let now = Date.now() * 1000; // date in microseconds
let past = Math.round(now / 1e3 - 1000);
let future = Math.round(now / 1e3 + 1000) + 20000;
let host = "example.com";
// add three cookies such that their order in the CookieEntry list is NOT
// sorted by age
// we set up a few cookies to get close to the chips limit, without going over
// if we front-load the list with enough recently used cookies
// we can trigger a crash in the CHIPS purging (before our fix in Bug 1971595)
addChipsCookie("c4", "4", host, future, past + 4000, past, schemaDb);
addChipsCookie("c5", "5", host, future, past + 4000, past, schemaDb);
addChipsCookie("c6", "6", host, future, past + 4000, past, schemaDb);
addChipsCookie("c7", "7", host, future, past + 4000, past, schemaDb);
addChipsCookie("c8", "8", host, future, past + 4000, past, schemaDb);
addChipsCookie("c1", "1", host, future, past, past, schemaDb);
addChipsCookie("c2", "2", host, future, past + 3000, past, schemaDb);
addChipsCookie("c3", "3", host, future, past + 2000, past, schemaDb);
// check that the cookies were added to the db
Assert.equal(do_count_cookies_in_db(schemaDb.db), 8); // total
Assert.equal(
do_count_cookies_in_db(schemaDb.db, "example.com"), // per host+OA
8
);
const PATH_EMPTY = "/";
const FIRST_PARTY = "example.com";
const URL_DOCUMENT_FIRSTPARTY = "https://" + FIRST_PARTY + PATH_EMPTY;
function createPartitionKey(url) {
let uri = NetUtil.newURI(url);
return `(${uri.scheme},${uri.host})`;
}
function createOriginAttributes(partitionKey) {
return JSON.stringify({
firstPartyDomain: "",
geckoViewSessionContextId: "",
inIsolatedMozBrowser: false,
partitionKey,
privateBrowsingId: 0,
userContextId: 0,
});
}
const partitionedOAs = createOriginAttributes(
createPartitionKey(URL_DOCUMENT_FIRSTPARTY)
);
// validate the db is as expected
// startup the cookie service and check the cookie count
// this shouldn't update the lastAccessed values (which determines cookie age)
let partitioned = Services.cookies.getCookiesWithOriginAttributes(
partitionedOAs,
FIRST_PARTY
);
// a printed list at this point is expected: c4, c5, ..., c8, c1, ...
Assert.equal(partitioned.length, 8);
// add a CHIPS cookie - triggers a CHIPS purge
// use enough Bytes to trigger the purging of many cookies added before
// this is where the crash occurs
const cv = Services.cookies.add(
host,
"/", // path
"cxxxxx", // name
"yyyyyy", // value
true, // secure
false, // http-only
true, // isSession
future,
{ partitionKey: "(https,example.com)" },
Ci.nsICookie.SAMESITE_UNSET, // SameSite
Ci.nsICookie.SCHEME_HTTPS,
true // partitioned
);
Assert.equal(cv.result, Ci.nsICookieValidation.eOK, "Valid cookie");
// check post-purge cookie count
let postPurgeCookies = Services.cookies.getCookiesWithOriginAttributes(
partitionedOAs,
FIRST_PARTY
);
Assert.equal(postPurgeCookies.length, 5);
schemaDb.close();
});