0

Extract UniqueCookieKey type

This introduces a new class, UniqueCookieKey, to replace 4 distinct
tuple aliases: StrictlyUniqueCookieKey, UniqueCookieKey,
UniqueDomainCookieKey, and LegacyUniqueCookieKey. Turning these into
dedicated types (rather than just aliases of tuples) has a few notable
consequences:

* Member accesses are more readable and maintainable, e.g. `signature.domain()` instead of `std::get<2>(signature)`.
* CookieMonster's duplicate filtering logic no longer needs to be aware of host cookies vs domain cookies; it can just call UniqueKey() which will do the right thing instead of requiring the caller to know how to branch correctly.
* We can now merge CookieBase::UniqueKey() and CookieBase::UniqueDomainKey() into a single function that is aware of what kind of key it should create.
* We can now guarantee that these keys can only be created via the accessors in CookieBase.
* The type system can no longer guarantee the usage of a Legacy key instead of a Strict key, or vice versa, since they're the same type. (This doesn't seem like a likely source of bugs to me, so I think this is fine. But we can also make Strict and Legacy keys their own types.)

Fixed: 390345080
Change-Id: Iaebf4d34e854adbbfc4483ad4d2fc58794659199
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/6175944
Reviewed-by: Steven Bingler <bingler@chromium.org>
Auto-Submit: Chris Fredrickson <cfredric@chromium.org>
Reviewed-by: David Song <wintermelons@google.com>
Reviewed-by: Maks Orlovich <morlovich@chromium.org>
Commit-Queue: Chris Fredrickson <cfredric@chromium.org>
Reviewed-by: Jood Hajeer <jood@google.com>
Cr-Commit-Position: refs/heads/main@{#1407461}
This commit is contained in:
Chris Fredrickson
2025-01-16 11:12:45 -08:00
committed by Chromium LUCI CQ
parent 651c992f3a
commit c9dad5877d
11 changed files with 278 additions and 172 deletions

@ -19,6 +19,7 @@
#include "net/cookies/canonical_cookie.h"
#include "net/cookies/cookie_constants.h"
#include "net/cookies/cookie_partition_key.h"
#include "net/cookies/unique_cookie_key.h"
namespace ash::floating_sso {
@ -186,8 +187,16 @@ std::optional<std::string> SerializedKey(const net::CanonicalCookie& cookie) {
return std::nullopt;
}
const auto& [partition_key, name, domain, path, source_scheme, source_port] =
cookie.StrictlyUniqueKey();
const net::UniqueCookieKey strict_unique_key = cookie.StrictlyUniqueKey();
const std::string& name = strict_unique_key.name();
const std::string& domain = strict_unique_key.domain();
const std::string& path = strict_unique_key.path();
// `source_scheme()` and `port()` are guaranteed to return non-nullopt values,
// since we created the key via StrictlyUniqueKey.
const net::CookieSourceScheme source_scheme =
strict_unique_key.source_scheme().value();
const int source_port = strict_unique_key.port().value();
// We just concatenate all involved strings.
std::string serialized_key = base::StrCat(
{serialized_partition_key->TopLevelSite(),

@ -11,6 +11,7 @@
#include "mojo/public/cpp/bindings/receiver.h"
#include "net/cookies/canonical_cookie.h"
#include "net/cookies/cookie_change_dispatcher.h"
#include "net/cookies/unique_cookie_key.h"
#include "services/network/public/mojom/network_context.mojom.h"
#include "url/gurl.h"
@ -150,8 +151,7 @@ class CookiesIteratorImpl final : public fuchsia::web::CookiesIterator,
// Map from "unique key"s (see net::CanonicalCookie::UniqueKey()) to the
// corresponding fuchsia::web::Cookie.
std::map<net::CanonicalCookie::UniqueCookieKey, fuchsia::web::Cookie>
queued_cookies_;
std::map<net::UniqueCookieKey, fuchsia::web::Cookie> queued_cookies_;
};
void OnAllCookiesReceived(

@ -432,6 +432,8 @@ component("net") {
"cookies/site_for_cookies.h",
"cookies/static_cookie_policy.cc",
"cookies/static_cookie_policy.h",
"cookies/unique_cookie_key.cc",
"cookies/unique_cookie_key.h",
"device_bound_sessions/session_key.cc",
"device_bound_sessions/session_key.h",
"disk_cache/backend_cleanup_tracker.cc",

@ -240,17 +240,8 @@ class NET_EXPORT CanonicalCookie : public CookieBase {
bool IsEquivalent(const CanonicalCookie& ecc) const {
// It seems like it would make sense to take secure, httponly, and samesite
// into account, but the RFC doesn't specify this.
// NOTE: Keep this logic in-sync with TrimDuplicateCookiesForKey().
// A host cookie will never match a domain cookie or vice-versa, this is
// because the "host-only-flag" is encoded within the `domain` field of the
// respective keys. So we don't need to explicitly check if ecc is also host
// or domain.
if (IsHostCookie()) {
return UniqueKey() == ecc.UniqueKey();
}
// Is domain cookie
return UniqueDomainKey() == ecc.UniqueDomainKey();
return UniqueKey() == ecc.UniqueKey();
}
// Checks a looser set of equivalency rules than 'IsEquivalent()' in order

@ -7,6 +7,7 @@
#include "base/containers/contains.h"
#include "base/feature_list.h"
#include "base/strings/strcat.h"
#include "base/types/pass_key.h"
#include "net/base/features.h"
#include "net/cookies/cookie_constants.h"
#include "net/cookies/cookie_inclusion_status.h"
@ -553,30 +554,29 @@ std::string CookieBase::DomainWithoutDot() const {
return cookie_util::CookieDomainAsHost(domain_);
}
CookieBase::UniqueCookieKey CookieBase::UniqueKey() const {
std::optional<CookieSourceScheme> source_scheme =
cookie_util::IsSchemeBoundCookiesEnabled()
? std::make_optional(source_scheme_)
: std::nullopt;
std::optional<int> source_port = cookie_util::IsPortBoundCookiesEnabled()
? std::make_optional(source_port_)
: std::nullopt;
return std::make_tuple(partition_key_, name_, domain_, path_, source_scheme,
source_port);
}
CookieBase::UniqueDomainCookieKey CookieBase::UniqueDomainKey() const {
UniqueCookieKey CookieBase::UniqueKey() const {
std::optional<CookieSourceScheme> source_scheme =
cookie_util::IsSchemeBoundCookiesEnabled()
? std::make_optional(source_scheme_)
: std::nullopt;
return std::make_tuple(partition_key_, name_, domain_, path_, source_scheme);
if (IsHostCookie()) {
std::optional<int> source_port = cookie_util::IsPortBoundCookiesEnabled()
? std::make_optional(source_port_)
: std::nullopt;
return UniqueCookieKey::Host(base::PassKey<CookieBase>(), partition_key_,
name_, domain_, path_, source_scheme,
source_port);
}
return UniqueCookieKey::Domain(base::PassKey<CookieBase>(), partition_key_,
name_, domain_, path_, source_scheme);
}
CookieBase::LegacyUniqueCookieKey CookieBase::LegacyUniqueKey() const {
return std::make_tuple(partition_key_, name_, domain_, path_);
UniqueCookieKey CookieBase::LegacyUniqueKey() const {
return UniqueCookieKey::Legacy(base::PassKey<CookieBase>(), partition_key_,
name_, domain_, path_);
}
void CookieBase::SetSourcePort(int port) {

@ -9,12 +9,14 @@
#include <string>
#include <tuple>
#include "base/types/pass_key.h"
#include "net/base/net_export.h"
#include "net/cookies/cookie_access_params.h"
#include "net/cookies/cookie_access_result.h"
#include "net/cookies/cookie_constants.h"
#include "net/cookies/cookie_options.h"
#include "net/cookies/cookie_partition_key.h"
#include "net/cookies/unique_cookie_key.h"
class GURL;
@ -25,39 +27,6 @@ namespace net {
// the request context.
class NET_EXPORT CookieBase {
public:
// StrictlyUniqueCookieKey always populates the cookie's source scheme and
// source port.
using StrictlyUniqueCookieKey = std::tuple<std::optional<CookiePartitionKey>,
/*name=*/std::string,
/*domain=*/std::string,
/*path=*/std::string,
CookieSourceScheme,
/*source_port=*/int>;
// Conditionally populates the source scheme and source port depending on the
// state of their associated feature.
using UniqueCookieKey = std::tuple<std::optional<CookiePartitionKey>,
/*name=*/std::string,
/*domain=*/std::string,
/*path=*/std::string,
std::optional<CookieSourceScheme>,
/*source_port=*/std::optional<int>>;
// Same as UniqueCookieKey but for use with Domain cookies, which do not
// consider the source_port.
using UniqueDomainCookieKey = std::tuple<std::optional<CookiePartitionKey>,
/*name=*/std::string,
/*domain=*/std::string,
/*path=*/std::string,
std::optional<CookieSourceScheme>>;
// Same as UniqueCookieKey but for use with Legacy Scoped cookies, which do
// not consider the source_port or source_scheme.
using LegacyUniqueCookieKey = std::tuple<std::optional<CookiePartitionKey>,
/*name=*/std::string,
/*domain=*/std::string,
/*path=*/std::string>;
// Returns if the cookie should be included (and if not, why) for the given
// request |url| using the CookieInclusionStatus enum. HTTP only cookies can
// be filter by using appropriate cookie |options|.
@ -160,9 +129,12 @@ class NET_EXPORT CookieBase {
// This corresponds to the "cookie's domain" as described in RFC 6265bis.
std::string DomainWithoutDot() const;
StrictlyUniqueCookieKey StrictlyUniqueKey() const {
return std::make_tuple(partition_key_, name_, domain_, path_,
source_scheme_, source_port_);
// StrictlyUniqueKey always includes the cookie's source scheme and source
// port.
UniqueCookieKey StrictlyUniqueKey() const {
return UniqueCookieKey::Strict(base::PassKey<CookieBase>(), partition_key_,
name_, domain_, path_, source_scheme_,
source_port_);
}
// Returns a key such that two cookies with the same UniqueKey() are
@ -173,14 +145,10 @@ class NET_EXPORT CookieBase {
// associated features are enabled.
UniqueCookieKey UniqueKey() const;
// Same as UniqueKey() except it does not contain a source_port field. For use
// with Domain cookies, which do not consider the source_port.
UniqueDomainCookieKey UniqueDomainKey() const;
// Same as UniqueKey() except it does not contain a source_port or
// source_scheme field. For use for determining aliasing cookies, which do not
// consider the source_port or source_scheme.
LegacyUniqueCookieKey LegacyUniqueKey() const;
UniqueCookieKey LegacyUniqueKey() const;
void SetSourceScheme(CookieSourceScheme source_scheme) {
source_scheme_ = source_scheme;

@ -80,6 +80,7 @@
#include "net/base/schemeful_site.h"
#include "net/base/url_util.h"
#include "net/cookies/canonical_cookie.h"
#include "net/cookies/cookie_base.h"
#include "net/cookies/cookie_constants.h"
#include "net/cookies/cookie_monster_change_dispatcher.h"
#include "net/cookies/cookie_monster_netlog_params.h"
@ -1170,15 +1171,10 @@ void CookieMonster::TrimDuplicateCookiesForKey(
typedef std::multiset<CookieMap::iterator, OrderByCreationTimeDesc> CookieSet;
// Helper map we populate to find the duplicates.
typedef std::map<CanonicalCookie::UniqueCookieKey, CookieSet> EquivalenceMap;
typedef std::map<CanonicalCookie::UniqueDomainCookieKey, CookieSet>
DomainEquivalenceMap;
EquivalenceMap equivalent_cookies;
DomainEquivalenceMap equivalent_domain_cookies;
std::map<UniqueCookieKey, CookieSet> equivalent_cookies;
// The number of duplicate cookies that have been found.
int num_duplicates = 0;
int num_domain_duplicates = 0;
// Iterate through all of the cookies in our range, and insert them into
// the equivalence map.
@ -1186,49 +1182,31 @@ void CookieMonster::TrimDuplicateCookiesForKey(
DCHECK_EQ(key, it->first);
CanonicalCookie* cookie = it->second.get();
if (cookie->IsHostCookie()) {
CanonicalCookie::UniqueCookieKey signature(cookie->UniqueKey());
CookieSet& set = equivalent_cookies[signature];
UniqueCookieKey signature(cookie->UniqueKey());
CookieSet& set = equivalent_cookies[signature];
// We found a duplicate!
if (!set.empty()) {
num_duplicates++;
}
// We save the iterator into |cookies_| rather than the actual cookie
// pointer, since we may need to delete it later.
set.insert(it);
// We found a duplicate!
if (!set.empty()) {
num_duplicates++;
}
// Is a domain cookie.
else {
CanonicalCookie::UniqueDomainCookieKey signature(
cookie->UniqueDomainKey());
CookieSet& domain_set = equivalent_domain_cookies[signature];
// We found a duplicate!
if (!domain_set.empty()) {
num_domain_duplicates++;
}
// We save the iterator into |cookies_| rather than the actual cookie
// pointer, since we may need to delete it later.
domain_set.insert(it);
}
// We save the iterator into |cookies_| rather than the actual cookie
// pointer, since we may need to delete it later.
set.insert(it);
}
// If there were no duplicates, we are done!
if (num_duplicates == 0 && num_domain_duplicates == 0) {
if (num_duplicates == 0) {
return;
}
// Make sure we find everything below that we did above.
int num_duplicates_found = 0;
// Otherwise, delete all the duplicate host cookies, both from our in-memory
// Otherwise, delete all the duplicate cookies, both from our in-memory
// store and from the backing store.
for (std::pair<const CanonicalCookie::UniqueCookieKey, CookieSet>&
equivalent_cookie : equivalent_cookies) {
const CanonicalCookie::UniqueCookieKey& signature = equivalent_cookie.first;
for (auto& equivalent_cookie : equivalent_cookies) {
const UniqueCookieKey& signature = equivalent_cookie.first;
CookieSet& dupes = equivalent_cookie.second;
if (dupes.size() <= 1) {
@ -1248,9 +1226,8 @@ void CookieMonster::TrimDuplicateCookiesForKey(
LOG(ERROR) << base::StringPrintf(
"Found %d duplicate cookies for key='%s', "
"with {name='%s', domain='%s', path='%s'}",
static_cast<int>(dupes.size()), key.c_str(),
std::get<1>(signature).c_str(), std::get<2>(signature).c_str(),
std::get<3>(signature).c_str());
static_cast<int>(dupes.size()), key.c_str(), signature.name().c_str(),
signature.domain().c_str(), signature.path().c_str());
// Remove all the cookies identified by |dupes|. It is valid to delete our
// list of iterators one at a time, since |cookies_| is a multimap (they
@ -1267,58 +1244,6 @@ void CookieMonster::TrimDuplicateCookiesForKey(
}
}
CHECK_EQ(num_duplicates, num_duplicates_found);
// Do the same again for domain cookies.
if (num_domain_duplicates == 0) {
return;
}
int num_domain_duplicates_found = 0;
for (std::pair<const CanonicalCookie::UniqueDomainCookieKey, CookieSet>&
equivalent_domain_cookie : equivalent_domain_cookies) {
const CanonicalCookie::UniqueDomainCookieKey& signature =
equivalent_domain_cookie.first;
CookieSet& dupes = equivalent_domain_cookie.second;
if (dupes.size() <= 1) {
continue;
}
num_domain_duplicates_found += dupes.size() - 1;
// Since |dupes| is sorted by creation time (descending), the first cookie
// is the most recent one (or tied for it), so we will keep it. The rest are
// duplicates.
dupes.erase(dupes.begin());
// TODO(crbug.com/40188414) Include cookie partition key in this log
// statement as well if needed.
// TODO(crbug.com/40165805): Include source scheme and source port.
LOG(ERROR) << base::StringPrintf(
"Found %d duplicate domain cookies for key='%s', "
"with {name='%s', domain='%s', path='%s'}",
static_cast<int>(dupes.size()), key.c_str(),
std::get<1>(signature).c_str(), std::get<2>(signature).c_str(),
std::get<3>(signature).c_str());
// Remove all the cookies identified by |dupes|. It is valid to delete our
// list of iterators one at a time, since |cookies_| is a multimap (they
// don't invalidate existing iterators following deletion).
for (const CookieMap::iterator& dupe : dupes) {
if (cookie_partition_it) {
InternalDeletePartitionedCookie(
cookie_partition_it.value(), dupe, true,
DELETE_COOKIE_DUPLICATE_IN_BACKING_STORE);
} else {
InternalDeleteCookie(dupe, true,
DELETE_COOKIE_DUPLICATE_IN_BACKING_STORE);
}
}
}
CHECK_EQ(num_domain_duplicates, num_domain_duplicates_found);
}
std::vector<CanonicalCookie*>
@ -1336,8 +1261,7 @@ CookieMonster::FindCookiesForRegistryControlledHost(
// This map stores the most recently created cookie's creation time and if it
// is expired or not. This is used to keep track if the entire group of
// aliasing cookies should be deleted.
std::map<CanonicalCookie::LegacyUniqueCookieKey, std::pair<Time, bool>>
most_recent_cookie;
std::map<UniqueCookieKey, std::pair<Time, bool>> most_recent_cookie;
bool legacy_mode_active = false;
@ -1477,9 +1401,8 @@ void CookieMonster::FilterCookiesWithOptions(
}
}
// Map to store the most recent aliasing cookie and it's CookieAccessResult
std::map<CanonicalCookie::LegacyUniqueCookieKey, CookieAndAccessResult*>
latest_aliasing_cookies;
// Map to store the most recent aliasing cookie and its CookieAccessResult
std::map<UniqueCookieKey, CookieAndAccessResult*> latest_aliasing_cookies;
for (auto& cookie_result : cookies_and_access_results) {
CanonicalCookie* cookie_ptr = cookie_result.first;

@ -170,8 +170,7 @@ class MockSimplePersistentCookieStore
~MockSimplePersistentCookieStore() override;
private:
typedef std::map<CanonicalCookie::UniqueCookieKey, CanonicalCookie>
CanonicalCookieMap;
typedef std::map<UniqueCookieKey, CanonicalCookie> CanonicalCookieMap;
CanonicalCookieMap cookies_;

@ -0,0 +1,106 @@
// Copyright 2025 The Chromium Authors
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#include "net/cookies/unique_cookie_key.h"
#include <optional>
#include <string>
#include <utility>
#include "net/cookies/cookie_constants.h"
#include "net/cookies/cookie_partition_key.h"
namespace net {
class CookieBase;
// static
UniqueCookieKey UniqueCookieKey::Strict(
base::PassKey<CookieBase>,
std::optional<CookiePartitionKey> partition_key,
std::string name,
std::string domain,
std::string path,
CookieSourceScheme source_scheme,
int source_port) {
return UniqueCookieKey(KeyType::kStrict, std::move(partition_key),
std::move(name), std::move(domain), std::move(path),
source_scheme, source_port);
}
// static
UniqueCookieKey UniqueCookieKey::Host(
base::PassKey<CookieBase>,
std::optional<CookiePartitionKey> partition_key,
std::string name,
std::string domain,
std::string path,
std::optional<CookieSourceScheme> source_scheme,
std::optional<int> source_port) {
return UniqueCookieKey(KeyType::kHost, std::move(partition_key),
std::move(name), std::move(domain), std::move(path),
source_scheme, source_port);
}
// static
UniqueCookieKey UniqueCookieKey::Domain(
base::PassKey<CookieBase>,
std::optional<CookiePartitionKey> partition_key,
std::string name,
std::string domain,
std::string path,
std::optional<CookieSourceScheme> source_scheme) {
return UniqueCookieKey(KeyType::kDomain, std::move(partition_key),
std::move(name), std::move(domain), std::move(path),
source_scheme, /*port=*/std::nullopt);
}
// static
UniqueCookieKey UniqueCookieKey::Legacy(
base::PassKey<CookieBase>,
std::optional<CookiePartitionKey> partition_key,
std::string name,
std::string domain,
std::string path) {
return UniqueCookieKey(KeyType::kLegacy, std::move(partition_key),
std::move(name), std::move(domain), std::move(path),
/*source_scheme=*/std::nullopt,
/*port=*/std::nullopt);
}
UniqueCookieKey::UniqueCookieKey(UniqueCookieKey&& other) = default;
UniqueCookieKey::UniqueCookieKey(const UniqueCookieKey& other) = default;
UniqueCookieKey& UniqueCookieKey::operator=(UniqueCookieKey&& other) = default;
UniqueCookieKey& UniqueCookieKey::operator=(const UniqueCookieKey& other) =
default;
UniqueCookieKey::~UniqueCookieKey() = default;
bool UniqueCookieKey::operator==(const UniqueCookieKey& other) const = default;
bool UniqueCookieKey::operator<(const UniqueCookieKey& other) const {
return std::tie(key_type_, partition_key_, name_, domain_, path_,
source_scheme_,
port_) < std::tie(other.key_type_, other.partition_key_,
other.name_, other.domain_, other.path_,
other.source_scheme_, other.port_);
}
UniqueCookieKey::UniqueCookieKey(
KeyType key_type,
std::optional<CookiePartitionKey> partition_key,
std::string name,
std::string domain,
std::string path,
std::optional<CookieSourceScheme> source_scheme,
std::optional<int> port)
: key_type_(key_type),
partition_key_(std::move(partition_key)),
name_(std::move(name)),
domain_(std::move(domain)),
path_(std::move(path)),
source_scheme_(source_scheme),
port_(port) {}
} // namespace net

@ -0,0 +1,108 @@
// Copyright 2025 The Chromium Authors
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#ifndef NET_COOKIES_UNIQUE_COOKIE_KEY_H_
#define NET_COOKIES_UNIQUE_COOKIE_KEY_H_
#include <optional>
#include <string>
#include "base/types/pass_key.h"
#include "net/base/net_export.h"
#include "net/cookies/cookie_constants.h"
#include "net/cookies/cookie_partition_key.h"
namespace net {
class CookieBase;
class NET_EXPORT UniqueCookieKey {
public:
// Always populates the cookie's source scheme and source port.
static UniqueCookieKey Strict(base::PassKey<CookieBase>,
std::optional<CookiePartitionKey> partition_key,
std::string name,
std::string domain,
std::string path,
CookieSourceScheme source_scheme,
int source_port);
// Conditionally populates the source scheme and source port depending on the
// state of their associated feature.
static UniqueCookieKey Host(base::PassKey<CookieBase>,
std::optional<CookiePartitionKey> partition_key,
std::string name,
std::string domain,
std::string path,
std::optional<CookieSourceScheme> source_scheme,
std::optional<int> source_port);
// Same as Host but for use with Domain cookies, which do not
// consider the source_port.
static UniqueCookieKey Domain(
base::PassKey<CookieBase>,
std::optional<CookiePartitionKey> partition_key,
std::string name,
std::string domain,
std::string path,
std::optional<CookieSourceScheme> source_scheme);
// Same as Host but for use with Legacy Scoped cookies, which do
// not consider the source_port or source_scheme.
static UniqueCookieKey Legacy(base::PassKey<CookieBase>,
std::optional<CookiePartitionKey> partition_key,
std::string name,
std::string domain,
std::string path);
UniqueCookieKey(UniqueCookieKey&& other);
UniqueCookieKey(const UniqueCookieKey& other);
UniqueCookieKey& operator=(UniqueCookieKey&& other);
UniqueCookieKey& operator=(const UniqueCookieKey& other);
~UniqueCookieKey();
bool operator==(const UniqueCookieKey& other) const;
bool operator<(const UniqueCookieKey& other) const;
const std::string& name() const { return name_; }
const std::string& domain() const { return domain_; }
const std::string& path() const { return path_; }
std::optional<CookieSourceScheme> source_scheme() const {
return source_scheme_;
}
std::optional<int> port() const { return port_; }
private:
enum class KeyType {
kStrict,
kHost,
kDomain,
kLegacy,
};
UniqueCookieKey(KeyType key_type,
std::optional<CookiePartitionKey> partition_key,
std::string name,
std::string domain,
std::string path,
std::optional<CookieSourceScheme> source_scheme,
std::optional<int> port);
// Keys of different "types" (i.e., created by different factory functions)
// are never considered equivalent.
KeyType key_type_;
std::optional<CookiePartitionKey> partition_key_;
std::string name_;
std::string domain_;
std::string path_;
// Nullopt in kLegacy keys; may be nullopt in kDomain and kHost keys.
std::optional<CookieSourceScheme> source_scheme_;
// Nullopt in kLegacy and kDomain keys; may be nullopt in kHost keys.
std::optional<int> port_;
};
} // namespace net
#endif // NET_COOKIES_UNIQUE_COOKIE_KEY_H_

@ -36,6 +36,7 @@
#include "net/cookies/canonical_cookie.h"
#include "net/cookies/cookie_constants.h"
#include "net/cookies/cookie_util.h"
#include "net/cookies/unique_cookie_key.h"
#include "net/extras/sqlite/cookie_crypto_delegate.h"
#include "net/extras/sqlite/sqlite_persistent_store_backend_base.h"
#include "net/log/net_log.h"
@ -488,8 +489,7 @@ class SQLitePersistentCookieStore::Backend
}
typedef std::list<std::unique_ptr<PendingOperation>> PendingOperationsForKey;
typedef std::map<CanonicalCookie::StrictlyUniqueCookieKey,
PendingOperationsForKey>
typedef std::map<UniqueCookieKey, PendingOperationsForKey>
PendingOperationsMap;
PendingOperationsMap pending_ GUARDED_BY(lock_);
PendingOperationsMap::size_type num_pending_ GUARDED_BY(lock_) = 0;