#ifdef UNSAFE_BUFFERS_BUILD
#pragma allow_unsafe_buffers
#endif
#include "net/cookies/cookie_monster.h"
#include <functional>
#include <list>
#include <numeric>
#include <optional>
#include <set>
#include <string_view>
#include <utility>
#include "base/check_is_test.h"
#include "base/containers/flat_map.h"
#include "base/feature_list.h"
#include "base/functional/bind.h"
#include "base/functional/callback.h"
#include "base/location.h"
#include "base/logging.h"
#include "base/metrics/field_trial.h"
#include "base/metrics/histogram_functions.h"
#include "base/metrics/histogram_macros.h"
#include "base/ranges/algorithm.h"
#include "base/strings/strcat.h"
#include "base/strings/string_util.h"
#include "base/strings/stringprintf.h"
#include "base/task/single_thread_task_runner.h"
#include "base/threading/thread_checker.h"
#include "base/time/time.h"
#include "net/base/isolation_info.h"
#include "net/base/registry_controlled_domains/registry_controlled_domain.h"
#include "net/base/schemeful_site.h"
#include "net/base/url_util.h"
#include "net/cookies/canonical_cookie.h"
#include "net/cookies/cookie_constants.h"
#include "net/cookies/cookie_monster_change_dispatcher.h"
#include "net/cookies/cookie_monster_netlog_params.h"
#include "net/cookies/cookie_partition_key.h"
#include "net/cookies/cookie_partition_key_collection.h"
#include "net/cookies/cookie_util.h"
#include "net/cookies/parsed_cookie.h"
#include "net/http/http_util.h"
#include "net/log/net_log.h"
#include "net/log/net_log_values.h"
#include "url/origin.h"
#include "url/third_party/mozilla/url_parse.h"
#include "url/url_canon.h"
#include "url/url_constants.h"
Time;
TimeTicks;
TimeRange;
static const int kDaysInTenYears = …;
static const int kMinutesInTenYears = …;
namespace {
enum CookieType { … };
void MaybeRunDeleteCallback(base::WeakPtr<net::CookieMonster> cookie_monster,
base::OnceClosure callback) { … }
template <typename CB, typename... R>
void MaybeRunCookieCallback(base::OnceCallback<CB> callback, R&&... result) { … }
bool IncludeUnpartitionedCookies(
const net::CookiePartitionKeyCollection& list) { … }
size_t NameValueSizeBytes(const net::CanonicalCookie& cc) { … }
size_t NumBytesInCookieMapForKey(
const net::CookieMonster::CookieMap& cookie_map,
const std::string& key) { … }
size_t NumBytesInCookieItVector(
const net::CookieMonster::CookieItVector& cookie_its) { … }
void LogStoredCookieToUMA(const net::CanonicalCookie& cc,
const net::CookieAccessResult& access_result) { … }
}
namespace net {
const size_t CookieMonster::kDomainMaxCookies = …;
const size_t CookieMonster::kDomainPurgeCookies = …;
const size_t CookieMonster::kMaxCookies = …;
const size_t CookieMonster::kPurgeCookies = …;
const size_t CookieMonster::kMaxDomainPurgedKeys = …;
const size_t CookieMonster::kPerPartitionDomainMaxCookieBytes = …;
const size_t CookieMonster::kPerPartitionDomainMaxCookies = …;
const size_t CookieMonster::kDomainCookiesQuotaLow = …;
const size_t CookieMonster::kDomainCookiesQuotaMedium = …;
const size_t CookieMonster::kDomainCookiesQuotaHigh = …;
const int CookieMonster::kSafeFromGlobalPurgeDays = …;
namespace {
bool ContainsControlCharacter(const std::string& s) { … }
CanonicalCookieVector;
const int kDefaultAccessUpdateThresholdSeconds = …;
struct OrderByCreationTimeDesc { … };
bool LRACookieSorter(const CookieMonster::CookieMap::iterator& it1,
const CookieMonster::CookieMap::iterator& it2) { … }
void SortLeastRecentlyAccessed(CookieMonster::CookieItVector::iterator it_begin,
CookieMonster::CookieItVector::iterator it_end,
size_t num_sort) { … }
void SplitCookieVectorIntoSecureAndNonSecure(
const CookieMonster::CookieItVector& cookie_its,
CookieMonster::CookieItVector* secure_cookie_its,
CookieMonster::CookieItVector* non_secure_cookie_its) { … }
bool LowerBoundAccessDateComparator(const CookieMonster::CookieMap::iterator it,
const Time& access_date) { … }
CookieMonster::CookieItVector::iterator LowerBoundAccessDate(
const CookieMonster::CookieItVector::iterator its_begin,
const CookieMonster::CookieItVector::iterator its_end,
const Time& access_date) { … }
ChangeCausePair;
const ChangeCausePair kChangeCauseMapping[] = …;
bool IsCookieEligibleForEviction(CookiePriority current_priority_level,
bool protect_secure_cookies,
const CanonicalCookie* cookie) { … }
size_t CountCookiesForPossibleDeletion(
CookiePriority priority,
const CookieMonster::CookieItVector* cookies,
bool protect_secure_cookies) { … }
struct DeletionCookieLists { … };
size_t CountCookiesAndGenerateListsForPossibleDeletion(
CookiePriority priority,
DeletionCookieLists& could_be_deleted,
const CookieMonster::CookieItList* cookies,
bool generate_for_secure) { … }
void HistogramExpirationDuration(const CanonicalCookie& cookie,
base::Time creation_time) { … }
}
CookieMonster::CookieMonster(scoped_refptr<PersistentCookieStore> store,
NetLog* net_log)
: … { … }
CookieMonster::CookieMonster(scoped_refptr<PersistentCookieStore> store,
base::TimeDelta last_access_threshold,
NetLog* net_log)
: … { … }
void CookieMonster::FlushStore(base::OnceClosure callback) { … }
void CookieMonster::SetForceKeepSessionState() { … }
void CookieMonster::SetAllCookiesAsync(const CookieList& list,
SetCookiesCallback callback) { … }
void CookieMonster::SetCanonicalCookieAsync(
std::unique_ptr<CanonicalCookie> cookie,
const GURL& source_url,
const CookieOptions& options,
SetCookiesCallback callback,
std::optional<CookieAccessResult> cookie_access_result) { … }
void CookieMonster::GetCookieListWithOptionsAsync(
const GURL& url,
const CookieOptions& options,
const CookiePartitionKeyCollection& cookie_partition_key_collection,
GetCookieListCallback callback) { … }
void CookieMonster::GetAllCookiesAsync(GetAllCookiesCallback callback) { … }
void CookieMonster::GetAllCookiesWithAccessSemanticsAsync(
GetAllCookiesWithAccessSemanticsCallback callback) { … }
void CookieMonster::DeleteCanonicalCookieAsync(const CanonicalCookie& cookie,
DeleteCallback callback) { … }
void CookieMonster::DeleteAllCreatedInTimeRangeAsync(
const TimeRange& creation_range,
DeleteCallback callback) { … }
void CookieMonster::DeleteAllMatchingInfoAsync(CookieDeletionInfo delete_info,
DeleteCallback callback) { … }
void CookieMonster::DeleteSessionCookiesAsync(
CookieStore::DeleteCallback callback) { … }
void CookieMonster::DeleteMatchingCookiesAsync(
CookieStore::DeletePredicate predicate,
CookieStore::DeleteCallback callback) { … }
void CookieMonster::SetCookieableSchemes(
const std::vector<std::string>& schemes,
SetCookieableSchemesCallback callback) { … }
void CookieMonster::SetPersistSessionCookies(bool persist_session_cookies) { … }
const char* const CookieMonster::kDefaultCookieableSchemes[] = …;
const int CookieMonster::kDefaultCookieableSchemesCount = …;
CookieChangeDispatcher& CookieMonster::GetChangeDispatcher() { … }
CookieMonster::~CookieMonster() { … }
bool CookieMonster::CookieSorter(const CanonicalCookie* cc1,
const CanonicalCookie* cc2) { … }
void CookieMonster::GetAllCookies(GetAllCookiesCallback callback) { … }
void CookieMonster::AttachAccessSemanticsListForCookieList(
GetAllCookiesWithAccessSemanticsCallback callback,
const CookieList& cookie_list) { … }
void CookieMonster::GetCookieListWithOptions(
const GURL& url,
const CookieOptions& options,
const CookiePartitionKeyCollection& cookie_partition_key_collection,
GetCookieListCallback callback) { … }
void CookieMonster::DeleteAllCreatedInTimeRange(const TimeRange& creation_range,
DeleteCallback callback) { … }
bool CookieMonster::MatchCookieDeletionInfo(
const CookieDeletionInfo& delete_info,
const net::CanonicalCookie& cookie) { … }
void CookieMonster::DeleteCanonicalCookie(const CanonicalCookie& cookie,
DeleteCallback callback) { … }
void CookieMonster::DeleteMatchingCookies(DeletePredicate predicate,
DeletionCause cause,
DeleteCallback callback) { … }
void CookieMonster::MarkCookieStoreAsInitialized() { … }
void CookieMonster::FetchAllCookiesIfNecessary() { … }
void CookieMonster::FetchAllCookies() { … }
void CookieMonster::OnLoaded(
TimeTicks beginning_time,
std::vector<std::unique_ptr<CanonicalCookie>> cookies) { … }
void CookieMonster::OnKeyLoaded(
const std::string& key,
std::vector<std::unique_ptr<CanonicalCookie>> cookies) { … }
void CookieMonster::StoreLoadedCookies(
std::vector<std::unique_ptr<CanonicalCookie>> cookies) { … }
void CookieMonster::InvokeQueue() { … }
void CookieMonster::EnsureCookiesMapIsValid() { … }
void CookieMonster::TrimDuplicateCookiesForKey(
const std::string& key,
CookieMap::iterator begin,
CookieMap::iterator end,
std::optional<PartitionedCookieMap::iterator> cookie_partition_it) { … }
std::vector<CanonicalCookie*>
CookieMonster::FindCookiesForRegistryControlledHost(
const GURL& url,
CookieMap* cookie_map,
CookieMonster::PartitionedCookieMap::iterator* partition_it) { … }
std::vector<CanonicalCookie*>
CookieMonster::FindPartitionedCookiesForRegistryControlledHost(
const CookiePartitionKey& cookie_partition_key,
const GURL& url) { … }
void CookieMonster::FilterCookiesWithOptions(
const GURL url,
const CookieOptions options,
std::vector<CanonicalCookie*>* cookie_ptrs,
CookieAccessResultList* included_cookies,
CookieAccessResultList* excluded_cookies) { … }
void CookieMonster::MaybeDeleteEquivalentCookieAndUpdateStatus(
const std::string& key,
const CanonicalCookie& cookie_being_set,
bool allowed_to_set_secure_cookie,
bool skip_httponly,
bool already_expired,
base::Time* creation_date_to_inherit,
CookieInclusionStatus* status,
std::optional<PartitionedCookieMap::iterator> cookie_partition_it) { … }
CookieMonster::CookieMap::iterator CookieMonster::InternalInsertCookie(
const std::string& key,
std::unique_ptr<CanonicalCookie> cc,
bool sync_to_store,
const CookieAccessResult& access_result,
bool dispatch_change) { … }
bool CookieMonster::ShouldUpdatePersistentStore(CanonicalCookie* cc) { … }
CookieMonster::PartitionedCookieMapIterators
CookieMonster::InternalInsertPartitionedCookie(
std::string key,
std::unique_ptr<CanonicalCookie> cc,
bool sync_to_store,
const CookieAccessResult& access_result,
bool dispatch_change) { … }
void CookieMonster::SetCanonicalCookie(
std::unique_ptr<CanonicalCookie> cc,
const GURL& source_url,
const CookieOptions& options,
SetCookiesCallback callback,
std::optional<CookieAccessResult> cookie_access_result) { … }
void CookieMonster::SetAllCookies(CookieList list,
SetCookiesCallback callback) { … }
void CookieMonster::InternalUpdateCookieAccessTime(CanonicalCookie* cc,
const Time& current) { … }
void CookieMonster::InternalDeleteCookie(CookieMap::iterator it,
bool sync_to_store,
DeletionCause deletion_cause) { … }
void CookieMonster::InternalDeletePartitionedCookie(
PartitionedCookieMap::iterator partition_it,
CookieMap::iterator cookie_it,
bool sync_to_store,
DeletionCause deletion_cause) { … }
size_t CookieMonster::GarbageCollect(const Time& current,
const std::string& key) { … }
size_t CookieMonster::GarbageCollectPartitionedCookies(
const base::Time& current,
const CookiePartitionKey& cookie_partition_key,
const std::string& key) { … }
size_t CookieMonster::PurgeLeastRecentMatches(CookieItVector* cookies,
CookiePriority priority,
size_t to_protect,
size_t purge_goal,
bool protect_secure_cookies) { … }
size_t CookieMonster::PurgeLeastRecentMatchesForOBC(
CookieItList* cookies,
CookiePriority priority,
size_t to_protect,
size_t purge_goal,
bool delete_secure_cookies) { … }
size_t CookieMonster::GarbageCollectExpired(const Time& current,
const CookieMapItPair& itpair,
CookieItVector* cookie_its) { … }
size_t CookieMonster::GarbageCollectExpiredPartitionedCookies(
const Time& current,
const PartitionedCookieMap::iterator& cookie_partition_it,
const CookieMapItPair& itpair,
CookieItVector* cookie_its) { … }
void CookieMonster::GarbageCollectAllExpiredPartitionedCookies(
const Time& current) { … }
size_t CookieMonster::GarbageCollectDeleteRange(
const Time& current,
DeletionCause cause,
CookieItVector::iterator it_begin,
CookieItVector::iterator it_end) { … }
size_t CookieMonster::GarbageCollectLeastRecentlyAccessed(
const base::Time& current,
const base::Time& safe_date,
size_t purge_goal,
CookieItVector cookie_its,
base::Time* earliest_time) { … }
std::string CookieMonster::GetKey(std::string_view domain) { … }
bool CookieMonster::HasCookieableScheme(const GURL& url) { … }
CookieAccessSemantics CookieMonster::GetAccessSemanticsForCookie(
const CanonicalCookie& cookie) const { … }
void CookieMonster::RecordPeriodicStats(const base::Time& current_time) { … }
bool CookieMonster::DoRecordPeriodicStats() { … }
void CookieMonster::RecordPeriodicFirstPartySetsStats(
base::flat_map<SchemefulSite, FirstPartySetEntry> sets) const { … }
void CookieMonster::DoCookieCallback(base::OnceClosure callback) { … }
void CookieMonster::DoCookieCallbackForURL(base::OnceClosure callback,
const GURL& url) { … }
void CookieMonster::DoCookieCallbackForHostOrDomain(
base::OnceClosure callback,
std::string_view host_or_domain) { … }
CookieMonster::CookieSentToSamePort
CookieMonster::IsCookieSentToSamePortThatSetIt(
const GURL& destination,
int source_port,
CookieSourceScheme source_scheme) { … }
std::optional<bool> CookieMonster::SiteHasCookieInOtherPartition(
const net::SchemefulSite& site,
const std::optional<CookiePartitionKey>& partition_key) const { … }
}