summaryrefslogtreecommitdiff
path: root/chromium/net/cookies
diff options
context:
space:
mode:
authorAllan Sandfeld Jensen <allan.jensen@qt.io>2021-03-12 09:13:00 +0100
committerAllan Sandfeld Jensen <allan.jensen@qt.io>2021-03-16 09:58:26 +0000
commit03561cae90f1d99b5c54b1ef3be69f10e882b25e (patch)
treecc5f0958e823c044e7ae51cc0117fe51432abe5e /chromium/net/cookies
parentfa98118a45f7e169f8846086dc2c22c49a8ba310 (diff)
downloadqtwebengine-chromium-03561cae90f1d99b5c54b1ef3be69f10e882b25e.tar.gz
BASELINE: Update Chromium to 88.0.4324.208
Change-Id: I3ae87d23e4eff4b4a469685658740a213600c667 Reviewed-by: Allan Sandfeld Jensen <allan.jensen@qt.io>
Diffstat (limited to 'chromium/net/cookies')
-rw-r--r--chromium/net/cookies/DIR_METADATA11
-rw-r--r--chromium/net/cookies/OWNERS2
-rw-r--r--chromium/net/cookies/canonical_cookie.cc100
-rw-r--r--chromium/net/cookies/canonical_cookie.h90
-rw-r--r--chromium/net/cookies/canonical_cookie_fuzzer.cc5
-rw-r--r--chromium/net/cookies/canonical_cookie_unittest.cc521
-rw-r--r--chromium/net/cookies/cookie_constants.cc195
-rw-r--r--chromium/net/cookies/cookie_constants.h127
-rw-r--r--chromium/net/cookies/cookie_constants_unittest.cc37
-rw-r--r--chromium/net/cookies/cookie_deletion_info_unittest.cc33
-rw-r--r--chromium/net/cookies/cookie_inclusion_status.cc2
-rw-r--r--chromium/net/cookies/cookie_inclusion_status.h39
-rw-r--r--chromium/net/cookies/cookie_monster.cc270
-rw-r--r--chromium/net/cookies/cookie_monster.h99
-rw-r--r--chromium/net/cookies/cookie_monster_netlog_params.cc1
-rw-r--r--chromium/net/cookies/cookie_monster_store_test.cc4
-rw-r--r--chromium/net/cookies/cookie_monster_unittest.cc570
-rw-r--r--chromium/net/cookies/cookie_options.cc8
-rw-r--r--chromium/net/cookies/cookie_options.h24
-rw-r--r--chromium/net/cookies/cookie_store_unittest.h55
-rw-r--r--chromium/net/cookies/cookie_util.cc60
-rw-r--r--chromium/net/cookies/cookie_util.h18
-rw-r--r--chromium/net/cookies/cookie_util_unittest.cc2
-rw-r--r--chromium/net/cookies/parse_cookie_line_fuzzer.cc5
-rw-r--r--chromium/net/cookies/parsed_cookie.cc26
-rw-r--r--chromium/net/cookies/parsed_cookie.h23
-rw-r--r--chromium/net/cookies/parsed_cookie_unittest.cc97
27 files changed, 1659 insertions, 765 deletions
diff --git a/chromium/net/cookies/DIR_METADATA b/chromium/net/cookies/DIR_METADATA
new file mode 100644
index 00000000000..1b6e5edfbf2
--- /dev/null
+++ b/chromium/net/cookies/DIR_METADATA
@@ -0,0 +1,11 @@
+# Metadata information for this directory.
+#
+# For more information on DIR_METADATA files, see:
+# https://source.chromium.org/chromium/infra/infra/+/master:go/src/infra/tools/dirmd/README.md
+#
+# For the schema of this file, see Metadata message:
+# https://source.chromium.org/chromium/infra/infra/+/master:go/src/infra/tools/dirmd/proto/dir_metadata.proto
+
+monorail {
+ component: "Internals>Network>Cookies"
+} \ No newline at end of file
diff --git a/chromium/net/cookies/OWNERS b/chromium/net/cookies/OWNERS
index 9b5ffc36540..2ddd82195da 100644
--- a/chromium/net/cookies/OWNERS
+++ b/chromium/net/cookies/OWNERS
@@ -3,5 +3,3 @@ estark@chromium.org
mkwst@chromium.org
mmenke@chromium.org
morlovich@chromium.org
-
-# COMPONENT: Internals>Network>Cookies
diff --git a/chromium/net/cookies/canonical_cookie.cc b/chromium/net/cookies/canonical_cookie.cc
index 1c85b9d7daf..1db40c01ebb 100644
--- a/chromium/net/cookies/canonical_cookie.cc
+++ b/chromium/net/cookies/canonical_cookie.cc
@@ -50,6 +50,7 @@
#include "base/feature_list.h"
#include "base/format_macros.h"
#include "base/logging.h"
+#include "base/metrics/histogram_functions.h"
#include "base/metrics/histogram_macros.h"
#include "base/strings/strcat.h"
#include "base/strings/string_util.h"
@@ -256,13 +257,7 @@ void ApplySameSiteCookieWarningToStatus(
} // namespace
-// Keep defaults here in sync with content/public/common/cookie_manager.mojom.
-CanonicalCookie::CanonicalCookie()
- : secure_(false),
- httponly_(false),
- same_site_(CookieSameSite::NO_RESTRICTION),
- priority_(COOKIE_PRIORITY_MEDIUM),
- source_scheme_(CookieSourceScheme::kUnset) {}
+CanonicalCookie::CanonicalCookie() = default;
CanonicalCookie::CanonicalCookie(const CanonicalCookie& other) = default;
@@ -277,7 +272,9 @@ CanonicalCookie::CanonicalCookie(const std::string& name,
bool httponly,
CookieSameSite same_site,
CookiePriority priority,
- CookieSourceScheme scheme_secure)
+ bool same_party,
+ CookieSourceScheme scheme_secure,
+ int source_port)
: name_(name),
value_(value),
domain_(domain),
@@ -289,7 +286,10 @@ CanonicalCookie::CanonicalCookie(const std::string& name,
httponly_(httponly),
same_site_(same_site),
priority_(priority),
- source_scheme_(scheme_secure) {}
+ same_party_(same_party),
+ source_scheme_(scheme_secure) {
+ SetSourcePort(source_port);
+}
CanonicalCookie::~CanonicalCookie() = default;
@@ -408,22 +408,35 @@ std::unique_ptr<CanonicalCookie> CanonicalCookie::Create(
status->AddExclusionReason(CookieInclusionStatus::EXCLUDE_INVALID_PREFIX);
}
+ bool is_same_party_valid = IsCookieSamePartyValid(parsed_cookie);
+ if (!is_same_party_valid) {
+ status->AddExclusionReason(
+ CookieInclusionStatus::EXCLUDE_INVALID_SAMEPARTY);
+ }
+
+ // Collect metrics on whether usage of SameParty attribute is correct.
+ if (parsed_cookie.IsSameParty())
+ base::UmaHistogramBoolean("Cookie.IsSamePartyValid", is_same_party_valid);
+
// TODO(chlily): Log metrics.
if (!status->IsInclude())
return nullptr;
CookieSameSiteString samesite_string = CookieSameSiteString::kUnspecified;
CookieSameSite samesite = parsed_cookie.SameSite(&samesite_string);
- RecordCookieSameSiteAttributeValueHistogram(samesite_string);
+ RecordCookieSameSiteAttributeValueHistogram(samesite_string,
+ parsed_cookie.IsSameParty());
CookieSourceScheme source_scheme = url.SchemeIsCryptographic()
? CookieSourceScheme::kSecure
: CookieSourceScheme::kNonSecure;
+ // Get the port, this will get a default value if a port isn't provided.
+ int source_port = url.EffectiveIntPort();
std::unique_ptr<CanonicalCookie> cc(std::make_unique<CanonicalCookie>(
parsed_cookie.Name(), parsed_cookie.Value(), cookie_domain, cookie_path,
creation_time, cookie_expires, creation_time, parsed_cookie.IsSecure(),
parsed_cookie.IsHttpOnly(), samesite, parsed_cookie.Priority(),
- source_scheme));
+ parsed_cookie.IsSameParty(), source_scheme, source_port));
DCHECK(cc->IsCanonical());
@@ -445,7 +458,8 @@ std::unique_ptr<CanonicalCookie> CanonicalCookie::CreateSanitizedCookie(
bool secure,
bool http_only,
CookieSameSite same_site,
- CookiePriority priority) {
+ CookiePriority priority,
+ bool same_party) {
// Validate consistency of passed arguments.
if (ParsedCookie::ParseTokenString(name) != name ||
ParsedCookie::ParseValueString(value) != value ||
@@ -475,6 +489,9 @@ std::unique_ptr<CanonicalCookie> CanonicalCookie::CreateSanitizedCookie(
if (secure && source_scheme == CookieSourceScheme::kNonSecure)
return nullptr;
+ // Get the port, this will get a default value if a port isn't provided.
+ int source_port = url.EffectiveIntPort();
+
std::string cookie_path = CanonicalCookie::CanonPathWithString(url, path);
if (!path.empty() && cookie_path != path)
return nullptr;
@@ -484,6 +501,9 @@ std::unique_ptr<CanonicalCookie> CanonicalCookie::CreateSanitizedCookie(
return nullptr;
}
+ if (!IsCookieSamePartyValid(same_party, secure, same_site))
+ return nullptr;
+
if (!last_access_time.is_null() && creation_time.is_null())
return nullptr;
@@ -498,16 +518,51 @@ std::unique_ptr<CanonicalCookie> CanonicalCookie::CreateSanitizedCookie(
std::unique_ptr<CanonicalCookie> cc(std::make_unique<CanonicalCookie>(
name, value, cookie_domain, cookie_path, creation_time, expiration_time,
- last_access_time, secure, http_only, same_site, priority, source_scheme));
+ last_access_time, secure, http_only, same_site, priority, same_party,
+ source_scheme, source_port));
DCHECK(cc->IsCanonical());
return cc;
}
+// static
+std::unique_ptr<CanonicalCookie> CanonicalCookie::FromStorage(
+ const std::string& name,
+ const std::string& value,
+ const std::string& domain,
+ const std::string& path,
+ const base::Time& creation,
+ const base::Time& expiration,
+ const base::Time& last_access,
+ bool secure,
+ bool httponly,
+ CookieSameSite same_site,
+ CookiePriority priority,
+ bool same_party,
+ CookieSourceScheme source_scheme,
+ int source_port) {
+ std::unique_ptr<CanonicalCookie> cc(std::make_unique<CanonicalCookie>(
+ name, value, domain, path, creation, expiration, last_access, secure,
+ httponly, same_site, priority, same_party, source_scheme, source_port));
+ if (!cc->IsCanonical())
+ return nullptr;
+ return cc;
+}
+
std::string CanonicalCookie::DomainWithoutDot() const {
return cookie_util::CookieDomainAsHost(domain_);
}
+void CanonicalCookie::SetSourcePort(int port) {
+ if ((port >= 0 && port <= 65535) || port == url::PORT_UNSPECIFIED) {
+ // 0 would be really weird as it has a special meaning, but it's still
+ // technically a valid tcp/ip port so we're going to accept it here.
+ source_port_ = port;
+ } else {
+ source_port_ = url::PORT_INVALID;
+ }
+}
+
bool CanonicalCookie::IsEquivalentForSecureCookieMatching(
const CanonicalCookie& secure_cookie) const {
// Names must be the same
@@ -828,7 +883,7 @@ bool CanonicalCookie::IsCanonical() const {
break;
}
- return true;
+ return IsCookieSamePartyValid(same_party_, secure_, same_site_);
}
bool CanonicalCookie::IsEffectivelySameSiteNone(
@@ -959,6 +1014,23 @@ bool CanonicalCookie::IsRecentlyCreated(base::TimeDelta age_threshold) const {
return (base::Time::Now() - creation_date_) <= age_threshold;
}
+// static
+bool CanonicalCookie::IsCookieSamePartyValid(
+ const ParsedCookie& parsed_cookie) {
+ return IsCookieSamePartyValid(parsed_cookie.IsSameParty(),
+ parsed_cookie.IsSecure(),
+ parsed_cookie.SameSite());
+}
+
+// static
+bool CanonicalCookie::IsCookieSamePartyValid(bool is_same_party,
+ bool is_secure,
+ CookieSameSite same_site) {
+ if (!is_same_party)
+ return true;
+ return is_secure && (same_site != CookieSameSite::STRICT_MODE);
+}
+
CookieAndLineWithAccessResult::CookieAndLineWithAccessResult() = default;
CookieAndLineWithAccessResult::CookieAndLineWithAccessResult(
diff --git a/chromium/net/cookies/canonical_cookie.h b/chromium/net/cookies/canonical_cookie.h
index 4cb63368be1..5ab0c2c9efc 100644
--- a/chromium/net/cookies/canonical_cookie.h
+++ b/chromium/net/cookies/canonical_cookie.h
@@ -18,6 +18,7 @@
#include "net/cookies/cookie_constants.h"
#include "net/cookies/cookie_inclusion_status.h"
#include "net/cookies/cookie_options.h"
+#include "url/third_party/mozilla/url_parse.h"
class GURL;
@@ -47,19 +48,20 @@ class NET_EXPORT CanonicalCookie {
// themselves.
// NOTE: Prefer using CreateSanitizedCookie() over directly using this
// constructor.
- CanonicalCookie(
- const std::string& name,
- const std::string& value,
- const std::string& domain,
- const std::string& path,
- const base::Time& creation,
- const base::Time& expiration,
- const base::Time& last_access,
- bool secure,
- bool httponly,
- CookieSameSite same_site,
- CookiePriority priority,
- CookieSourceScheme scheme_secure = CookieSourceScheme::kUnset);
+ CanonicalCookie(const std::string& name,
+ const std::string& value,
+ const std::string& domain,
+ const std::string& path,
+ const base::Time& creation,
+ const base::Time& expiration,
+ const base::Time& last_access,
+ bool secure,
+ bool httponly,
+ CookieSameSite same_site,
+ CookiePriority priority,
+ bool same_party,
+ CookieSourceScheme scheme_secure = CookieSourceScheme::kUnset,
+ int source_port = url::PORT_UNSPECIFIED);
~CanonicalCookie();
@@ -104,7 +106,31 @@ class NET_EXPORT CanonicalCookie {
bool secure,
bool http_only,
CookieSameSite same_site,
- CookiePriority priority);
+ CookiePriority priority,
+ bool same_party);
+
+ // FromStorage is a factory method which is meant for creating a new
+ // CanonicalCookie using properties of a previously existing cookie
+ // that was already ingested into the cookie store.
+ // This should NOT be used to create a new CanonicalCookie that was not
+ // already in the store.
+ // Returns nullptr if the resulting cookie is not canonical,
+ // i.e. cc->IsCanonical() returns false.
+ static std::unique_ptr<CanonicalCookie> FromStorage(
+ const std::string& name,
+ const std::string& value,
+ const std::string& domain,
+ const std::string& path,
+ const base::Time& creation,
+ const base::Time& expiration,
+ const base::Time& last_access,
+ bool secure,
+ bool httponly,
+ CookieSameSite same_site,
+ CookiePriority priority,
+ bool same_party,
+ CookieSourceScheme source_scheme,
+ int source_port);
const std::string& Name() const { return name_; }
const std::string& Value() const { return value_; }
@@ -122,10 +148,15 @@ class NET_EXPORT CanonicalCookie {
bool IsHttpOnly() const { return httponly_; }
CookieSameSite SameSite() const { return same_site_; }
CookiePriority Priority() const { return priority_; }
+ bool IsSameParty() const { return same_party_; }
// Returns an enum indicating the source scheme that set this cookie. This is
// not part of the cookie spec but is being used to collect metrics for a
// potential change to the cookie spec.
CookieSourceScheme SourceScheme() const { return source_scheme_; }
+ // Returns the port of the origin that originally set this cookie (the
+ // source port). This is not part of the cookie spec but is being used to
+ // collect metrics for a potential change to the cookie spec.
+ int SourcePort() const { return source_port_; }
bool IsDomainCookie() const {
return !domain_.empty() && domain_[0] == '.'; }
bool IsHostCookie() const { return !IsDomainCookie(); }
@@ -197,6 +228,11 @@ class NET_EXPORT CanonicalCookie {
void SetSourceScheme(CookieSourceScheme source_scheme) {
source_scheme_ = source_scheme;
}
+
+ // Set the source port value. Performs a range check and sets the port to
+ // url::PORT_INVALID if value isn't in [0,65535] or url::PORT_UNSPECIFIED.
+ void SetSourcePort(int port);
+
void SetLastAccessDate(const base::Time& date) {
last_access_date_ = date;
}
@@ -347,6 +383,16 @@ class NET_EXPORT CanonicalCookie {
// Returns whether the cookie was created at most |age_threshold| ago.
bool IsRecentlyCreated(base::TimeDelta age_threshold) const;
+ // Returns true iff the cookie does not violate any rules associated with
+ // creating a cookie with the SameParty attribute. In particular, if a cookie
+ // has SameParty, then it must be Secure and must not be SameSite=Strict.
+ static bool IsCookieSamePartyValid(const ParsedCookie& parsed_cookie);
+ static bool IsCookieSamePartyValid(bool is_same_party,
+ bool is_secure,
+ CookieSameSite same_site);
+
+ // Keep defaults here in sync with
+ // services/network/public/interfaces/cookie_manager.mojom.
std::string name_;
std::string value_;
std::string domain_;
@@ -354,11 +400,17 @@ class NET_EXPORT CanonicalCookie {
base::Time creation_date_;
base::Time expiry_date_;
base::Time last_access_date_;
- bool secure_;
- bool httponly_;
- CookieSameSite same_site_;
- CookiePriority priority_;
- CookieSourceScheme source_scheme_;
+ bool secure_{false};
+ bool httponly_{false};
+ CookieSameSite same_site_{CookieSameSite::NO_RESTRICTION};
+ CookiePriority priority_{COOKIE_PRIORITY_MEDIUM};
+ bool same_party_{false};
+ CookieSourceScheme source_scheme_{CookieSourceScheme::kUnset};
+ // This can be [0,65535], PORT_UNSPECIFIED, or PORT_INVALID.
+ // PORT_UNSPECIFIED is used for cookies which already existed in the cookie
+ // store prior to this change and therefore their port is unknown.
+ // PORT_INVALID is an error for when an out of range port is provided.
+ int source_port_{url::PORT_UNSPECIFIED};
};
// Used to pass excluded cookie information when it's possible that the
diff --git a/chromium/net/cookies/canonical_cookie_fuzzer.cc b/chromium/net/cookies/canonical_cookie_fuzzer.cc
index 9aecd883fb4..68a4d08c134 100644
--- a/chromium/net/cookies/canonical_cookie_fuzzer.cc
+++ b/chromium/net/cookies/canonical_cookie_fuzzer.cc
@@ -56,8 +56,9 @@ extern "C" int LLVMFuzzerTestOneInput(const uint8_t* data, size_t size) {
const std::unique_ptr<const CanonicalCookie> sanitized_cookie =
CanonicalCookie::CreateSanitizedCookie(
url, name, value, domain, path, creation, expiration, last_access,
- data_provider.ConsumeBool(), data_provider.ConsumeBool(), same_site,
- priority);
+ data_provider.ConsumeBool() /* secure */,
+ data_provider.ConsumeBool() /* httponly */, same_site, priority,
+ data_provider.ConsumeBool() /* same_party */);
if (sanitized_cookie) {
CHECK(sanitized_cookie->IsCanonical());
diff --git a/chromium/net/cookies/canonical_cookie_unittest.cc b/chromium/net/cookies/canonical_cookie_unittest.cc
index 04c1b6488f5..6da0dbb0ecd 100644
--- a/chromium/net/cookies/canonical_cookie_unittest.cc
+++ b/chromium/net/cookies/canonical_cookie_unittest.cc
@@ -13,6 +13,7 @@
#include "net/cookies/cookie_options.h"
#include "testing/gtest/include/gtest/gtest.h"
#include "url/gurl.h"
+#include "url/third_party/mozilla/url_parse.h"
namespace net {
@@ -31,13 +32,12 @@ void MatchCookieLineToVector(
} // namespace
TEST(CanonicalCookieTest, Constructor) {
- GURL url("http://www.example.com/test");
base::Time current_time = base::Time::Now();
std::unique_ptr<CanonicalCookie> cookie1(std::make_unique<CanonicalCookie>(
"A", "2", "www.example.com", "/test", current_time, base::Time(),
base::Time(), false, false, CookieSameSite::NO_RESTRICTION,
- COOKIE_PRIORITY_DEFAULT, CookieSourceScheme::kSecure));
+ COOKIE_PRIORITY_DEFAULT, false, CookieSourceScheme::kSecure, 443));
EXPECT_EQ("A", cookie1->Name());
EXPECT_EQ("2", cookie1->Value());
EXPECT_EQ("www.example.com", cookie1->Domain());
@@ -45,12 +45,15 @@ TEST(CanonicalCookieTest, Constructor) {
EXPECT_FALSE(cookie1->IsSecure());
EXPECT_FALSE(cookie1->IsHttpOnly());
EXPECT_EQ(CookieSameSite::NO_RESTRICTION, cookie1->SameSite());
+ EXPECT_EQ(CookiePriority::COOKIE_PRIORITY_DEFAULT, cookie1->Priority());
+ EXPECT_FALSE(cookie1->IsSameParty());
EXPECT_EQ(cookie1->SourceScheme(), CookieSourceScheme::kSecure);
+ EXPECT_EQ(cookie1->SourcePort(), 443);
std::unique_ptr<CanonicalCookie> cookie2(std::make_unique<CanonicalCookie>(
"A", "2", ".www.example.com", "/", current_time, base::Time(),
base::Time(), false, false, CookieSameSite::NO_RESTRICTION,
- COOKIE_PRIORITY_DEFAULT, CookieSourceScheme::kNonSecure));
+ COOKIE_PRIORITY_DEFAULT, true, CookieSourceScheme::kNonSecure, 65536));
EXPECT_EQ("A", cookie2->Name());
EXPECT_EQ("2", cookie2->Value());
EXPECT_EQ(".www.example.com", cookie2->Domain());
@@ -58,20 +61,27 @@ TEST(CanonicalCookieTest, Constructor) {
EXPECT_FALSE(cookie2->IsSecure());
EXPECT_FALSE(cookie2->IsHttpOnly());
EXPECT_EQ(CookieSameSite::NO_RESTRICTION, cookie2->SameSite());
+ EXPECT_EQ(CookiePriority::COOKIE_PRIORITY_DEFAULT, cookie2->Priority());
+ EXPECT_TRUE(cookie2->IsSameParty());
EXPECT_EQ(cookie2->SourceScheme(), CookieSourceScheme::kNonSecure);
+ // Because the port can be set explicitly in the constructor its value can be
+ // independent of the other parameters. In this case, test that an invalid
+ // port value is interpreted as such.
+ EXPECT_EQ(cookie2->SourcePort(), url::PORT_INVALID);
- // Set Secure to true but don't specify is_source_scheme_secure
+ // Set Secure to true but don't specify source_scheme or port.
auto cookie3 = std::make_unique<CanonicalCookie>(
"A", "2", ".www.example.com", "/", current_time, base::Time(),
base::Time(), true /* secure */, false, CookieSameSite::NO_RESTRICTION,
- COOKIE_PRIORITY_DEFAULT);
+ COOKIE_PRIORITY_DEFAULT, false);
EXPECT_TRUE(cookie3->IsSecure());
EXPECT_EQ(cookie3->SourceScheme(), CookieSourceScheme::kUnset);
+ EXPECT_EQ(cookie3->SourcePort(), url::PORT_UNSPECIFIED);
auto cookie4 = std::make_unique<CanonicalCookie>(
"A", "2", ".www.example.com", "/test", current_time, base::Time(),
base::Time(), false, false, CookieSameSite::NO_RESTRICTION,
- COOKIE_PRIORITY_DEFAULT);
+ COOKIE_PRIORITY_DEFAULT, false);
EXPECT_EQ("A", cookie4->Name());
EXPECT_EQ("2", cookie4->Value());
EXPECT_EQ(".www.example.com", cookie4->Domain());
@@ -79,6 +89,25 @@ TEST(CanonicalCookieTest, Constructor) {
EXPECT_FALSE(cookie4->IsSecure());
EXPECT_FALSE(cookie4->IsHttpOnly());
EXPECT_EQ(CookieSameSite::NO_RESTRICTION, cookie4->SameSite());
+ EXPECT_FALSE(cookie4->IsSameParty());
+ EXPECT_EQ(cookie4->SourceScheme(), CookieSourceScheme::kUnset);
+ EXPECT_EQ(cookie4->SourcePort(), url::PORT_UNSPECIFIED);
+
+ // Test some port edge cases: unspecified.
+ auto cookie5 = std::make_unique<CanonicalCookie>(
+ "A", "2", ".www.example.com", "/", current_time, base::Time(),
+ base::Time(), true /* secure */, false, CookieSameSite::NO_RESTRICTION,
+ COOKIE_PRIORITY_DEFAULT, false, CookieSourceScheme::kUnset,
+ url::PORT_UNSPECIFIED);
+ EXPECT_EQ(cookie5->SourcePort(), url::PORT_UNSPECIFIED);
+
+ // Test some port edge cases: invalid.
+ auto cookie6 = std::make_unique<CanonicalCookie>(
+ "A", "2", ".www.example.com", "/", current_time, base::Time(),
+ base::Time(), true /* secure */, false, CookieSameSite::NO_RESTRICTION,
+ COOKIE_PRIORITY_DEFAULT, false, CookieSourceScheme::kUnset,
+ url::PORT_INVALID);
+ EXPECT_EQ(cookie6->SourcePort(), url::PORT_INVALID);
}
TEST(CanonicalCookie, CreationCornerCases) {
@@ -113,6 +142,7 @@ TEST(CanonicalCookieTest, Create) {
EXPECT_EQ("/test", cookie->Path());
EXPECT_FALSE(cookie->IsSecure());
EXPECT_EQ(cookie->SourceScheme(), CookieSourceScheme::kNonSecure);
+ EXPECT_EQ(cookie->SourcePort(), 80);
GURL url2("http://www.foo.com");
cookie = CanonicalCookie::Create(url2, "B=1", creation_time, server_time);
@@ -122,6 +152,7 @@ TEST(CanonicalCookieTest, Create) {
EXPECT_EQ("/", cookie->Path());
EXPECT_FALSE(cookie->IsSecure());
EXPECT_EQ(cookie->SourceScheme(), CookieSourceScheme::kNonSecure);
+ EXPECT_EQ(cookie->SourcePort(), 80);
// Test creating secure cookies. Secure scheme is not checked upon creation,
// so a URL of any scheme can create a Secure cookie.
@@ -174,6 +205,33 @@ TEST(CanonicalCookieTest, Create) {
cookie = CanonicalCookie::Create(url, "A=2", creation_time, server_time);
ASSERT_TRUE(cookie.get());
EXPECT_EQ(CookieSameSite::UNSPECIFIED, cookie->SameSite());
+
+ // Test creating cookies with different ports.
+ cookie = CanonicalCookie::Create(GURL("http://www.foo.com"), "B=1",
+ creation_time, server_time);
+ EXPECT_EQ(cookie->SourcePort(), 80);
+
+ cookie = CanonicalCookie::Create(GURL("http://www.foo.com:81"), "B=1",
+ creation_time, server_time);
+ EXPECT_EQ(cookie->SourcePort(), 81);
+
+ cookie = CanonicalCookie::Create(GURL("https://www.foo.com"), "B=1",
+ creation_time, server_time);
+ EXPECT_EQ(cookie->SourcePort(), 443);
+
+ cookie = CanonicalCookie::Create(GURL("https://www.foo.com:1234"), "B=1",
+ creation_time, server_time);
+ EXPECT_EQ(cookie->SourcePort(), 1234);
+
+ cookie = CanonicalCookie::Create(GURL("http://www.foo.com:443"), "B=1",
+ creation_time, server_time);
+ EXPECT_EQ(cookie->SourcePort(), 443);
+
+ // GURL's port parsing will handle any invalid ports, but let's still make
+ // sure we get the expected result anyway.
+ cookie = CanonicalCookie::Create(GURL("http://www.foo.com:70000"), "B=1",
+ creation_time, server_time);
+ EXPECT_EQ(cookie->SourcePort(), url::PORT_INVALID);
}
TEST(CanonicalCookieTest, CreateNonStandardSameSite) {
@@ -240,6 +298,53 @@ TEST(CanonicalCookieTest, CreateWithInvalidDomain) {
{CookieInclusionStatus::EXCLUDE_INVALID_DOMAIN}));
}
+TEST(CanonicalCookieTest, CreateSameParty) {
+ GURL url("http://www.example.com/test/foo.html");
+ GURL https_url("https://www.example.com/test/foo.html");
+ base::Time creation_time = base::Time::Now();
+ base::Optional<base::Time> server_time = base::nullopt;
+
+ CookieInclusionStatus status;
+ std::unique_ptr<CanonicalCookie> cookie = CanonicalCookie::Create(
+ url, "A=2; SameParty; Secure", creation_time, server_time, &status);
+ ASSERT_TRUE(cookie.get());
+ EXPECT_TRUE(status.IsInclude());
+ EXPECT_TRUE(cookie->IsSecure());
+ EXPECT_TRUE(cookie->IsSameParty());
+ EXPECT_EQ(CookieSameSite::UNSPECIFIED, cookie->SameSite());
+
+ cookie = CanonicalCookie::Create(url, "A=2; SameParty; SameSite=None; Secure",
+ creation_time, server_time, &status);
+ ASSERT_TRUE(cookie.get());
+ EXPECT_TRUE(status.IsInclude());
+ EXPECT_TRUE(cookie->IsSecure());
+ EXPECT_TRUE(cookie->IsSameParty());
+ EXPECT_EQ(CookieSameSite::NO_RESTRICTION, cookie->SameSite());
+
+ cookie = CanonicalCookie::Create(url, "A=2; SameParty; SameSite=Lax; Secure",
+ creation_time, server_time, &status);
+ ASSERT_TRUE(cookie.get());
+ EXPECT_TRUE(status.IsInclude());
+ EXPECT_TRUE(cookie->IsSecure());
+ EXPECT_TRUE(cookie->IsSameParty());
+ EXPECT_EQ(CookieSameSite::LAX_MODE, cookie->SameSite());
+
+ // SameParty cookie with SameSite=Strict is invalid.
+ cookie =
+ CanonicalCookie::Create(url, "A=2; SameParty; SameSite=Strict; Secure",
+ creation_time, server_time, &status);
+ EXPECT_FALSE(cookie.get());
+ EXPECT_TRUE(status.HasExactlyExclusionReasonsForTesting(
+ {CookieInclusionStatus::EXCLUDE_INVALID_SAMEPARTY}));
+
+ // SameParty cookie without Secure is invalid.
+ cookie = CanonicalCookie::Create(url, "A=2; SameParty; SameSite=Lax",
+ creation_time, server_time, &status);
+ EXPECT_FALSE(cookie.get());
+ EXPECT_TRUE(status.HasExactlyExclusionReasonsForTesting(
+ {CookieInclusionStatus::EXCLUDE_INVALID_SAMEPARTY}));
+}
+
TEST(CanonicalCookieTest, EmptyExpiry) {
GURL url("http://www7.ipdl.inpit.go.jp/Tokujitu/tjkta.ipdl?N0000=108");
base::Time creation_time = base::Time::Now();
@@ -281,15 +386,16 @@ TEST(CanonicalCookieTest, IsEquivalent) {
std::string cookie_path = "/path";
base::Time creation_time = base::Time::Now();
base::Time expiration_time = creation_time + base::TimeDelta::FromDays(2);
- bool secure(false);
- bool httponly(false);
- CookieSameSite same_site(CookieSameSite::NO_RESTRICTION);
+ bool secure = false;
+ bool httponly = false;
+ CookieSameSite same_site = CookieSameSite::NO_RESTRICTION;
+ bool same_party = false;
// Test that a cookie is equivalent to itself.
std::unique_ptr<CanonicalCookie> cookie(std::make_unique<CanonicalCookie>(
cookie_name, cookie_value, cookie_domain, cookie_path, creation_time,
expiration_time, base::Time(), secure, httponly, same_site,
- COOKIE_PRIORITY_MEDIUM));
+ COOKIE_PRIORITY_MEDIUM, same_party));
EXPECT_TRUE(cookie->IsEquivalent(*cookie));
EXPECT_TRUE(cookie->IsEquivalentForSecureCookieMatching(*cookie));
@@ -298,7 +404,7 @@ TEST(CanonicalCookieTest, IsEquivalent) {
std::make_unique<CanonicalCookie>(
cookie_name, cookie_value, cookie_domain, cookie_path, creation_time,
expiration_time, base::Time(), secure, httponly, same_site,
- COOKIE_PRIORITY_MEDIUM));
+ COOKIE_PRIORITY_MEDIUM, same_party));
EXPECT_TRUE(cookie->IsEquivalent(*other_cookie));
EXPECT_TRUE(other_cookie->IsEquivalentForSecureCookieMatching(*cookie));
@@ -307,7 +413,7 @@ TEST(CanonicalCookieTest, IsEquivalent) {
other_cookie = std::make_unique<CanonicalCookie>(
cookie_name, "2", cookie_domain, cookie_path, creation_time,
expiration_time, base::Time(), secure, httponly, same_site,
- COOKIE_PRIORITY_HIGH);
+ COOKIE_PRIORITY_HIGH, same_party);
EXPECT_TRUE(cookie->IsEquivalent(*other_cookie));
EXPECT_TRUE(cookie->IsEquivalentForSecureCookieMatching(*other_cookie));
EXPECT_TRUE(other_cookie->IsEquivalentForSecureCookieMatching(*cookie));
@@ -317,7 +423,7 @@ TEST(CanonicalCookieTest, IsEquivalent) {
other_cookie = std::make_unique<CanonicalCookie>(
cookie_name, "2", cookie_domain, cookie_path, other_creation_time,
expiration_time, base::Time(), secure, httponly, same_site,
- COOKIE_PRIORITY_MEDIUM);
+ COOKIE_PRIORITY_MEDIUM, same_party);
EXPECT_TRUE(cookie->IsEquivalent(*other_cookie));
EXPECT_TRUE(cookie->IsEquivalentForSecureCookieMatching(*other_cookie));
EXPECT_TRUE(other_cookie->IsEquivalentForSecureCookieMatching(*cookie));
@@ -325,7 +431,7 @@ TEST(CanonicalCookieTest, IsEquivalent) {
other_cookie = std::make_unique<CanonicalCookie>(
cookie_name, cookie_name, cookie_domain, cookie_path, creation_time,
expiration_time, base::Time(), true, httponly, same_site,
- COOKIE_PRIORITY_LOW);
+ COOKIE_PRIORITY_LOW, same_party);
EXPECT_TRUE(cookie->IsEquivalent(*other_cookie));
EXPECT_TRUE(cookie->IsEquivalentForSecureCookieMatching(*other_cookie));
EXPECT_TRUE(other_cookie->IsEquivalentForSecureCookieMatching(*cookie));
@@ -333,7 +439,7 @@ TEST(CanonicalCookieTest, IsEquivalent) {
other_cookie = std::make_unique<CanonicalCookie>(
cookie_name, cookie_name, cookie_domain, cookie_path, creation_time,
expiration_time, base::Time(), secure, true, same_site,
- COOKIE_PRIORITY_LOW);
+ COOKIE_PRIORITY_LOW, same_party);
EXPECT_TRUE(cookie->IsEquivalent(*other_cookie));
EXPECT_TRUE(cookie->IsEquivalentForSecureCookieMatching(*other_cookie));
EXPECT_TRUE(other_cookie->IsEquivalentForSecureCookieMatching(*cookie));
@@ -341,7 +447,7 @@ TEST(CanonicalCookieTest, IsEquivalent) {
other_cookie = std::make_unique<CanonicalCookie>(
cookie_name, cookie_name, cookie_domain, cookie_path, creation_time,
expiration_time, base::Time(), secure, httponly,
- CookieSameSite::STRICT_MODE, COOKIE_PRIORITY_LOW);
+ CookieSameSite::STRICT_MODE, COOKIE_PRIORITY_LOW, same_party);
EXPECT_TRUE(cookie->IsEquivalent(*other_cookie));
EXPECT_TRUE(cookie->IsEquivalentForSecureCookieMatching(*other_cookie));
EXPECT_TRUE(other_cookie->IsEquivalentForSecureCookieMatching(*cookie));
@@ -350,7 +456,7 @@ TEST(CanonicalCookieTest, IsEquivalent) {
other_cookie = std::make_unique<CanonicalCookie>(
"B", cookie_value, cookie_domain, cookie_path, creation_time,
expiration_time, base::Time(), secure, httponly, same_site,
- COOKIE_PRIORITY_MEDIUM);
+ COOKIE_PRIORITY_MEDIUM, same_party);
EXPECT_FALSE(cookie->IsEquivalent(*other_cookie));
EXPECT_FALSE(cookie->IsEquivalentForSecureCookieMatching(*other_cookie));
EXPECT_FALSE(other_cookie->IsEquivalentForSecureCookieMatching(*cookie));
@@ -361,7 +467,7 @@ TEST(CanonicalCookieTest, IsEquivalent) {
other_cookie = std::make_unique<CanonicalCookie>(
cookie_name, cookie_value, "www.example.com", cookie_path, creation_time,
expiration_time, base::Time(), secure, httponly, same_site,
- COOKIE_PRIORITY_MEDIUM);
+ COOKIE_PRIORITY_MEDIUM, same_party);
EXPECT_TRUE(cookie->IsDomainCookie());
EXPECT_FALSE(other_cookie->IsDomainCookie());
EXPECT_FALSE(cookie->IsEquivalent(*other_cookie));
@@ -373,7 +479,7 @@ TEST(CanonicalCookieTest, IsEquivalent) {
other_cookie = std::make_unique<CanonicalCookie>(
cookie_name, cookie_value, ".example.com", cookie_path, creation_time,
expiration_time, base::Time(), secure, httponly, same_site,
- COOKIE_PRIORITY_MEDIUM);
+ COOKIE_PRIORITY_MEDIUM, same_party);
EXPECT_FALSE(cookie->IsEquivalent(*other_cookie));
EXPECT_TRUE(cookie->IsEquivalentForSecureCookieMatching(*other_cookie));
EXPECT_TRUE(other_cookie->IsEquivalentForSecureCookieMatching(*cookie));
@@ -386,7 +492,7 @@ TEST(CanonicalCookieTest, IsEquivalent) {
other_cookie = std::make_unique<CanonicalCookie>(
cookie_name, cookie_value, cookie_domain, "/test", creation_time,
expiration_time, base::Time(), secure, httponly, same_site,
- COOKIE_PRIORITY_MEDIUM);
+ COOKIE_PRIORITY_MEDIUM, same_party);
EXPECT_FALSE(cookie->IsEquivalent(*other_cookie));
EXPECT_FALSE(cookie->IsEquivalentForSecureCookieMatching(*other_cookie));
EXPECT_FALSE(other_cookie->IsEquivalentForSecureCookieMatching(*cookie));
@@ -394,7 +500,7 @@ TEST(CanonicalCookieTest, IsEquivalent) {
other_cookie = std::make_unique<CanonicalCookie>(
cookie_name, cookie_value, cookie_domain, cookie_path + "/subpath",
creation_time, expiration_time, base::Time(), secure, httponly, same_site,
- COOKIE_PRIORITY_MEDIUM);
+ COOKIE_PRIORITY_MEDIUM, same_party);
EXPECT_FALSE(cookie->IsEquivalent(*other_cookie));
// The path comparison is asymmetric
EXPECT_FALSE(cookie->IsEquivalentForSecureCookieMatching(*other_cookie));
@@ -403,7 +509,7 @@ TEST(CanonicalCookieTest, IsEquivalent) {
other_cookie = std::make_unique<CanonicalCookie>(
cookie_name, cookie_value, cookie_domain, "/", creation_time,
expiration_time, base::Time(), secure, httponly, same_site,
- COOKIE_PRIORITY_MEDIUM);
+ COOKIE_PRIORITY_MEDIUM, same_party);
EXPECT_FALSE(cookie->IsEquivalent(*other_cookie));
EXPECT_TRUE(cookie->IsEquivalentForSecureCookieMatching(*other_cookie));
EXPECT_FALSE(other_cookie->IsEquivalentForSecureCookieMatching(*cookie));
@@ -445,12 +551,12 @@ TEST(CanonicalCookieTest, IsEquivalentForSecureCookieMatching) {
auto cookie = std::make_unique<CanonicalCookie>(
test.cookie.name, "value1", test.cookie.domain, test.cookie.path,
base::Time(), base::Time(), base::Time(), false /* secure */, false,
- CookieSameSite::LAX_MODE, COOKIE_PRIORITY_MEDIUM);
+ CookieSameSite::LAX_MODE, COOKIE_PRIORITY_MEDIUM, false);
auto secure_cookie = std::make_unique<CanonicalCookie>(
test.secure_cookie.name, "value2", test.secure_cookie.domain,
test.secure_cookie.path, base::Time(), base::Time(), base::Time(),
true /* secure */, false, CookieSameSite::LAX_MODE,
- COOKIE_PRIORITY_MEDIUM);
+ COOKIE_PRIORITY_MEDIUM, false);
EXPECT_EQ(test.equivalent,
cookie->IsEquivalentForSecureCookieMatching(*secure_cookie));
@@ -534,7 +640,7 @@ void VerifyEffectiveSameSiteTestCases(
CanonicalCookie cookie("A", "2", "example.test", "/", creation_time,
expiry_time, base::Time(), true /* secure */,
false /* httponly */, test_case.same_site,
- COOKIE_PRIORITY_DEFAULT);
+ COOKIE_PRIORITY_DEFAULT, false);
EXPECT_EQ(
test_case.effective_same_site,
cookie.GetEffectiveSameSiteForTesting(test_case.access_semantics));
@@ -1196,7 +1302,7 @@ TEST(CanonicalCookieTest, MultipleExclusionReasons) {
CanonicalCookie cookie1 = CanonicalCookie(
"name", "value", "other-domain.com", "/bar", creation_time, base::Time(),
base::Time(), true /* secure */, true /* httponly */,
- CookieSameSite::STRICT_MODE, COOKIE_PRIORITY_DEFAULT);
+ CookieSameSite::STRICT_MODE, COOKIE_PRIORITY_DEFAULT, false);
EXPECT_TRUE(cookie1.IncludeForRequestURL(url, options)
.status.HasExactlyExclusionReasonsForTesting(
{CookieInclusionStatus::EXCLUDE_HTTP_ONLY,
@@ -1390,42 +1496,42 @@ TEST(CanonicalCookieTest, IsCanonical) {
EXPECT_TRUE(CanonicalCookie("A", "B", "x.y", "/path", base::Time(),
base::Time(), base::Time(), false, false,
CookieSameSite::NO_RESTRICTION,
- COOKIE_PRIORITY_LOW)
+ COOKIE_PRIORITY_LOW, false)
.IsCanonical());
// Newline in name.
EXPECT_FALSE(CanonicalCookie("A\n", "B", "x.y", "/path", base::Time(),
base::Time(), base::Time(), false, false,
CookieSameSite::NO_RESTRICTION,
- COOKIE_PRIORITY_LOW)
+ COOKIE_PRIORITY_LOW, false)
.IsCanonical());
// Carriage return in name.
EXPECT_FALSE(CanonicalCookie("A\r", "B", "x.y", "/path", base::Time(),
base::Time(), base::Time(), false, false,
CookieSameSite::NO_RESTRICTION,
- COOKIE_PRIORITY_LOW)
+ COOKIE_PRIORITY_LOW, false)
.IsCanonical());
// Null character in name.
EXPECT_FALSE(CanonicalCookie(std::string("A\0Z", 3), "B", "x.y", "/path",
base::Time(), base::Time(), base::Time(), false,
false, CookieSameSite::NO_RESTRICTION,
- COOKIE_PRIORITY_LOW)
+ COOKIE_PRIORITY_LOW, false)
.IsCanonical());
// Name begins with whitespace.
EXPECT_FALSE(CanonicalCookie(" A", "B", "x.y", "/path", base::Time(),
base::Time(), base::Time(), false, false,
CookieSameSite::NO_RESTRICTION,
- COOKIE_PRIORITY_LOW)
+ COOKIE_PRIORITY_LOW, false)
.IsCanonical());
// Name ends with whitespace.
EXPECT_FALSE(CanonicalCookie("A ", "B", "x.y", "/path", base::Time(),
base::Time(), base::Time(), false, false,
CookieSameSite::NO_RESTRICTION,
- COOKIE_PRIORITY_LOW)
+ COOKIE_PRIORITY_LOW, false)
.IsCanonical());
// Empty name. (Note this is against the spec but compatible with other
@@ -1433,70 +1539,70 @@ TEST(CanonicalCookieTest, IsCanonical) {
EXPECT_TRUE(CanonicalCookie("", "B", "x.y", "/path", base::Time(),
base::Time(), base::Time(), false, false,
CookieSameSite::NO_RESTRICTION,
- COOKIE_PRIORITY_LOW)
+ COOKIE_PRIORITY_LOW, false)
.IsCanonical());
// Space in name
EXPECT_TRUE(CanonicalCookie("A C", "B", "x.y", "/path", base::Time(),
base::Time(), base::Time(), false, false,
CookieSameSite::NO_RESTRICTION,
- COOKIE_PRIORITY_LOW)
+ COOKIE_PRIORITY_LOW, false)
.IsCanonical());
// Extra space suffixing name.
EXPECT_FALSE(CanonicalCookie("A ", "B", "x.y", "/path", base::Time(),
base::Time(), base::Time(), false, false,
CookieSameSite::NO_RESTRICTION,
- COOKIE_PRIORITY_LOW)
+ COOKIE_PRIORITY_LOW, false)
.IsCanonical());
// '=' character in name.
EXPECT_FALSE(CanonicalCookie("A=", "B", "x.y", "/path", base::Time(),
base::Time(), base::Time(), false, false,
CookieSameSite::NO_RESTRICTION,
- COOKIE_PRIORITY_LOW)
+ COOKIE_PRIORITY_LOW, false)
.IsCanonical());
// Separator in name.
EXPECT_FALSE(CanonicalCookie("A;", "B", "x.y", "/path", base::Time(),
base::Time(), base::Time(), false, false,
CookieSameSite::NO_RESTRICTION,
- COOKIE_PRIORITY_LOW)
+ COOKIE_PRIORITY_LOW, false)
.IsCanonical());
// '=' character in value.
EXPECT_TRUE(CanonicalCookie("A", "B=", "x.y", "/path", base::Time(),
base::Time(), base::Time(), false, false,
CookieSameSite::NO_RESTRICTION,
- COOKIE_PRIORITY_LOW)
+ COOKIE_PRIORITY_LOW, false)
.IsCanonical());
// Separator in value.
EXPECT_FALSE(CanonicalCookie("A", "B;", "x.y", "/path", base::Time(),
base::Time(), base::Time(), false, false,
CookieSameSite::NO_RESTRICTION,
- COOKIE_PRIORITY_LOW)
+ COOKIE_PRIORITY_LOW, false)
.IsCanonical());
// Separator in domain.
EXPECT_FALSE(CanonicalCookie("A", "B", ";x.y", "/path", base::Time(),
base::Time(), base::Time(), false, false,
CookieSameSite::NO_RESTRICTION,
- COOKIE_PRIORITY_LOW)
+ COOKIE_PRIORITY_LOW, false)
.IsCanonical());
// Garbage in domain.
EXPECT_FALSE(CanonicalCookie("A", "B", "@:&", "/path", base::Time(),
base::Time(), base::Time(), false, false,
CookieSameSite::NO_RESTRICTION,
- COOKIE_PRIORITY_LOW)
+ COOKIE_PRIORITY_LOW, false)
.IsCanonical());
// Space in domain.
EXPECT_FALSE(CanonicalCookie("A", "B", "x.y ", "/path", base::Time(),
base::Time(), base::Time(), false, false,
CookieSameSite::NO_RESTRICTION,
- COOKIE_PRIORITY_LOW)
+ COOKIE_PRIORITY_LOW, false)
.IsCanonical());
// Empty domain. (This is against cookie spec, but needed for Chrome's
@@ -1504,64 +1610,65 @@ TEST(CanonicalCookieTest, IsCanonical) {
EXPECT_TRUE(CanonicalCookie("A", "B", "", "/path", base::Time(), base::Time(),
base::Time(), false, false,
CookieSameSite::NO_RESTRICTION,
- COOKIE_PRIORITY_LOW)
+ COOKIE_PRIORITY_LOW, false)
.IsCanonical());
// Path does not start with a "/".
EXPECT_FALSE(CanonicalCookie("A", "B", "x.y", "path", base::Time(),
base::Time(), base::Time(), false, false,
CookieSameSite::NO_RESTRICTION,
- COOKIE_PRIORITY_LOW)
+ COOKIE_PRIORITY_LOW, false)
.IsCanonical());
// Empty path.
EXPECT_FALSE(CanonicalCookie("A", "B", "x.y", "", base::Time(), base::Time(),
base::Time(), false, false,
CookieSameSite::NO_RESTRICTION,
- COOKIE_PRIORITY_LOW)
+ COOKIE_PRIORITY_LOW, false)
.IsCanonical());
// Simple IPv4 address as domain.
EXPECT_TRUE(CanonicalCookie("A", "B", "1.2.3.4", "/path", base::Time(),
base::Time(), base::Time(), false, false,
CookieSameSite::NO_RESTRICTION,
- COOKIE_PRIORITY_LOW)
+ COOKIE_PRIORITY_LOW, false)
.IsCanonical());
// NOn-canonical IPv4 address as domain.
EXPECT_FALSE(CanonicalCookie("A", "B", "01.2.03.4", "/path", base::Time(),
base::Time(), base::Time(), false, false,
CookieSameSite::NO_RESTRICTION,
- COOKIE_PRIORITY_LOW)
+ COOKIE_PRIORITY_LOW, false)
.IsCanonical());
// Null IPv6 address as domain.
EXPECT_TRUE(CanonicalCookie("A", "B", "[::]", "/path", base::Time(),
base::Time(), base::Time(), false, false,
CookieSameSite::NO_RESTRICTION,
- COOKIE_PRIORITY_LOW)
+ COOKIE_PRIORITY_LOW, false)
.IsCanonical());
// Localhost IPv6 address as domain.
EXPECT_TRUE(CanonicalCookie("A", "B", "[::1]", "/path", base::Time(),
base::Time(), base::Time(), false, false,
CookieSameSite::NO_RESTRICTION,
- COOKIE_PRIORITY_LOW)
+ COOKIE_PRIORITY_LOW, false)
.IsCanonical());
// Fully speced IPv6 address as domain.
- EXPECT_FALSE(CanonicalCookie(
- "A", "B", "[2001:0DB8:AC10:FE01:0000:0000:0000:0000]",
- "/path", base::Time(), base::Time(), base::Time(), false,
- false, CookieSameSite::NO_RESTRICTION, COOKIE_PRIORITY_LOW)
- .IsCanonical());
+ EXPECT_FALSE(
+ CanonicalCookie("A", "B", "[2001:0DB8:AC10:FE01:0000:0000:0000:0000]",
+ "/path", base::Time(), base::Time(), base::Time(), false,
+ false, CookieSameSite::NO_RESTRICTION,
+ COOKIE_PRIORITY_LOW, false)
+ .IsCanonical());
// Zero abbreviated IPv6 address as domain. Not canonical because of leading
// zeros & uppercase hex letters.
EXPECT_FALSE(CanonicalCookie("A", "B", "[2001:0DB8:AC10:FE01::]", "/path",
base::Time(), base::Time(), base::Time(), false,
false, CookieSameSite::NO_RESTRICTION,
- COOKIE_PRIORITY_LOW)
+ COOKIE_PRIORITY_LOW, false)
.IsCanonical());
// Zero prefixes removed IPv6 address as domain. Not canoncial because of
@@ -1569,70 +1676,101 @@ TEST(CanonicalCookieTest, IsCanonical) {
EXPECT_FALSE(CanonicalCookie("A", "B", "[2001:DB8:AC10:FE01::]", "/path",
base::Time(), base::Time(), base::Time(), false,
false, CookieSameSite::NO_RESTRICTION,
- COOKIE_PRIORITY_LOW)
+ COOKIE_PRIORITY_LOW, false)
.IsCanonical());
// Lowercased hex IPv6 address as domain.
EXPECT_TRUE(CanonicalCookie("A", "B", "[2001:db8:ac10:fe01::]", "/path",
base::Time(), base::Time(), base::Time(), false,
false, CookieSameSite::NO_RESTRICTION,
- COOKIE_PRIORITY_LOW)
+ COOKIE_PRIORITY_LOW, false)
.IsCanonical());
// Properly formatted host cookie.
EXPECT_TRUE(CanonicalCookie("__Host-A", "B", "x.y", "/", base::Time(),
base::Time(), base::Time(), true, false,
CookieSameSite::NO_RESTRICTION,
- COOKIE_PRIORITY_LOW)
+ COOKIE_PRIORITY_LOW, false)
.IsCanonical());
// Insecure host cookie.
EXPECT_FALSE(CanonicalCookie("__Host-A", "B", "x.y", "/", base::Time(),
base::Time(), base::Time(), false, false,
CookieSameSite::NO_RESTRICTION,
- COOKIE_PRIORITY_LOW)
+ COOKIE_PRIORITY_LOW, false)
.IsCanonical());
// Host cookie with non-null path.
EXPECT_FALSE(CanonicalCookie("__Host-A", "B", "x.y", "/path", base::Time(),
base::Time(), base::Time(), true, false,
CookieSameSite::NO_RESTRICTION,
- COOKIE_PRIORITY_LOW)
+ COOKIE_PRIORITY_LOW, false)
.IsCanonical());
// Host cookie with empty domain.
EXPECT_FALSE(CanonicalCookie("__Host-A", "B", "", "/", base::Time(),
base::Time(), base::Time(), true, false,
CookieSameSite::NO_RESTRICTION,
- COOKIE_PRIORITY_LOW)
+ COOKIE_PRIORITY_LOW, false)
.IsCanonical());
// Host cookie with period prefixed domain.
EXPECT_FALSE(CanonicalCookie("__Host-A", "B", ".x.y", "/", base::Time(),
base::Time(), base::Time(), true, false,
CookieSameSite::NO_RESTRICTION,
- COOKIE_PRIORITY_LOW)
+ COOKIE_PRIORITY_LOW, false)
.IsCanonical());
// Properly formatted secure cookie.
EXPECT_TRUE(CanonicalCookie("__Secure-A", "B", "x.y", "/", base::Time(),
base::Time(), base::Time(), true, false,
CookieSameSite::NO_RESTRICTION,
- COOKIE_PRIORITY_LOW)
+ COOKIE_PRIORITY_LOW, false)
.IsCanonical());
// Insecure secure cookie.
EXPECT_FALSE(CanonicalCookie("__Secure-A", "B", "x.y", "/", base::Time(),
base::Time(), base::Time(), false, false,
CookieSameSite::NO_RESTRICTION,
- COOKIE_PRIORITY_LOW)
+ COOKIE_PRIORITY_LOW, false)
+ .IsCanonical());
+
+ // SameParty attribute used correctly (with Secure and non-Strict SameSite).
+ EXPECT_TRUE(CanonicalCookie("A", "B", "x.y", "/", base::Time(), base::Time(),
+ base::Time(), true, false,
+ CookieSameSite::NO_RESTRICTION,
+ COOKIE_PRIORITY_LOW, true)
+ .IsCanonical());
+ EXPECT_TRUE(CanonicalCookie("A", "B", "x.y", "/", base::Time(), base::Time(),
+ base::Time(), true, false,
+ CookieSameSite::UNSPECIFIED, COOKIE_PRIORITY_LOW,
+ true)
+ .IsCanonical());
+ EXPECT_TRUE(CanonicalCookie("A", "B", "x.y", "/", base::Time(), base::Time(),
+ base::Time(), true, false,
+ CookieSameSite::LAX_MODE, COOKIE_PRIORITY_LOW,
+ true)
+ .IsCanonical());
+
+ // SameParty without Secure is not canonical.
+ EXPECT_FALSE(CanonicalCookie("A", "B", "x.y", "/", base::Time(), base::Time(),
+ base::Time(), false, false,
+ CookieSameSite::LAX_MODE, COOKIE_PRIORITY_LOW,
+ true)
+ .IsCanonical());
+
+ // SameParty with SameSite=Strict is not canonical.
+ EXPECT_FALSE(CanonicalCookie("A", "B", "x.y", "/", base::Time(), base::Time(),
+ base::Time(), true, false,
+ CookieSameSite::STRICT_MODE, COOKIE_PRIORITY_LOW,
+ true)
.IsCanonical());
}
TEST(CanonicalCookieTest, TestSetCreationDate) {
- CanonicalCookie cookie("A", "B", "x.y", "/path", base::Time(), base::Time(),
- base::Time(), false, false,
- CookieSameSite::NO_RESTRICTION, COOKIE_PRIORITY_LOW);
+ CanonicalCookie cookie(
+ "A", "B", "x.y", "/path", base::Time(), base::Time(), base::Time(), false,
+ false, CookieSameSite::NO_RESTRICTION, COOKIE_PRIORITY_LOW, false);
EXPECT_TRUE(cookie.CreationDate().is_null());
base::Time now(base::Time::Now());
@@ -1727,7 +1865,7 @@ TEST(CanonicalCookieTest, CreateSanitizedCookie_Inputs) {
GURL("https://www.foo.com"), "A", "B", std::string(), "/foo",
base::Time(), base::Time(), base::Time(), false /*secure*/,
false /*httponly*/, CookieSameSite::NO_RESTRICTION,
- COOKIE_PRIORITY_DEFAULT);
+ COOKIE_PRIORITY_DEFAULT, false /*same_party*/);
EXPECT_TRUE(cc);
EXPECT_EQ("A", cc->Name());
EXPECT_EQ("B", cc->Value());
@@ -1740,6 +1878,7 @@ TEST(CanonicalCookieTest, CreateSanitizedCookie_Inputs) {
EXPECT_FALSE(cc->IsHttpOnly());
EXPECT_EQ(CookieSameSite::NO_RESTRICTION, cc->SameSite());
EXPECT_EQ(COOKIE_PRIORITY_MEDIUM, cc->Priority());
+ EXPECT_FALSE(cc->IsSameParty());
EXPECT_FALSE(cc->IsDomainCookie());
// Creation date
@@ -1747,7 +1886,7 @@ TEST(CanonicalCookieTest, CreateSanitizedCookie_Inputs) {
GURL("https://www.foo.com"), "A", "B", std::string(), "/foo",
two_hours_ago, base::Time(), base::Time(), false /*secure*/,
false /*httponly*/, CookieSameSite::NO_RESTRICTION,
- COOKIE_PRIORITY_DEFAULT);
+ COOKIE_PRIORITY_DEFAULT, false /*same_party*/);
EXPECT_TRUE(cc);
EXPECT_EQ(two_hours_ago, cc->CreationDate());
@@ -1756,7 +1895,7 @@ TEST(CanonicalCookieTest, CreateSanitizedCookie_Inputs) {
GURL("https://www.foo.com"), "A", "B", std::string(), "/foo",
two_hours_ago, base::Time(), one_hour_ago, false /*secure*/,
false /*httponly*/, CookieSameSite::NO_RESTRICTION,
- COOKIE_PRIORITY_DEFAULT);
+ COOKIE_PRIORITY_DEFAULT, false /*same_party*/);
EXPECT_TRUE(cc);
EXPECT_EQ(one_hour_ago, cc->LastAccessDate());
@@ -1765,7 +1904,7 @@ TEST(CanonicalCookieTest, CreateSanitizedCookie_Inputs) {
GURL("https://www.foo.com"), "A", "B", std::string(), "/foo",
base::Time(), one_hour_from_now, base::Time(), false /*secure*/,
false /*httponly*/, CookieSameSite::NO_RESTRICTION,
- COOKIE_PRIORITY_DEFAULT);
+ COOKIE_PRIORITY_DEFAULT, false /*same_party*/);
EXPECT_TRUE(cc);
EXPECT_EQ(one_hour_from_now, cc->ExpiryDate());
@@ -1774,7 +1913,7 @@ TEST(CanonicalCookieTest, CreateSanitizedCookie_Inputs) {
GURL("https://www.foo.com"), "A", "B", std::string(), "/foo",
base::Time(), base::Time(), base::Time(), true /*secure*/,
false /*httponly*/, CookieSameSite::NO_RESTRICTION,
- COOKIE_PRIORITY_DEFAULT);
+ COOKIE_PRIORITY_DEFAULT, false /*same_party*/);
EXPECT_TRUE(cc);
EXPECT_TRUE(cc->IsSecure());
@@ -1783,7 +1922,7 @@ TEST(CanonicalCookieTest, CreateSanitizedCookie_Inputs) {
GURL("https://www.foo.com"), "A", "B", std::string(), "/foo",
base::Time(), base::Time(), base::Time(), false /*secure*/,
true /*httponly*/, CookieSameSite::NO_RESTRICTION,
- COOKIE_PRIORITY_DEFAULT);
+ COOKIE_PRIORITY_DEFAULT, false /*same_party*/);
EXPECT_TRUE(cc);
EXPECT_TRUE(cc->IsHttpOnly());
@@ -1791,7 +1930,8 @@ TEST(CanonicalCookieTest, CreateSanitizedCookie_Inputs) {
cc = CanonicalCookie::CreateSanitizedCookie(
GURL("https://www.foo.com"), "A", "B", std::string(), "/foo",
base::Time(), base::Time(), base::Time(), false /*secure*/,
- false /*httponly*/, CookieSameSite::LAX_MODE, COOKIE_PRIORITY_DEFAULT);
+ false /*httponly*/, CookieSameSite::LAX_MODE, COOKIE_PRIORITY_DEFAULT,
+ false /*same_party*/);
EXPECT_TRUE(cc);
EXPECT_EQ(CookieSameSite::LAX_MODE, cc->SameSite());
@@ -1799,7 +1939,8 @@ TEST(CanonicalCookieTest, CreateSanitizedCookie_Inputs) {
cc = CanonicalCookie::CreateSanitizedCookie(
GURL("https://www.foo.com"), "A", "B", std::string(), "/foo",
base::Time(), base::Time(), base::Time(), false /*secure*/,
- false /*httponly*/, CookieSameSite::NO_RESTRICTION, COOKIE_PRIORITY_LOW);
+ false /*httponly*/, CookieSameSite::NO_RESTRICTION, COOKIE_PRIORITY_LOW,
+ false /*same_party*/);
EXPECT_TRUE(cc);
EXPECT_EQ(COOKIE_PRIORITY_LOW, cc->Priority());
@@ -1808,9 +1949,18 @@ TEST(CanonicalCookieTest, CreateSanitizedCookie_Inputs) {
GURL("https://www.foo.com"), "A", "B", "www.foo.com", "/foo",
base::Time(), base::Time(), base::Time(), false /*secure*/,
false /*httponly*/, CookieSameSite::NO_RESTRICTION,
- COOKIE_PRIORITY_DEFAULT);
+ COOKIE_PRIORITY_DEFAULT, false /*same_party*/);
EXPECT_TRUE(cc);
EXPECT_TRUE(cc->IsDomainCookie());
+
+ // SameParty
+ cc = CanonicalCookie::CreateSanitizedCookie(
+ GURL("https://www.foo.com"), "A", "B", std::string(), "/foo",
+ base::Time(), base::Time(), base::Time(), true /*secure*/,
+ false /*httponly*/, CookieSameSite::NO_RESTRICTION, COOKIE_PRIORITY_LOW,
+ true /*same_party*/);
+ EXPECT_TRUE(cc);
+ EXPECT_TRUE(cc->IsSameParty());
}
// Make sure sanitization and blocking of cookies works correctly.
@@ -1825,94 +1975,97 @@ TEST(CanonicalCookieTest, CreateSanitizedCookie_Logic) {
GURL("http://www.foo.com/foo"), "A", "B", std::string(), "/foo",
one_hour_ago, one_hour_from_now, base::Time(), false /*secure*/,
false /*httponly*/, CookieSameSite::NO_RESTRICTION,
- COOKIE_PRIORITY_DEFAULT));
+ COOKIE_PRIORITY_DEFAULT, false /*same_party*/));
EXPECT_TRUE(CanonicalCookie::CreateSanitizedCookie(
GURL("http://www.foo.com/bar"), "C", "D", "www.foo.com", "/",
two_hours_ago, base::Time(), one_hour_ago, false /*secure*/,
true /*httponly*/, CookieSameSite::NO_RESTRICTION,
- COOKIE_PRIORITY_DEFAULT));
+ COOKIE_PRIORITY_DEFAULT, false /*same_party*/));
EXPECT_TRUE(CanonicalCookie::CreateSanitizedCookie(
GURL("https://www.foo.com"), "E", "F", std::string(), std::string(),
base::Time(), base::Time(), base::Time(), true /*secure*/,
false /*httponly*/, CookieSameSite::NO_RESTRICTION,
- COOKIE_PRIORITY_DEFAULT));
+ COOKIE_PRIORITY_DEFAULT, false /*same_party*/));
// Test the file:// protocol.
EXPECT_TRUE(CanonicalCookie::CreateSanitizedCookie(
GURL("file:///"), "A", "B", std::string(), "/foo", one_hour_ago,
one_hour_from_now, base::Time(), false /*secure*/, false /*httponly*/,
- CookieSameSite::NO_RESTRICTION, COOKIE_PRIORITY_DEFAULT));
+ CookieSameSite::NO_RESTRICTION, COOKIE_PRIORITY_DEFAULT,
+ false /*same_party*/));
EXPECT_TRUE(CanonicalCookie::CreateSanitizedCookie(
GURL("file:///home/user/foo.txt"), "A", "B", std::string(), "/foo",
one_hour_ago, one_hour_from_now, base::Time(), false /*secure*/,
false /*httponly*/, CookieSameSite::NO_RESTRICTION,
- COOKIE_PRIORITY_DEFAULT));
+ COOKIE_PRIORITY_DEFAULT, false /*same_party*/));
EXPECT_FALSE(CanonicalCookie::CreateSanitizedCookie(
GURL("file:///home/user/foo.txt"), "A", "B", "home", "/foo", one_hour_ago,
one_hour_from_now, base::Time(), false /*secure*/, false /*httponly*/,
- CookieSameSite::NO_RESTRICTION, COOKIE_PRIORITY_DEFAULT));
+ CookieSameSite::NO_RESTRICTION, COOKIE_PRIORITY_DEFAULT,
+ false /*same_party*/));
// Test that malformed attributes fail to set the cookie.
EXPECT_FALSE(CanonicalCookie::CreateSanitizedCookie(
GURL("http://www.foo.com/foo"), " A", "B", std::string(), "/foo",
base::Time(), base::Time(), base::Time(), false /*secure*/,
false /*httponly*/, CookieSameSite::NO_RESTRICTION,
- COOKIE_PRIORITY_DEFAULT));
+ COOKIE_PRIORITY_DEFAULT, false /*same_party*/));
EXPECT_FALSE(CanonicalCookie::CreateSanitizedCookie(
GURL("http://www.foo.com/foo"), "A;", "B", std::string(), "/foo",
base::Time(), base::Time(), base::Time(), false /*secure*/,
false /*httponly*/, CookieSameSite::NO_RESTRICTION,
- COOKIE_PRIORITY_DEFAULT));
+ COOKIE_PRIORITY_DEFAULT, false /*same_party*/));
EXPECT_FALSE(CanonicalCookie::CreateSanitizedCookie(
GURL("http://www.foo.com/foo"), "A=", "B", std::string(), "/foo",
base::Time(), base::Time(), base::Time(), false /*secure*/,
false /*httponly*/, CookieSameSite::NO_RESTRICTION,
- COOKIE_PRIORITY_DEFAULT));
+ COOKIE_PRIORITY_DEFAULT, false /*same_party*/));
EXPECT_FALSE(CanonicalCookie::CreateSanitizedCookie(
GURL("http://www.foo.com/foo"), "A\x07", "B", std::string(), "/foo",
one_hour_ago, one_hour_from_now, base::Time(), false /*secure*/,
false /*httponly*/, CookieSameSite::NO_RESTRICTION,
- COOKIE_PRIORITY_DEFAULT));
+ COOKIE_PRIORITY_DEFAULT, false /*same_party*/));
EXPECT_FALSE(CanonicalCookie::CreateSanitizedCookie(
GURL("http://www.foo.com"), "A", " B", std::string(), "/foo",
base::Time(), base::Time(), base::Time(), false /*secure*/,
false /*httponly*/, CookieSameSite::NO_RESTRICTION,
- COOKIE_PRIORITY_DEFAULT));
+ COOKIE_PRIORITY_DEFAULT, false /*same_party*/));
EXPECT_FALSE(CanonicalCookie::CreateSanitizedCookie(
GURL("http://www.foo.com"), "A", "\x0fZ", std::string(), "/foo",
base::Time(), base::Time(), base::Time(), false /*secure*/,
false /*httponly*/, CookieSameSite::NO_RESTRICTION,
- COOKIE_PRIORITY_DEFAULT));
+ COOKIE_PRIORITY_DEFAULT, false /*same_party*/));
EXPECT_FALSE(CanonicalCookie::CreateSanitizedCookie(
GURL("http://www.foo.com"), "A", "B", "www.foo.com ", "/foo",
base::Time(), base::Time(), base::Time(), false /*secure*/,
false /*httponly*/, CookieSameSite::NO_RESTRICTION,
- COOKIE_PRIORITY_DEFAULT));
+ COOKIE_PRIORITY_DEFAULT, false /*same_party*/));
EXPECT_FALSE(CanonicalCookie::CreateSanitizedCookie(
GURL("http://www.foo.com/foo"), "A", "B", "foo.ozzzzzzle", "/foo",
base::Time(), base::Time(), base::Time(), false /*secure*/,
false /*httponly*/, CookieSameSite::NO_RESTRICTION,
- COOKIE_PRIORITY_DEFAULT));
+ COOKIE_PRIORITY_DEFAULT, false /*same_party*/));
EXPECT_FALSE(CanonicalCookie::CreateSanitizedCookie(
GURL("http://www.foo.com/foo"), "A", "B", std::string(), "foo",
base::Time(), base::Time(), base::Time(), false /*secure*/,
false /*httponly*/, CookieSameSite::NO_RESTRICTION,
- COOKIE_PRIORITY_DEFAULT));
+ COOKIE_PRIORITY_DEFAULT, false /*same_party*/));
EXPECT_FALSE(CanonicalCookie::CreateSanitizedCookie(
GURL("http://www.foo.com"), "A", "B", std::string(), "/foo ",
base::Time(), base::Time(), base::Time(), false /*secure*/,
false /*httponly*/, CookieSameSite::NO_RESTRICTION,
- COOKIE_PRIORITY_DEFAULT));
+ COOKIE_PRIORITY_DEFAULT, false /*same_party*/));
EXPECT_FALSE(CanonicalCookie::CreateSanitizedCookie(
GURL("http://www.foo.com/foo"), "A", "B", "%2Efoo.com", "/foo",
one_hour_ago, one_hour_from_now, base::Time(), false /*secure*/,
false /*httponly*/, CookieSameSite::NO_RESTRICTION,
- COOKIE_PRIORITY_DEFAULT));
+ COOKIE_PRIORITY_DEFAULT, false /*same_party*/));
EXPECT_FALSE(CanonicalCookie::CreateSanitizedCookie(
GURL("http://domaintest.%E3%81%BF%E3%82%93%E3%81%AA"), "A", "B",
"domaintest.%E3%81%BF%E3%82%93%E3%81%AA", "/foo", base::Time(),
base::Time(), base::Time(), false /*secure*/, false /*httponly*/,
- CookieSameSite::NO_RESTRICTION, COOKIE_PRIORITY_DEFAULT));
+ CookieSameSite::NO_RESTRICTION, COOKIE_PRIORITY_DEFAULT,
+ false /*same_party*/));
std::unique_ptr<CanonicalCookie> cc;
@@ -1922,7 +2075,7 @@ TEST(CanonicalCookieTest, CreateSanitizedCookie_Logic) {
GURL("http://www.foo.com/foo"), "A", "B", "www.foo.com", "/foo",
one_hour_ago, one_hour_from_now, base::Time(), false /*secure*/,
false /*httponly*/, CookieSameSite::NO_RESTRICTION,
- COOKIE_PRIORITY_DEFAULT);
+ COOKIE_PRIORITY_DEFAULT, false /*same_party*/);
ASSERT_TRUE(cc);
EXPECT_TRUE(cc->IsDomainCookie());
EXPECT_EQ(".www.foo.com", cc->Domain());
@@ -1931,7 +2084,7 @@ TEST(CanonicalCookieTest, CreateSanitizedCookie_Logic) {
GURL("http://www.foo.com/foo"), "A", "B", ".www.foo.com", "/foo",
one_hour_ago, one_hour_from_now, base::Time(), false /*secure*/,
false /*httponly*/, CookieSameSite::NO_RESTRICTION,
- COOKIE_PRIORITY_DEFAULT);
+ COOKIE_PRIORITY_DEFAULT, false /*same_party*/);
ASSERT_TRUE(cc);
EXPECT_TRUE(cc->IsDomainCookie());
EXPECT_EQ(".www.foo.com", cc->Domain());
@@ -1940,7 +2093,7 @@ TEST(CanonicalCookieTest, CreateSanitizedCookie_Logic) {
GURL("http://www.foo.com/foo"), "A", "B", ".foo.com", "/foo",
one_hour_ago, one_hour_from_now, base::Time(), false /*secure*/,
false /*httponly*/, CookieSameSite::NO_RESTRICTION,
- COOKIE_PRIORITY_DEFAULT);
+ COOKIE_PRIORITY_DEFAULT, false /*same_party*/);
ASSERT_TRUE(cc);
EXPECT_TRUE(cc->IsDomainCookie());
EXPECT_EQ(".foo.com", cc->Domain());
@@ -1949,7 +2102,7 @@ TEST(CanonicalCookieTest, CreateSanitizedCookie_Logic) {
GURL("http://www.foo.com/foo"), "A", "B", ".www2.www.foo.com", "/foo",
one_hour_ago, one_hour_from_now, base::Time(), false /*secure*/,
false /*httponly*/, CookieSameSite::NO_RESTRICTION,
- COOKIE_PRIORITY_DEFAULT);
+ COOKIE_PRIORITY_DEFAULT, false /*same_party*/);
EXPECT_FALSE(cc);
// Secure/URL Scheme mismatch.
@@ -1957,26 +2110,28 @@ TEST(CanonicalCookieTest, CreateSanitizedCookie_Logic) {
GURL("http://www.foo.com"), "A", "B", std::string(), "/foo ",
base::Time(), base::Time(), base::Time(), true /*secure*/,
false /*httponly*/, CookieSameSite::NO_RESTRICTION,
- COOKIE_PRIORITY_DEFAULT));
+ COOKIE_PRIORITY_DEFAULT, false /*same_party*/));
// Null creation date/non-null last access date conflict.
EXPECT_FALSE(CanonicalCookie::CreateSanitizedCookie(
GURL("http://www.foo.com"), "A", "B", std::string(), "/foo", base::Time(),
base::Time(), base::Time::Now(), false /*secure*/, false /*httponly*/,
- CookieSameSite::NO_RESTRICTION, COOKIE_PRIORITY_DEFAULT));
+ CookieSameSite::NO_RESTRICTION, COOKIE_PRIORITY_DEFAULT,
+ false /*same_party*/));
// Domain doesn't match URL
EXPECT_FALSE(CanonicalCookie::CreateSanitizedCookie(
GURL("http://www.foo.com"), "A", "B", "www.bar.com", "/", base::Time(),
base::Time(), base::Time(), false /*secure*/, false /*httponly*/,
- CookieSameSite::NO_RESTRICTION, COOKIE_PRIORITY_DEFAULT));
+ CookieSameSite::NO_RESTRICTION, COOKIE_PRIORITY_DEFAULT,
+ false /*same_party*/));
// Path with unusual characters escaped.
cc = CanonicalCookie::CreateSanitizedCookie(
GURL("http://www.foo.com"), "A", "B", std::string(), "/foo",
base::Time(), base::Time(), base::Time(), false /*secure*/,
false /*httponly*/, CookieSameSite::NO_RESTRICTION,
- COOKIE_PRIORITY_DEFAULT);
+ COOKIE_PRIORITY_DEFAULT, false /*same_party*/);
ASSERT_TRUE(cc);
EXPECT_EQ("/foo%7F", cc->Path());
@@ -1984,79 +2139,116 @@ TEST(CanonicalCookieTest, CreateSanitizedCookie_Logic) {
EXPECT_FALSE(CanonicalCookie::CreateSanitizedCookie(
GURL("http://www.foo.com"), "", "", std::string(), "/", base::Time(),
base::Time(), base::Time(), false /*secure*/, false /*httponly*/,
- CookieSameSite::NO_RESTRICTION, COOKIE_PRIORITY_DEFAULT));
+ CookieSameSite::NO_RESTRICTION, COOKIE_PRIORITY_DEFAULT,
+ false /*same_party*/));
// A __Secure- cookie must be Secure.
EXPECT_TRUE(CanonicalCookie::CreateSanitizedCookie(
GURL("https://www.foo.com"), "__Secure-A", "B", ".www.foo.com", "/",
two_hours_ago, one_hour_from_now, one_hour_ago, true, false,
- CookieSameSite::NO_RESTRICTION, CookiePriority::COOKIE_PRIORITY_DEFAULT));
+ CookieSameSite::NO_RESTRICTION, CookiePriority::COOKIE_PRIORITY_DEFAULT,
+ false));
EXPECT_FALSE(CanonicalCookie::CreateSanitizedCookie(
GURL("https://www.foo.com"), "__Secure-A", "B", ".www.foo.com", "/",
two_hours_ago, one_hour_from_now, one_hour_ago, false, false,
- CookieSameSite::NO_RESTRICTION, CookiePriority::COOKIE_PRIORITY_DEFAULT));
+ CookieSameSite::NO_RESTRICTION, CookiePriority::COOKIE_PRIORITY_DEFAULT,
+ false));
// A __Host- cookie must be Secure.
EXPECT_TRUE(CanonicalCookie::CreateSanitizedCookie(
GURL("https://www.foo.com"), "__Host-A", "B", std::string(), "/",
two_hours_ago, one_hour_from_now, one_hour_ago, true, false,
- CookieSameSite::NO_RESTRICTION, CookiePriority::COOKIE_PRIORITY_DEFAULT));
+ CookieSameSite::NO_RESTRICTION, CookiePriority::COOKIE_PRIORITY_DEFAULT,
+ false));
EXPECT_FALSE(CanonicalCookie::CreateSanitizedCookie(
GURL("https://www.foo.com"), "__Host-A", "B", std::string(), "/",
two_hours_ago, one_hour_from_now, one_hour_ago, false, false,
- CookieSameSite::NO_RESTRICTION, CookiePriority::COOKIE_PRIORITY_DEFAULT));
+ CookieSameSite::NO_RESTRICTION, CookiePriority::COOKIE_PRIORITY_DEFAULT,
+ false));
// A __Host- cookie must have path "/".
EXPECT_TRUE(CanonicalCookie::CreateSanitizedCookie(
GURL("https://www.foo.com"), "__Host-A", "B", std::string(), "/",
two_hours_ago, one_hour_from_now, one_hour_ago, true, false,
- CookieSameSite::NO_RESTRICTION, CookiePriority::COOKIE_PRIORITY_DEFAULT));
+ CookieSameSite::NO_RESTRICTION, CookiePriority::COOKIE_PRIORITY_DEFAULT,
+ false));
EXPECT_FALSE(CanonicalCookie::CreateSanitizedCookie(
GURL("https://www.foo.com"), "__Host-A", "B", std::string(), "/foo",
two_hours_ago, one_hour_from_now, one_hour_ago, true, false,
- CookieSameSite::NO_RESTRICTION, CookiePriority::COOKIE_PRIORITY_DEFAULT));
+ CookieSameSite::NO_RESTRICTION, CookiePriority::COOKIE_PRIORITY_DEFAULT,
+ false));
// A __Host- cookie must not specify a domain.
EXPECT_TRUE(CanonicalCookie::CreateSanitizedCookie(
GURL("https://www.foo.com"), "__Host-A", "B", std::string(), "/",
two_hours_ago, one_hour_from_now, one_hour_ago, true, false,
- CookieSameSite::NO_RESTRICTION, CookiePriority::COOKIE_PRIORITY_DEFAULT));
+ CookieSameSite::NO_RESTRICTION, CookiePriority::COOKIE_PRIORITY_DEFAULT,
+ false));
EXPECT_FALSE(CanonicalCookie::CreateSanitizedCookie(
GURL("https://www.foo.com"), "__Host-A", "B", ".www.foo.com", "/",
two_hours_ago, one_hour_from_now, one_hour_ago, true, false,
- CookieSameSite::NO_RESTRICTION, CookiePriority::COOKIE_PRIORITY_DEFAULT));
+ CookieSameSite::NO_RESTRICTION, CookiePriority::COOKIE_PRIORITY_DEFAULT,
+ false));
// Without __Host- prefix, this is a valid host cookie because it does not
// specify a domain.
EXPECT_TRUE(CanonicalCookie::CreateSanitizedCookie(
GURL("https://www.foo.com"), "A", "B", std::string(), "/", two_hours_ago,
one_hour_from_now, one_hour_ago, true, false,
- CookieSameSite::NO_RESTRICTION, CookiePriority::COOKIE_PRIORITY_DEFAULT));
+ CookieSameSite::NO_RESTRICTION, CookiePriority::COOKIE_PRIORITY_DEFAULT,
+ false));
// Without __Host- prefix, this is a valid domain (not host) cookie.
EXPECT_TRUE(CanonicalCookie::CreateSanitizedCookie(
GURL("https://www.foo.com"), "A", "B", ".www.foo.com", "/", two_hours_ago,
one_hour_from_now, one_hour_ago, true, false,
- CookieSameSite::NO_RESTRICTION, CookiePriority::COOKIE_PRIORITY_DEFAULT));
+ CookieSameSite::NO_RESTRICTION, CookiePriority::COOKIE_PRIORITY_DEFAULT,
+ false));
// The __Host- prefix should not prevent otherwise-valid host cookies from
// being accepted.
EXPECT_TRUE(CanonicalCookie::CreateSanitizedCookie(
GURL("https://127.0.0.1"), "A", "B", std::string(), "/", two_hours_ago,
one_hour_from_now, one_hour_ago, true, false,
- CookieSameSite::NO_RESTRICTION, CookiePriority::COOKIE_PRIORITY_DEFAULT));
+ CookieSameSite::NO_RESTRICTION, CookiePriority::COOKIE_PRIORITY_DEFAULT,
+ false));
EXPECT_TRUE(CanonicalCookie::CreateSanitizedCookie(
GURL("https://127.0.0.1"), "__Host-A", "B", std::string(), "/",
two_hours_ago, one_hour_from_now, one_hour_ago, true, false,
- CookieSameSite::NO_RESTRICTION, CookiePriority::COOKIE_PRIORITY_DEFAULT));
+ CookieSameSite::NO_RESTRICTION, CookiePriority::COOKIE_PRIORITY_DEFAULT,
+ false));
// Host cookies should not specify domain unless it is an IP address that
// matches the URL.
EXPECT_TRUE(CanonicalCookie::CreateSanitizedCookie(
GURL("https://127.0.0.1"), "A", "B", "127.0.0.1", "/", two_hours_ago,
one_hour_from_now, one_hour_ago, true, false,
- CookieSameSite::NO_RESTRICTION, CookiePriority::COOKIE_PRIORITY_DEFAULT));
+ CookieSameSite::NO_RESTRICTION, CookiePriority::COOKIE_PRIORITY_DEFAULT,
+ false));
EXPECT_TRUE(CanonicalCookie::CreateSanitizedCookie(
GURL("https://127.0.0.1"), "__Host-A", "B", "127.0.0.1", "/",
two_hours_ago, one_hour_from_now, one_hour_ago, true, false,
- CookieSameSite::NO_RESTRICTION, CookiePriority::COOKIE_PRIORITY_DEFAULT));
+ CookieSameSite::NO_RESTRICTION, CookiePriority::COOKIE_PRIORITY_DEFAULT,
+ false));
+
+ // SameParty attribute requires Secure and forbids SameSite=Strict.
+ EXPECT_TRUE(CanonicalCookie::CreateSanitizedCookie(
+ GURL("https://www.foo.com"), "A", "B", ".www.foo.com", "/", two_hours_ago,
+ one_hour_from_now, one_hour_ago, true /*secure*/, false,
+ CookieSameSite::NO_RESTRICTION, CookiePriority::COOKIE_PRIORITY_DEFAULT,
+ true /*same_party*/));
+ EXPECT_FALSE(CanonicalCookie::CreateSanitizedCookie(
+ GURL("https://www.foo.com"), "A", "B", ".www.foo.com", "/", two_hours_ago,
+ one_hour_from_now, one_hour_ago, false /*secure*/, false,
+ CookieSameSite::LAX_MODE, CookiePriority::COOKIE_PRIORITY_DEFAULT,
+ true /*same_party*/));
+ EXPECT_FALSE(CanonicalCookie::CreateSanitizedCookie(
+ GURL("https://www.foo.com"), "A", "B", ".www.foo.com", "/", two_hours_ago,
+ one_hour_from_now, one_hour_ago, true /*secure*/, false,
+ CookieSameSite::STRICT_MODE, CookiePriority::COOKIE_PRIORITY_DEFAULT,
+ true /*same_party*/));
+ EXPECT_FALSE(CanonicalCookie::CreateSanitizedCookie(
+ GURL("https://www.foo.com"), "A", "B", ".www.foo.com", "/", two_hours_ago,
+ one_hour_from_now, one_hour_ago, false /*secure*/, false,
+ CookieSameSite::STRICT_MODE, CookiePriority::COOKIE_PRIORITY_DEFAULT,
+ true /*same_party*/));
// Check that CreateSanitizedCookie can gracefully fail on inputs that would
// crash cookie_util::GetCookieDomainWithString due to failing
@@ -2066,30 +2258,30 @@ TEST(CanonicalCookieTest, CreateSanitizedCookie_Logic) {
EXPECT_FALSE(CanonicalCookie::CreateSanitizedCookie(
GURL("http://..."), "A", "B", "...", "/", base::Time(), base::Time(),
base::Time(), false /*secure*/, false /*httponly*/,
- CookieSameSite::NO_RESTRICTION, COOKIE_PRIORITY_DEFAULT));
+ CookieSameSite::NO_RESTRICTION, COOKIE_PRIORITY_DEFAULT, false));
EXPECT_FALSE(CanonicalCookie::CreateSanitizedCookie(
GURL("http://."), "A", "B", std::string(), "/", base::Time(),
base::Time(), base::Time(), false /*secure*/, false /*httponly*/,
- CookieSameSite::NO_RESTRICTION, COOKIE_PRIORITY_DEFAULT));
+ CookieSameSite::NO_RESTRICTION, COOKIE_PRIORITY_DEFAULT, false));
EXPECT_FALSE(CanonicalCookie::CreateSanitizedCookie(
GURL("http://.chromium.org"), "A", "B", ".chromium.org", "/",
base::Time(), base::Time(), base::Time(), false /*secure*/,
false /*httponly*/, CookieSameSite::NO_RESTRICTION,
- COOKIE_PRIORITY_DEFAULT));
+ COOKIE_PRIORITY_DEFAULT, false));
// Check that a file URL with an IPv6 host, and matching IPv6 domain, are
// valid.
EXPECT_TRUE(CanonicalCookie::CreateSanitizedCookie(
GURL("file://[A::]"), "A", "B", "[A::]", "", base::Time(), base::Time(),
base::Time(), false /*secure*/, false /*httponly*/,
- CookieSameSite::NO_RESTRICTION, COOKIE_PRIORITY_DEFAULT));
+ CookieSameSite::NO_RESTRICTION, COOKIE_PRIORITY_DEFAULT, false));
// On Windows, URLs beginning with two backslashes are considered file
// URLs. On other platforms, they are invalid.
auto double_backslash_ipv6_cookie = CanonicalCookie::CreateSanitizedCookie(
GURL("\\\\[A::]"), "A", "B", "[A::]", "", base::Time(), base::Time(),
base::Time(), false /*secure*/, false /*httponly*/,
- CookieSameSite::NO_RESTRICTION, COOKIE_PRIORITY_DEFAULT);
+ CookieSameSite::NO_RESTRICTION, COOKIE_PRIORITY_DEFAULT, false);
#if defined(OS_WIN)
EXPECT_TRUE(double_backslash_ipv6_cookie);
EXPECT_TRUE(double_backslash_ipv6_cookie->IsCanonical());
@@ -2098,6 +2290,69 @@ TEST(CanonicalCookieTest, CreateSanitizedCookie_Logic) {
#endif
}
+TEST(CanonicalCookieTest, FromStorage) {
+ base::Time two_hours_ago = base::Time::Now() - base::TimeDelta::FromHours(2);
+ base::Time one_hour_ago = base::Time::Now() - base::TimeDelta::FromHours(1);
+ base::Time one_hour_from_now =
+ base::Time::Now() + base::TimeDelta::FromHours(1);
+
+ std::unique_ptr<CanonicalCookie> cc = CanonicalCookie::FromStorage(
+ "A", "B", "www.foo.com", "/bar", two_hours_ago, one_hour_from_now,
+ one_hour_ago, false /*secure*/, false /*httponly*/,
+ CookieSameSite::NO_RESTRICTION, COOKIE_PRIORITY_DEFAULT,
+ false /*same_party*/, CookieSourceScheme::kSecure, 87);
+ EXPECT_TRUE(cc);
+ EXPECT_EQ("A", cc->Name());
+ EXPECT_EQ("B", cc->Value());
+ EXPECT_EQ("www.foo.com", cc->Domain());
+ EXPECT_EQ("/bar", cc->Path());
+ EXPECT_EQ(two_hours_ago, cc->CreationDate());
+ EXPECT_EQ(one_hour_ago, cc->LastAccessDate());
+ EXPECT_EQ(one_hour_from_now, cc->ExpiryDate());
+ EXPECT_FALSE(cc->IsSecure());
+ EXPECT_FALSE(cc->IsHttpOnly());
+ EXPECT_EQ(CookieSameSite::NO_RESTRICTION, cc->SameSite());
+ EXPECT_EQ(COOKIE_PRIORITY_MEDIUM, cc->Priority());
+ EXPECT_EQ(CookieSourceScheme::kSecure, cc->SourceScheme());
+ EXPECT_FALSE(cc->IsDomainCookie());
+ EXPECT_EQ(cc->SourcePort(), 87);
+
+ // Should return nullptr when the cookie is not canonical.
+ // In this case the cookie is not canonical because its name attribute
+ // contains a newline character.
+ EXPECT_FALSE(CanonicalCookie::FromStorage(
+ "A\n", "B", "www.foo.com", "/bar", two_hours_ago, one_hour_from_now,
+ one_hour_ago, false /*secure*/, false /*httponly*/,
+ CookieSameSite::NO_RESTRICTION, COOKIE_PRIORITY_DEFAULT,
+ false /*same_party*/, CookieSourceScheme::kSecure, 80));
+
+ // If the port information gets corrupted out of the valid range
+ // FromStorage() should result in a PORT_INVALID.
+ std::unique_ptr<CanonicalCookie> cc2 = CanonicalCookie::FromStorage(
+ "A", "B", "www.foo.com", "/bar", two_hours_ago, one_hour_from_now,
+ one_hour_ago, false /*secure*/, false /*httponly*/,
+ CookieSameSite::NO_RESTRICTION, COOKIE_PRIORITY_DEFAULT,
+ false /*same_party*/, CookieSourceScheme::kSecure, 80000);
+
+ EXPECT_EQ(cc2->SourcePort(), url::PORT_INVALID);
+
+ // Test port edge cases: unspecified.
+ std::unique_ptr<CanonicalCookie> cc3 = CanonicalCookie::FromStorage(
+ "A", "B", "www.foo.com", "/bar", two_hours_ago, one_hour_from_now,
+ one_hour_ago, false /*secure*/, false /*httponly*/,
+ CookieSameSite::NO_RESTRICTION, COOKIE_PRIORITY_DEFAULT,
+ false /*same_party*/, CookieSourceScheme::kSecure, url::PORT_UNSPECIFIED);
+ EXPECT_EQ(cc3->SourcePort(), url::PORT_UNSPECIFIED);
+
+ // Test port edge cases: invalid.
+ std::unique_ptr<CanonicalCookie> cc4 = CanonicalCookie::FromStorage(
+ "A", "B", "www.foo.com", "/bar", two_hours_ago, one_hour_from_now,
+ one_hour_ago, false /*secure*/, false /*httponly*/,
+ CookieSameSite::NO_RESTRICTION, COOKIE_PRIORITY_DEFAULT,
+ false /*same_party*/, CookieSourceScheme::kSecure, url::PORT_INVALID);
+ EXPECT_EQ(cc4->SourcePort(), url::PORT_INVALID);
+}
+
TEST(CanonicalCookieTest, IsSetPermittedInContext) {
GURL url("http://www.example.com/test");
base::Time current_time = base::Time::Now();
@@ -2105,11 +2360,11 @@ TEST(CanonicalCookieTest, IsSetPermittedInContext) {
CanonicalCookie cookie_scriptable(
"A", "2", "www.example.com", "/test", current_time, base::Time(),
base::Time(), true /*secure*/, false /*httponly*/,
- CookieSameSite::NO_RESTRICTION, COOKIE_PRIORITY_DEFAULT);
+ CookieSameSite::NO_RESTRICTION, COOKIE_PRIORITY_DEFAULT, false);
CanonicalCookie cookie_httponly(
"A", "2", "www.example.com", "/test", current_time, base::Time(),
base::Time(), true /*secure*/, true /*httponly*/,
- CookieSameSite::NO_RESTRICTION, COOKIE_PRIORITY_DEFAULT);
+ CookieSameSite::NO_RESTRICTION, COOKIE_PRIORITY_DEFAULT, false);
CookieOptions context_script;
CookieOptions context_network;
@@ -2158,7 +2413,7 @@ TEST(CanonicalCookieTest, IsSetPermittedInContext) {
CanonicalCookie cookie_same_site_unrestricted(
"A", "2", "www.example.com", "/test", current_time, base::Time(),
base::Time(), true /*secure*/, false /*httponly*/,
- CookieSameSite::NO_RESTRICTION, COOKIE_PRIORITY_DEFAULT);
+ CookieSameSite::NO_RESTRICTION, COOKIE_PRIORITY_DEFAULT, false);
EXPECT_TRUE(cookie_same_site_unrestricted
.IsSetPermittedInContext(context_cross_site)
@@ -2224,7 +2479,7 @@ TEST(CanonicalCookieTest, IsSetPermittedInContext) {
CanonicalCookie cookie_same_site_lax(
"A", "2", "www.example.com", "/test", current_time, base::Time(),
base::Time(), true /*secure*/, false /*httponly*/,
- CookieSameSite::LAX_MODE, COOKIE_PRIORITY_DEFAULT);
+ CookieSameSite::LAX_MODE, COOKIE_PRIORITY_DEFAULT, false);
EXPECT_TRUE(cookie_same_site_lax.IsSetPermittedInContext(context_cross_site)
.status.HasExactlyExclusionReasonsForTesting(
@@ -2298,7 +2553,7 @@ TEST(CanonicalCookieTest, IsSetPermittedInContext) {
CanonicalCookie cookie_same_site_strict(
"A", "2", "www.example.com", "/test", current_time, base::Time(),
base::Time(), true /*secure*/, false /*httponly*/,
- CookieSameSite::STRICT_MODE, COOKIE_PRIORITY_DEFAULT);
+ CookieSameSite::STRICT_MODE, COOKIE_PRIORITY_DEFAULT, false);
// TODO(morlovich): Do compatibility testing on whether set of strict in lax
// context really should be accepted.
@@ -2400,7 +2655,7 @@ TEST(CanonicalCookieTest, IsSetPermittedInContext) {
CanonicalCookie cookie_same_site_unspecified(
"A", "2", "www.example.com", "/test", current_time, base::Time(),
base::Time(), true /*secure*/, false /*httponly*/,
- CookieSameSite::UNSPECIFIED, COOKIE_PRIORITY_DEFAULT);
+ CookieSameSite::UNSPECIFIED, COOKIE_PRIORITY_DEFAULT, false);
{
base::test::ScopedFeatureList feature_list;
@@ -2503,7 +2758,7 @@ TEST(CanonicalCookieTest, IsSetPermittedEffectiveSameSite) {
CanonicalCookie cookie_no_restriction(
"A", "2", "www.example.com", "/test", current_time, base::Time(),
base::Time(), true /*secure*/, false /*httponly*/,
- CookieSameSite::NO_RESTRICTION, COOKIE_PRIORITY_DEFAULT);
+ CookieSameSite::NO_RESTRICTION, COOKIE_PRIORITY_DEFAULT, false);
EXPECT_EQ(
cookie_no_restriction
@@ -2516,7 +2771,7 @@ TEST(CanonicalCookieTest, IsSetPermittedEffectiveSameSite) {
CanonicalCookie cookie_lax("A", "2", "www.example.com", "/test", current_time,
base::Time(), base::Time(), true /*secure*/,
false /*httponly*/, CookieSameSite::LAX_MODE,
- COOKIE_PRIORITY_DEFAULT);
+ COOKIE_PRIORITY_DEFAULT, false);
EXPECT_EQ(
cookie_lax
@@ -2529,7 +2784,7 @@ TEST(CanonicalCookieTest, IsSetPermittedEffectiveSameSite) {
CanonicalCookie cookie_strict(
"A", "2", "www.example.com", "/test", current_time, base::Time(),
base::Time(), true /*secure*/, false /*httponly*/,
- CookieSameSite::STRICT_MODE, COOKIE_PRIORITY_DEFAULT);
+ CookieSameSite::STRICT_MODE, COOKIE_PRIORITY_DEFAULT, false);
EXPECT_EQ(
cookie_strict
@@ -2543,11 +2798,11 @@ TEST(CanonicalCookieTest, IsSetPermittedEffectiveSameSite) {
CanonicalCookie cookie_old_unspecified(
"A", "2", "www.example.com", "/test", creation_time, base::Time(),
base::Time(), true /*secure*/, false /*httponly*/,
- CookieSameSite::UNSPECIFIED, COOKIE_PRIORITY_DEFAULT);
+ CookieSameSite::UNSPECIFIED, COOKIE_PRIORITY_DEFAULT, false);
CanonicalCookie cookie_unspecified(
"A", "2", "www.example.com", "/test", current_time, base::Time(),
base::Time(), true /*secure*/, false /*httponly*/,
- CookieSameSite::UNSPECIFIED, COOKIE_PRIORITY_DEFAULT);
+ CookieSameSite::UNSPECIFIED, COOKIE_PRIORITY_DEFAULT, false);
EXPECT_EQ(
cookie_old_unspecified
diff --git a/chromium/net/cookies/cookie_constants.cc b/chromium/net/cookies/cookie_constants.cc
index bf8dd08c555..117fe0c90f5 100644
--- a/chromium/net/cookies/cookie_constants.cc
+++ b/chromium/net/cookies/cookie_constants.cc
@@ -4,6 +4,7 @@
#include "net/cookies/cookie_constants.h"
+#include "base/metrics/histogram_functions.h"
#include "base/metrics/histogram_macros.h"
#include "base/notreached.h"
#include "base/strings/string_util.h"
@@ -97,8 +98,200 @@ CookieSameSite StringToCookieSameSite(const std::string& same_site,
return samesite;
}
-void RecordCookieSameSiteAttributeValueHistogram(CookieSameSiteString value) {
+void RecordCookieSameSiteAttributeValueHistogram(CookieSameSiteString value,
+ bool is_cookie_same_party) {
UMA_HISTOGRAM_ENUMERATION("Cookie.SameSiteAttributeValue", value);
+ if (is_cookie_same_party) {
+ base::UmaHistogramEnumeration(
+ "Cookie.SamePartyCookieSameSiteAttributeValue", value);
+ }
+}
+
+CookiePort ReducePortRangeForCookieHistogram(const int port) {
+ switch (port) {
+ case 80:
+ return CookiePort::k80;
+ case 81:
+ return CookiePort::k81;
+ case 82:
+ return CookiePort::k82;
+ case 83:
+ return CookiePort::k83;
+ case 84:
+ return CookiePort::k84;
+ case 85:
+ return CookiePort::k85;
+ case 443:
+ return CookiePort::k443;
+ case 444:
+ return CookiePort::k444;
+ case 445:
+ return CookiePort::k445;
+ case 446:
+ return CookiePort::k446;
+ case 447:
+ return CookiePort::k447;
+ case 448:
+ return CookiePort::k448;
+ case 3000:
+ return CookiePort::k3000;
+ case 3001:
+ return CookiePort::k3001;
+ case 3002:
+ return CookiePort::k3002;
+ case 3003:
+ return CookiePort::k3003;
+ case 3004:
+ return CookiePort::k3004;
+ case 3005:
+ return CookiePort::k3005;
+ case 4200:
+ return CookiePort::k4200;
+ case 4201:
+ return CookiePort::k4201;
+ case 4202:
+ return CookiePort::k4202;
+ case 4203:
+ return CookiePort::k4203;
+ case 4204:
+ return CookiePort::k4204;
+ case 4205:
+ return CookiePort::k4205;
+ case 5000:
+ return CookiePort::k5000;
+ case 5001:
+ return CookiePort::k5001;
+ case 5002:
+ return CookiePort::k5002;
+ case 5003:
+ return CookiePort::k5003;
+ case 5004:
+ return CookiePort::k5004;
+ case 5005:
+ return CookiePort::k5005;
+ case 7000:
+ return CookiePort::k7000;
+ case 7001:
+ return CookiePort::k7001;
+ case 7002:
+ return CookiePort::k7002;
+ case 7003:
+ return CookiePort::k7003;
+ case 7004:
+ return CookiePort::k7004;
+ case 7005:
+ return CookiePort::k7005;
+ case 8000:
+ return CookiePort::k8000;
+ case 8001:
+ return CookiePort::k8001;
+ case 8002:
+ return CookiePort::k8002;
+ case 8003:
+ return CookiePort::k8003;
+ case 8004:
+ return CookiePort::k8004;
+ case 8005:
+ return CookiePort::k8005;
+ case 8080:
+ return CookiePort::k8080;
+ case 8081:
+ return CookiePort::k8081;
+ case 8082:
+ return CookiePort::k8082;
+ case 8083:
+ return CookiePort::k8083;
+ case 8084:
+ return CookiePort::k8084;
+ case 8085:
+ return CookiePort::k8085;
+ case 8090:
+ return CookiePort::k8090;
+ case 8091:
+ return CookiePort::k8091;
+ case 8092:
+ return CookiePort::k8092;
+ case 8093:
+ return CookiePort::k8093;
+ case 8094:
+ return CookiePort::k8094;
+ case 8095:
+ return CookiePort::k8095;
+ case 8100:
+ return CookiePort::k8100;
+ case 8101:
+ return CookiePort::k8101;
+ case 8102:
+ return CookiePort::k8102;
+ case 8103:
+ return CookiePort::k8103;
+ case 8104:
+ return CookiePort::k8104;
+ case 8105:
+ return CookiePort::k8105;
+ case 8200:
+ return CookiePort::k8200;
+ case 8201:
+ return CookiePort::k8201;
+ case 8202:
+ return CookiePort::k8202;
+ case 8203:
+ return CookiePort::k8203;
+ case 8204:
+ return CookiePort::k8204;
+ case 8205:
+ return CookiePort::k8205;
+ case 8443:
+ return CookiePort::k8443;
+ case 8444:
+ return CookiePort::k8444;
+ case 8445:
+ return CookiePort::k8445;
+ case 8446:
+ return CookiePort::k8446;
+ case 8447:
+ return CookiePort::k8447;
+ case 8448:
+ return CookiePort::k8448;
+ case 8888:
+ return CookiePort::k8888;
+ case 8889:
+ return CookiePort::k8889;
+ case 8890:
+ return CookiePort::k8890;
+ case 8891:
+ return CookiePort::k8891;
+ case 8892:
+ return CookiePort::k8892;
+ case 8893:
+ return CookiePort::k8893;
+ case 9000:
+ return CookiePort::k9000;
+ case 9001:
+ return CookiePort::k9001;
+ case 9002:
+ return CookiePort::k9002;
+ case 9003:
+ return CookiePort::k9003;
+ case 9004:
+ return CookiePort::k9004;
+ case 9005:
+ return CookiePort::k9005;
+ case 9090:
+ return CookiePort::k9090;
+ case 9091:
+ return CookiePort::k9091;
+ case 9092:
+ return CookiePort::k9092;
+ case 9093:
+ return CookiePort::k9093;
+ case 9094:
+ return CookiePort::k9094;
+ case 9095:
+ return CookiePort::k9095;
+ default:
+ return CookiePort::kOther;
+ }
}
} // namespace net
diff --git a/chromium/net/cookies/cookie_constants.h b/chromium/net/cookies/cookie_constants.h
index 8397a471a8b..8fb0df7e5ff 100644
--- a/chromium/net/cookies/cookie_constants.h
+++ b/chromium/net/cookies/cookie_constants.h
@@ -95,6 +95,125 @@ enum class CookieSourceScheme {
kMaxValue = kSecure // Keep as the last value.
};
+enum class CookiePort {
+ // DO NOT REORDER OR RENUMBER. These are used for histograms.
+
+ // Potentially interesting port values for cookies for use with histograms.
+
+ // Not a port explicitly listed below, including invalid ports (-1, 65536,
+ // etc).
+ kOther = 0,
+ // HTTP
+ k80 = 1,
+ k81 = 2,
+ k82 = 3,
+ k83 = 4,
+ k84 = 5,
+ k85 = 6,
+ // HTTPS
+ k443 = 7,
+ k444 = 8,
+ k445 = 9,
+ k446 = 10,
+ k447 = 11,
+ k448 = 12,
+ // JS Framework
+ k3000 = 13,
+ k3001 = 14,
+ k3002 = 15,
+ k3003 = 16,
+ k3004 = 17,
+ k3005 = 18,
+ // JS Framework
+ k4200 = 19,
+ k4201 = 20,
+ k4202 = 21,
+ k4203 = 22,
+ k4204 = 23,
+ k4205 = 24,
+ // JS Framework
+ k5000 = 25,
+ k5001 = 26,
+ k5002 = 27,
+ k5003 = 28,
+ k5004 = 29,
+ k5005 = 30,
+ // Common Dev Ports
+ k7000 = 31,
+ k7001 = 32,
+ k7002 = 33,
+ k7003 = 34,
+ k7004 = 35,
+ k7005 = 36,
+ // HTTP
+ k8000 = 37,
+ k8001 = 38,
+ k8002 = 39,
+ k8003 = 40,
+ k8004 = 41,
+ k8005 = 42,
+ // HTTP
+ k8080 = 43,
+ k8081 = 44,
+ k8082 = 45,
+ k8083 = 46,
+ k8084 = 47,
+ k8085 = 48,
+ // HTTP
+ k8090 = 49,
+ k8091 = 50,
+ k8092 = 51,
+ k8093 = 52,
+ k8094 = 53,
+ k8095 = 54,
+ // JS Framework
+ k8100 = 55,
+ k8101 = 56,
+ k8102 = 57,
+ k8103 = 58,
+ k8104 = 59,
+ k8105 = 60,
+ // JS Framework
+ k8200 = 61,
+ k8201 = 62,
+ k8202 = 63,
+ k8203 = 64,
+ k8204 = 65,
+ k8205 = 66,
+ // HTTP(S)
+ k8443 = 67,
+ k8444 = 68,
+ k8445 = 69,
+ k8446 = 70,
+ k8447 = 71,
+ k8448 = 72,
+ // HTTP
+ k8888 = 73,
+ k8889 = 74,
+ k8890 = 75,
+ k8891 = 76,
+ k8892 = 77,
+ k8893 = 78,
+ // Common Dev Ports
+ k9000 = 79,
+ k9001 = 80,
+ k9002 = 81,
+ k9003 = 82,
+ k9004 = 83,
+ k9005 = 84,
+ // HTTP
+ k9090 = 85,
+ k9091 = 86,
+ k9092 = 87,
+ k9093 = 88,
+ k9094 = 89,
+ k9095 = 90,
+
+ // Keep as last value.
+ kMaxValue = k9095
+
+};
+
// Returns the Set-Cookie header priority token corresponding to |priority|.
NET_EXPORT std::string CookiePriorityToString(CookiePriority priority);
@@ -116,7 +235,13 @@ StringToCookieSameSite(const std::string& same_site,
CookieSameSiteString* samesite_string = nullptr);
NET_EXPORT void RecordCookieSameSiteAttributeValueHistogram(
- CookieSameSiteString value);
+ CookieSameSiteString value,
+ bool is_cookie_same_party = false);
+
+// This function reduces the 65535 available TCP port values down to a <100
+// potentially interesting values that cookies could be set by or sent to. This
+// is because UMA cannot handle the full range.
+NET_EXPORT CookiePort ReducePortRangeForCookieHistogram(const int port);
} // namespace net
diff --git a/chromium/net/cookies/cookie_constants_unittest.cc b/chromium/net/cookies/cookie_constants_unittest.cc
index 8fab6e292c9..a66a3bbbe7b 100644
--- a/chromium/net/cookies/cookie_constants_unittest.cc
+++ b/chromium/net/cookies/cookie_constants_unittest.cc
@@ -62,4 +62,41 @@ TEST(CookieConstantsTest, TestCookieSameSite) {
}
}
+TEST(CookieConstantsTest, TestReducePortRangeForCookieHistogram) {
+ struct TestData {
+ int input_port;
+ CookiePort expected_enum;
+ };
+
+ const TestData kTestValues[] = {
+ {-1234 /* Invalid port. */, CookiePort::kOther},
+ {0 /* Invalid port. */, CookiePort::kOther},
+ {1 /* Valid but outside range. */, CookiePort::kOther},
+ {79 /* Valid but outside range. */, CookiePort::kOther},
+ {80, CookiePort::k80},
+ {445, CookiePort::k445},
+ {3001, CookiePort::k3001},
+ {4200, CookiePort::k4200},
+ {5002, CookiePort::k5002},
+ {7003, CookiePort::k7003},
+ {8001, CookiePort::k8001},
+ {8080, CookiePort::k8080},
+ {8086 /* Valid but outside range. */, CookiePort::kOther},
+ {8095, CookiePort::k8095},
+ {8100, CookiePort::k8100},
+ {8201, CookiePort::k8201},
+ {8445, CookiePort::k8445},
+ {8888, CookiePort::k8888},
+ {9004, CookiePort::k9004},
+ {9091, CookiePort::k9091},
+ {65535 /* Valid but outside range. */, CookiePort::kOther},
+ {655356 /* Invalid port. */, CookiePort::kOther},
+ };
+
+ for (const auto& value : kTestValues) {
+ EXPECT_EQ(value.expected_enum,
+ ReducePortRangeForCookieHistogram(value.input_port));
+ }
+}
+
} // namespace net
diff --git a/chromium/net/cookies/cookie_deletion_info_unittest.cc b/chromium/net/cookies/cookie_deletion_info_unittest.cc
index 39131b50175..ff629f91223 100644
--- a/chromium/net/cookies/cookie_deletion_info_unittest.cc
+++ b/chromium/net/cookies/cookie_deletion_info_unittest.cc
@@ -90,7 +90,8 @@ TEST(CookieDeletionInfoTest, CookieDeletionInfoMatchSessionControl) {
/*secure=*/true,
/*httponly=*/false,
CookieSameSite::NO_RESTRICTION,
- CookiePriority::COOKIE_PRIORITY_DEFAULT);
+ CookiePriority::COOKIE_PRIORITY_DEFAULT,
+ /*sameparty=*/false);
CanonicalCookie session_cookie(
"session-cookie", "session-value", "session-domain", "session-path",
@@ -99,7 +100,8 @@ TEST(CookieDeletionInfoTest, CookieDeletionInfoMatchSessionControl) {
/*last_access=*/base::Time::Now(),
/*secure=*/true,
/*httponly=*/false, CookieSameSite::NO_RESTRICTION,
- CookiePriority::COOKIE_PRIORITY_DEFAULT);
+ CookiePriority::COOKIE_PRIORITY_DEFAULT,
+ /*sameparty=*/false);
CookieDeletionInfo delete_info;
EXPECT_TRUE(delete_info.Matches(persistent_cookie));
@@ -125,7 +127,8 @@ TEST(CookieDeletionInfoTest, CookieDeletionInfoMatchHost) {
/*secure=*/true,
/*httponly=*/false,
CookieSameSite::NO_RESTRICTION,
- CookiePriority::COOKIE_PRIORITY_DEFAULT);
+ CookiePriority::COOKIE_PRIORITY_DEFAULT,
+ /*sameparty=*/false);
CanonicalCookie host_cookie("host-cookie", "host-cookie-value",
/*domain=*/"thehost.hosting.com", "/path",
@@ -135,7 +138,8 @@ TEST(CookieDeletionInfoTest, CookieDeletionInfoMatchHost) {
/*secure=*/true,
/*httponly=*/false,
CookieSameSite::NO_RESTRICTION,
- CookiePriority::COOKIE_PRIORITY_DEFAULT);
+ CookiePriority::COOKIE_PRIORITY_DEFAULT,
+ /*sameparty=*/false);
EXPECT_TRUE(domain_cookie.IsDomainCookie());
EXPECT_TRUE(host_cookie.IsHostCookie());
@@ -165,7 +169,8 @@ TEST(CookieDeletionInfoTest, CookieDeletionInfoMatchName) {
/*last_access=*/base::Time::Now(),
/*secure=*/true,
/*httponly=*/false, CookieSameSite::NO_RESTRICTION,
- CookiePriority::COOKIE_PRIORITY_DEFAULT);
+ CookiePriority::COOKIE_PRIORITY_DEFAULT,
+ /*sameparty=*/false);
CanonicalCookie cookie2("cookie2-name", "cookie2-value",
/*domain=*/".example.com", "/path",
/*creation=*/base::Time::Now(),
@@ -173,7 +178,8 @@ TEST(CookieDeletionInfoTest, CookieDeletionInfoMatchName) {
/*last_access=*/base::Time::Now(),
/*secure=*/true,
/*httponly=*/false, CookieSameSite::NO_RESTRICTION,
- CookiePriority::COOKIE_PRIORITY_DEFAULT);
+ CookiePriority::COOKIE_PRIORITY_DEFAULT,
+ /*sameparty=*/false);
CookieDeletionInfo delete_info;
delete_info.name = "cookie1-name";
@@ -189,7 +195,8 @@ TEST(CookieDeletionInfoTest, CookieDeletionInfoMatchValue) {
/*last_access=*/base::Time::Now(),
/*secure=*/true,
/*httponly=*/false, CookieSameSite::NO_RESTRICTION,
- CookiePriority::COOKIE_PRIORITY_DEFAULT);
+ CookiePriority::COOKIE_PRIORITY_DEFAULT,
+ /*sameparty=*/false);
CanonicalCookie cookie2("cookie2-name", "cookie2-value",
/*domain=*/".example.com", "/path",
/*creation=*/base::Time::Now(),
@@ -197,7 +204,8 @@ TEST(CookieDeletionInfoTest, CookieDeletionInfoMatchValue) {
/*last_access=*/base::Time::Now(),
/*secure=*/true,
/*httponly=*/false, CookieSameSite::NO_RESTRICTION,
- CookiePriority::COOKIE_PRIORITY_DEFAULT);
+ CookiePriority::COOKIE_PRIORITY_DEFAULT,
+ /*sameparty=*/false);
CookieDeletionInfo delete_info;
delete_info.value_for_testing = "cookie2-value";
@@ -213,7 +221,8 @@ TEST(CookieDeletionInfoTest, CookieDeletionInfoMatchUrl) {
/*last_access=*/base::Time::Now(),
/*secure=*/true,
/*httponly=*/false, CookieSameSite::NO_RESTRICTION,
- CookiePriority::COOKIE_PRIORITY_DEFAULT);
+ CookiePriority::COOKIE_PRIORITY_DEFAULT,
+ /*sameparty=*/false);
CookieDeletionInfo delete_info;
delete_info.url = GURL("https://www.example.com/path");
@@ -242,7 +251,8 @@ TEST(CookieDeletionInfoTest, CookieDeletionInfoDomainMatchesDomain) {
/*secure=*/true,
/*httponly=*/false,
/*same_site=*/CookieSameSite::NO_RESTRICTION,
- /*priority=*/CookiePriority::COOKIE_PRIORITY_DEFAULT);
+ /*priority=*/CookiePriority::COOKIE_PRIORITY_DEFAULT,
+ /*sameparty=*/false);
return cookie;
};
@@ -278,7 +288,8 @@ TEST(CookieDeletionInfoTest, CookieDeletionInfoMatchesDomainList) {
/*secure=*/false,
/*httponly=*/false,
/*same_site=*/CookieSameSite::NO_RESTRICTION,
- /*priority=*/CookiePriority::COOKIE_PRIORITY_DEFAULT);
+ /*priority=*/CookiePriority::COOKIE_PRIORITY_DEFAULT,
+ /*sameparty=*/false);
return cookie;
};
diff --git a/chromium/net/cookies/cookie_inclusion_status.cc b/chromium/net/cookies/cookie_inclusion_status.cc
index 240b17cd1b0..468526f3142 100644
--- a/chromium/net/cookies/cookie_inclusion_status.cc
+++ b/chromium/net/cookies/cookie_inclusion_status.cc
@@ -226,6 +226,8 @@ std::string CookieInclusionStatus::GetDebugString() const {
base::StrAppend(&out, {"EXCLUDE_INVALID_DOMAIN, "});
if (HasExclusionReason(EXCLUDE_INVALID_PREFIX))
base::StrAppend(&out, {"EXCLUDE_INVALID_PREFIX, "});
+ if (HasExclusionReason(EXCLUDE_INVALID_SAMEPARTY))
+ base::StrAppend(&out, {"EXCLUDE_INVALID_SAMEPARTY, "});
// Add warning
if (!ShouldWarn()) {
diff --git a/chromium/net/cookies/cookie_inclusion_status.h b/chromium/net/cookies/cookie_inclusion_status.h
index 9e506b55501..4a875067ee6 100644
--- a/chromium/net/cookies/cookie_inclusion_status.h
+++ b/chromium/net/cookies/cookie_inclusion_status.h
@@ -27,29 +27,54 @@ class NET_EXPORT CookieInclusionStatus {
enum ExclusionReason {
EXCLUDE_UNKNOWN_ERROR = 0,
+ // Statuses applied when accessing a cookie (either sending or setting):
+
+ // Cookie was HttpOnly, but the attempted access was through a non-HTTP API.
EXCLUDE_HTTP_ONLY = 1,
+ // Cookie was Secure, but the URL was not allowed to access Secure cookies.
EXCLUDE_SECURE_ONLY = 2,
+ // The cookie's domain attribute did not match the domain of the URL
+ // attempting access.
EXCLUDE_DOMAIN_MISMATCH = 3,
+ // The cookie's path attribute did not match the path of the URL attempting
+ // access.
EXCLUDE_NOT_ON_PATH = 4,
+ // The cookie had SameSite=Strict, and the attempted access did not have an
+ // appropriate SameSiteCookieContext.
EXCLUDE_SAMESITE_STRICT = 5,
+ // The cookie had SameSite=Lax, and the attempted access did not have an
+ // appropriate SameSiteCookieContext.
EXCLUDE_SAMESITE_LAX = 6,
-
- // The following two are used for the SameSiteByDefaultCookies experiment,
- // where if the SameSite attribute is not specified, it will be treated as
- // SameSite=Lax by default.
+ // The cookie did not specify a SameSite attribute, and therefore was
+ // treated as if it were SameSite=Lax, and the attempted access did not have
+ // an appropriate SameSiteCookieContext.
EXCLUDE_SAMESITE_UNSPECIFIED_TREATED_AS_LAX = 7,
- // This is used if SameSite=None is specified, but the cookie is not
- // Secure.
+ // The cookie specified SameSite=None, but it was not Secure.
EXCLUDE_SAMESITE_NONE_INSECURE = 8,
+ // Caller did not allow access to the cookie.
EXCLUDE_USER_PREFERENCES = 9,
- // Statuses specific to setting cookies
+ // Statuses only applied when creating/setting cookies:
+
+ // Cookie was malformed and could not be stored.
EXCLUDE_FAILURE_TO_STORE = 10,
+ // Attempted to set a cookie from a scheme that does not support cookies.
EXCLUDE_NONCOOKIEABLE_SCHEME = 11,
+ // Cookie would have overwritten a Secure cookie, and was not allowed to do
+ // so. (See "Leave Secure Cookies Alone":
+ // https://tools.ietf.org/html/draft-west-leave-secure-cookies-alone-05 )
EXCLUDE_OVERWRITE_SECURE = 12,
+ // Cookie would have overwritten an HttpOnly cookie, and was not allowed to
+ // do so.
EXCLUDE_OVERWRITE_HTTP_ONLY = 13,
+ // Cookie was set with an invalid Domain attribute.
EXCLUDE_INVALID_DOMAIN = 14,
+ // Cookie was set with an invalid __Host- or __Secure- prefix.
EXCLUDE_INVALID_PREFIX = 15,
+ // Cookie was set with an invalid SameParty attribute in combination with
+ // other attributes. (SameParty is invalid if Secure is not present, or if
+ // SameSite=Strict is present.)
+ EXCLUDE_INVALID_SAMEPARTY = 16,
// This should be kept last.
NUM_EXCLUSION_REASONS
diff --git a/chromium/net/cookies/cookie_monster.cc b/chromium/net/cookies/cookie_monster.cc
index 140b61a81dc..77b0d86b38c 100644
--- a/chromium/net/cookies/cookie_monster.cc
+++ b/chromium/net/cookies/cookie_monster.cc
@@ -63,6 +63,7 @@
#include "base/threading/thread_task_runner_handle.h"
#include "base/trace_event/process_memory_dump.h"
#include "net/base/registry_controlled_domains/registry_controlled_domain.h"
+#include "net/base/url_util.h"
#include "net/cookies/canonical_cookie.h"
#include "net/cookies/cookie_monster_change_dispatcher.h"
#include "net/cookies/cookie_monster_netlog_params.h"
@@ -71,6 +72,8 @@
#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"
using base::Time;
using base::TimeDelta;
@@ -299,16 +302,6 @@ size_t CountCookiesForPossibleDeletion(
return cookies_count;
}
-// Returns whether the CookieOptions has at least as same-site of a context as
-// |same_site_requirement|, and the options permit HttpOnly access.
-bool IsHttpSameSiteContextAtLeast(
- const CookieOptions& options,
- CookieOptions::SameSiteCookieContext::ContextType same_site_requirement) {
- return !options.exclude_httponly() &&
- options.same_site_cookie_context().GetContextForCookieInclusion() >=
- same_site_requirement;
-}
-
} // namespace
CookieMonster::CookieMonster(scoped_refptr<PersistentCookieStore> store,
@@ -570,7 +563,7 @@ void CookieMonster::AttachAccessSemanticsListForCookieList(
const CookieList& cookie_list) {
std::vector<CookieAccessSemantics> access_semantics_list;
for (const CanonicalCookie& cookie : cookie_list) {
- access_semantics_list.push_back(GetAccessSemanticsForCookieGet(cookie));
+ access_semantics_list.push_back(GetAccessSemanticsForCookie(cookie));
}
MaybeRunCookieCallback(std::move(callback), cookie_list,
access_semantics_list);
@@ -629,8 +622,7 @@ void CookieMonster::DeleteAllMatchingInfo(CookieDeletionInfo delete_info,
CanonicalCookie* cc = curit->second.get();
++it;
- if (delete_info.Matches(*cc, GetAccessSemanticsForCookie(
- *cc, false /* legacy_access_granted */))) {
+ if (delete_info.Matches(*cc, GetAccessSemanticsForCookie(*cc))) {
InternalDeleteCookie(curit, true, /*sync_to_store*/
DELETE_COOKIE_EXPLICIT);
++num_deleted;
@@ -971,7 +963,7 @@ void CookieMonster::FilterCookiesWithOptions(
// given |url|. HTTP only cookies are filtered depending on the passed
// cookie |options|.
CookieAccessResult access_result = (*it)->IncludeForRequestURL(
- url, options, GetAccessSemanticsForCookieGet(**it));
+ url, options, GetAccessSemanticsForCookie(**it));
if (!access_result.status.IsInclude()) {
if (options.return_excluded_cookies())
@@ -982,7 +974,32 @@ void CookieMonster::FilterCookiesWithOptions(
if (options.update_access_time())
InternalUpdateCookieAccessTime(*it, current_time);
- MaybeRecordCookieAccessWithOptions(**it, options, false);
+ int destination_port = url.EffectiveIntPort();
+
+ if (IsLocalhost(url)) {
+ UMA_HISTOGRAM_ENUMERATION(
+ "Cookie.Port.Read.Localhost",
+ ReducePortRangeForCookieHistogram(destination_port));
+ UMA_HISTOGRAM_ENUMERATION(
+ "Cookie.Port.ReadDiffersFromSet.Localhost",
+ IsCookieSentToSamePortThatSetIt(url, (*it)->SourcePort(),
+ (*it)->SourceScheme()));
+ } else {
+ UMA_HISTOGRAM_ENUMERATION(
+ "Cookie.Port.Read.RemoteHost",
+ ReducePortRangeForCookieHistogram(destination_port));
+ UMA_HISTOGRAM_ENUMERATION(
+ "Cookie.Port.ReadDiffersFromSet.RemoteHost",
+ IsCookieSentToSamePortThatSetIt(url, (*it)->SourcePort(),
+ (*it)->SourceScheme()));
+ }
+
+ if ((*it)->IsDomainCookie()) {
+ UMA_HISTOGRAM_ENUMERATION(
+ "Cookie.Port.ReadDiffersFromSet.DomainSet",
+ IsCookieSentToSamePortThatSetIt(url, (*it)->SourcePort(),
+ (*it)->SourceScheme()));
+ }
included_cookies->push_back({**it, access_result});
}
@@ -1089,31 +1106,6 @@ void CookieMonster::MaybeDeleteEquivalentCookieAndUpdateStatus(
}
}
-// Find the creation time of an equivalent cookie with the same value
-// ("identical", well, modulo other attributes that don't get compared)
-// if any. This iterates through the matching range of the |cookies_| map an
-// extra time, but this is ok because it is only used if
-// RecentCreationTimeGrantsLegacyCookieSemantics is enabled.
-base::Time CookieMonster::EffectiveCreationTimeForMaybePreexistingCookie(
- const std::string& key,
- const CanonicalCookie& cookie) const {
- DCHECK(cookie_util::IsRecentCreationTimeGrantsLegacyCookieSemanticsEnabled());
- base::Time effective_creation_time = cookie.CreationDate();
- const auto range_its = cookies_.equal_range(key);
- for (auto cur_it = range_its.first; cur_it != range_its.second; ++cur_it) {
- CanonicalCookie* preexisting_maybe_identical_cookie = cur_it->second.get();
- if (cookie.IsEquivalent(*preexisting_maybe_identical_cookie)) {
- if (preexisting_maybe_identical_cookie->Value() == cookie.Value()) {
- effective_creation_time =
- preexisting_maybe_identical_cookie->CreationDate();
- }
- // There should only ever be at most one equivalent cookie in the store.
- break;
- }
- }
- return effective_creation_time;
-}
-
CookieMonster::CookieMap::iterator CookieMonster::InternalInsertCookie(
const std::string& key,
std::unique_ptr<CanonicalCookie> cc,
@@ -1187,14 +1179,8 @@ void CookieMonster::SetCanonicalCookie(std::unique_ptr<CanonicalCookie> cc,
const std::string key(GetKey(cc->Domain()));
- cc->IsSetPermittedInContext(
- options,
- GetAccessSemanticsForCookieSet(
- *cc, options,
- cookie_util::IsRecentCreationTimeGrantsLegacyCookieSemanticsEnabled()
- ? EffectiveCreationTimeForMaybePreexistingCookie(key, *cc)
- : base::Time()),
- &access_result);
+ cc->IsSetPermittedInContext(options, GetAccessSemanticsForCookie(*cc),
+ &access_result);
base::Time creation_date = cc->CreationDate();
if (creation_date.is_null()) {
@@ -1236,8 +1222,13 @@ void CookieMonster::SetCanonicalCookie(std::unique_ptr<CanonicalCookie> cc,
if (!already_expired) {
// See InitializeHistograms() for details.
if (cc->IsPersistent()) {
- histogram_expiration_duration_minutes_->Add(
- (cc->ExpiryDate() - creation_date).InMinutes());
+ if (cc->IsSecure()) {
+ histogram_expiration_duration_minutes_secure_->Add(
+ (cc->ExpiryDate() - creation_date).InMinutes());
+ } else {
+ histogram_expiration_duration_minutes_non_secure_->Add(
+ (cc->ExpiryDate() - creation_date).InMinutes());
+ }
}
// Histogram the type of scheme used on URLs that set cookies. This
@@ -1255,12 +1246,12 @@ void CookieMonster::SetCanonicalCookie(std::unique_ptr<CanonicalCookie> cc,
: COOKIE_SOURCE_NONSECURE_COOKIE_NONCRYPTOGRAPHIC_SCHEME));
histogram_cookie_source_scheme_->Add(cookie_source_sample);
+ UMA_HISTOGRAM_BOOLEAN("Cookie.DomainSet", cc->IsDomainCookie());
+
if (!creation_date_to_inherit.is_null()) {
cc->SetCreationDate(creation_date_to_inherit);
}
- MaybeRecordCookieAccessWithOptions(*cc, options, true);
-
InternalInsertCookie(key, std::move(cc), true, access_result);
} else {
DVLOG(net::cookie_util::kVlogSetCookies)
@@ -1273,6 +1264,16 @@ void CookieMonster::SetCanonicalCookie(std::unique_ptr<CanonicalCookie> cc,
// that if a cookie was set, in the common case it will be used soon after,
// and we will purge the expired cookies in GetCookies().
GarbageCollect(creation_date, key);
+
+ if (IsLocalhost(source_url)) {
+ UMA_HISTOGRAM_ENUMERATION(
+ "Cookie.Port.Set.Localhost",
+ ReducePortRangeForCookieHistogram(source_url.EffectiveIntPort()));
+ } else {
+ UMA_HISTOGRAM_ENUMERATION(
+ "Cookie.Port.Set.RemoteHost",
+ ReducePortRangeForCookieHistogram(source_url.EffectiveIntPort()));
+ }
}
// TODO(chlily): Log metrics.
@@ -1297,13 +1298,17 @@ void CookieMonster::SetAllCookies(CookieList list,
continue;
if (cookie.IsPersistent()) {
- histogram_expiration_duration_minutes_->Add(
- (cookie.ExpiryDate() - creation_time).InMinutes());
+ if (cookie.IsSecure()) {
+ histogram_expiration_duration_minutes_secure_->Add(
+ (cookie.ExpiryDate() - creation_time).InMinutes());
+ } else {
+ histogram_expiration_duration_minutes_non_secure_->Add(
+ (cookie.ExpiryDate() - creation_time).InMinutes());
+ }
}
CookieAccessResult access_result;
- access_result.access_semantics = GetAccessSemanticsForCookie(
- cookie, false /* legacy_semantics_granted */);
+ access_result.access_semantics = GetAccessSemanticsForCookie(cookie);
InternalInsertCookie(key, std::make_unique<CanonicalCookie>(cookie), true,
access_result);
GarbageCollect(creation_time, key);
@@ -1359,26 +1364,16 @@ void CookieMonster::InternalDeleteCookie(CookieMap::iterator it,
});
}
- // Skip this if the map is empty, to avoid unnecessarily constructing the
- // UniqueCookieKey.
- if (!last_http_same_site_accesses_.empty()) {
- DCHECK(cookie_util::
- IsRecentHttpSameSiteAccessGrantsLegacyCookieSemanticsEnabled());
- last_http_same_site_accesses_.erase(it->second->UniqueKey());
- }
-
if ((cc->IsPersistent() || persist_session_cookies_) && store_.get() &&
sync_to_store) {
store_->DeleteCookie(*cc);
}
change_dispatcher_.DispatchChange(
- CookieChangeInfo(
- *cc,
- CookieAccessResult(CookieEffectiveSameSite::UNDEFINED,
- CookieInclusionStatus(),
- GetAccessSemanticsForCookie(
- *cc, false /* legacy_access_granted */)),
- mapping.cause),
+ CookieChangeInfo(*cc,
+ CookieAccessResult(CookieEffectiveSameSite::UNDEFINED,
+ CookieInclusionStatus(),
+ GetAccessSemanticsForCookie(*cc)),
+ mapping.cause),
mapping.notify);
// If this is the last cookie in |cookies_| with this key, decrement the
@@ -1728,95 +1723,12 @@ bool CookieMonster::HasCookieableScheme(const GURL& url) {
}
CookieAccessSemantics CookieMonster::GetAccessSemanticsForCookie(
- const CanonicalCookie& cookie,
- bool legacy_semantics_granted) const {
- if (legacy_semantics_granted)
- return CookieAccessSemantics::LEGACY;
+ const CanonicalCookie& cookie) const {
if (cookie_access_delegate())
return cookie_access_delegate()->GetAccessSemantics(cookie);
return CookieAccessSemantics::UNKNOWN;
}
-CookieAccessSemantics CookieMonster::GetAccessSemanticsForCookieGet(
- const CanonicalCookie& cookie) const {
- bool legacy_semantics_granted =
- cookie_util::DoesLastHttpSameSiteAccessGrantLegacySemantics(
- LastAccessFromHttpSameSiteContext(cookie)) ||
- cookie_util::DoesCreationTimeGrantLegacySemantics(cookie.CreationDate());
- return GetAccessSemanticsForCookie(cookie, legacy_semantics_granted);
-}
-
-CookieAccessSemantics CookieMonster::GetAccessSemanticsForCookieSet(
- const CanonicalCookie& cookie,
- const CookieOptions& options,
- base::Time effective_creation_time) const {
- // If the current cookie access is a set, directly treat the cookie as LEGACY
- // if the |options| qualify, because there may not be a time entry in
- // |last_http_same_site_accesses_| since it may be a new cookie without a
- // previous access. It will still only be added to the map as a qualifying
- // cookie access if the final inclusion status is include.
- bool legacy_semantics_granted =
- (cookie_util::
- IsRecentHttpSameSiteAccessGrantsLegacyCookieSemanticsEnabled() &&
- IsHttpSameSiteContextAtLeast(
- options,
- CookieOptions::SameSiteCookieContext::ContextType::SAME_SITE_LAX));
-
- // If the current cookie access is not itself http-and-same-site, but the last
- // one that was, was recent enough, (and the corresponding feature is enabled)
- // grant legacy semantics.
- legacy_semantics_granted =
- legacy_semantics_granted ||
- cookie_util::DoesLastHttpSameSiteAccessGrantLegacySemantics(
- LastAccessFromHttpSameSiteContext(cookie));
-
- // If the cookie's creation time (or that of an identical preexisting cookie)
- // was recent enough (and the corresponding feature is enabled), grant legacy
- // semantics.
- legacy_semantics_granted = legacy_semantics_granted ||
- cookie_util::DoesCreationTimeGrantLegacySemantics(
- effective_creation_time);
-
- return GetAccessSemanticsForCookie(cookie, legacy_semantics_granted);
-}
-
-base::TimeTicks CookieMonster::LastAccessFromHttpSameSiteContext(
- const CanonicalCookie& cookie) const {
- // Return early to avoid unnecessarily constructing the UniqueCookieKey
- if (last_http_same_site_accesses_.empty()) {
- return base::TimeTicks();
- }
-
- const auto it = last_http_same_site_accesses_.find(cookie.UniqueKey());
- if (it != last_http_same_site_accesses_.end())
- return it->second;
- return base::TimeTicks();
-}
-
-void CookieMonster::MaybeRecordCookieAccessWithOptions(
- const CanonicalCookie& cookie,
- const CookieOptions& options,
- bool is_set) {
- // Don't populate |last_http_same_site_accesses_| if the relevant feature is
- // not enabled.
- if (!cookie_util::
- IsRecentHttpSameSiteAccessGrantsLegacyCookieSemanticsEnabled()) {
- return;
- }
-
- // Don't update time for accesses that don't update access time. (E.g. the
- // time should not be updated when the cookie is accessed to populate the UI.)
- if (!options.update_access_time())
- return;
- CookieOptions::SameSiteCookieContext::ContextType same_site_requirement;
- same_site_requirement =
- is_set
- ? CookieOptions::SameSiteCookieContext::ContextType::SAME_SITE_LAX
- : CookieOptions::SameSiteCookieContext::ContextType::SAME_SITE_STRICT;
- if (IsHttpSameSiteContextAtLeast(options, same_site_requirement))
- last_http_same_site_accesses_[cookie.UniqueKey()] = base::TimeTicks::Now();
-}
-
// Test to see if stats should be recorded, and record them if so.
// The goal here is to get sampling for the average browser-hour of
// activity. We won't take samples when the web isn't being surfed,
@@ -1885,9 +1797,13 @@ void CookieMonster::InitializeHistograms() {
DCHECK(thread_checker_.CalledOnValidThread());
// From UMA_HISTOGRAM_CUSTOM_COUNTS
- histogram_expiration_duration_minutes_ = base::Histogram::FactoryGet(
- "Cookie.ExpirationDurationMinutes", 1, kMinutesInTenYears, 50,
+ histogram_expiration_duration_minutes_secure_ = base::Histogram::FactoryGet(
+ "Cookie.ExpirationDurationMinutesSecure", 1, kMinutesInTenYears, 50,
base::Histogram::kUmaTargetedHistogramFlag);
+ histogram_expiration_duration_minutes_non_secure_ =
+ base::Histogram::FactoryGet("Cookie.ExpirationDurationMinutesNonSecure",
+ 1, kMinutesInTenYears, 50,
+ base::Histogram::kUmaTargetedHistogramFlag);
histogram_count_ = base::Histogram::FactoryGet(
"Cookie.Count", 1, 4000, 50, base::Histogram::kUmaTargetedHistogramFlag);
@@ -1965,4 +1881,44 @@ void CookieMonster::DoCookieCallbackForHostOrDomain(
std::move(callback).Run();
}
+CookieMonster::CookieSentToSamePort
+CookieMonster::IsCookieSentToSamePortThatSetIt(
+ const GURL& destination,
+ int source_port,
+ CookieSourceScheme source_scheme) {
+ if (source_port == url::PORT_UNSPECIFIED)
+ return CookieSentToSamePort::kSourcePortUnspecified;
+
+ if (source_port == url::PORT_INVALID)
+ return CookieSentToSamePort::kInvalid;
+
+ int destination_port = destination.EffectiveIntPort();
+ if (source_port == destination_port)
+ return CookieSentToSamePort::kYes;
+
+ const std::string& destination_scheme = destination.scheme();
+ bool destination_port_is_default =
+ url::DefaultPortForScheme(destination_scheme.c_str(),
+ destination_scheme.length()) ==
+ destination_port;
+
+ // Since the source port has to be specified if we got to this point, that
+ // means this is a newer cookie that therefore has its scheme set as well.
+ DCHECK(source_scheme != CookieSourceScheme::kUnset);
+ std::string source_scheme_string =
+ source_scheme == CookieSourceScheme::kSecure
+ ? url::kHttpsScheme
+ : url::kHttpScheme; // wss/ws have the same default port values as
+ // https/http, so it's ok that we use these.
+
+ bool source_port_is_default =
+ url::DefaultPortForScheme(source_scheme_string.c_str(),
+ source_scheme_string.length()) == source_port;
+
+ if (destination_port_is_default && source_port_is_default)
+ return CookieSentToSamePort::kNoButDefault;
+
+ return CookieSentToSamePort::kNo;
+}
+
} // namespace net
diff --git a/chromium/net/cookies/cookie_monster.h b/chromium/net/cookies/cookie_monster.h
index 57ce9d640ac..1c798ba1c78 100644
--- a/chromium/net/cookies/cookie_monster.h
+++ b/chromium/net/cookies/cookie_monster.h
@@ -237,6 +237,11 @@ class NET_EXPORT CookieMonster : public CookieStore {
FRIEND_TEST_ALL_PREFIXES(CookieMonsterTest,
CookieDeleteEquivalentHistogramTest);
+ // For CookieSentToSamePort enum.
+ FRIEND_TEST_ALL_PREFIXES(CookieMonsterTest,
+ CookiePortReadDiffersFromSetHistogram);
+ FRIEND_TEST_ALL_PREFIXES(CookieMonsterTest, IsCookieSentToSamePortThatSetIt);
+
// Internal reasons for deletion, used to populate informative histograms
// and to provide a public cause for onCookieChange notifications.
//
@@ -310,6 +315,28 @@ class NET_EXPORT CookieMonster : public CookieStore {
COOKIE_SOURCE_LAST_ENTRY
};
+ // Enum for collecting metrics on how frequently a cookie is sent to the same
+ // port it was set by.
+ //
+ // kNoButDefault exists because we expect for cookies being sent between
+ // schemes to have a port mismatch and want to separate those out from other,
+ // more interesting, cases.
+ //
+ // Do not reorder or renumber. Used for metrics.
+ enum class CookieSentToSamePort {
+ kSourcePortUnspecified = 0, // Cookie's source port is unspecified, we
+ // can't know if this is the same port or not.
+ kInvalid = 1, // The source port was corrupted to be PORT_INVALID, we
+ // can't know if this is the same port or not.
+ kNo = 2, // Source port and destination port are different.
+ kNoButDefault =
+ 3, // Source and destination ports are different but they're
+ // the defaults for their scheme. This can mean that an http
+ // cookie was sent to a https origin or vice-versa.
+ kYes = 4, // They're the same.
+ kMaxValue = kYes
+ };
+
// Record statistics every kRecordStatisticsIntervalSeconds of uptime.
static const int kRecordStatisticsIntervalSeconds = 10 * 60;
@@ -438,14 +465,6 @@ class NET_EXPORT CookieMonster : public CookieStore {
base::Time* creation_date_to_inherit,
CookieInclusionStatus* status);
- // This is only used if the RecentCreationTimeGrantsLegacyCookieSemantics
- // feature is enabled. It finds an equivalent cookie (based on name, domain,
- // path) with the same value, if there is any, and returns its creation time,
- // or the creation time of the |cookie| itself, if there is none.
- base::Time EffectiveCreationTimeForMaybePreexistingCookie(
- const std::string& key,
- const CanonicalCookie& cookie) const;
-
// Inserts |cc| into cookies_. Returns an iterator that points to the inserted
// cookie in cookies_. Guarantee: all iterators to cookies_ remain valid.
CookieMap::iterator InternalInsertCookie(
@@ -522,50 +541,12 @@ class NET_EXPORT CookieMonster : public CookieStore {
bool HasCookieableScheme(const GURL& url);
- // Get the cookie's access semantics (LEGACY or NONLEGACY), considering any
- // features granting legacy semantics for special conditions (if any are
- // active and meet the conditions for granting legacy access, pass true for
- // |legacy_semantics_granted|). If none are active, this then checks for a
+ // Get the cookie's access semantics (LEGACY or NONLEGACY), by checking for a
// value from the cookie access delegate, if it is non-null. Otherwise returns
// UNKNOWN.
CookieAccessSemantics GetAccessSemanticsForCookie(
- const CanonicalCookie& cookie,
- bool legacy_semantics_granted) const;
-
- // This is called for getting a cookie.
- CookieAccessSemantics GetAccessSemanticsForCookieGet(
- const CanonicalCookie& cookie) const;
-
- // This is called for setting a cookie with the options specified by
- // |options|. For setting a cookie, a same-site access is lax or better (since
- // CookieOptions for setting a cookie will never be strict).
- // |effective_creation_time| is the time that should be used for deciding
- // whether the RecentCreationTimeGrantsLegacyCookieSemantics feature should
- // grant legacy semantics. This may differ from the CreationDate() field of
- // the cookie, if there was a preexisting equivalent cookie (in which case it
- // is the creation time of that equivalent cookie).
- CookieAccessSemantics GetAccessSemanticsForCookieSet(
- const CanonicalCookie& cookie,
- const CookieOptions& options,
- base::Time effective_creation_time) const;
-
- // Looks up the last time a cookie matching the (name, domain, path) of
- // |cookie| was accessed in a same-site context permitting HttpOnly
- // cookie access. If there was none, this returns a null base::Time.
- // Returns null value if RecentHttpSameSiteAccessGrantsLegacyCookieSemantics
- // is not enabled.
- base::TimeTicks LastAccessFromHttpSameSiteContext(
const CanonicalCookie& cookie) const;
- // Updates |last_http_same_site_accesses_| with the current time if the
- // |options| are appropriate (same-site and permits HttpOnly access).
- // |is_set| is true if the access is setting the cookie, false otherwise (e.g.
- // if getting the cookie). Does nothing if
- // RecentHttpSameSiteAccessGrantsLegacyCookieSemantics is not enabled.
- void MaybeRecordCookieAccessWithOptions(const CanonicalCookie& cookie,
- const CookieOptions& options,
- bool is_set);
-
// Statistics support
// This function should be called repeatedly, and will record
@@ -594,9 +575,20 @@ class NET_EXPORT CookieMonster : public CookieStore {
void DoCookieCallbackForHostOrDomain(base::OnceClosure callback,
base::StringPiece host_or_domain);
+ // Checks to see if a cookie is being sent to the same port it was set by. For
+ // metrics.
+ //
+ // This is in CookieMonster because only CookieMonster uses it. It's otherwise
+ // a standalone utility function.
+ static CookieSentToSamePort IsCookieSentToSamePortThatSetIt(
+ const GURL& destination,
+ int source_port,
+ CookieSourceScheme source_scheme);
+
// Histogram variables; see CookieMonster::InitializeHistograms() in
// cookie_monster.cc for details.
- base::HistogramBase* histogram_expiration_duration_minutes_;
+ base::HistogramBase* histogram_expiration_duration_minutes_secure_;
+ base::HistogramBase* histogram_expiration_duration_minutes_non_secure_;
base::HistogramBase* histogram_count_;
base::HistogramBase* histogram_cookie_type_;
base::HistogramBase* histogram_cookie_source_scheme_;
@@ -662,17 +654,6 @@ class NET_EXPORT CookieMonster : public CookieStore {
// wanted. Thus this value is not initialized.
base::Time earliest_access_time_;
- // Records the last access to a cookie (either getting or setting) from a
- // context that is both same-site and permits HttpOnly access.
- // The access is considered same-site if it is at least laxly same-site for
- // set, or strictly same-site for get.
- // This information is used to determine if the feature
- // kRecentSameSiteAccessGrantsLegacyCookieSemantics should grant legacy
- // access semantics to a cookie for subsequent accesses.
- // This map is not used if that feature is not enabled.
- std::map<CanonicalCookie::UniqueCookieKey, base::TimeTicks>
- last_http_same_site_accesses_;
-
std::vector<std::string> cookieable_schemes_;
base::Time last_statistic_record_time_;
diff --git a/chromium/net/cookies/cookie_monster_netlog_params.cc b/chromium/net/cookies/cookie_monster_netlog_params.cc
index 89b38d4170d..fad5f472ee6 100644
--- a/chromium/net/cookies/cookie_monster_netlog_params.cc
+++ b/chromium/net/cookies/cookie_monster_netlog_params.cc
@@ -32,6 +32,7 @@ base::Value NetLogCookieMonsterCookieAdded(const CanonicalCookie* cookie,
dict.SetStringKey("same_site", CookieSameSiteToString(cookie->SameSite()));
dict.SetBoolKey("is_persistent", cookie->IsPersistent());
dict.SetBoolKey("sync_requested", sync_requested);
+ dict.SetBoolKey("same_party", cookie->IsSameParty());
return dict;
}
diff --git a/chromium/net/cookies/cookie_monster_store_test.cc b/chromium/net/cookies/cookie_monster_store_test.cc
index b50d1b074f1..f37b1a2cd8f 100644
--- a/chromium/net/cookies/cookie_monster_store_test.cc
+++ b/chromium/net/cookies/cookie_monster_store_test.cc
@@ -122,7 +122,7 @@ std::unique_ptr<CanonicalCookie> BuildCanonicalCookie(
return std::make_unique<CanonicalCookie>(
pc.Name(), pc.Value(), "." + url.host(), cookie_path, creation_time,
cookie_expires, base::Time(), pc.IsSecure(), pc.IsHttpOnly(),
- pc.SameSite(), pc.Priority());
+ pc.SameSite(), pc.Priority(), pc.IsSameParty());
}
void AddCookieToList(const GURL& url,
@@ -236,7 +236,7 @@ std::unique_ptr<CookieMonster> CreateMonsterFromStoreForGC(
std::unique_ptr<CanonicalCookie> cc(std::make_unique<CanonicalCookie>(
"a", "1", base::StringPrintf("h%05d.izzle", i), "/path", creation_time,
expiration_time, base::Time(), secure, false,
- CookieSameSite::NO_RESTRICTION, COOKIE_PRIORITY_DEFAULT));
+ CookieSameSite::NO_RESTRICTION, COOKIE_PRIORITY_DEFAULT, false));
cc->SetLastAccessDate(last_access_time);
store->AddCookie(*cc);
}
diff --git a/chromium/net/cookies/cookie_monster_unittest.cc b/chromium/net/cookies/cookie_monster_unittest.cc
index a4b72d59e64..01ee039244e 100644
--- a/chromium/net/cookies/cookie_monster_unittest.cc
+++ b/chromium/net/cookies/cookie_monster_unittest.cc
@@ -11,7 +11,7 @@
#include <vector>
#include "base/bind.h"
-#include "base/bind_helpers.h"
+#include "base/callback_helpers.h"
#include "base/containers/queue.h"
#include "base/location.h"
#include "base/memory/ref_counted.h"
@@ -26,7 +26,7 @@
#include "base/strings/string_split.h"
#include "base/strings/string_tokenizer.h"
#include "base/strings/stringprintf.h"
-#include "base/test/bind_test_util.h"
+#include "base/test/bind.h"
#include "base/test/metrics/histogram_tester.h"
#include "base/test/mock_callback.h"
#include "base/test/scoped_feature_list.h"
@@ -51,6 +51,7 @@
#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"
#include "url/url_constants.h"
namespace net {
@@ -59,11 +60,6 @@ using base::Time;
using base::TimeDelta;
using CookieDeletionInfo = net::CookieDeletionInfo;
using features::kCookiesWithoutSameSiteMustBeSecure;
-using features::kRecentCreationTimeGrantsLegacyCookieSemantics;
-using features::kRecentCreationTimeGrantsLegacyCookieSemanticsMilliseconds;
-using features::kRecentHttpSameSiteAccessGrantsLegacyCookieSemantics;
-using features::
- kRecentHttpSameSiteAccessGrantsLegacyCookieSemanticsMilliseconds;
using features::kSameSiteByDefaultCookies;
namespace {
@@ -214,71 +210,71 @@ class CookieMonsterTestBase : public CookieStoreTest<T> {
cookies.push_back(std::make_unique<CanonicalCookie>(
"dom_1", "A", ".harvard.edu", "/", base::Time(), base::Time(),
base::Time(), false, false, CookieSameSite::LAX_MODE,
- COOKIE_PRIORITY_DEFAULT));
+ COOKIE_PRIORITY_DEFAULT, false));
cookies.push_back(std::make_unique<CanonicalCookie>(
"dom_2", "B", ".math.harvard.edu", "/", base::Time(), base::Time(),
base::Time(), false, false, CookieSameSite::LAX_MODE,
- COOKIE_PRIORITY_DEFAULT));
+ COOKIE_PRIORITY_DEFAULT, false));
cookies.push_back(std::make_unique<CanonicalCookie>(
"dom_3", "C", ".bourbaki.math.harvard.edu", "/", base::Time(),
base::Time(), base::Time(), false, false, CookieSameSite::LAX_MODE,
- COOKIE_PRIORITY_DEFAULT));
+ COOKIE_PRIORITY_DEFAULT, false));
// Host cookies
cookies.push_back(std::make_unique<CanonicalCookie>(
"host_1", "A", url_top_level_domain_plus_1, "/", base::Time(),
base::Time(), base::Time(), false, false, CookieSameSite::LAX_MODE,
- COOKIE_PRIORITY_DEFAULT));
+ COOKIE_PRIORITY_DEFAULT, false));
cookies.push_back(std::make_unique<CanonicalCookie>(
"host_2", "B", url_top_level_domain_plus_2, "/", base::Time(),
base::Time(), base::Time(), false, false, CookieSameSite::LAX_MODE,
- COOKIE_PRIORITY_DEFAULT));
+ COOKIE_PRIORITY_DEFAULT, false));
cookies.push_back(std::make_unique<CanonicalCookie>(
"host_3", "C", url_top_level_domain_plus_3, "/", base::Time(),
base::Time(), base::Time(), false, false, CookieSameSite::LAX_MODE,
- COOKIE_PRIORITY_DEFAULT));
+ COOKIE_PRIORITY_DEFAULT, false));
// http_only cookie
cookies.push_back(std::make_unique<CanonicalCookie>(
"httpo_check", "A", url_top_level_domain_plus_2, "/", base::Time(),
base::Time(), base::Time(), false, true, CookieSameSite::LAX_MODE,
- COOKIE_PRIORITY_DEFAULT));
+ COOKIE_PRIORITY_DEFAULT, false));
// same-site cookie
cookies.push_back(std::make_unique<CanonicalCookie>(
"firstp_check", "A", url_top_level_domain_plus_2, "/", base::Time(),
base::Time(), base::Time(), false, false, CookieSameSite::STRICT_MODE,
- COOKIE_PRIORITY_DEFAULT));
+ COOKIE_PRIORITY_DEFAULT, false));
// Secure cookies
cookies.push_back(std::make_unique<CanonicalCookie>(
"sec_dom", "A", ".math.harvard.edu", "/", base::Time(), base::Time(),
base::Time(), true, false, CookieSameSite::NO_RESTRICTION,
- COOKIE_PRIORITY_DEFAULT));
+ COOKIE_PRIORITY_DEFAULT, false));
cookies.push_back(std::make_unique<CanonicalCookie>(
"sec_host", "B", url_top_level_domain_plus_2, "/", base::Time(),
base::Time(), base::Time(), true, false, CookieSameSite::NO_RESTRICTION,
- COOKIE_PRIORITY_DEFAULT));
+ COOKIE_PRIORITY_DEFAULT, false));
// Domain path cookies
cookies.push_back(std::make_unique<CanonicalCookie>(
"dom_path_1", "A", ".math.harvard.edu", "/dir1", base::Time(),
base::Time(), base::Time(), false, false, CookieSameSite::LAX_MODE,
- COOKIE_PRIORITY_DEFAULT));
+ COOKIE_PRIORITY_DEFAULT, false));
cookies.push_back(std::make_unique<CanonicalCookie>(
"dom_path_2", "B", ".math.harvard.edu", "/dir1/dir2", base::Time(),
base::Time(), base::Time(), false, false, CookieSameSite::LAX_MODE,
- COOKIE_PRIORITY_DEFAULT));
+ COOKIE_PRIORITY_DEFAULT, false));
// Host path cookies
cookies.push_back(std::make_unique<CanonicalCookie>(
"host_path_1", "A", url_top_level_domain_plus_2, "/dir1", base::Time(),
base::Time(), base::Time(), false, false, CookieSameSite::LAX_MODE,
- COOKIE_PRIORITY_DEFAULT));
+ COOKIE_PRIORITY_DEFAULT, false));
cookies.push_back(std::make_unique<CanonicalCookie>(
"host_path_2", "B", url_top_level_domain_plus_2, "/dir1/dir2",
base::Time(), base::Time(), base::Time(), false, false,
- CookieSameSite::LAX_MODE, COOKIE_PRIORITY_DEFAULT));
+ CookieSameSite::LAX_MODE, COOKIE_PRIORITY_DEFAULT, false));
for (auto& cookie : cookies) {
GURL source_url = cookie_util::SimulatedCookieSource(
@@ -838,7 +834,7 @@ class CookieMonsterTestBase : public CookieStoreTest<T> {
creation_time, base::Time() /* expiration_time */,
creation_time /* last_access */, true /* secure */,
false /* http_only */, CookieSameSite::NO_RESTRICTION,
- COOKIE_PRIORITY_DEFAULT));
+ COOKIE_PRIORITY_DEFAULT, false /* same_party */));
GURL source_url = cookie_util::SimulatedCookieSource(*cc, "https");
cm->SetCanonicalCookieAsync(std::move(cc), source_url,
CookieOptions::MakeAllInclusive(),
@@ -879,6 +875,7 @@ struct CookiesInputInfo {
bool http_only;
CookieSameSite same_site;
CookiePriority priority;
+ bool same_party;
};
} // namespace
@@ -1014,11 +1011,11 @@ TEST_F(DeferredCookieTaskTest, DeferredSetAllCookies) {
list.push_back(CanonicalCookie("A", "B", "." + http_www_foo_.domain(), "/",
base::Time::Now(), base::Time(), base::Time(),
false, true, CookieSameSite::NO_RESTRICTION,
- COOKIE_PRIORITY_DEFAULT));
+ COOKIE_PRIORITY_DEFAULT, false));
list.push_back(CanonicalCookie("C", "D", "." + http_www_foo_.domain(), "/",
base::Time::Now(), base::Time(), base::Time(),
false, true, CookieSameSite::NO_RESTRICTION,
- COOKIE_PRIORITY_DEFAULT));
+ COOKIE_PRIORITY_DEFAULT, false));
ResultSavingCookieCallback<CookieAccessResult> call1;
cookie_monster_->SetAllCookiesAsync(list, call1.MakeCallback());
@@ -1996,13 +1993,13 @@ TEST_F(CookieMonsterTest, BackingStoreCommunication) {
const CookiesInputInfo input_info[] = {
{GURL("https://a.b.foo.com"), "a", "1", "a.b.foo.com", "/path/to/cookie",
expires, true /* secure */, false, CookieSameSite::NO_RESTRICTION,
- COOKIE_PRIORITY_DEFAULT},
+ COOKIE_PRIORITY_DEFAULT, false},
{GURL("https://www.foo.com"), "b", "2", ".foo.com", "/path/from/cookie",
expires + TimeDelta::FromSeconds(10), true, true,
- CookieSameSite::NO_RESTRICTION, COOKIE_PRIORITY_DEFAULT},
+ CookieSameSite::NO_RESTRICTION, COOKIE_PRIORITY_DEFAULT, true},
{GURL("https://foo.com"), "c", "3", "foo.com", "/another/path/to/cookie",
base::Time::Now() + base::TimeDelta::FromSeconds(100), false, false,
- CookieSameSite::STRICT_MODE, COOKIE_PRIORITY_DEFAULT}};
+ CookieSameSite::STRICT_MODE, COOKIE_PRIORITY_DEFAULT, false}};
const int INPUT_DELETE = 1;
// Create new cookies and flush them to the store.
@@ -2015,7 +2012,8 @@ TEST_F(CookieMonsterTest, BackingStoreCommunication) {
std::make_unique<CanonicalCookie>(
cookie.name, cookie.value, cookie.domain, cookie.path,
base::Time(), cookie.expiration_time, base::Time(), cookie.secure,
- cookie.http_only, cookie.same_site, cookie.priority),
+ cookie.http_only, cookie.same_site, cookie.priority,
+ cookie.same_party),
cookie.url, true /*modify_httponly*/));
}
@@ -2468,15 +2466,15 @@ TEST_F(CookieMonsterTest, SetAllCookies) {
list.push_back(CanonicalCookie(
"A", "B", "." + http_www_foo_.url().host(), "/", base::Time::Now(),
base::Time(), base::Time(), false, false, CookieSameSite::NO_RESTRICTION,
- COOKIE_PRIORITY_DEFAULT));
+ COOKIE_PRIORITY_DEFAULT, false));
list.push_back(CanonicalCookie(
"W", "X", "." + http_www_foo_.url().host(), "/bar", base::Time::Now(),
base::Time(), base::Time(), false, false, CookieSameSite::NO_RESTRICTION,
- COOKIE_PRIORITY_DEFAULT));
+ COOKIE_PRIORITY_DEFAULT, false));
list.push_back(CanonicalCookie(
"Y", "Z", "." + http_www_foo_.url().host(), "/", base::Time::Now(),
base::Time(), base::Time(), false, false, CookieSameSite::NO_RESTRICTION,
- COOKIE_PRIORITY_DEFAULT));
+ COOKIE_PRIORITY_DEFAULT, false));
// SetAllCookies must not flush.
ASSERT_EQ(0, store->flush_count());
@@ -2551,7 +2549,7 @@ TEST_F(CookieMonsterTest, HistogramCheck) {
// since the histogram should have been initialized by the CM construction
// above.
base::HistogramBase* expired_histogram = base::Histogram::FactoryGet(
- "Cookie.ExpirationDurationMinutes", 1, 10 * 365 * 24 * 60, 50,
+ "Cookie.ExpirationDurationMinutesSecure", 1, 10 * 365 * 24 * 60, 50,
base::Histogram::kUmaTargetedHistogramFlag);
std::unique_ptr<base::HistogramSamples> samples1(
@@ -2559,7 +2557,7 @@ TEST_F(CookieMonsterTest, HistogramCheck) {
auto cookie = std::make_unique<CanonicalCookie>(
"a", "b", "a.url", "/", base::Time(),
base::Time::Now() + base::TimeDelta::FromMinutes(59), base::Time(), true,
- false, CookieSameSite::NO_RESTRICTION, COOKIE_PRIORITY_DEFAULT);
+ false, CookieSameSite::NO_RESTRICTION, COOKIE_PRIORITY_DEFAULT, false);
GURL source_url = cookie_util::SimulatedCookieSource(*cookie, "https");
ASSERT_TRUE(SetCanonicalCookie(cm.get(), std::move(cookie), source_url,
true /*modify_httponly*/));
@@ -2687,7 +2685,7 @@ TEST_F(CookieMonsterTest, ControlCharacterPurge) {
"\x05"
"boo",
"." + domain, path, now2, later, base::Time(), false, false,
- CookieSameSite::NO_RESTRICTION, COOKIE_PRIORITY_DEFAULT);
+ CookieSameSite::NO_RESTRICTION, COOKIE_PRIORITY_DEFAULT, false);
initial_cookies.push_back(std::move(cc));
AddCookieToList(url, "hello=world; path=" + path, now3, &initial_cookies);
@@ -4023,59 +4021,26 @@ class CookieMonsterLegacyCookieAccessTest : public CookieMonsterTest {
~CookieMonsterLegacyCookieAccessTest() override {}
- // The third parameter is nullopt if
- // kRecentHttpSameSiteAccessGrantsLegacyCookieSemantics is not enabled.
- // Otherwise it gives the value of the corresponding parameter.
- // Similarly for the fourth parameter, which is for
- // kRecentCreationTimeGrantsLegacyCookieSemantics.
- void SetFeatures(
- bool is_same_site_by_default_cookies_enabled,
- bool is_cookies_without_samesite_must_be_secure_enabled,
- base::Optional<int>
- milliseconds_for_http_same_site_access_grants_legacy_semantics,
- base::Optional<int>
- milliseconds_for_creation_time_grants_legacy_semantics) {
+ void SetFeatures(bool is_same_site_by_default_cookies_enabled,
+ bool is_cookies_without_samesite_must_be_secure_enabled) {
feature_list_ = std::make_unique<base::test::ScopedFeatureList>();
- std::vector<base::test::ScopedFeatureList::FeatureAndParams> enabled;
+ std::vector<base::Feature> enabled;
std::vector<base::Feature> disabled;
if (is_same_site_by_default_cookies_enabled) {
- enabled.push_back({kSameSiteByDefaultCookies, {}});
+ enabled.push_back(kSameSiteByDefaultCookies);
} else {
disabled.push_back(kSameSiteByDefaultCookies);
}
if (is_cookies_without_samesite_must_be_secure_enabled) {
- enabled.push_back({kCookiesWithoutSameSiteMustBeSecure, {}});
+ enabled.push_back(kCookiesWithoutSameSiteMustBeSecure);
} else {
disabled.push_back(kCookiesWithoutSameSiteMustBeSecure);
}
- if (milliseconds_for_http_same_site_access_grants_legacy_semantics) {
- enabled.push_back(
- {kRecentHttpSameSiteAccessGrantsLegacyCookieSemantics,
- {{kRecentHttpSameSiteAccessGrantsLegacyCookieSemanticsMilliseconds
- .name,
- base::NumberToString(
- milliseconds_for_http_same_site_access_grants_legacy_semantics
- .value())}}});
- } else {
- disabled.push_back(kRecentHttpSameSiteAccessGrantsLegacyCookieSemantics);
- }
-
- if (milliseconds_for_creation_time_grants_legacy_semantics) {
- enabled.push_back(
- {kRecentCreationTimeGrantsLegacyCookieSemantics,
- {{kRecentCreationTimeGrantsLegacyCookieSemanticsMilliseconds.name,
- base::NumberToString(
- milliseconds_for_creation_time_grants_legacy_semantics
- .value())}}});
- } else {
- disabled.push_back(kRecentCreationTimeGrantsLegacyCookieSemantics);
- }
-
- feature_list_->InitWithFeaturesAndParameters(enabled, disabled);
+ feature_list_->InitWithFeatures(enabled, disabled);
}
protected:
@@ -4091,7 +4056,7 @@ class CookieMonsterLegacyCookieAccessTest : public CookieMonsterTest {
};
TEST_F(CookieMonsterLegacyCookieAccessTest, SetLegacyNoSameSiteCookie) {
- SetFeatures(true, true, base::nullopt, base::nullopt);
+ SetFeatures(true, true);
// Check that setting unspecified-SameSite cookie from cross-site context
// fails if not set to Legacy semantics, but succeeds if set to legacy.
EXPECT_FALSE(CreateAndSetCookie(cm_.get(), kHttpUrl, "cookie=chocolate_chip",
@@ -4113,13 +4078,13 @@ TEST_F(CookieMonsterLegacyCookieAccessTest, SetLegacyNoSameSiteCookie) {
TEST_F(CookieMonsterLegacyCookieAccessTest, GetLegacyNoSameSiteCookie) {
// Set an unspecified-SameSite cookie with SameSite features turned off.
// Getting the cookie will succeed.
- SetFeatures(false, false, base::nullopt, base::nullopt);
+ SetFeatures(false, false);
ASSERT_TRUE(CreateAndSetCookie(cm_.get(), kHttpUrl, "cookie=chocolate_chip",
CookieOptions()));
EXPECT_EQ("cookie=chocolate_chip",
GetCookiesWithOptions(cm_.get(), kHttpUrl, CookieOptions()));
// Turn on the features. Now getting the cookie fails.
- SetFeatures(true, true, base::nullopt, base::nullopt);
+ SetFeatures(true, true);
access_delegate_->SetExpectationForCookieDomain(
kDomain, CookieAccessSemantics::UNKNOWN);
EXPECT_EQ("", GetCookiesWithOptions(cm_.get(), kHttpUrl, CookieOptions()));
@@ -4135,7 +4100,7 @@ TEST_F(CookieMonsterLegacyCookieAccessTest, GetLegacyNoSameSiteCookie) {
TEST_F(CookieMonsterLegacyCookieAccessTest,
SetLegacySameSiteNoneInsecureCookie) {
- SetFeatures(true, true, base::nullopt, base::nullopt);
+ SetFeatures(true, true);
access_delegate_->SetExpectationForCookieDomain(
kDomain, CookieAccessSemantics::UNKNOWN);
EXPECT_FALSE(CreateAndSetCookie(cm_.get(), kHttpsUrl,
@@ -4160,14 +4125,14 @@ TEST_F(CookieMonsterLegacyCookieAccessTest,
GetLegacySameSiteNoneInsecureCookie) {
// Set an SameSite=None insecure cookie with SameSite features turned off.
// Getting the cookie will succeed.
- SetFeatures(false, false, base::nullopt, base::nullopt);
+ SetFeatures(false, false);
ASSERT_TRUE(CreateAndSetCookie(cm_.get(), kHttpUrl,
"cookie=oatmeal_raisin; SameSite=None",
CookieOptions()));
EXPECT_EQ("cookie=oatmeal_raisin",
GetCookiesWithOptions(cm_.get(), kHttpUrl, CookieOptions()));
// Turn on the features. Now getting the cookie fails.
- SetFeatures(true, true, base::nullopt, base::nullopt);
+ SetFeatures(true, true);
access_delegate_->SetExpectationForCookieDomain(
kDomain, CookieAccessSemantics::UNKNOWN);
EXPECT_EQ("", GetCookiesWithOptions(cm_.get(), kHttpUrl, CookieOptions()));
@@ -4183,7 +4148,7 @@ TEST_F(CookieMonsterLegacyCookieAccessTest,
TEST_F(CookieMonsterLegacyCookieAccessTest, NonlegacyCookie) {
// Nonlegacy cookie will have default as Lax.
- SetFeatures(false, false, base::nullopt, base::nullopt);
+ SetFeatures(false, false);
access_delegate_->SetExpectationForCookieDomain(
kDomain, CookieAccessSemantics::NONLEGACY);
EXPECT_FALSE(CreateAndSetCookie(cm_.get(), kHttpUrl, "cookie=chocolate_chip",
@@ -4198,164 +4163,311 @@ TEST_F(CookieMonsterLegacyCookieAccessTest, NonlegacyCookie) {
GetCookiesWithOptions(cm_.get(), kHttpUrl, CookieOptions()));
}
-// Test the RecentHttpSameSiteAccessGrantsLegacyCookieSemantics feature.
-TEST_F(CookieMonsterLegacyCookieAccessTest, RecentHttpSameSiteAccess) {
- SetFeatures(true, true, 100, base::nullopt);
- // This feature overrides the CookieAccessDelegate setting.
- access_delegate_->SetExpectationForCookieDomain(
- kDomain, CookieAccessSemantics::NONLEGACY);
+TEST_F(CookieMonsterTest, IsCookieSentToSamePortThatSetIt) {
+ // Note: `IsCookieSentToSamePortThatSetIt()` only uses the source_scheme if
+ // the port is valid, specified, and doesn't match the url's port. So for test
+ // cases where the above aren't true the value of source_scheme is irreleant.
+
+ // Test unspecified.
+ ASSERT_EQ(CookieMonster::IsCookieSentToSamePortThatSetIt(
+ GURL("https://foo.com"), url::PORT_UNSPECIFIED,
+ CookieSourceScheme::kSecure),
+ CookieMonster::CookieSentToSamePort::kSourcePortUnspecified);
+
+ // Test invalid.
+ ASSERT_EQ(CookieMonster::IsCookieSentToSamePortThatSetIt(
+ GURL("https://foo.com"), url::PORT_INVALID,
+ CookieSourceScheme::kSecure),
+ CookieMonster::CookieSentToSamePort::kInvalid);
+
+ // Test same.
+ ASSERT_EQ(CookieMonster::IsCookieSentToSamePortThatSetIt(
+ GURL("https://foo.com"), 443, CookieSourceScheme::kSecure),
+ CookieMonster::CookieSentToSamePort::kYes);
+
+ ASSERT_EQ(
+ CookieMonster::IsCookieSentToSamePortThatSetIt(
+ GURL("https://foo.com:1234"), 1234, CookieSourceScheme::kSecure),
+ CookieMonster::CookieSentToSamePort::kYes);
+
+ // Test different but default.
+ ASSERT_EQ(CookieMonster::IsCookieSentToSamePortThatSetIt(
+ GURL("https://foo.com"), 80, CookieSourceScheme::kNonSecure),
+ CookieMonster::CookieSentToSamePort::kNoButDefault);
+
+ ASSERT_EQ(
+ CookieMonster::IsCookieSentToSamePortThatSetIt(
+ GURL("https://foo.com:443"), 80, CookieSourceScheme::kNonSecure),
+ CookieMonster::CookieSentToSamePort::kNoButDefault);
+
+ ASSERT_EQ(CookieMonster::IsCookieSentToSamePortThatSetIt(
+ GURL("wss://foo.com"), 80, CookieSourceScheme::kNonSecure),
+ CookieMonster::CookieSentToSamePort::kNoButDefault);
+
+ ASSERT_EQ(CookieMonster::IsCookieSentToSamePortThatSetIt(
+ GURL("http://foo.com"), 443, CookieSourceScheme::kSecure),
+ CookieMonster::CookieSentToSamePort::kNoButDefault);
+
+ ASSERT_EQ(CookieMonster::IsCookieSentToSamePortThatSetIt(
+ GURL("ws://foo.com"), 443, CookieSourceScheme::kSecure),
+ CookieMonster::CookieSentToSamePort::kNoButDefault);
+
+ // Test different.
+ ASSERT_EQ(CookieMonster::IsCookieSentToSamePortThatSetIt(
+ GURL("http://foo.com:9000"), 85, CookieSourceScheme::kSecure),
+ CookieMonster::CookieSentToSamePort::kNo);
+
+ ASSERT_EQ(CookieMonster::IsCookieSentToSamePortThatSetIt(
+ GURL("https://foo.com"), 80, CookieSourceScheme::kSecure),
+ CookieMonster::CookieSentToSamePort::kNo);
+
+ ASSERT_EQ(CookieMonster::IsCookieSentToSamePortThatSetIt(
+ GURL("wss://foo.com"), 80, CookieSourceScheme::kSecure),
+ CookieMonster::CookieSentToSamePort::kNo);
+
+ ASSERT_EQ(CookieMonster::IsCookieSentToSamePortThatSetIt(
+ GURL("http://foo.com"), 443, CookieSourceScheme::kNonSecure),
+ CookieMonster::CookieSentToSamePort::kNo);
+
+ ASSERT_EQ(CookieMonster::IsCookieSentToSamePortThatSetIt(
+ GURL("ws://foo.com"), 443, CookieSourceScheme::kNonSecure),
+ CookieMonster::CookieSentToSamePort::kNo);
+
+ ASSERT_EQ(CookieMonster::IsCookieSentToSamePortThatSetIt(
+ GURL("http://foo.com:444"), 443, CookieSourceScheme::kSecure),
+ CookieMonster::CookieSentToSamePort::kNo);
+}
- // Set a cookie from a qualifying (HTTP and same-site) context.
- CookieOptions http_lax_options;
- http_lax_options.set_include_httponly();
- http_lax_options.set_same_site_cookie_context(
- CookieOptions::SameSiteCookieContext(
- CookieOptions::SameSiteCookieContext::ContextType::SAME_SITE_LAX));
- // This one only works because it's treated as Legacy, otherwise it would be
- // rejected for being SameSite=None without secure.
- EXPECT_TRUE(CreateAndSetCookie(cm_.get(), kHttpUrl, "cookie=1;SameSite=None",
- http_lax_options));
- // Subsequently getting the cookie from a cross-site context also works
- // because we just accessed it in an eligible context.
- EXPECT_EQ("cookie=1",
- GetCookiesWithOptions(cm_.get(), kHttpUrl, CookieOptions()));
- // This one should work regardless.
- EXPECT_TRUE(
- CreateAndSetCookie(cm_.get(), kHttpUrl, "cookie=2", http_lax_options));
- // Subsequently getting the cookie from a cross-site context works even though
- // it defaults to Lax, because we just accessed it in an eligible context.
- EXPECT_EQ("cookie=2",
- GetCookiesWithOptions(cm_.get(), kHttpUrl, CookieOptions()));
- // After some delay less than the recency threshold, we can still get the
- // cookie from a cross-site context because the last eligible access was
- // recent enough.
- task_environment_->FastForwardBy(TimeDelta::FromMilliseconds(90));
- EXPECT_EQ("cookie=2",
- GetCookiesWithOptions(cm_.get(), kHttpUrl, CookieOptions()));
- // After a further delay that passes the recency threshold, we can no longer
- // get the cookie from a cross-site context.
- // Notably, the last access didn't reset the timer because it wasn't a
- // same-site access.
- task_environment_->FastForwardBy(TimeDelta::FromMilliseconds(20));
- EXPECT_EQ("", GetCookiesWithOptions(cm_.get(), kHttpUrl, CookieOptions()));
+TEST_F(CookieMonsterTest, CookieDomainSetHistogram) {
+ base::HistogramTester histograms;
+ const char kHistogramName[] = "Cookie.DomainSet";
- // Deleting the cookie clears the last access time.
- DeleteAll(cm_.get());
+ scoped_refptr<MockPersistentCookieStore> store(new MockPersistentCookieStore);
+ std::unique_ptr<CookieMonster> cm(new CookieMonster(store.get(), &net_log_));
- // Set a cookie from a same-site but not Http context. This should work
- // because it's same-site, but does not activate the feature because it isn't
- // http.
- CookieOptions exclude_http_lax_options;
- exclude_http_lax_options.set_exclude_httponly();
- exclude_http_lax_options.set_same_site_cookie_context(
- CookieOptions::SameSiteCookieContext(
- CookieOptions::SameSiteCookieContext::ContextType::SAME_SITE_LAX));
- EXPECT_TRUE(CreateAndSetCookie(cm_.get(), kHttpUrl, "cookie=1",
- exclude_http_lax_options));
- // There is no recent eligible last access time, because we deleted the
- // cookie and subsequently re-set it from a non-eligible context.
- EXPECT_EQ("", GetCookiesWithOptions(cm_.get(), kHttpUrl, CookieOptions()));
- // Accessing it from a laxly same-site context works (because the cookie
- // defaults to lax).
- EXPECT_EQ("cookie=1",
- GetCookiesWithOptions(cm_.get(), kHttpUrl, http_lax_options));
- // However that doesn't count as a recent http same-site access because it was
- // only laxly (not strictly) same-site, so getting the cookie from a
- // cross-site context does not currently work.
- EXPECT_EQ("", GetCookiesWithOptions(cm_.get(), kHttpUrl, CookieOptions()));
- // Attempting to set a cookie (unsuccessfully) from an eligible context does
- // not count.
- CookieOptions http_strict_options;
- http_strict_options.set_include_httponly();
- http_strict_options.set_same_site_cookie_context(
- CookieOptions::SameSiteCookieContext(
- CookieOptions::SameSiteCookieContext::ContextType::SAME_SITE_STRICT));
- EXPECT_FALSE(CreateAndSetCookie(cm_.get(), kHttpUrl, "cookie=2;Secure",
- http_strict_options));
- EXPECT_EQ("", GetCookiesWithOptions(cm_.get(), kHttpUrl, CookieOptions()));
- // Now get the cookie from an eligible, Http and strictly same-site context.
- EXPECT_EQ("cookie=1",
- GetCookiesWithOptions(cm_.get(), kHttpUrl, http_strict_options));
- // Subsequently getting the cookie from a cross-site context also works
- // because we just accessed it in an eligible context.
- EXPECT_EQ("cookie=1",
- GetCookiesWithOptions(cm_.get(), kHttpUrl, CookieOptions()));
- // After some delay less than the recency threshold, we can still get the
- // cookie from a cross-site context because the last eligible access was
- // recent enough.
- task_environment_->FastForwardBy(TimeDelta::FromMilliseconds(90));
- EXPECT_EQ("cookie=1",
- GetCookiesWithOptions(cm_.get(), kHttpUrl, CookieOptions()));
- // After a further delay that passes the recency threshold, we can no longer
- // get the cookie from a cross-site context.
- // Notably, the last access didn't reset the timer because it wasn't a
- // same-site access.
- task_environment_->FastForwardBy(TimeDelta::FromMilliseconds(20));
- EXPECT_EQ("", GetCookiesWithOptions(cm_.get(), kHttpUrl, CookieOptions()));
+ histograms.ExpectTotalCount(kHistogramName, 0);
+
+ // Set a host only cookie (non-Domain).
+ EXPECT_TRUE(SetCookie(cm.get(), https_www_foo_.url(), "A=B"));
+ histograms.ExpectTotalCount(kHistogramName, 1);
+ histograms.ExpectBucketCount(kHistogramName, false, 1);
+
+ // Set a domain cookie.
+ EXPECT_TRUE(SetCookie(cm.get(), https_www_foo_.url(),
+ "A=B; Domain=" + https_www_foo_.host()));
+ histograms.ExpectTotalCount(kHistogramName, 2);
+ histograms.ExpectBucketCount(kHistogramName, true, 1);
+
+ // Invalid cookies don't count toward the histogram.
+ EXPECT_FALSE(
+ SetCookie(cm.get(), https_www_foo_.url(), "A=B; Domain=other.com"));
+ histograms.ExpectTotalCount(kHistogramName, 2);
+ histograms.ExpectBucketCount(kHistogramName, false, 1);
}
-// Test the RecentCreationTimeGrantsLegacyCookieSemantics feature.
-TEST_F(CookieMonsterLegacyCookieAccessTest, RecentCreationTime) {
- SetFeatures(true, true, base::nullopt, 100);
- // This feature overrides the CookieAccessDelegate setting.
- access_delegate_->SetExpectationForCookieDomain(
- kDomain, CookieAccessSemantics::NONLEGACY);
+TEST_F(CookieMonsterTest, CookiePortReadHistogram) {
+ base::HistogramTester histograms;
+ const char kHistogramName[] = "Cookie.Port.Read.RemoteHost";
+ const char kHistogramNameLocal[] = "Cookie.Port.Read.Localhost";
- // While the grace period is active, even if the delegate returns NONLEGACY
- // semantics, we are able to set unspecified-SameSite cookies from a
- // cross-site context, and we are allowed to set SameSite=None cookies without
- // Secure. We are also allowed to get such cookies.
- EXPECT_TRUE(CreateAndSetCookie(cm_.get(), kHttpUrl, "cookie1=chocolate_chip",
- CookieOptions()));
- EXPECT_TRUE(CreateAndSetCookie(cm_.get(), kHttpUrl,
- "cookie2=oatmeal_raisin; SameSite=None",
- CookieOptions()));
- EXPECT_EQ("cookie1=chocolate_chip; cookie2=oatmeal_raisin",
- GetCookiesWithOptions(cm_.get(), kHttpUrl, CookieOptions()));
+ scoped_refptr<MockPersistentCookieStore> store(new MockPersistentCookieStore);
+ std::unique_ptr<CookieMonster> cm(new CookieMonster(store.get(), &net_log_));
- // After some time passes, but we are still under the time threshold,
- // the cookie is still accessible in a cross-site context.
- task_environment_->FastForwardBy(TimeDelta::FromMilliseconds(90));
- EXPECT_EQ("cookie1=chocolate_chip; cookie2=oatmeal_raisin",
- GetCookiesWithOptions(cm_.get(), kHttpUrl, CookieOptions()));
- // After the grace period expires, these cookies are now blocked.
- task_environment_->FastForwardBy(TimeDelta::FromMilliseconds(20));
- EXPECT_EQ("", GetCookiesWithOptions(cm_.get(), kHttpUrl, CookieOptions()));
+ histograms.ExpectTotalCount(kHistogramName, 0);
- // Also, now that there is a preexisting cookie in the store that's older than
- // the grace period, the same cookie will not be granted legacy semantics
- // again because the creation date of the preexisting identical cookie is
- // inherited. (This disallows refreshing the grace period by repeatedly
- // setting an identical cookie.)
- EXPECT_FALSE(CreateAndSetCookie(cm_.get(), kHttpUrl, "cookie1=chocolate_chip",
- CookieOptions()));
- EXPECT_FALSE(CreateAndSetCookie(cm_.get(), kHttpUrl,
- "cookie2=oatmeal_raisin; SameSite=None",
- CookieOptions()));
- // However, an equivalent (but not identical) cookie can still be set with
- // legacy semantics, because now the creation date isn't inherited from the
- // preexisting cookie.
- // TODO(chlily): It might not actually make sense to allow this... This could
- // in effect allow repeatedly refreshing the grace period by setting a cookie
- // with a different value and then immediately setting it back to the original
- // value.
- EXPECT_TRUE(CreateAndSetCookie(cm_.get(), kHttpUrl, "cookie1=snickerdoodle",
- CookieOptions()));
- EXPECT_TRUE(CreateAndSetCookie(cm_.get(), kHttpUrl,
- "cookie2=gingerbread; SameSite=None",
- CookieOptions()));
+ EXPECT_TRUE(SetCookie(cm.get(), GURL("https://www.foo.com"), "A=B"));
- // Test the behavior when the time threshold is 0 (the default value).
- SetFeatures(true, true, base::nullopt, 0);
- // No legacy behavior is used if there is no active, non-zero grace period.
- // In particular, if there is a zero grace period, we don't allow setting the
- // cookie even if it was created at the very instant it was attempted to be
- // set.
- EXPECT_FALSE(CreateAndSetCookie(cm_.get(), kHttpUrl, "cookie1=chocolate_chip",
- CookieOptions()));
- EXPECT_FALSE(CreateAndSetCookie(cm_.get(), kHttpUrl,
- "cookie2=oatmeal_raisin; SameSite=None",
- CookieOptions()));
+ // May as well check that it didn't change the histogram...
+ histograms.ExpectTotalCount(kHistogramName, 0);
+
+ // Now read it from some different ports. This requires some knowledge of how
+ // `ReducePortRangeForCookieHistogram` maps ports, but that's probably fine.
+ EXPECT_EQ(GetCookies(cm.get(), GURL("https://www.foo.com")), "A=B");
+ // https default is 443, so check that.
+ histograms.ExpectTotalCount(kHistogramName, 1);
+ histograms.ExpectBucketCount(kHistogramName,
+ ReducePortRangeForCookieHistogram(443), 1);
+
+ EXPECT_EQ(GetCookies(cm.get(), GURL("https://www.foo.com:82")), "A=B");
+ histograms.ExpectTotalCount(kHistogramName, 2);
+ histograms.ExpectBucketCount(kHistogramName,
+ ReducePortRangeForCookieHistogram(82), 1);
+
+ EXPECT_EQ(GetCookies(cm.get(), GURL("https://www.foo.com:8080")), "A=B");
+ histograms.ExpectTotalCount(kHistogramName, 3);
+ histograms.ExpectBucketCount(kHistogramName,
+ ReducePortRangeForCookieHistogram(8080), 1);
+
+ EXPECT_EQ(GetCookies(cm.get(), GURL("https://www.foo.com:1234")), "A=B");
+ histograms.ExpectTotalCount(kHistogramName, 4);
+ histograms.ExpectBucketCount(kHistogramName,
+ ReducePortRangeForCookieHistogram(1234), 1);
+
+ // Histogram should not increment if nothing is read.
+ EXPECT_EQ(GetCookies(cm.get(), GURL("https://www.other.com")), "");
+ histograms.ExpectTotalCount(kHistogramName, 4);
+
+ // Make sure the correct histogram is chosen for localhost.
+ EXPECT_TRUE(SetCookie(cm.get(), GURL("https://localhost"), "local=host"));
+
+ histograms.ExpectTotalCount(kHistogramNameLocal, 0);
+
+ EXPECT_EQ(GetCookies(cm.get(), GURL("https://localhost:82")), "local=host");
+ histograms.ExpectTotalCount(kHistogramNameLocal, 1);
+ histograms.ExpectBucketCount(kHistogramNameLocal,
+ ReducePortRangeForCookieHistogram(82), 1);
+}
+
+TEST_F(CookieMonsterTest, CookiePortSetHistogram) {
+ base::HistogramTester histograms;
+ const char kHistogramName[] = "Cookie.Port.Set.RemoteHost";
+ const char kHistogramNameLocal[] = "Cookie.Port.Set.Localhost";
+
+ scoped_refptr<MockPersistentCookieStore> store(new MockPersistentCookieStore);
+ std::unique_ptr<CookieMonster> cm(new CookieMonster(store.get(), &net_log_));
+
+ histograms.ExpectTotalCount(kHistogramName, 0);
+
+ // Set some cookies. This requires some knowledge of how
+ // ReducePortRangeForCookieHistogram maps ports, but that's probably fine.
+
+ EXPECT_TRUE(SetCookie(cm.get(), GURL("https://www.foo.com"), "A=B"));
+ histograms.ExpectTotalCount(kHistogramName, 1);
+ histograms.ExpectBucketCount(kHistogramName,
+ ReducePortRangeForCookieHistogram(443), 1);
+
+ EXPECT_TRUE(SetCookie(cm.get(), GURL("https://www.foo.com:80"), "A=B"));
+ histograms.ExpectTotalCount(kHistogramName, 2);
+ histograms.ExpectBucketCount(kHistogramName,
+ ReducePortRangeForCookieHistogram(80), 1);
+
+ EXPECT_TRUE(SetCookie(cm.get(), GURL("https://www.foo.com:9000"), "A=B"));
+ histograms.ExpectTotalCount(kHistogramName, 3);
+ histograms.ExpectBucketCount(kHistogramName,
+ ReducePortRangeForCookieHistogram(9000), 1);
+
+ EXPECT_TRUE(SetCookie(cm.get(), GURL("https://www.foo.com:1234"), "A=B"));
+ histograms.ExpectTotalCount(kHistogramName, 4);
+ histograms.ExpectBucketCount(kHistogramName,
+ ReducePortRangeForCookieHistogram(1234), 1);
+
+ // Histogram should not increment for invalid cookie.
+ EXPECT_FALSE(SetCookie(cm.get(), GURL("https://www.foo.com"),
+ "A=B; Domain=malformedcookie.com"));
+ histograms.ExpectTotalCount(kHistogramName, 4);
+
+ // Nor should it increment for a read operation
+ EXPECT_NE(GetCookies(cm.get(), GURL("https://www.foo.com")), "");
+ histograms.ExpectTotalCount(kHistogramName, 4);
+
+ // Make sure the correct histogram is chosen for localhost.
+ histograms.ExpectTotalCount(kHistogramNameLocal, 0);
+
+ EXPECT_TRUE(
+ SetCookie(cm.get(), GURL("https://localhost:1234"), "local=host"));
+ histograms.ExpectTotalCount(kHistogramNameLocal, 1);
+ histograms.ExpectBucketCount(kHistogramNameLocal,
+ ReducePortRangeForCookieHistogram(1234), 1);
+}
+
+TEST_F(CookieMonsterTest, CookiePortReadDiffersFromSetHistogram) {
+ base::HistogramTester histograms;
+ const char kHistogramName[] = "Cookie.Port.ReadDiffersFromSet.RemoteHost";
+ const char kHistogramNameLocal[] = "Cookie.Port.ReadDiffersFromSet.Localhost";
+ const char kHistogramNameDomainSet[] =
+ "Cookie.Port.ReadDiffersFromSet.DomainSet";
+
+ scoped_refptr<MockPersistentCookieStore> store(new MockPersistentCookieStore);
+ std::unique_ptr<CookieMonster> cm(new CookieMonster(store.get(), &net_log_));
+
+ histograms.ExpectTotalCount(kHistogramName, 0);
+
+ // Set some cookies. One with a port, one without, and one with an invalid
+ // port.
+ EXPECT_TRUE(SetCookie(cm.get(), GURL("https://www.foo.com/withport"),
+ "A=B; Path=/withport")); // Port 443
+
+ auto unspecified_cookie = CanonicalCookie::Create(
+ GURL("https://www.foo.com/withoutport"), "C=D; Path=/withoutport",
+ base::Time::Now(), base::nullopt);
+ // Force to be unspecified.
+ unspecified_cookie->SetSourcePort(url::PORT_UNSPECIFIED);
+ EXPECT_TRUE(SetCanonicalCookieReturnAccessResult(
+ cm.get(), std::move(unspecified_cookie),
+ GURL("https://www.foo.com/withoutport"),
+ false /*can_modify_httponly*/)
+ .status.IsInclude());
+
+ auto invalid_cookie = CanonicalCookie::Create(
+ GURL("https://www.foo.com/invalidport"), "E=F; Path=/invalidport",
+ base::Time::Now(), base::nullopt);
+ // Force to be invalid.
+ invalid_cookie->SetSourcePort(99999);
+ EXPECT_TRUE(SetCanonicalCookieReturnAccessResult(
+ cm.get(), std::move(invalid_cookie),
+ GURL("https://www.foo.com/invalidport"),
+ false /*can_modify_httponly*/)
+ .status.IsInclude());
+
+ // Try same port.
+ EXPECT_EQ(GetCookies(cm.get(), GURL("https://www.foo.com/withport")), "A=B");
+ histograms.ExpectTotalCount(kHistogramName, 1);
+ histograms.ExpectBucketCount(kHistogramName,
+ CookieMonster::CookieSentToSamePort::kYes, 1);
+
+ // Try different port.
+ EXPECT_EQ(GetCookies(cm.get(), GURL("https://www.foo.com:8080/withport")),
+ "A=B");
+ histograms.ExpectTotalCount(kHistogramName, 2);
+ histograms.ExpectBucketCount(kHistogramName,
+ CookieMonster::CookieSentToSamePort::kNo, 1);
+
+ // Try different port, but it's the default for a different scheme.
+ EXPECT_EQ(GetCookies(cm.get(), GURL("http://www.foo.com/withport")), "A=B");
+ histograms.ExpectTotalCount(kHistogramName, 3);
+ histograms.ExpectBucketCount(
+ kHistogramName, CookieMonster::CookieSentToSamePort::kNoButDefault, 1);
+
+ // Now try it with an unspecified port cookie.
+ EXPECT_EQ(GetCookies(cm.get(), GURL("http://www.foo.com/withoutport")),
+ "C=D");
+ histograms.ExpectTotalCount(kHistogramName, 4);
+ histograms.ExpectBucketCount(
+ kHistogramName,
+ CookieMonster::CookieSentToSamePort::kSourcePortUnspecified, 1);
+
+ // Finally try it with an invalid port cookie.
+ EXPECT_EQ(GetCookies(cm.get(), GURL("http://www.foo.com/invalidport")),
+ "E=F");
+ histograms.ExpectTotalCount(kHistogramName, 5);
+ histograms.ExpectBucketCount(
+ kHistogramName, CookieMonster::CookieSentToSamePort::kInvalid, 1);
+
+ // Make sure the correct histogram is chosen for localhost.
+ histograms.ExpectTotalCount(kHistogramNameLocal, 0);
+ EXPECT_TRUE(SetCookie(cm.get(), GURL("https://localhost"), "local=host"));
+
+ EXPECT_EQ(GetCookies(cm.get(), GURL("https://localhost")), "local=host");
+ histograms.ExpectTotalCount(kHistogramNameLocal, 1);
+ histograms.ExpectBucketCount(kHistogramNameLocal,
+ CookieMonster::CookieSentToSamePort::kYes, 1);
+
+ // Make sure the Domain set version works.
+ EXPECT_TRUE(SetCookie(cm.get(), GURL("https://www.foo.com/withDomain"),
+ "W=D; Domain=foo.com; Path=/withDomain"));
+
+ histograms.ExpectTotalCount(kHistogramNameDomainSet, 0);
+
+ EXPECT_EQ(GetCookies(cm.get(), GURL("https://www.foo.com/withDomain")),
+ "W=D");
+ histograms.ExpectTotalCount(kHistogramNameDomainSet, 1);
+ histograms.ExpectBucketCount(kHistogramNameDomainSet,
+ CookieMonster::CookieSentToSamePort::kYes, 1);
+ // The RemoteHost histogram should also increase with this cookie. Domain
+ // cookies aren't special insofar as this metric is concerned.
+ histograms.ExpectTotalCount(kHistogramName, 6);
+ histograms.ExpectBucketCount(kHistogramName,
+ CookieMonster::CookieSentToSamePort::kYes, 2);
}
} // namespace net
diff --git a/chromium/net/cookies/cookie_options.cc b/chromium/net/cookies/cookie_options.cc
index 3ab86e67f0c..c05d0c00c23 100644
--- a/chromium/net/cookies/cookie_options.cc
+++ b/chromium/net/cookies/cookie_options.cc
@@ -51,12 +51,20 @@ CookieOptions::CookieOptions()
update_access_time_(true),
return_excluded_cookies_(false) {}
+CookieOptions::CookieOptions(const CookieOptions& other) = default;
+CookieOptions::CookieOptions(CookieOptions&& other) = default;
+CookieOptions::~CookieOptions() = default;
+
+CookieOptions& CookieOptions::operator=(const CookieOptions&) = default;
+CookieOptions& CookieOptions::operator=(CookieOptions&&) = default;
+
// static
CookieOptions CookieOptions::MakeAllInclusive() {
CookieOptions options;
options.set_include_httponly();
options.set_same_site_cookie_context(SameSiteCookieContext::MakeInclusive());
options.set_do_not_update_access_time();
+ options.set_full_party_context(std::set<net::SchemefulSite>());
return options;
}
diff --git a/chromium/net/cookies/cookie_options.h b/chromium/net/cookies/cookie_options.h
index abf074b6aab..821ac334199 100644
--- a/chromium/net/cookies/cookie_options.h
+++ b/chromium/net/cookies/cookie_options.h
@@ -7,8 +7,12 @@
#ifndef NET_COOKIES_COOKIE_OPTIONS_H_
#define NET_COOKIES_COOKIE_OPTIONS_H_
+#include <set>
+
+#include "base/optional.h"
#include "base/time/time.h"
#include "net/base/net_export.h"
+#include "net/base/schemeful_site.h"
#include "net/cookies/cookie_constants.h"
#include "url/gurl.h"
@@ -88,13 +92,21 @@ class NET_EXPORT CookieOptions {
// * Excludes SameSite cookies
// * Updates last-accessed time.
// * Does not report excluded cookies in APIs that can do so.
+ // * Excludes SameParty cookies.
//
// These settings can be altered by calling:
//
// * |set_{include,exclude}_httponly()|
// * |set_same_site_cookie_context()|
// * |set_do_not_update_access_time()|
+ // * |set_full_party_context()|
CookieOptions();
+ CookieOptions(const CookieOptions& other);
+ CookieOptions(CookieOptions&& other);
+ ~CookieOptions();
+
+ CookieOptions& operator=(const CookieOptions&);
+ CookieOptions& operator=(CookieOptions&&);
void set_exclude_httponly() { exclude_httponly_ = true; }
void set_include_httponly() { exclude_httponly_ = false; }
@@ -118,6 +130,15 @@ class NET_EXPORT CookieOptions {
void unset_return_excluded_cookies() { return_excluded_cookies_ = false; }
bool return_excluded_cookies() const { return return_excluded_cookies_; }
+ void set_full_party_context(
+ const base::Optional<std::set<net::SchemefulSite>>& full_party_context) {
+ full_party_context_ = full_party_context;
+ }
+ const base::Optional<std::set<net::SchemefulSite>>& full_party_context()
+ const {
+ return full_party_context_;
+ }
+
// Convenience method for where you need a CookieOptions that will
// work for getting/setting all types of cookies, including HttpOnly and
// SameSite cookies. Also specifies not to update the access time, because
@@ -130,7 +151,8 @@ class NET_EXPORT CookieOptions {
bool exclude_httponly_;
SameSiteCookieContext same_site_cookie_context_;
bool update_access_time_;
- bool return_excluded_cookies_;
+ bool return_excluded_cookies_ = false;
+ base::Optional<std::set<net::SchemefulSite>> full_party_context_;
};
} // namespace net
diff --git a/chromium/net/cookies/cookie_store_unittest.h b/chromium/net/cookies/cookie_store_unittest.h
index c2f495bedce..29a520956b6 100644
--- a/chromium/net/cookies/cookie_store_unittest.h
+++ b/chromium/net/cookies/cookie_store_unittest.h
@@ -423,7 +423,7 @@ TYPED_TEST_P(CookieStoreTest, FilterTest) {
std::unique_ptr<CanonicalCookie> cc(CanonicalCookie::CreateSanitizedCookie(
this->www_foo_foo_.url(), "A", "B", std::string(), "/foo", one_hour_ago,
one_hour_from_now, base::Time(), false, false,
- CookieSameSite::STRICT_MODE, COOKIE_PRIORITY_DEFAULT));
+ CookieSameSite::STRICT_MODE, COOKIE_PRIORITY_DEFAULT, false));
ASSERT_TRUE(cc);
EXPECT_TRUE(this->SetCanonicalCookie(
cs, std::move(cc), this->www_foo_foo_.url(), true /*modify_httponly*/));
@@ -433,7 +433,7 @@ TYPED_TEST_P(CookieStoreTest, FilterTest) {
cc = CanonicalCookie::CreateSanitizedCookie(
this->www_foo_bar_.url(), "C", "D", this->www_foo_bar_.domain(), "/bar",
two_hours_ago, base::Time(), one_hour_ago, false, true,
- CookieSameSite::STRICT_MODE, COOKIE_PRIORITY_DEFAULT);
+ CookieSameSite::STRICT_MODE, COOKIE_PRIORITY_DEFAULT, false);
ASSERT_TRUE(cc);
EXPECT_TRUE(this->SetCanonicalCookie(
cs, std::move(cc), this->www_foo_bar_.url(), true /*modify_httponly*/));
@@ -444,13 +444,13 @@ TYPED_TEST_P(CookieStoreTest, FilterTest) {
cc = CanonicalCookie::CreateSanitizedCookie(
this->http_www_foo_.url(), "E", "F", std::string(), std::string(),
base::Time(), base::Time(), base::Time(), true, false,
- CookieSameSite::NO_RESTRICTION, COOKIE_PRIORITY_DEFAULT);
+ CookieSameSite::NO_RESTRICTION, COOKIE_PRIORITY_DEFAULT, false);
ASSERT_FALSE(cc);
cc = CanonicalCookie::CreateSanitizedCookie(
this->https_www_foo_.url(), "E", "F", std::string(), std::string(),
base::Time(), base::Time(), base::Time(), true, false,
- CookieSameSite::NO_RESTRICTION, COOKIE_PRIORITY_DEFAULT);
+ CookieSameSite::NO_RESTRICTION, COOKIE_PRIORITY_DEFAULT, false);
ASSERT_TRUE(cc);
EXPECT_TRUE(this->SetCanonicalCookie(
cs, std::move(cc), this->https_www_foo_.url(), true /*modify_httponly*/));
@@ -550,14 +550,14 @@ TYPED_TEST_P(CookieStoreTest, SetCanonicalCookieTest) {
std::make_unique<CanonicalCookie>(
"A", "B", foo_foo_host, "/foo", one_hour_ago, one_hour_from_now,
base::Time(), false /* secure */, false /* httponly */,
- CookieSameSite::LAX_MODE, COOKIE_PRIORITY_DEFAULT),
+ CookieSameSite::LAX_MODE, COOKIE_PRIORITY_DEFAULT, false),
this->www_foo_foo_.url(), true));
EXPECT_TRUE(this->SetCanonicalCookie(
cs,
std::make_unique<CanonicalCookie>(
"C", "D", "." + foo_bar_domain, "/bar", two_hours_ago, base::Time(),
one_hour_ago, false, true, CookieSameSite::LAX_MODE,
- COOKIE_PRIORITY_DEFAULT),
+ COOKIE_PRIORITY_DEFAULT, false),
this->www_foo_bar_.url(), true));
// A secure source is required for setting secure cookies.
@@ -567,7 +567,7 @@ TYPED_TEST_P(CookieStoreTest, SetCanonicalCookieTest) {
std::make_unique<CanonicalCookie>(
"E", "F", http_foo_host, "/", base::Time(), base::Time(),
base::Time(), true, false, CookieSameSite::NO_RESTRICTION,
- COOKIE_PRIORITY_DEFAULT),
+ COOKIE_PRIORITY_DEFAULT, false),
this->http_www_foo_.url(), true)
.status.HasExclusionReason(
CookieInclusionStatus::EXCLUDE_SECURE_ONLY));
@@ -592,19 +592,20 @@ TYPED_TEST_P(CookieStoreTest, SetCanonicalCookieTest) {
std::make_unique<CanonicalCookie>(
"E", "F", https_foo_host, "/", base::Time(), base::Time(),
base::Time(), true /* secure */, false /* httponly */,
- CookieSameSite::NO_RESTRICTION, COOKIE_PRIORITY_DEFAULT),
+ CookieSameSite::NO_RESTRICTION, COOKIE_PRIORITY_DEFAULT,
+ false /* same_party */),
this->https_www_foo_.url(), true /* modify_http_only */));
- EXPECT_TRUE(
- this->SetCanonicalCookieReturnAccessResult(
- cs,
- std::make_unique<CanonicalCookie>(
- "E", "F", http_foo_host, "/", base::Time(), base::Time(),
- base::Time(), true /* secure */, false /* httponly */,
- CookieSameSite::NO_RESTRICTION, COOKIE_PRIORITY_DEFAULT),
- this->http_www_foo_.url(), true /* modify_http_only */)
- .status.HasExclusionReason(
- CookieInclusionStatus::EXCLUDE_SECURE_ONLY));
+ EXPECT_TRUE(this->SetCanonicalCookieReturnAccessResult(
+ cs,
+ std::make_unique<CanonicalCookie>(
+ "E", "F", http_foo_host, "/", base::Time(),
+ base::Time(), base::Time(), true /* secure */,
+ false /* httponly */, CookieSameSite::NO_RESTRICTION,
+ COOKIE_PRIORITY_DEFAULT, false /* same_party */),
+ this->http_www_foo_.url(), true /* modify_http_only */)
+ .status.HasExclusionReason(
+ CookieInclusionStatus::EXCLUDE_SECURE_ONLY));
if (TypeParam::supports_http_only) {
// Permission to modify http only cookies is required to set an
@@ -615,7 +616,7 @@ TYPED_TEST_P(CookieStoreTest, SetCanonicalCookieTest) {
"G", "H", http_foo_host, "/unique", base::Time(),
base::Time(), base::Time(), false /* secure */,
true /* httponly */, CookieSameSite::LAX_MODE,
- COOKIE_PRIORITY_DEFAULT),
+ COOKIE_PRIORITY_DEFAULT, false /* same_party */),
this->http_www_foo_.url(), false /* modify_http_only */)
.status.HasExclusionReason(
CookieInclusionStatus::EXCLUDE_HTTP_ONLY));
@@ -641,7 +642,8 @@ TYPED_TEST_P(CookieStoreTest, SetCanonicalCookieTest) {
std::make_unique<CanonicalCookie>(
"G", "H", http_foo_host, "/unique", base::Time(), base::Time(),
base::Time(), false /* secure */, true /* httponly */,
- CookieSameSite::LAX_MODE, COOKIE_PRIORITY_DEFAULT),
+ CookieSameSite::LAX_MODE, COOKIE_PRIORITY_DEFAULT,
+ false /* same_party */),
this->http_www_foo_.url(), true /* modify_http_only */));
EXPECT_TRUE(this->SetCanonicalCookieReturnAccessResult(
@@ -650,7 +652,7 @@ TYPED_TEST_P(CookieStoreTest, SetCanonicalCookieTest) {
"G", "H", http_foo_host, "/unique", base::Time(),
base::Time(), base::Time(), false /* secure */,
true /* httponly */, CookieSameSite::LAX_MODE,
- COOKIE_PRIORITY_DEFAULT),
+ COOKIE_PRIORITY_DEFAULT, false /* same_party */),
this->http_www_foo_.url(), false /* modify_http_only */)
.status.HasExclusionReason(
CookieInclusionStatus::EXCLUDE_HTTP_ONLY));
@@ -661,7 +663,8 @@ TYPED_TEST_P(CookieStoreTest, SetCanonicalCookieTest) {
std::make_unique<CanonicalCookie>(
"G", "H", http_foo_host, "/unique", base::Time(), base::Time(),
base::Time(), false /* secure */, true /* httponly */,
- CookieSameSite::LAX_MODE, COOKIE_PRIORITY_DEFAULT),
+ CookieSameSite::LAX_MODE, COOKIE_PRIORITY_DEFAULT,
+ false /* same_party */),
this->http_www_foo_.url(), true /* modify_http_only */));
}
@@ -739,28 +742,28 @@ TYPED_TEST_P(CookieStoreTest, SecureEnforcement) {
std::make_unique<CanonicalCookie>(
"A", "B", http_domain, "/", base::Time::Now(), base::Time(),
base::Time(), true, false, CookieSameSite::STRICT_MODE,
- COOKIE_PRIORITY_DEFAULT),
+ COOKIE_PRIORITY_DEFAULT, false /* same_party */),
http_url, true /*modify_httponly*/));
EXPECT_TRUE(this->SetCanonicalCookie(
cs,
std::make_unique<CanonicalCookie>(
"A", "B", http_domain, "/", base::Time::Now(), base::Time(),
base::Time(), true, false, CookieSameSite::STRICT_MODE,
- COOKIE_PRIORITY_DEFAULT),
+ COOKIE_PRIORITY_DEFAULT, false /* same_party */),
https_url, true /*modify_httponly*/));
EXPECT_TRUE(this->SetCanonicalCookie(
cs,
std::make_unique<CanonicalCookie>(
"A", "B", http_domain, "/", base::Time::Now(), base::Time(),
base::Time(), false, false, CookieSameSite::STRICT_MODE,
- COOKIE_PRIORITY_DEFAULT),
+ COOKIE_PRIORITY_DEFAULT, false /* same_party */),
https_url, true /*modify_httponly*/));
EXPECT_TRUE(this->SetCanonicalCookie(
cs,
std::make_unique<CanonicalCookie>(
"A", "B", http_domain, "/", base::Time::Now(), base::Time(),
base::Time(), false, false, CookieSameSite::STRICT_MODE,
- COOKIE_PRIORITY_DEFAULT),
+ COOKIE_PRIORITY_DEFAULT, false /* same_party */),
http_url, true /*modify_httponly*/));
}
diff --git a/chromium/net/cookies/cookie_util.cc b/chromium/net/cookies/cookie_util.cc
index 86735d1d510..27d2486ba40 100644
--- a/chromium/net/cookies/cookie_util.cc
+++ b/chromium/net/cookies/cookie_util.cc
@@ -630,51 +630,6 @@ bool IsSchemefulSameSiteEnabled() {
return base::FeatureList::IsEnabled(features::kSchemefulSameSite);
}
-bool IsRecentHttpSameSiteAccessGrantsLegacyCookieSemanticsEnabled() {
- return IsSameSiteByDefaultCookiesEnabled() &&
- base::FeatureList::IsEnabled(
- features::kRecentHttpSameSiteAccessGrantsLegacyCookieSemantics) &&
- features::
- kRecentHttpSameSiteAccessGrantsLegacyCookieSemanticsMilliseconds
- .Get() > 0;
-}
-
-bool IsRecentCreationTimeGrantsLegacyCookieSemanticsEnabled() {
- return IsSameSiteByDefaultCookiesEnabled() &&
- base::FeatureList::IsEnabled(
- features::kRecentCreationTimeGrantsLegacyCookieSemantics) &&
- features::kRecentCreationTimeGrantsLegacyCookieSemanticsMilliseconds
- .Get() > 0;
-}
-
-bool DoesLastHttpSameSiteAccessGrantLegacySemantics(
- base::TimeTicks last_http_same_site_access) {
- if (last_http_same_site_access.is_null())
- return false;
- if (!IsRecentHttpSameSiteAccessGrantsLegacyCookieSemanticsEnabled())
- return false;
-
- base::TimeDelta recency_threshold = base::TimeDelta::FromMilliseconds(
- features::kRecentHttpSameSiteAccessGrantsLegacyCookieSemanticsMilliseconds
- .Get());
- DCHECK(!recency_threshold.is_zero());
- return (base::TimeTicks::Now() - last_http_same_site_access) <
- recency_threshold;
-}
-
-bool DoesCreationTimeGrantLegacySemantics(base::Time creation_date) {
- if (creation_date.is_null())
- return false;
- if (!IsRecentCreationTimeGrantsLegacyCookieSemanticsEnabled())
- return false;
-
- base::TimeDelta recency_threshold = base::TimeDelta::FromMilliseconds(
- features::kRecentCreationTimeGrantsLegacyCookieSemanticsMilliseconds
- .Get());
- DCHECK(!recency_threshold.is_zero());
- return (base::Time::Now() - creation_date) < recency_threshold;
-}
-
base::OnceCallback<void(CookieAccessResult)> AdaptCookieAccessResultToBool(
base::OnceCallback<void(bool)> callback) {
return base::BindOnce(
@@ -696,5 +651,20 @@ CookieList StripAccessResults(
return cookies;
}
+NET_EXPORT void RecordCookiePortOmniboxHistograms(const GURL& url) {
+ int port = url.EffectiveIntPort();
+
+ if (port == url::PORT_UNSPECIFIED)
+ return;
+
+ if (IsLocalhost(url)) {
+ UMA_HISTOGRAM_ENUMERATION("Cookie.Port.OmniboxURLNavigation.Localhost",
+ ReducePortRangeForCookieHistogram(port));
+ } else {
+ UMA_HISTOGRAM_ENUMERATION("Cookie.Port.OmniboxURLNavigation.RemoteHost",
+ ReducePortRangeForCookieHistogram(port));
+ }
+}
+
} // namespace cookie_util
} // namespace net
diff --git a/chromium/net/cookies/cookie_util.h b/chromium/net/cookies/cookie_util.h
index b2b7992d03b..89209de68f7 100644
--- a/chromium/net/cookies/cookie_util.h
+++ b/chromium/net/cookies/cookie_util.h
@@ -230,21 +230,6 @@ NET_EXPORT bool IsSameSiteCompatPair(const CanonicalCookie& c1,
NET_EXPORT bool IsSameSiteByDefaultCookiesEnabled();
NET_EXPORT bool IsCookiesWithoutSameSiteMustBeSecureEnabled();
NET_EXPORT bool IsSchemefulSameSiteEnabled();
-bool IsRecentHttpSameSiteAccessGrantsLegacyCookieSemanticsEnabled();
-bool IsRecentCreationTimeGrantsLegacyCookieSemanticsEnabled();
-
-// Determines whether the last same-site access to a cookie should grant legacy
-// access semantics to the current attempted cookies access, based on the state
-// of the feature kRecentSameSiteAccessGrantsLegacyCookieSemantics, the value of
-// the feature param, and the time since the last eligible same-site access.
-bool DoesLastHttpSameSiteAccessGrantLegacySemantics(
- base::TimeTicks last_http_same_site_access);
-
-// Determines whether the creation time of a cookie should grant legacy
-// access semantics to the current attempted cookies access, based on the state
-// of the feature kRecentCreationTimeGrantsLegacyCookieSemantics, the value of
-// the feature param, and the creation time of the cookie.
-bool DoesCreationTimeGrantLegacySemantics(base::Time creation_date);
// Takes a callback accepting a CookieAccessResult and returns a callback
// that accepts a bool, setting the bool to true if the CookieInclusionStatus
@@ -260,6 +245,9 @@ AdaptCookieAccessResultToBool(base::OnceCallback<void(bool)> callback);
NET_EXPORT CookieList
StripAccessResults(const CookieAccessResultList& cookie_access_result_list);
+// Records port related metrics from Omnibox navigations.
+NET_EXPORT void RecordCookiePortOmniboxHistograms(const GURL& url);
+
} // namespace cookie_util
} // namespace net
diff --git a/chromium/net/cookies/cookie_util_unittest.cc b/chromium/net/cookies/cookie_util_unittest.cc
index 8093a6f440e..a4a3f625423 100644
--- a/chromium/net/cookies/cookie_util_unittest.cc
+++ b/chromium/net/cookies/cookie_util_unittest.cc
@@ -7,7 +7,7 @@
#include "base/callback.h"
#include "base/strings/string_split.h"
-#include "base/test/bind_test_util.h"
+#include "base/test/bind.h"
#include "net/cookies/cookie_util.h"
#include "testing/gtest/include/gtest/gtest.h"
diff --git a/chromium/net/cookies/parse_cookie_line_fuzzer.cc b/chromium/net/cookies/parse_cookie_line_fuzzer.cc
index 4ea774ab748..037662209c2 100644
--- a/chromium/net/cookies/parse_cookie_line_fuzzer.cc
+++ b/chromium/net/cookies/parse_cookie_line_fuzzer.cc
@@ -25,7 +25,7 @@ extern "C" int LLVMFuzzerTestOneInput(const uint8_t* data, size_t size) {
// Call zero or one of ParsedCookie's mutator methods. Should not call
// anything other than SetName/SetValue when !IsValid().
- const uint8_t action = data_provider.ConsumeIntegralInRange(0, 10);
+ const uint8_t action = data_provider.ConsumeIntegralInRange(0, 11);
switch (action) {
case 1:
parsed_cookie.SetName(GetArbitraryString(&data_provider));
@@ -62,6 +62,9 @@ extern "C" int LLVMFuzzerTestOneInput(const uint8_t* data, size_t size) {
case 10:
parsed_cookie.SetPriority(GetArbitraryString(&data_provider));
break;
+ case 11:
+ parsed_cookie.SetIsSameParty(data_provider.ConsumeBool());
+ break;
}
}
diff --git a/chromium/net/cookies/parsed_cookie.cc b/chromium/net/cookies/parsed_cookie.cc
index 6da21345f8b..a2626774945 100644
--- a/chromium/net/cookies/parsed_cookie.cc
+++ b/chromium/net/cookies/parsed_cookie.cc
@@ -60,6 +60,7 @@ const char kSecureTokenName[] = "secure";
const char kHttpOnlyTokenName[] = "httponly";
const char kSameSiteTokenName[] = "samesite";
const char kPriorityTokenName[] = "priority";
+const char kSamePartyTokenName[] = "sameparty";
const char kTerminator[] = "\n\r\0";
const int kTerminatorLen = sizeof(kTerminator) - 1;
@@ -129,15 +130,7 @@ bool IsControlCharacter(unsigned char c) {
namespace net {
-ParsedCookie::ParsedCookie(const std::string& cookie_line)
- : path_index_(0),
- domain_index_(0),
- expires_index_(0),
- maxage_index_(0),
- secure_index_(0),
- httponly_index_(0),
- same_site_index_(0),
- priority_index_(0) {
+ParsedCookie::ParsedCookie(const std::string& cookie_line) {
if (cookie_line.size() > kMaxCookieSize) {
DVLOG(1) << "Not parsing cookie, too large: " << cookie_line.size();
return;
@@ -232,6 +225,10 @@ bool ParsedCookie::SetPriority(const std::string& priority) {
return SetString(&priority_index_, kPriorityTokenName, priority);
}
+bool ParsedCookie::SetIsSameParty(bool is_same_party) {
+ return SetBool(&same_party_index_, kSamePartyTokenName, is_same_party);
+}
+
std::string ParsedCookie::ToCookieLine() const {
std::string out;
for (auto it = pairs_.begin(); it != pairs_.end(); ++it) {
@@ -242,7 +239,8 @@ std::string ParsedCookie::ToCookieLine() const {
// print it for the first pair(see crbug.com/977619). After the first pair,
// we need to consider whether the name component is a special token.
if (it == pairs_.begin() ||
- (it->first != kSecureTokenName && it->first != kHttpOnlyTokenName)) {
+ (it->first != kSecureTokenName && it->first != kHttpOnlyTokenName &&
+ it->first != kSamePartyTokenName)) {
out.append("=");
out.append(it->second);
}
@@ -464,6 +462,8 @@ void ParsedCookie::SetupAttributes() {
same_site_index_ = i;
} else if (pairs_[i].first == kPriorityTokenName) {
priority_index_ = i;
+ } else if (pairs_[i].first == kSamePartyTokenName) {
+ same_party_index_ = i;
} else {
/* some attribute we don't know or don't care about. */
}
@@ -529,9 +529,9 @@ void ParsedCookie::ClearAttributePair(size_t index) {
if (index == 0)
return;
- size_t* indexes[] = {&path_index_, &domain_index_, &expires_index_,
- &maxage_index_, &secure_index_, &httponly_index_,
- &same_site_index_, &priority_index_};
+ size_t* indexes[] = {&path_index_, &domain_index_, &expires_index_,
+ &maxage_index_, &secure_index_, &httponly_index_,
+ &same_site_index_, &priority_index_, &same_party_index_};
for (size_t* attribute_index : indexes) {
if (*attribute_index == index)
*attribute_index = 0;
diff --git a/chromium/net/cookies/parsed_cookie.h b/chromium/net/cookies/parsed_cookie.h
index 7917c681c86..f555814bc2f 100644
--- a/chromium/net/cookies/parsed_cookie.h
+++ b/chromium/net/cookies/parsed_cookie.h
@@ -53,6 +53,7 @@ class NET_EXPORT ParsedCookie {
CookieSameSite SameSite(
CookieSameSiteString* samesite_string = nullptr) const;
CookiePriority Priority() const;
+ bool IsSameParty() const { return same_party_index_ != 0; }
// Returns the number of attributes, for example, returning 2 for:
// "BLAH=hah; path=/; domain=.google.com"
@@ -76,6 +77,7 @@ class NET_EXPORT ParsedCookie {
bool SetIsHttpOnly(bool is_http_only);
bool SetSameSite(const std::string& same_site);
bool SetPriority(const std::string& priority);
+ bool SetIsSameParty(bool is_same_party);
// Returns the cookie description as it appears in a HTML response header.
std::string ToCookieLine() const;
@@ -139,17 +141,16 @@ class NET_EXPORT ParsedCookie {
PairList pairs_;
// These will default to 0, but that should never be valid since the
- // 0th index is the user supplied token/value, not an attribute.
- // We're really never going to have more than like 8 attributes, so we
- // could fit these into 3 bits each if we're worried about size...
- size_t path_index_;
- size_t domain_index_;
- size_t expires_index_;
- size_t maxage_index_;
- size_t secure_index_;
- size_t httponly_index_;
- size_t same_site_index_;
- size_t priority_index_;
+ // 0th index is the user supplied cookie name/value, not an attribute.
+ size_t path_index_ = 0;
+ size_t domain_index_ = 0;
+ size_t expires_index_ = 0;
+ size_t maxage_index_ = 0;
+ size_t secure_index_ = 0;
+ size_t httponly_index_ = 0;
+ size_t same_site_index_ = 0;
+ size_t priority_index_ = 0;
+ size_t same_party_index_ = 0;
DISALLOW_COPY_AND_ASSIGN(ParsedCookie);
};
diff --git a/chromium/net/cookies/parsed_cookie_unittest.cc b/chromium/net/cookies/parsed_cookie_unittest.cc
index 27ce53d1249..d4671514d23 100644
--- a/chromium/net/cookies/parsed_cookie_unittest.cc
+++ b/chromium/net/cookies/parsed_cookie_unittest.cc
@@ -11,11 +11,38 @@
namespace net {
TEST(ParsedCookieTest, TestBasic) {
- ParsedCookie pc("a=b");
- EXPECT_TRUE(pc.IsValid());
- EXPECT_FALSE(pc.IsSecure());
- EXPECT_EQ("a", pc.Name());
- EXPECT_EQ("b", pc.Value());
+ ParsedCookie pc1("a=b");
+ EXPECT_TRUE(pc1.IsValid());
+ EXPECT_FALSE(pc1.IsSecure());
+ EXPECT_FALSE(pc1.IsHttpOnly());
+ EXPECT_FALSE(pc1.IsSameParty());
+ EXPECT_EQ("a", pc1.Name());
+ EXPECT_EQ("b", pc1.Value());
+ EXPECT_FALSE(pc1.HasPath());
+ EXPECT_FALSE(pc1.HasDomain());
+ EXPECT_FALSE(pc1.HasExpires());
+ EXPECT_FALSE(pc1.HasMaxAge());
+ EXPECT_EQ(CookieSameSite::UNSPECIFIED, pc1.SameSite());
+ EXPECT_EQ(CookiePriority::COOKIE_PRIORITY_DEFAULT, pc1.Priority());
+
+ ParsedCookie pc2(
+ "c=d; secure; httponly; sameparty; path=/foo; domain=bar.test; "
+ "max-age=60; samesite=lax; priority=high");
+ EXPECT_TRUE(pc2.IsValid());
+ EXPECT_TRUE(pc2.IsSecure());
+ EXPECT_TRUE(pc2.IsHttpOnly());
+ EXPECT_TRUE(pc2.IsSameParty());
+ EXPECT_EQ("c", pc2.Name());
+ EXPECT_EQ("d", pc2.Value());
+ EXPECT_TRUE(pc2.HasPath());
+ EXPECT_EQ("/foo", pc2.Path());
+ EXPECT_TRUE(pc2.HasDomain());
+ EXPECT_EQ("bar.test", pc2.Domain());
+ EXPECT_FALSE(pc2.HasExpires());
+ EXPECT_TRUE(pc2.HasMaxAge());
+ EXPECT_EQ("60", pc2.MaxAge());
+ EXPECT_EQ(CookieSameSite::LAX_MODE, pc2.SameSite());
+ EXPECT_EQ(CookiePriority::COOKIE_PRIORITY_HIGH, pc2.Priority());
}
TEST(ParsedCookieTest, TestEmpty) {
@@ -48,7 +75,7 @@ TEST(ParsedCookieTest, TestSetEmptyNameValue) {
EXPECT_EQ("value", empty_name.Value());
EXPECT_FALSE(empty_name.SetValue(""));
EXPECT_EQ("value", empty_name.Value());
- EXPECT_TRUE(empty_value.IsValid());
+ EXPECT_TRUE(empty_name.IsValid());
}
TEST(ParsedCookieTest, TestQuoted) {
@@ -111,17 +138,18 @@ TEST(ParsedCookieTest, TestNameless) {
TEST(ParsedCookieTest, TestAttributeCase) {
ParsedCookie pc(
- "BLAHHH; Path=/; sECuRe; httpONLY; sAmESitE=StrIct; pRIoRitY=hIgH");
+ "BLAH; Path=/; sECuRe; httpONLY; sAmESitE=LaX; pRIoRitY=hIgH; samePaRtY");
EXPECT_TRUE(pc.IsValid());
EXPECT_TRUE(pc.IsSecure());
EXPECT_TRUE(pc.IsHttpOnly());
- EXPECT_EQ(CookieSameSite::STRICT_MODE, pc.SameSite());
+ EXPECT_TRUE(pc.IsSameParty());
+ EXPECT_EQ(CookieSameSite::LAX_MODE, pc.SameSite());
EXPECT_TRUE(pc.HasPath());
EXPECT_EQ("/", pc.Path());
EXPECT_EQ("", pc.Name());
- EXPECT_EQ("BLAHHH", pc.Value());
+ EXPECT_EQ("BLAH", pc.Value());
EXPECT_EQ(COOKIE_PRIORITY_HIGH, pc.Priority());
- EXPECT_EQ(5U, pc.NumberOfAttributes());
+ EXPECT_EQ(6U, pc.NumberOfAttributes());
}
TEST(ParsedCookieTest, TestDoubleQuotedNameless) {
@@ -367,10 +395,11 @@ TEST(ParsedCookieTest, SetAttributes) {
EXPECT_TRUE(pc.SetIsHttpOnly(true));
EXPECT_TRUE(pc.SetSameSite("LAX"));
EXPECT_TRUE(pc.SetPriority("HIGH"));
+ EXPECT_TRUE(pc.SetIsSameParty(true));
EXPECT_EQ(
"name=value; domain=domain.com; path=/; "
"expires=Sun, 18-Apr-2027 21:06:29 GMT; max-age=12345; secure; "
- "httponly; samesite=LAX; priority=HIGH",
+ "httponly; samesite=LAX; priority=HIGH; sameparty",
pc.ToCookieLine());
EXPECT_TRUE(pc.HasDomain());
EXPECT_TRUE(pc.HasPath());
@@ -380,22 +409,35 @@ TEST(ParsedCookieTest, SetAttributes) {
EXPECT_TRUE(pc.IsHttpOnly());
EXPECT_EQ(CookieSameSite::LAX_MODE, pc.SameSite());
EXPECT_EQ(COOKIE_PRIORITY_HIGH, pc.Priority());
+ EXPECT_TRUE(pc.IsSameParty());
- // Clear one attribute from the middle.
+ // Modify one attribute in the middle.
EXPECT_TRUE(pc.SetPath("/foo"));
EXPECT_TRUE(pc.HasDomain());
EXPECT_TRUE(pc.HasPath());
+ EXPECT_EQ("/foo", pc.Path());
EXPECT_TRUE(pc.HasExpires());
EXPECT_TRUE(pc.IsSecure());
EXPECT_TRUE(pc.IsHttpOnly());
+ EXPECT_TRUE(pc.IsSameParty());
EXPECT_EQ(
"name=value; domain=domain.com; path=/foo; "
"expires=Sun, 18-Apr-2027 21:06:29 GMT; max-age=12345; secure; "
- "httponly; samesite=LAX; priority=HIGH",
+ "httponly; samesite=LAX; priority=HIGH; sameparty",
pc.ToCookieLine());
// Set priority to medium.
EXPECT_TRUE(pc.SetPriority("medium"));
+ EXPECT_EQ(CookiePriority::COOKIE_PRIORITY_MEDIUM, pc.Priority());
+ EXPECT_EQ(
+ "name=value; domain=domain.com; path=/foo; "
+ "expires=Sun, 18-Apr-2027 21:06:29 GMT; max-age=12345; secure; "
+ "httponly; samesite=LAX; priority=medium; sameparty",
+ pc.ToCookieLine());
+
+ // Clear attribute from the end.
+ EXPECT_TRUE(pc.SetIsSameParty(false));
+ EXPECT_FALSE(pc.IsSameParty());
EXPECT_EQ(
"name=value; domain=domain.com; path=/foo; "
"expires=Sun, 18-Apr-2027 21:06:29 GMT; max-age=12345; secure; "
@@ -421,6 +463,7 @@ TEST(ParsedCookieTest, SetAttributes) {
EXPECT_FALSE(pc.IsHttpOnly());
EXPECT_EQ(CookieSameSite::UNSPECIFIED, pc.SameSite());
EXPECT_EQ("name2=value2", pc.ToCookieLine());
+ EXPECT_FALSE(pc.IsSameParty());
}
// Set the domain attribute twice in a cookie line. If the second attribute's
@@ -570,8 +613,8 @@ TEST(ParsedCookieTest, SettersInputValidation) {
}
TEST(ParsedCookieTest, ToCookieLineSpecialTokens) {
- // Special tokens "secure" and "httponly" should be treated as any other name
- // when they are in the first position.
+ // Special tokens "secure", "httponly", and "sameparty" should be treated as
+ // any other name when they are in the first position.
{
ParsedCookie pc("");
pc.SetName("secure");
@@ -594,6 +637,10 @@ TEST(ParsedCookieTest, ToCookieLineSpecialTokens) {
EXPECT_EQ(pc.ToCookieLine(), "httponly=foo");
}
{
+ ParsedCookie pc("sameparty=foo");
+ EXPECT_EQ(pc.ToCookieLine(), "sameparty=foo");
+ }
+ {
ParsedCookie pc("foo");
pc.SetName("secure");
EXPECT_EQ(pc.ToCookieLine(), "secure=foo");
@@ -622,9 +669,29 @@ TEST(ParsedCookieTest, ToCookieLineSpecialTokens) {
EXPECT_EQ(pc.ToCookieLine(), "name=foo; httponly");
}
{
+ ParsedCookie pc("name=foo; sameparty=baz");
+ EXPECT_EQ(pc.ToCookieLine(), "name=foo; sameparty");
+ }
+ {
ParsedCookie pc("name=foo; bar=secure");
EXPECT_EQ(pc.ToCookieLine(), "name=foo; bar=secure");
}
+ // Repeated instances of the special tokens are also fine.
+ {
+ ParsedCookie pc("name=foo; secure; secure=yesplease; secure; secure");
+ EXPECT_TRUE(pc.IsValid());
+ EXPECT_TRUE(pc.IsSecure());
+ EXPECT_FALSE(pc.IsHttpOnly());
+ EXPECT_FALSE(pc.IsSameParty());
+ }
+ {
+ ParsedCookie pc("sameparty; sameparty; secure; httponly; httponly; secure");
+ EXPECT_EQ("", pc.Name());
+ EXPECT_EQ("sameparty", pc.Value());
+ EXPECT_TRUE(pc.IsSecure());
+ EXPECT_TRUE(pc.IsSameParty());
+ EXPECT_TRUE(pc.IsHttpOnly());
+ }
}
TEST(ParsedCookieTest, SameSiteValues) {