#include "net/extras/sqlite/sqlite_persistent_cookie_store.h"
#include <stdint.h>
#include <map>
#include <memory>
#include <optional>
#include <set>
#include <utility>
#include <vector>
#include "base/containers/span.h"
#include "base/files/file.h"
#include "base/files/file_util.h"
#include "base/files/scoped_temp_dir.h"
#include "base/functional/bind.h"
#include "base/functional/callback.h"
#include "base/location.h"
#include "base/memory/ref_counted.h"
#include "base/memory/weak_ptr.h"
#include "base/run_loop.h"
#include "base/sequence_checker.h"
#include "base/strings/stringprintf.h"
#include "base/synchronization/waitable_event.h"
#include "base/task/sequenced_task_runner.h"
#include "base/task/single_thread_task_runner.h"
#include "base/task/thread_pool.h"
#include "base/test/bind.h"
#include "base/test/metrics/histogram_tester.h"
#include "base/threading/thread_restrictions.h"
#include "base/time/time.h"
#include "crypto/encryptor.h"
#include "crypto/symmetric_key.h"
#include "net/base/test_completion_callback.h"
#include "net/cookies/canonical_cookie.h"
#include "net/cookies/cookie_constants.h"
#include "net/cookies/cookie_inclusion_status.h"
#include "net/cookies/cookie_store_test_callbacks.h"
#include "net/extras/sqlite/cookie_crypto_delegate.h"
#include "net/log/net_log_capture_mode.h"
#include "net/log/test_net_log.h"
#include "net/log/test_net_log_util.h"
#include "net/test/test_with_task_environment.h"
#include "sql/database.h"
#include "sql/meta_table.h"
#include "sql/statement.h"
#include "sql/transaction.h"
#include "testing/gmock/include/gmock/gmock-matchers.h"
#include "testing/gmock/include/gmock/gmock.h"
#include "testing/gtest/include/gtest/gtest.h"
#include "url/gurl.h"
#include "url/third_party/mozilla/url_parse.h"
namespace net {
namespace {
const base::FilePath::CharType kCookieFilename[] = …);
class CookieCryptor : public CookieCryptoDelegate { … };
CookieCryptor::CookieCryptor()
: … { … }
base::OnceClosure CookieCryptor::GetInitClosure(base::OnceClosure callback) { … }
void CookieCryptor::Init(base::OnceClosure callback) { … }
bool CookieCryptor::EncryptString(const std::string& plaintext,
std::string* ciphertext) { … }
bool CookieCryptor::DecryptString(const std::string& ciphertext,
std::string* plaintext) { … }
void CookieCryptor::InitComplete() { … }
MATCHER_P2(MatchesCookieKeyAndLastAccessDate,
StrictlyUniqueKey,
last_access_date,
"") { … }
MATCHER_P(MatchesEveryCookieField, cookie, "") { … }
}
CanonicalCookieVector;
class SQLitePersistentCookieStoreTest : public TestWithTaskEnvironment { … };
TEST_F(SQLitePersistentCookieStoreTest, TestInvalidVersionRecovery) { … }
TEST_F(SQLitePersistentCookieStoreTest, TestInvalidMetaTableRecovery) { … }
TEST_F(SQLitePersistentCookieStoreTest, TestPersistance) { … }
TEST_F(SQLitePersistentCookieStoreTest, TestSessionCookiesDeletedOnStartup) { … }
TEST_F(SQLitePersistentCookieStoreTest, TestLoadCookiesForKey) { … }
TEST_F(SQLitePersistentCookieStoreTest, TestBeforeCommitCallback) { … }
TEST_F(SQLitePersistentCookieStoreTest, TestFlush) { … }
TEST_F(SQLitePersistentCookieStoreTest, TestLoadOldSessionCookies) { … }
TEST_F(SQLitePersistentCookieStoreTest, TestDontLoadOldSessionCookies) { … }
TEST_F(SQLitePersistentCookieStoreTest, FilterBadCookiesAndFixupDb) { … }
TEST_F(SQLitePersistentCookieStoreTest, PersistIsPersistent) { … }
TEST_F(SQLitePersistentCookieStoreTest, PriorityIsPersistent) { … }
TEST_F(SQLitePersistentCookieStoreTest, SameSiteIsPersistent) { … }
TEST_F(SQLitePersistentCookieStoreTest, SameSiteExtendedTreatedAsUnspecified) { … }
TEST_F(SQLitePersistentCookieStoreTest, SourcePortIsPersistent) { … }
TEST_F(SQLitePersistentCookieStoreTest, UpdateToEncryption) { … }
bool CompareCookies(const std::unique_ptr<CanonicalCookie>& a,
const std::unique_ptr<CanonicalCookie>& b) { … }
TEST_F(SQLitePersistentCookieStoreTest, IdenticalCreationTimes) { … }
TEST_F(SQLitePersistentCookieStoreTest, KeyInconsistency) { … }
TEST_F(SQLitePersistentCookieStoreTest, OpsIfInitFailed) { … }
TEST_F(SQLitePersistentCookieStoreTest, Coalescing) { … }
TEST_F(SQLitePersistentCookieStoreTest, NoCoalesceUnrelated) { … }
#if BUILDFLAG(IS_WIN)
class SQLitePersistentCookieStoreExclusiveAccessTest
: public SQLitePersistentCookieStoreTest,
public ::testing::WithParamInterface<bool> {
protected:
const bool& ShouldBeExclusive() { return GetParam(); }
};
TEST_P(SQLitePersistentCookieStoreExclusiveAccessTest, LockedStore) {
Create(false, false,
true,
ShouldBeExclusive());
base::RunLoop run_loop;
store_->Load(base::BindLambdaForTesting(
[&](CanonicalCookieVector cookies) { run_loop.Quit(); }),
NetLogWithSource());
run_loop.Run();
std::unique_ptr<CanonicalCookie> cookie = CanonicalCookie::CreateForTesting(
GURL("http://www.example.com/path"), "Tasty=Yes", base::Time::Now());
background_task_runner_->PostTask(
FROM_HERE, base::BindOnce(&SQLitePersistentCookieStoreTest::WaitOnDBEvent,
base::Unretained(this)));
store_->AddCookie(*cookie);
{
base::File file(
temp_dir_.GetPath().Append(kCookieFilename),
base::File::Flags::FLAG_OPEN_ALWAYS | base::File::Flags::FLAG_READ);
EXPECT_EQ(ShouldBeExclusive(), !file.IsValid());
}
db_thread_event_.Signal();
}
TEST_P(SQLitePersistentCookieStoreExclusiveAccessTest, LockedStoreAlreadyOpen) {
base::HistogramTester histograms;
base::File file(
temp_dir_.GetPath().Append(kCookieFilename),
base::File::Flags::FLAG_CREATE | base::File::Flags::FLAG_READ);
ASSERT_TRUE(file.IsValid());
Create(false, false,
true,
ShouldBeExclusive());
base::RunLoop run_loop;
store_->Load(base::BindLambdaForTesting(
[&](CanonicalCookieVector cookies) { run_loop.Quit(); }),
NetLogWithSource());
run_loop.Run();
if (ShouldBeExclusive()) {
expect_init_errors_ = true;
histograms.ExpectUniqueSample("Cookie.ErrorInitializeDB",
sql::SqliteLoggedResultCode::kCantOpen, 1);
histograms.ExpectUniqueSample("Cookie.WinGetLastErrorInitializeDB",
ERROR_SHARING_VIOLATION, 1);
}
}
INSTANTIATE_TEST_SUITE_P(All,
SQLitePersistentCookieStoreExclusiveAccessTest,
::testing::Bool(),
[](const auto& info) {
return info.param ? "Exclusive" : "NotExclusive";
});
#endif
TEST_F(SQLitePersistentCookieStoreTest, CorruptStore) { … }
bool CreateV18Schema(sql::Database* db) { … }
bool CreateV20Schema(sql::Database* db) { … }
bool CreateV21Schema(sql::Database* db) { … }
bool CreateV22Schema(sql::Database* db) { … }
bool CreateV23Schema(sql::Database* db) { … }
int GetDBCurrentVersionNumber(sql::Database* db) { … }
std::vector<CanonicalCookie> CookiesForMigrationTest() { … }
bool AddV18CookiesToDB(sql::Database* db,
base::TimeDelta max_expiration_delta) { … }
bool AddV20CookiesToDB(sql::Database* db) { … }
bool AddV21CookiesToDB(sql::Database* db) { … }
bool AddV22CookiesToDB(sql::Database* db,
const std::vector<CanonicalCookie>& cookies) { … }
bool AddV23EncryptedCookiesToDB(sql::Database* db,
const std::vector<CanonicalCookie>& cookies,
CookieCryptoDelegate* crypto) { … }
void ConfirmCookiesAfterMigrationTest(
std::vector<std::unique_ptr<CanonicalCookie>> read_in_cookies,
bool expect_last_update_date = false) { … }
void ConfirmDatabaseVersionAfterMigration(const base::FilePath path,
int version) { … }
TEST_F(SQLitePersistentCookieStoreTest, UpgradeToSchemaVersion19) { … }
TEST_F(SQLitePersistentCookieStoreTest, UpgradeToSchemaVersion20) { … }
TEST_F(SQLitePersistentCookieStoreTest, UpgradeToSchemaVersion21) { … }
TEST_F(SQLitePersistentCookieStoreTest, UpgradeToSchemaVersion22) { … }
TEST_F(SQLitePersistentCookieStoreTest, UpgradeToSchemaVersion23) { … }
TEST_F(SQLitePersistentCookieStoreTest, UpgradeToSchemaVersion24) { … }
TEST_F(SQLitePersistentCookieStoreTest, CannotModifyHostName) { … }
TEST_F(SQLitePersistentCookieStoreTest, ShortHash) { … }
TEST_F(SQLitePersistentCookieStoreTest,
UpgradeToSchemaVersion23_ConfirmSourceSchemeRecalculation) { … }
class SQLitePersistentCookieStoreTest_OriginBoundCookies
: public SQLitePersistentCookieStoreTest { … };
TEST_F(SQLitePersistentCookieStoreTest_OriginBoundCookies,
UniquenessConstraint) { … }
TEST_F(SQLitePersistentCookieStoreTest_OriginBoundCookies, DeleteCookie) { … }
TEST_F(SQLitePersistentCookieStoreTest_OriginBoundCookies,
UpdateCookieAccessTime) { … }
TEST_F(SQLitePersistentCookieStoreTest, SavingPartitionedCookies) { … }
TEST_F(SQLitePersistentCookieStoreTest, LoadingPartitionedCookies) { … }
std::unique_ptr<CanonicalCookie> CreatePartitionedCookie(
const std::string& name,
const std::string& domain,
const std::string& top_frame_site_key,
CookiePartitionKey::AncestorChainBit ancestor_chain_bit,
CookieSourceScheme scheme = CookieSourceScheme::kUnset,
bool partitioned_cookies_enabled = true) { … }
std::vector<std::pair<CanonicalCookie, std::string>>
GenerateHasCrossSiteAncestorCookiesAndVals(bool migrating = false) { … }
TEST_F(SQLitePersistentCookieStoreTest,
UpgradeToSchemaVersion23_AddingHasCrossSiteAncestor) { … }
TEST_F(SQLitePersistentCookieStoreTest,
TestValueOfHasCrossSiteAncestorOnDoCommit) { … }
}