зеркало из https://github.com/mozilla/gecko-dev.git
Bug 1638358 - Cookie Schemeful Same-Site - part 2 - schemeMap in the cookie DB, r=mayhemer
Differential Revision: https://phabricator.services.mozilla.com/D75626
This commit is contained in:
Родитель
4afe05e324
Коммит
8d0f3f353b
|
@ -96,6 +96,9 @@ class Cookie final : public nsICookie {
|
|||
// Set the creation time manually, overriding the monotonicity checks in
|
||||
// Create(). Use with caution!
|
||||
inline void SetCreationTime(int64_t aTime) { mData.creationTime() = aTime; }
|
||||
inline void SetSchemeMap(uint8_t aSchemeMap) {
|
||||
mData.schemeMap() = aSchemeMap;
|
||||
}
|
||||
|
||||
bool IsStale() const;
|
||||
|
||||
|
|
|
@ -27,7 +27,7 @@
|
|||
// This is a hack to hide HttpOnly cookies from older browsers
|
||||
#define HTTP_ONLY_PREFIX "#HttpOnly_"
|
||||
|
||||
constexpr auto COOKIES_SCHEMA_VERSION = 11;
|
||||
constexpr auto COOKIES_SCHEMA_VERSION = 12;
|
||||
|
||||
// parameter indexes; see |Read|
|
||||
constexpr auto IDX_NAME = 0;
|
||||
|
@ -42,6 +42,7 @@ constexpr auto IDX_HTTPONLY = 8;
|
|||
constexpr auto IDX_ORIGIN_ATTRIBUTES = 9;
|
||||
constexpr auto IDX_SAME_SITE = 10;
|
||||
constexpr auto IDX_RAW_SAME_SITE = 11;
|
||||
constexpr auto IDX_SCHEME_MAP = 12;
|
||||
|
||||
#define COOKIES_FILE "cookies.sqlite"
|
||||
|
||||
|
@ -112,6 +113,10 @@ void BindCookieParameters(mozIStorageBindingParamsArray* aParamsArray,
|
|||
aCookie->RawSameSite());
|
||||
MOZ_ASSERT(NS_SUCCEEDED(rv));
|
||||
|
||||
rv = params->BindInt32ByName(NS_LITERAL_CSTRING("schemeMap"),
|
||||
aCookie->SchemeMap());
|
||||
MOZ_ASSERT(NS_SUCCEEDED(rv));
|
||||
|
||||
// Bind the params to the array.
|
||||
rv = aParamsArray->AddParams(params);
|
||||
MOZ_ASSERT(NS_SUCCEEDED(rv));
|
||||
|
@ -1384,6 +1389,17 @@ CookiePersistentStorage::OpenDBResult CookiePersistentStorage::TryInitDB(
|
|||
|
||||
COOKIE_LOGSTRING(LogLevel::Debug,
|
||||
("Upgraded database to schema version 11"));
|
||||
}
|
||||
[[fallthrough]];
|
||||
|
||||
case 11: {
|
||||
// Add the schemeMap column to the table.
|
||||
rv = mSyncConn->ExecuteSimpleSQL(NS_LITERAL_CSTRING(
|
||||
"ALTER TABLE moz_cookies ADD schemeMap INTEGER DEFAULT 0;"));
|
||||
NS_ENSURE_SUCCESS(rv, RESULT_RETRY);
|
||||
|
||||
COOKIE_LOGSTRING(LogLevel::Debug,
|
||||
("Upgraded database to schema version 12"));
|
||||
|
||||
// No more upgrades. Update the schema version.
|
||||
rv = mSyncConn->SetSchemaVersion(COOKIES_SCHEMA_VERSION);
|
||||
|
@ -1430,7 +1446,8 @@ CookiePersistentStorage::OpenDBResult CookiePersistentStorage::TryInitDB(
|
|||
"isSecure, "
|
||||
"isHttpOnly, "
|
||||
"sameSite, "
|
||||
"rawSameSite "
|
||||
"rawSameSite, "
|
||||
"schemeMap "
|
||||
"FROM moz_cookies"),
|
||||
getter_AddRefs(stmt));
|
||||
if (NS_SUCCEEDED(rv)) {
|
||||
|
@ -1604,7 +1621,8 @@ CookiePersistentStorage::OpenDBResult CookiePersistentStorage::Read() {
|
|||
"isHttpOnly, "
|
||||
"originAttributes, "
|
||||
"sameSite, "
|
||||
"rawSameSite "
|
||||
"rawSameSite, "
|
||||
"schemeMap "
|
||||
"FROM moz_cookies"),
|
||||
getter_AddRefs(stmt));
|
||||
|
||||
|
@ -1684,11 +1702,13 @@ UniquePtr<CookieStruct> CookiePersistentStorage::GetCookieFromRow(
|
|||
bool isHttpOnly = 0 != aRow->AsInt32(IDX_HTTPONLY);
|
||||
int32_t sameSite = aRow->AsInt32(IDX_SAME_SITE);
|
||||
int32_t rawSameSite = aRow->AsInt32(IDX_RAW_SAME_SITE);
|
||||
int32_t schemeMap = aRow->AsInt32(IDX_SCHEME_MAP);
|
||||
|
||||
// Create a new constCookie and assign the data.
|
||||
return MakeUnique<CookieStruct>(
|
||||
name, value, host, path, expiry, lastAccessed, creationTime, isHttpOnly,
|
||||
false, isSecure, sameSite, rawSameSite, nsICookie::SCHEME_UNSET);
|
||||
false, isSecure, sameSite, rawSameSite,
|
||||
static_cast<nsICookie::schemeType>(schemeMap));
|
||||
}
|
||||
|
||||
void CookiePersistentStorage::EnsureReadComplete() {
|
||||
|
@ -1824,7 +1844,8 @@ nsresult CookiePersistentStorage::InitDBConnInternal() {
|
|||
"isSecure, "
|
||||
"isHttpOnly, "
|
||||
"sameSite, "
|
||||
"rawSameSite "
|
||||
"rawSameSite, "
|
||||
"schemeMap "
|
||||
") VALUES ("
|
||||
":originAttributes, "
|
||||
":name, "
|
||||
|
@ -1837,7 +1858,8 @@ nsresult CookiePersistentStorage::InitDBConnInternal() {
|
|||
":isSecure, "
|
||||
":isHttpOnly, "
|
||||
":sameSite, "
|
||||
":rawSameSite "
|
||||
":rawSameSite, "
|
||||
":schemeMap "
|
||||
")"),
|
||||
getter_AddRefs(mStmtInsert));
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
@ -1881,6 +1903,7 @@ nsresult CookiePersistentStorage::CreateTableWorker(const char* aName) {
|
|||
"inBrowserElement INTEGER DEFAULT 0, "
|
||||
"sameSite INTEGER DEFAULT 0, "
|
||||
"rawSameSite INTEGER DEFAULT 0, "
|
||||
"schemeMap INTEGER DEFAULT 0, "
|
||||
"CONSTRAINT moz_uniqueid UNIQUE (name, host, path, originAttributes)"
|
||||
")");
|
||||
return mSyncConn->ExecuteSimpleSQL(command);
|
||||
|
|
|
@ -976,6 +976,16 @@ bool CookieService::CanSetCookie(
|
|||
// init expiryTime such that session cookies won't prematurely expire
|
||||
aCookieData.expiry() = INT64_MAX;
|
||||
|
||||
if (aHostURI->SchemeIs("https")) {
|
||||
aCookieData.schemeMap() = nsICookie::SCHEME_HTTPS;
|
||||
} else if (aHostURI->SchemeIs("http")) {
|
||||
aCookieData.schemeMap() = nsICookie::SCHEME_HTTP;
|
||||
} else if (aHostURI->SchemeIs("file")) {
|
||||
aCookieData.schemeMap() = nsICookie::SCHEME_FILE;
|
||||
} else {
|
||||
MOZ_CRASH("Unsupported scheme type");
|
||||
}
|
||||
|
||||
// aCookieHeader is an in/out param to point to the next cookie, if
|
||||
// there is one. Save the present value for logging purposes
|
||||
nsCString savedCookieHeader(aCookieHeader);
|
||||
|
|
|
@ -481,6 +481,7 @@ void CookieStorage::AddCookie(const nsACString& aBaseDomain,
|
|||
oldCookie->IsSession() == aCookie->IsSession() &&
|
||||
oldCookie->IsHttpOnly() == aCookie->IsHttpOnly() &&
|
||||
oldCookie->SameSite() == aCookie->SameSite() &&
|
||||
oldCookie->SchemeMap() == aCookie->SchemeMap() &&
|
||||
// We don't want to perform this optimization if the cookie is
|
||||
// considered stale, since in this case we would need to update the
|
||||
// database.
|
||||
|
@ -491,6 +492,10 @@ void CookieStorage::AddCookie(const nsACString& aBaseDomain,
|
|||
return;
|
||||
}
|
||||
|
||||
// Merge the scheme map in case the old cookie and the new cookie are
|
||||
// used with different schemes.
|
||||
MergeCookieSchemeMap(oldCookie, aCookie);
|
||||
|
||||
// Remove the old cookie.
|
||||
RemoveCookieFromList(exactIter);
|
||||
|
||||
|
@ -589,6 +594,11 @@ void CookieStorage::UpdateCookieOldestTime(Cookie* aCookie) {
|
|||
}
|
||||
}
|
||||
|
||||
void CookieStorage::MergeCookieSchemeMap(Cookie* aOldCookie,
|
||||
Cookie* aNewCookie) {
|
||||
aNewCookie->SetSchemeMap(aOldCookie->SchemeMap() | aNewCookie->SchemeMap());
|
||||
}
|
||||
|
||||
void CookieStorage::AddCookieToList(const nsACString& aBaseDomain,
|
||||
const OriginAttributes& aOriginAttributes,
|
||||
Cookie* aCookie) {
|
||||
|
|
|
@ -178,6 +178,8 @@ class CookieStorage : public nsIObserver, public nsSupportsWeakReference {
|
|||
|
||||
void UpdateCookieOldestTime(Cookie* aCookie);
|
||||
|
||||
void MergeCookieSchemeMap(Cookie* aOldCookie, Cookie* aNewCookie);
|
||||
|
||||
static already_AddRefed<nsIArray> CreatePurgeList(nsICookie* aCookie);
|
||||
|
||||
virtual already_AddRefed<nsIArray> PurgeCookies(int64_t aCurrentTimeInUsec,
|
||||
|
|
|
@ -61,7 +61,7 @@ conn.executeSimpleSQL(
|
|||
// Get sessionCookies to wait for the initialization in cookie thread
|
||||
const cookies = Services.cookies.sessionCookies;
|
||||
|
||||
Assert.equal(conn.schemaVersion, 11);
|
||||
Assert.equal(conn.schemaVersion, 12);
|
||||
let stmt = conn.createStatement(
|
||||
"SELECT sql FROM sqlite_master " +
|
||||
"WHERE type = 'table' AND " +
|
||||
|
|
|
@ -102,7 +102,7 @@ add_task(async _ => {
|
|||
await promise;
|
||||
|
||||
conn = storage.openDatabase(dbFile);
|
||||
Assert.equal(conn.schemaVersion, 11);
|
||||
Assert.equal(conn.schemaVersion, 12);
|
||||
|
||||
let stmt = conn.createStatement(
|
||||
"SELECT sameSite, rawSameSite FROM moz_cookies"
|
||||
|
|
|
@ -221,7 +221,8 @@ function Cookie(
|
|||
inBrowserElement = false,
|
||||
originAttributes = {},
|
||||
sameSite = Ci.nsICookie.SAMESITE_NONE,
|
||||
rawSameSite = Ci.nsICookie.SAMESITE_NONE
|
||||
rawSameSite = Ci.nsICookie.SAMESITE_NONE,
|
||||
schemeMap = Ci.nsICookie.SCHEME_UNSET
|
||||
) {
|
||||
this.name = name;
|
||||
this.value = value;
|
||||
|
@ -237,6 +238,7 @@ function Cookie(
|
|||
this.originAttributes = originAttributes;
|
||||
this.sameSite = sameSite;
|
||||
this.rawSameSite = rawSameSite;
|
||||
this.schemeMap = schemeMap;
|
||||
|
||||
let strippedHost = host.charAt(0) == "." ? host.slice(1) : host;
|
||||
|
||||
|
@ -628,6 +630,80 @@ function CookieDatabaseConnection(file, schema) {
|
|||
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!");
|
||||
}
|
||||
|
@ -728,6 +804,26 @@ CookieDatabaseConnection.prototype = {
|
|||
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!");
|
||||
}
|
||||
|
@ -755,6 +851,7 @@ CookieDatabaseConnection.prototype = {
|
|||
|
||||
case 10:
|
||||
case 11:
|
||||
case 12:
|
||||
this.stmtDelete.bindByName("name", cookie.name);
|
||||
this.stmtDelete.bindByName("host", cookie.host);
|
||||
this.stmtDelete.bindByName("path", cookie.path);
|
||||
|
@ -798,6 +895,7 @@ CookieDatabaseConnection.prototype = {
|
|||
|
||||
case 10:
|
||||
case 11:
|
||||
case 12:
|
||||
this.stmtDelete.bindByName("name", cookie.name);
|
||||
this.stmtDelete.bindByName("host", cookie.host);
|
||||
this.stmtDelete.bindByName("path", cookie.path);
|
||||
|
|
|
@ -123,7 +123,7 @@ async function run_test_1() {
|
|||
|
||||
// Open a database connection now, before we load the profile and begin
|
||||
// asynchronous write operations.
|
||||
let db = new CookieDatabaseConnection(do_get_cookie_file(profile), 11);
|
||||
let db = new CookieDatabaseConnection(do_get_cookie_file(profile), 12);
|
||||
Assert.equal(do_count_cookies_in_db(db.db), 1);
|
||||
|
||||
// Load the profile, and wait for async read completion...
|
||||
|
@ -481,7 +481,7 @@ async function run_test_5() {
|
|||
|
||||
// Open a database connection, and write a row that will trigger a constraint
|
||||
// violation.
|
||||
let db = new CookieDatabaseConnection(do_get_cookie_file(profile), 11);
|
||||
let db = new CookieDatabaseConnection(do_get_cookie_file(profile), 12);
|
||||
db.insertCookie(cookie);
|
||||
Assert.equal(do_count_cookies_in_db(db.db, "bar.com"), 1);
|
||||
Assert.equal(do_count_cookies_in_db(db.db), 1);
|
||||
|
|
|
@ -26,7 +26,7 @@ add_task(async () => {
|
|||
// completed. We may not be able to open one later once asynchronous writing
|
||||
// begins.
|
||||
Assert.ok(do_get_cookie_file(profile).exists());
|
||||
let db = new CookieDatabaseConnection(do_get_cookie_file(profile), 11);
|
||||
let db = new CookieDatabaseConnection(do_get_cookie_file(profile), 12);
|
||||
|
||||
let uri = NetUtil.newURI("http://foo.com/");
|
||||
let channel = NetUtil.newChannel({
|
||||
|
|
|
@ -28,7 +28,7 @@ let now;
|
|||
let futureExpiry;
|
||||
let cookie;
|
||||
|
||||
var COOKIE_DATABASE_SCHEMA_CURRENT = 11;
|
||||
var COOKIE_DATABASE_SCHEMA_CURRENT = 12;
|
||||
|
||||
var test_generator = do_run_test();
|
||||
|
||||
|
|
|
@ -49,7 +49,7 @@ add_task(async function() {
|
|||
Services.obs.notifyObservers(null, "profile-before-change");
|
||||
|
||||
// check for upgraded schema.
|
||||
Assert.equal(11, getDBVersion(destFile));
|
||||
Assert.equal(12, getDBVersion(destFile));
|
||||
|
||||
// Check that the index was deleted
|
||||
Assert.ok(!indexExists(destFile, "moz_basedomain"));
|
|
@ -2,7 +2,7 @@
|
|||
http://creativecommons.org/publicdomain/zero/1.0/ */
|
||||
|
||||
// Test cookie database migration from version 10 (prerelease Gecko 2.0) to the
|
||||
// current version, presently 11.
|
||||
// current version, presently 12.
|
||||
"use strict";
|
||||
|
||||
var test_generator = do_run_test();
|
||||
|
|
|
@ -193,7 +193,7 @@ skip-if = true # Bug 863738
|
|||
[test_cookies_sync_failure.js]
|
||||
[test_cookies_thirdparty.js]
|
||||
[test_cookies_thirdparty_session.js]
|
||||
[test_cookies_upgrade_10-11.js]
|
||||
[test_cookies_upgrade_10.js]
|
||||
[test_dns_cancel.js]
|
||||
[test_data_protocol.js]
|
||||
[test_dns_service.js]
|
||||
|
|
Загрузка…
Ссылка в новой задаче