• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 // Copyright 2012 The Chromium Authors
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
4 
5 #include "net/cookies/canonical_cookie.h"
6 
7 #include <memory>
8 #include <string>
9 #include <vector>
10 
11 #include "base/test/metrics/histogram_tester.h"
12 #include "base/test/scoped_feature_list.h"
13 #include "base/time/time.h"
14 #include "build/build_config.h"
15 #include "net/base/features.h"
16 #include "net/cookies/canonical_cookie_test_helpers.h"
17 #include "net/cookies/cookie_constants.h"
18 #include "net/cookies/cookie_inclusion_status.h"
19 #include "net/cookies/cookie_options.h"
20 #include "net/cookies/parsed_cookie.h"
21 #include "testing/gmock/include/gmock/gmock-matchers.h"
22 #include "testing/gmock/include/gmock/gmock.h"
23 #include "testing/gtest/include/gtest/gtest.h"
24 #include "third_party/abseil-cpp/absl/types/optional.h"
25 #include "url/gurl.h"
26 #include "url/third_party/mozilla/url_parse.h"
27 
28 namespace net {
29 
30 namespace {
31 const std::vector<std::string> kCookieableSchemes = {"http", "https", "ws",
32                                                      "wss"};
33 
34 // Helper for testing BuildCookieLine
MatchCookieLineToVector(const std::string & line,const std::vector<std::unique_ptr<CanonicalCookie>> & cookies)35 void MatchCookieLineToVector(
36     const std::string& line,
37     const std::vector<std::unique_ptr<CanonicalCookie>>& cookies) {
38   std::vector<CanonicalCookie> list;
39   for (const auto& cookie : cookies)
40     list.push_back(*cookie);
41   EXPECT_EQ(line, CanonicalCookie::BuildCookieLine(list));
42 }
43 
44 }  // namespace
45 
46 using testing::_;
47 using testing::AllOf;
48 using testing::Eq;
49 using testing::Not;
50 using testing::Property;
51 
52 // Tests which use this class verify the expiry date clamping behavior when
53 // kClampCookieExpiryTo400Days is enabled. This caps expiry dates on new/updated
54 // cookies to max of 400 days, but does not affect previously stored cookies.
55 class CanonicalCookieWithClampingTest
56     : public testing::Test,
57       public testing::WithParamInterface<bool> {
58  public:
CanonicalCookieWithClampingTest()59   CanonicalCookieWithClampingTest() {
60     scoped_feature_list_.InitWithFeatureState(
61         features::kClampCookieExpiryTo400Days,
62         IsClampCookieExpiryTo400DaysEnabled());
63   }
IsClampCookieExpiryTo400DaysEnabled()64   bool IsClampCookieExpiryTo400DaysEnabled() { return GetParam(); }
65 
66  private:
67   base::test::ScopedFeatureList scoped_feature_list_;
68 };
69 
70 INSTANTIATE_TEST_SUITE_P(/* no label */,
71                          CanonicalCookieWithClampingTest,
72                          testing::Bool());
73 
TEST(CanonicalCookieTest,Constructor)74 TEST(CanonicalCookieTest, Constructor) {
75   base::Time current_time = base::Time::Now();
76 
77   // CreateUnsafeCookieForTesting just forwards to the constructor.
78   auto cookie1 = CanonicalCookie::CreateUnsafeCookieForTesting(
79       "A", "2", "www.example.com", "/test", current_time, base::Time(),
80       base::Time(), base::Time(), false, false, CookieSameSite::NO_RESTRICTION,
81       COOKIE_PRIORITY_DEFAULT, false, absl::nullopt,
82       CookieSourceScheme::kSecure, 443);
83   EXPECT_EQ("A", cookie1->Name());
84   EXPECT_EQ("2", cookie1->Value());
85   EXPECT_EQ("www.example.com", cookie1->Domain());
86   EXPECT_EQ("/test", cookie1->Path());
87   EXPECT_FALSE(cookie1->IsSecure());
88   EXPECT_FALSE(cookie1->IsHttpOnly());
89   EXPECT_EQ(CookieSameSite::NO_RESTRICTION, cookie1->SameSite());
90   EXPECT_EQ(CookiePriority::COOKIE_PRIORITY_DEFAULT, cookie1->Priority());
91   EXPECT_FALSE(cookie1->IsSameParty());
92   EXPECT_FALSE(cookie1->IsPartitioned());
93   EXPECT_EQ(cookie1->SourceScheme(), CookieSourceScheme::kSecure);
94   EXPECT_EQ(cookie1->SourcePort(), 443);
95 
96   auto cookie2 = CanonicalCookie::CreateUnsafeCookieForTesting(
97       "A", "2", ".www.example.com", "/", current_time, base::Time(),
98       base::Time(), base::Time(), false, false, CookieSameSite::NO_RESTRICTION,
99       COOKIE_PRIORITY_DEFAULT, true,
100       CookiePartitionKey::FromURLForTesting(GURL("https://foo.com")),
101       CookieSourceScheme::kNonSecure, 65536);
102   EXPECT_EQ("A", cookie2->Name());
103   EXPECT_EQ("2", cookie2->Value());
104   EXPECT_EQ(".www.example.com", cookie2->Domain());
105   EXPECT_EQ("/", cookie2->Path());
106   EXPECT_FALSE(cookie2->IsSecure());
107   EXPECT_FALSE(cookie2->IsHttpOnly());
108   EXPECT_EQ(CookieSameSite::NO_RESTRICTION, cookie2->SameSite());
109   EXPECT_EQ(CookiePriority::COOKIE_PRIORITY_DEFAULT, cookie2->Priority());
110   EXPECT_TRUE(cookie2->IsSameParty());
111   EXPECT_TRUE(cookie2->IsPartitioned());
112   EXPECT_EQ(cookie2->SourceScheme(), CookieSourceScheme::kNonSecure);
113   // Because the port can be set explicitly in the constructor its value can be
114   // independent of the other parameters. In this case, test that an out of
115   // range port is kept out of range.
116   EXPECT_EQ(cookie2->SourcePort(), 65536);
117 
118   // Set Secure to true but don't specify source_scheme or port.
119   auto cookie3 = CanonicalCookie::CreateUnsafeCookieForTesting(
120       "A", "2", ".www.example.com", "/", current_time, base::Time(),
121       base::Time(), base::Time(), true /* secure */, false,
122       CookieSameSite::NO_RESTRICTION, COOKIE_PRIORITY_DEFAULT, false);
123   EXPECT_TRUE(cookie3->IsSecure());
124   EXPECT_EQ(cookie3->SourceScheme(), CookieSourceScheme::kUnset);
125   EXPECT_EQ(cookie3->SourcePort(), url::PORT_UNSPECIFIED);
126 
127   auto cookie4 = CanonicalCookie::CreateUnsafeCookieForTesting(
128       "A", "2", ".www.example.com", "/test", current_time, base::Time(),
129       base::Time(), base::Time(), false, false, CookieSameSite::NO_RESTRICTION,
130       COOKIE_PRIORITY_DEFAULT, false);
131   EXPECT_EQ("A", cookie4->Name());
132   EXPECT_EQ("2", cookie4->Value());
133   EXPECT_EQ(".www.example.com", cookie4->Domain());
134   EXPECT_EQ("/test", cookie4->Path());
135   EXPECT_FALSE(cookie4->IsSecure());
136   EXPECT_FALSE(cookie4->IsHttpOnly());
137   EXPECT_EQ(CookieSameSite::NO_RESTRICTION, cookie4->SameSite());
138   EXPECT_FALSE(cookie4->IsSameParty());
139   EXPECT_FALSE(cookie4->IsPartitioned());
140   EXPECT_EQ(cookie4->SourceScheme(), CookieSourceScheme::kUnset);
141   EXPECT_EQ(cookie4->SourcePort(), url::PORT_UNSPECIFIED);
142 
143   // Test some port edge cases: unspecified.
144   auto cookie5 = CanonicalCookie::CreateUnsafeCookieForTesting(
145       "A", "2", ".www.example.com", "/", current_time, base::Time(),
146       base::Time(), base::Time(), true /* secure */, false,
147       CookieSameSite::NO_RESTRICTION, COOKIE_PRIORITY_DEFAULT, false,
148       absl::nullopt, CookieSourceScheme::kUnset, url::PORT_UNSPECIFIED);
149   EXPECT_EQ(cookie5->SourcePort(), url::PORT_UNSPECIFIED);
150 
151   // Test some port edge cases: invalid.
152   auto cookie6 = CanonicalCookie::CreateUnsafeCookieForTesting(
153       "A", "2", ".www.example.com", "/", current_time, base::Time(),
154       base::Time(), base::Time(), true /* secure */, false,
155       CookieSameSite::NO_RESTRICTION, COOKIE_PRIORITY_DEFAULT, false,
156       absl::nullopt, CookieSourceScheme::kUnset, url::PORT_INVALID);
157   EXPECT_EQ(cookie6->SourcePort(), url::PORT_INVALID);
158 }
159 
TEST(CanonicalCookieTest,CreationCornerCases)160 TEST(CanonicalCookieTest, CreationCornerCases) {
161   base::Time creation_time = base::Time::Now();
162   std::unique_ptr<CanonicalCookie> cookie;
163   absl::optional<base::Time> server_time = absl::nullopt;
164 
165   // Space in name.
166   cookie = CanonicalCookie::Create(GURL("http://www.example.com/test/foo.html"),
167                                    "A C=2", creation_time, server_time,
168                                    absl::nullopt /* cookie_partition_key */);
169   EXPECT_TRUE(cookie.get());
170   EXPECT_EQ("A C", cookie->Name());
171 
172   // Semicolon in path.
173   cookie = CanonicalCookie::Create(GURL("http://fool/;/"), "*", creation_time,
174                                    server_time,
175                                    absl::nullopt /* cookie_partition_key */);
176   EXPECT_TRUE(cookie.get());
177 
178   // Control characters in name or value.
179   CookieInclusionStatus status;
180   cookie = CanonicalCookie::Create(
181       GURL("http://www.example.com/test/foo.html"), "\b=foo", creation_time,
182       server_time, absl::nullopt /* cookie_partition_key */, &status);
183   EXPECT_FALSE(cookie.get());
184   EXPECT_TRUE(status.HasExclusionReason(
185       CookieInclusionStatus::ExclusionReason::EXCLUDE_FAILURE_TO_STORE));
186   cookie = CanonicalCookie::Create(
187       GURL("http://www.example.com/test/foo.html"), "bar=\b", creation_time,
188       server_time, absl::nullopt /* cookie_partition_key */, &status);
189   EXPECT_FALSE(cookie.get());
190   EXPECT_TRUE(status.HasExclusionReason(
191       CookieInclusionStatus::ExclusionReason::EXCLUDE_FAILURE_TO_STORE));
192 
193   // The ParsedCookie constructor unit tests cover many edge cases related to
194   // invalid sizes when parsing a cookie line, and since CanonicalCookie::Create
195   // creates a ParsedCookie immediately, there's no point in replicating all
196   // of those tests here.  We should test that the corresponding ExclusionReason
197   // gets passed back correctly, though.
198   std::string too_long_value(ParsedCookie::kMaxCookieNamePlusValueSize + 1,
199                              'a');
200 
201   cookie = CanonicalCookie::Create(GURL("http://www.example.com/test/foo.html"),
202                                    too_long_value, creation_time, server_time,
203                                    absl::nullopt /* cookie_partition_key */,
204                                    &status);
205   EXPECT_FALSE(cookie.get());
206   EXPECT_TRUE(
207       status.HasExclusionReason(CookieInclusionStatus::ExclusionReason::
208                                     EXCLUDE_NAME_VALUE_PAIR_EXCEEDS_MAX_SIZE));
209 }
210 
TEST(CanonicalCookieTest,Create)211 TEST(CanonicalCookieTest, Create) {
212   // Test creating cookies from a cookie string.
213   GURL url("http://www.example.com/test/foo.html");
214   GURL https_url("https://www.example.com/test/foo.html");
215   base::Time creation_time = base::Time::Now();
216   absl::optional<base::Time> server_time = absl::nullopt;
217 
218   std::unique_ptr<CanonicalCookie> cookie(
219       CanonicalCookie::Create(url, "A=2", creation_time, server_time,
220                               absl::nullopt /* cookie_partition_key */));
221   EXPECT_EQ("A", cookie->Name());
222   EXPECT_EQ("2", cookie->Value());
223   EXPECT_EQ("www.example.com", cookie->Domain());
224   EXPECT_EQ("/test", cookie->Path());
225   EXPECT_FALSE(cookie->IsSecure());
226   EXPECT_EQ(cookie->SourceScheme(), CookieSourceScheme::kNonSecure);
227   EXPECT_EQ(cookie->SourcePort(), 80);
228 
229   GURL url2("http://www.foo.com");
230   cookie = CanonicalCookie::Create(url2, "B=1", creation_time, server_time,
231                                    absl::nullopt /* cookie_partition_key */);
232   EXPECT_EQ("B", cookie->Name());
233   EXPECT_EQ("1", cookie->Value());
234   EXPECT_EQ("www.foo.com", cookie->Domain());
235   EXPECT_EQ("/", cookie->Path());
236   EXPECT_FALSE(cookie->IsSecure());
237   EXPECT_EQ(cookie->SourceScheme(), CookieSourceScheme::kNonSecure);
238   EXPECT_EQ(cookie->SourcePort(), 80);
239 
240   // Test creating secure cookies. Secure scheme is not checked upon creation,
241   // so a URL of any scheme can create a Secure cookie.
242   cookie =
243       CanonicalCookie::Create(url, "A=2; Secure", creation_time, server_time,
244                               absl::nullopt /* cookie_partition_key */);
245   EXPECT_TRUE(cookie->IsSecure());
246 
247   cookie = CanonicalCookie::Create(https_url, "A=2; Secure", creation_time,
248                                    server_time,
249                                    absl::nullopt /* cookie_partition_key */);
250   EXPECT_TRUE(cookie->IsSecure());
251 
252   GURL url3("https://www.foo.com");
253   cookie =
254       CanonicalCookie::Create(url3, "A=2; Secure", creation_time, server_time,
255                               absl::nullopt /* cookie_partition_key */);
256   EXPECT_TRUE(cookie->IsSecure());
257   EXPECT_EQ(cookie->SourceScheme(), CookieSourceScheme::kSecure);
258 
259   cookie = CanonicalCookie::Create(url3, "A=2", creation_time, server_time,
260                                    absl::nullopt /* cookie_partition_key */);
261   EXPECT_FALSE(cookie->IsSecure());
262   EXPECT_EQ(cookie->SourceScheme(), CookieSourceScheme::kSecure);
263 
264   // Test creating cookie from localhost URL.
265   cookie = CanonicalCookie::Create(GURL("http://localhost/path"), "A=2",
266                                    creation_time, server_time,
267                                    absl::nullopt /* cookie_partition_key */);
268   EXPECT_EQ(cookie->SourceScheme(), CookieSourceScheme::kNonSecure);
269 
270   cookie = CanonicalCookie::Create(GURL("http://127.0.0.1/path"), "A=2",
271                                    creation_time, server_time,
272                                    absl::nullopt /* cookie_partition_key */);
273   EXPECT_EQ(cookie->SourceScheme(), CookieSourceScheme::kNonSecure);
274 
275   cookie = CanonicalCookie::Create(GURL("http://[::1]/path"), "A=2",
276                                    creation_time, server_time,
277                                    absl::nullopt /* cookie_partition_key */);
278   EXPECT_EQ(cookie->SourceScheme(), CookieSourceScheme::kNonSecure);
279 
280   cookie = CanonicalCookie::Create(GURL("https://localhost/path"), "A=2",
281                                    creation_time, server_time,
282                                    absl::nullopt /* cookie_partition_key */);
283   EXPECT_EQ(cookie->SourceScheme(), CookieSourceScheme::kSecure);
284 
285   cookie = CanonicalCookie::Create(GURL("https://127.0.0.1/path"), "A=2",
286                                    creation_time, server_time,
287                                    absl::nullopt /* cookie_partition_key */);
288   EXPECT_EQ(cookie->SourceScheme(), CookieSourceScheme::kSecure);
289 
290   cookie = CanonicalCookie::Create(GURL("https://[::1]/path"), "A=2",
291                                    creation_time, server_time,
292                                    absl::nullopt /* cookie_partition_key */);
293   EXPECT_EQ(cookie->SourceScheme(), CookieSourceScheme::kSecure);
294 
295   // Test creating http only cookies. HttpOnly is not checked upon creation.
296   cookie =
297       CanonicalCookie::Create(url, "A=2; HttpOnly", creation_time, server_time,
298                               absl::nullopt /* cookie_partition_key */);
299   EXPECT_TRUE(cookie->IsHttpOnly());
300 
301   cookie =
302       CanonicalCookie::Create(url, "A=2; HttpOnly", creation_time, server_time,
303                               absl::nullopt /* cookie_partition_key */);
304   EXPECT_TRUE(cookie->IsHttpOnly());
305 
306   // Test creating SameSite cookies. SameSite is not checked upon creation.
307   cookie = CanonicalCookie::Create(url, "A=2; SameSite=Strict", creation_time,
308                                    server_time,
309                                    absl::nullopt /* cookie_partition_key */);
310   ASSERT_TRUE(cookie.get());
311   EXPECT_EQ(CookieSameSite::STRICT_MODE, cookie->SameSite());
312   cookie = CanonicalCookie::Create(url, "A=2; SameSite=Lax", creation_time,
313                                    server_time,
314                                    absl::nullopt /* cookie_partition_key */);
315   ASSERT_TRUE(cookie.get());
316   EXPECT_EQ(CookieSameSite::LAX_MODE, cookie->SameSite());
317   cookie = CanonicalCookie::Create(url, "A=2; SameSite=Extended", creation_time,
318                                    server_time,
319                                    absl::nullopt /* cookie_partition_key */);
320   ASSERT_TRUE(cookie.get());
321   EXPECT_EQ(CookieSameSite::UNSPECIFIED, cookie->SameSite());
322   cookie = CanonicalCookie::Create(url, "A=2; SameSite=None", creation_time,
323                                    server_time,
324                                    absl::nullopt /* cookie_partition_key */);
325   ASSERT_TRUE(cookie.get());
326   EXPECT_EQ(CookieSameSite::NO_RESTRICTION, cookie->SameSite());
327   cookie = CanonicalCookie::Create(url, "A=2", creation_time, server_time,
328                                    absl::nullopt /* cookie_partition_key */);
329   ASSERT_TRUE(cookie.get());
330   EXPECT_EQ(CookieSameSite::UNSPECIFIED, cookie->SameSite());
331 
332   // Test creating cookies with different ports.
333   cookie = CanonicalCookie::Create(GURL("http://www.foo.com"), "B=1",
334                                    creation_time, server_time,
335                                    absl::nullopt /* cookie_partition_key */);
336   EXPECT_EQ(cookie->SourcePort(), 80);
337 
338   cookie = CanonicalCookie::Create(GURL("http://www.foo.com:81"), "B=1",
339                                    creation_time, server_time,
340                                    absl::nullopt /* cookie_partition_key */);
341   EXPECT_EQ(cookie->SourcePort(), 81);
342 
343   cookie = CanonicalCookie::Create(GURL("https://www.foo.com"), "B=1",
344                                    creation_time, server_time,
345                                    absl::nullopt /* cookie_partition_key */);
346   EXPECT_EQ(cookie->SourcePort(), 443);
347 
348   cookie = CanonicalCookie::Create(GURL("https://www.foo.com:1234"), "B=1",
349                                    creation_time, server_time,
350                                    absl::nullopt /* cookie_partition_key */);
351   EXPECT_EQ(cookie->SourcePort(), 1234);
352 
353   cookie = CanonicalCookie::Create(GURL("http://www.foo.com:443"), "B=1",
354                                    creation_time, server_time,
355                                    absl::nullopt /* cookie_partition_key */);
356   EXPECT_EQ(cookie->SourcePort(), 443);
357 
358   // An invalid port leads to an invalid GURL, which causes cookie creation
359   // to fail.
360   CookieInclusionStatus status;
361   cookie = CanonicalCookie::Create(
362       GURL("http://www.foo.com:70000"), "B=1", creation_time, server_time,
363       absl::nullopt /* cookie_partition_key */, &status);
364   EXPECT_FALSE(cookie.get());
365   EXPECT_TRUE(status.HasExclusionReason(
366       CookieInclusionStatus::ExclusionReason::EXCLUDE_FAILURE_TO_STORE));
367 }
368 
TEST(CanonicalCookieTest,CreateInvalidUrl)369 TEST(CanonicalCookieTest, CreateInvalidUrl) {
370   base::Time creation_time = base::Time::Now();
371   absl::optional<base::Time> server_time = absl::nullopt;
372   CookieInclusionStatus status;
373   std::unique_ptr<CanonicalCookie> cookie = CanonicalCookie::Create(
374       GURL("http://.127.0.0.1/path"), "A=2", creation_time, server_time,
375       absl::nullopt /* cookie_partition_key */, &status);
376   EXPECT_FALSE(cookie.get());
377   EXPECT_TRUE(status.HasExclusionReason(
378       CookieInclusionStatus::ExclusionReason::EXCLUDE_FAILURE_TO_STORE));
379 }
380 
381 // Test that a cookie string with an empty domain attribute generates a
382 // canonical host cookie.
TEST(CanonicalCookieTest,CreateHostCookieFromString)383 TEST(CanonicalCookieTest, CreateHostCookieFromString) {
384   // Create a new canonical host cookie via empty string domain in the
385   // cookie_line.
386   GURL url("http://www.example.com/test/foo.html");
387   base::Time creation_time = base::Time::Now();
388   absl::optional<base::Time> server_time = absl::nullopt;
389   std::unique_ptr<CanonicalCookie> cookie(CanonicalCookie::Create(
390       url, "A=2; domain=; Secure", creation_time, server_time,
391       absl::nullopt /*cookie_partition_key*/));
392   EXPECT_EQ("www.example.com", cookie->Domain());
393   EXPECT_TRUE(cookie->IsHostCookie());
394 }
395 
TEST(CanonicalCookieTest,CreateNonStandardSameSite)396 TEST(CanonicalCookieTest, CreateNonStandardSameSite) {
397   GURL url("http://www.example.com/test/foo.html");
398   base::Time now = base::Time::Now();
399   std::unique_ptr<CanonicalCookie> cookie;
400   absl::optional<base::Time> server_time = absl::nullopt;
401 
402   // Non-standard value for the SameSite attribute.
403   cookie = CanonicalCookie::Create(url, "A=2; SameSite=NonStandard", now,
404                                    server_time,
405                                    absl::nullopt /* cookie_partition_key */);
406   EXPECT_TRUE(cookie.get());
407   EXPECT_EQ(CookieSameSite::UNSPECIFIED, cookie->SameSite());
408 
409   // Omit value for the SameSite attribute.
410   cookie = CanonicalCookie::Create(url, "A=2; SameSite", now, server_time,
411                                    absl::nullopt /* cookie_partition_key */);
412   EXPECT_TRUE(cookie.get());
413   EXPECT_EQ(CookieSameSite::UNSPECIFIED, cookie->SameSite());
414 }
415 
TEST(CanonicalCookieTest,CreateSameSiteInCrossSiteContexts)416 TEST(CanonicalCookieTest, CreateSameSiteInCrossSiteContexts) {
417   GURL url("http://www.example.com/test/foo.html");
418   base::Time now = base::Time::Now();
419   std::unique_ptr<CanonicalCookie> cookie;
420   absl::optional<base::Time> server_time = absl::nullopt;
421 
422   // A cookie can be created from any SameSiteContext regardless of SameSite
423   // value (it is upon setting the cookie that the SameSiteContext comes into
424   // effect).
425   cookie =
426       CanonicalCookie::Create(url, "A=2; SameSite=Strict", now, server_time,
427                               absl::nullopt /* cookie_partition_key */);
428   EXPECT_TRUE(cookie.get());
429   cookie = CanonicalCookie::Create(url, "A=2; SameSite=Lax", now, server_time,
430                                    absl::nullopt /* cookie_partition_key */);
431   EXPECT_TRUE(cookie.get());
432   cookie = CanonicalCookie::Create(url, "A=2; SameSite=None", now, server_time,
433                                    absl::nullopt /* cookie_partition_key */);
434   EXPECT_TRUE(cookie.get());
435   cookie = CanonicalCookie::Create(url, "A=2;", now, server_time,
436                                    absl::nullopt /* cookie_partition_key */);
437   EXPECT_TRUE(cookie.get());
438 }
439 
TEST(CanonicalCookieTest,CreateHttpOnly)440 TEST(CanonicalCookieTest, CreateHttpOnly) {
441   GURL url("http://www.example.com/test/foo.html");
442   base::Time now = base::Time::Now();
443   absl::optional<base::Time> server_time = absl::nullopt;
444   CookieInclusionStatus status;
445 
446   // An HttpOnly cookie can be created.
447   std::unique_ptr<CanonicalCookie> cookie = CanonicalCookie::Create(
448       url, "A=2; HttpOnly", now, server_time,
449       absl::nullopt /* cookie_partition_key */, &status);
450   EXPECT_TRUE(cookie->IsHttpOnly());
451   EXPECT_TRUE(status.IsInclude());
452 }
453 
TEST(CanonicalCookieTest,CreateWithInvalidDomain)454 TEST(CanonicalCookieTest, CreateWithInvalidDomain) {
455   GURL url("http://www.example.com/test/foo.html");
456   base::Time now = base::Time::Now();
457   absl::optional<base::Time> server_time = absl::nullopt;
458   CookieInclusionStatus status;
459 
460   std::unique_ptr<CanonicalCookie> cookie = CanonicalCookie::Create(
461       url, "A=2; Domain=wrongdomain.com", now, server_time,
462       absl::nullopt /* cookie_partition_key */, &status);
463   EXPECT_EQ(nullptr, cookie.get());
464   EXPECT_TRUE(status.HasExactlyExclusionReasonsForTesting(
465       {CookieInclusionStatus::EXCLUDE_INVALID_DOMAIN}));
466 }
467 
468 // Creating a cookie for an eTLD is possible, but it must match the hostname and
469 // be a host cookie.
TEST(CanonicalCookieTest,CreateFromPublicSuffix)470 TEST(CanonicalCookieTest, CreateFromPublicSuffix) {
471   GURL url("http://com/path");
472   base::Time now = base::Time::Now();
473   absl::optional<base::Time> server_time = absl::nullopt;
474   CookieInclusionStatus status;
475 
476   // Host cookie can be created for an eTLD.
477   std::unique_ptr<CanonicalCookie> cookie = CanonicalCookie::Create(
478       url, "A=2", now, server_time, absl::nullopt, &status);
479   EXPECT_TRUE(status.IsInclude());
480   EXPECT_TRUE(cookie->IsHostCookie());
481   EXPECT_EQ("com", cookie->Domain());
482 
483   // Attempting to create a domain cookie still yields a valid cookie, but only
484   // if the domain attribute is the same as the URL's host, and it becomes a
485   // host cookie only.
486   cookie = CanonicalCookie::Create(url, "A=2; domain=com", now, server_time,
487                                    absl::nullopt, &status);
488   EXPECT_TRUE(status.IsInclude());
489   EXPECT_TRUE(cookie->IsHostCookie());
490   EXPECT_EQ("com", cookie->Domain());
491 
492   // Same thing if the domain attribute is specified with a dot.
493   cookie = CanonicalCookie::Create(url, "A=2; domain=.com", now, server_time,
494                                    absl::nullopt, &status);
495   EXPECT_TRUE(status.IsInclude());
496   EXPECT_TRUE(cookie->IsHostCookie());
497   EXPECT_EQ("com", cookie->Domain());
498 
499   // Capitalization is ok because everything is canonicalized.
500   cookie = CanonicalCookie::Create(url, "A=2; domain=CoM", now, server_time,
501                                    absl::nullopt, &status);
502   EXPECT_TRUE(status.IsInclude());
503   EXPECT_TRUE(cookie->IsHostCookie());
504   EXPECT_EQ("com", cookie->Domain());
505 
506   // Test an eTLD that is more than one label.
507   // If the domain attribute minus any leading dot is the same as the url's
508   // host, allow it to become a host cookie.
509   GURL multilabel_url = GURL("http://co.uk/path");
510   cookie = CanonicalCookie::Create(multilabel_url, "A=2", now, server_time,
511                                    absl::nullopt, &status);
512   EXPECT_TRUE(status.IsInclude());
513   EXPECT_TRUE(cookie->IsHostCookie());
514   EXPECT_EQ("co.uk", cookie->Domain());
515 
516   cookie = CanonicalCookie::Create(multilabel_url, "A=2; domain=co.uk", now,
517                                    server_time, absl::nullopt, &status);
518   EXPECT_TRUE(status.IsInclude());
519   EXPECT_TRUE(cookie->IsHostCookie());
520   EXPECT_EQ("co.uk", cookie->Domain());
521 
522   cookie = CanonicalCookie::Create(multilabel_url, "A=2; domain=.co.uk", now,
523                                    server_time, absl::nullopt, &status);
524   EXPECT_TRUE(status.IsInclude());
525   EXPECT_TRUE(cookie->IsHostCookie());
526   EXPECT_EQ("co.uk", cookie->Domain());
527 
528   // Don't allow setting a domain cookie from a public suffix for a superdomain.
529   cookie = CanonicalCookie::Create(multilabel_url, "A=2; domain=uk", now,
530                                    server_time, absl::nullopt, &status);
531   EXPECT_EQ(nullptr, cookie.get());
532   EXPECT_TRUE(status.HasExactlyExclusionReasonsForTesting(
533       {CookieInclusionStatus::EXCLUDE_INVALID_DOMAIN}));
534 
535   cookie = CanonicalCookie::Create(multilabel_url, "A=2; domain=.uk", now,
536                                    server_time, absl::nullopt, &status);
537   EXPECT_EQ(nullptr, cookie.get());
538   EXPECT_TRUE(status.HasExactlyExclusionReasonsForTesting(
539       {CookieInclusionStatus::EXCLUDE_INVALID_DOMAIN}));
540 
541   // Don't allow setting a domain cookie for an unrelated domain.
542   cookie = CanonicalCookie::Create(multilabel_url, "A=2; domain=foo.com", now,
543                                    server_time, absl::nullopt, &status);
544   EXPECT_EQ(nullptr, cookie.get());
545   EXPECT_TRUE(status.HasExactlyExclusionReasonsForTesting(
546       {CookieInclusionStatus::EXCLUDE_INVALID_DOMAIN}));
547 
548   // Don't allow setting a domain cookie for some other domain with no
549   // registrable domain.
550   cookie = CanonicalCookie::Create(multilabel_url, "A=2; domain=com", now,
551                                    server_time, absl::nullopt, &status);
552   EXPECT_EQ(nullptr, cookie.get());
553   EXPECT_TRUE(status.HasExactlyExclusionReasonsForTesting(
554       {CookieInclusionStatus::EXCLUDE_INVALID_DOMAIN}));
555 }
556 
TEST(CanonicalCookieTest,CreateWithNonASCIIDomain)557 TEST(CanonicalCookieTest, CreateWithNonASCIIDomain) {
558   GURL url("http://www.xn--xample-9ua.com/test/foo.html");
559   base::Time now = base::Time::Now();
560   absl::optional<base::Time> server_time = absl::nullopt;
561 
562   // Test with feature flag enabled.
563   {
564     base::test::ScopedFeatureList feature_list;
565     feature_list.InitAndEnableFeature(features::kCookieDomainRejectNonASCII);
566     CookieInclusionStatus status;
567 
568     // Test that non-ascii characters are rejected.
569     std::unique_ptr<CanonicalCookie> cookie = CanonicalCookie::Create(
570         url, "A=1; Domain=\xC3\xA9xample.com", now, server_time,
571         absl::nullopt /* cookie_partition_key */, &status);
572     EXPECT_EQ(nullptr, cookie.get());
573     EXPECT_TRUE(status.HasExactlyExclusionReasonsForTesting(
574         {CookieInclusionStatus::EXCLUDE_INVALID_DOMAIN,
575          CookieInclusionStatus::EXCLUDE_DOMAIN_NON_ASCII}));
576     EXPECT_FALSE(
577         status.HasWarningReason(CookieInclusionStatus::WARN_DOMAIN_NON_ASCII));
578   }
579 
580   // Test with feature flag disabled.
581   {
582     base::test::ScopedFeatureList feature_list;
583     feature_list.InitAndDisableFeature(features::kCookieDomainRejectNonASCII);
584     CookieInclusionStatus status2;
585 
586     std::unique_ptr<CanonicalCookie> cookie2 = CanonicalCookie::Create(
587         url, "A=2; Domain=\xC3\xA9xample.com", now, server_time,
588         absl::nullopt /* cookie_partition_key */, &status2);
589 
590     EXPECT_TRUE(cookie2.get());
591     EXPECT_TRUE(status2.IsInclude());
592     EXPECT_TRUE(
593         status2.HasWarningReason(CookieInclusionStatus::WARN_DOMAIN_NON_ASCII));
594   }
595 
596   // Test that regular ascii punycode still works.
597   CookieInclusionStatus status3;
598   std::unique_ptr<CanonicalCookie> cookie3 = CanonicalCookie::Create(
599       url, "A=3; Domain=xn--xample-9ua.com", now, server_time,
600       absl::nullopt /* cookie_partition_key */, &status3);
601   EXPECT_TRUE(cookie3.get());
602   EXPECT_TRUE(status3.IsInclude());
603   EXPECT_FALSE(
604       status3.HasWarningReason(CookieInclusionStatus::WARN_DOMAIN_NON_ASCII));
605 }
606 
TEST(CanonicalCookieTest,CreateWithDomainAsIP)607 TEST(CanonicalCookieTest, CreateWithDomainAsIP) {
608   GURL url("http://1.1.1.1");
609   GURL url6("http://[2606:2800:220:1:248:1893:25c8:1946]");
610 
611   base::Time now = base::Time::Now();
612   absl::optional<base::Time> server_time = absl::nullopt;
613   CookieInclusionStatus status;
614 
615   const struct {
616     const GURL url;
617     const std::string cookie_line;
618     const bool expectedResult;
619   } kTests[] = {
620       {url, "d=1;Domain=1.1.1.1;", true},
621       {url, "dd=1;Domain=.1.1.1.1;", true},
622       {url, "ds=1;Domain=1.1.1;", false},
623       {url, "dsd=1;Domain=.1.1.1;", false},
624       {url, "dx=1;Domain=0x01.0x1.0x1.0x1;", false},
625       {url, "dxd=1;Domain=.0x01.0x1.0x1.0x1;", false},
626       {url, "do=1;Domain=0001.0001.0001.0001;", false},
627       {url, "d10=1;Domain=16843009;", false},
628       {url, "d16=value;Domain=0x1010101;", false},
629       {url, "d8=1;Domain=0100200401;", false},
630       {url, "dm=1;Domain=00001.0x01.1.001;", false},
631       {url6, "d1ipv6=1;Domain=[2606:2800:220:1:248:1893:25c8:1946];", true},
632       {url6, "dd1ipv6=1;Domain=.[2606:2800:220:1:248:1893:25c8:1946];", true},
633       {url6, "dc1ipv6=1;Domain=[2606:2800:220:1:248:1893:25C8:1946];", true},
634       {url6, "d2ipv6=1;Domain=2606:2800:220:1:248:1893:25c8:1946;", false},
635       {url6, "dd2ipv6=1;Domain=.2606:2800:220:1:248:1893:25c8:1946;", false},
636       {url6, "dc2ipv6=1;Domain=2606:2800:220:1:248:1893:25C8:1946;", false},
637   };
638 
639   for (const auto& test : kTests) {
640     std::unique_ptr<CanonicalCookie> cookie = CanonicalCookie::Create(
641         test.url, test.cookie_line, now, server_time,
642         absl::nullopt /* cookie_partition_key */, &status);
643     if (test.expectedResult) {
644       ASSERT_TRUE(cookie.get());
645       EXPECT_EQ(test.url.host(), cookie->Domain());
646     } else {
647       EXPECT_EQ(nullptr, cookie.get());
648       EXPECT_TRUE(status.HasExactlyExclusionReasonsForTesting(
649           {CookieInclusionStatus::EXCLUDE_INVALID_DOMAIN}));
650     }
651   }
652 }
653 
TEST(CanonicalCookieTest,CreateSameParty)654 TEST(CanonicalCookieTest, CreateSameParty) {
655   GURL url("http://www.example.com/test/foo.html");
656   GURL https_url("https://www.example.com/test/foo.html");
657   base::Time creation_time = base::Time::Now();
658   absl::optional<base::Time> server_time = absl::nullopt;
659 
660   CookieInclusionStatus status;
661   std::unique_ptr<CanonicalCookie> cookie = CanonicalCookie::Create(
662       url, "A=2; SameParty; Secure", creation_time, server_time,
663       absl::nullopt /* cookie_partition_key */, &status);
664   ASSERT_TRUE(cookie.get());
665   EXPECT_TRUE(status.IsInclude());
666   EXPECT_TRUE(cookie->IsSecure());
667   EXPECT_TRUE(cookie->IsSameParty());
668   EXPECT_EQ(CookieSameSite::UNSPECIFIED, cookie->SameSite());
669 
670   cookie = CanonicalCookie::Create(
671       url, "A=2; SameParty; SameSite=None; Secure", creation_time, server_time,
672       absl::nullopt /* cookie_partition_key */, &status);
673   ASSERT_TRUE(cookie.get());
674   EXPECT_TRUE(status.IsInclude());
675   EXPECT_TRUE(cookie->IsSecure());
676   EXPECT_TRUE(cookie->IsSameParty());
677   EXPECT_EQ(CookieSameSite::NO_RESTRICTION, cookie->SameSite());
678 
679   cookie = CanonicalCookie::Create(
680       url, "A=2; SameParty; SameSite=Lax; Secure", creation_time, server_time,
681       absl::nullopt /* cookie_partition_key */, &status);
682   ASSERT_TRUE(cookie.get());
683   EXPECT_TRUE(status.IsInclude());
684   EXPECT_TRUE(cookie->IsSecure());
685   EXPECT_TRUE(cookie->IsSameParty());
686   EXPECT_EQ(CookieSameSite::LAX_MODE, cookie->SameSite());
687 
688   // SameParty cookie with SameSite=Strict is invalid.
689   cookie = CanonicalCookie::Create(
690       url, "A=2; SameParty; SameSite=Strict; Secure", creation_time,
691       server_time, absl::nullopt /* cookie_partition_key */, &status);
692   EXPECT_FALSE(cookie.get());
693   EXPECT_TRUE(status.HasExactlyExclusionReasonsForTesting(
694       {CookieInclusionStatus::EXCLUDE_INVALID_SAMEPARTY}));
695 
696   // SameParty cookie without Secure is invalid.
697   cookie = CanonicalCookie::Create(
698       url, "A=2; SameParty; SameSite=Lax", creation_time, server_time,
699       absl::nullopt /* cookie_partition_key */, &status);
700   EXPECT_FALSE(cookie.get());
701   EXPECT_TRUE(status.HasExactlyExclusionReasonsForTesting(
702       {CookieInclusionStatus::EXCLUDE_INVALID_SAMEPARTY}));
703 }
704 
TEST(CanonicalCookieTest,CreateWithPartitioned)705 TEST(CanonicalCookieTest, CreateWithPartitioned) {
706   GURL url("https://www.example.com/test/foo.html");
707   base::Time creation_time = base::Time::Now();
708   absl::optional<base::Time> server_time = absl::nullopt;
709   auto partition_key = absl::make_optional(
710       CookiePartitionKey::FromURLForTesting(GURL("https://toplevelsite.com")));
711   CookieInclusionStatus status;
712 
713   // Valid Partitioned attribute
714   std::unique_ptr<CanonicalCookie> cookie = CanonicalCookie::Create(
715       url, "__Host-A=2; Partitioned; Path=/; Secure", creation_time,
716       server_time, partition_key, &status);
717   ASSERT_TRUE(cookie.get());
718   EXPECT_TRUE(status.IsInclude());
719   EXPECT_TRUE(cookie->IsSecure());
720   EXPECT_TRUE(cookie->IsPartitioned());
721   EXPECT_EQ(partition_key, cookie->PartitionKey());
722   EXPECT_EQ(CookieSameSite::UNSPECIFIED, cookie->SameSite());
723 
724   // Create() without Partitioned in the cookie line should not result in a
725   // partitioned cookie.
726   status = CookieInclusionStatus();
727   cookie =
728       CanonicalCookie::Create(url, "__Host-A=2; Path=/; Secure", creation_time,
729                               server_time, partition_key, &status);
730   ASSERT_TRUE(cookie.get());
731   EXPECT_TRUE(status.IsInclude());
732   EXPECT_FALSE(cookie->IsPartitioned());
733   EXPECT_FALSE(cookie->PartitionKey());
734 
735   // Partitioned cookies with no __Host- prefix are still valid if they still
736   // have Secure, Path=/, and no Domain.
737   status = CookieInclusionStatus();
738   cookie = CanonicalCookie::Create(url, "A=2; Partitioned; Path=/; Secure",
739                                    creation_time, server_time, partition_key,
740                                    &status);
741   EXPECT_TRUE(cookie.get());
742   EXPECT_TRUE(status.IsInclude());
743   EXPECT_TRUE(cookie->IsPartitioned());
744   EXPECT_EQ(partition_key, cookie->PartitionKey());
745 
746   // Invalid Partitioned attribute: No Secure attribute.
747   status = CookieInclusionStatus();
748   cookie =
749       CanonicalCookie::Create(url, "A=2; Partitioned; Path=/", creation_time,
750                               server_time, partition_key, &status);
751   EXPECT_FALSE(cookie.get());
752   EXPECT_TRUE(status.HasExactlyExclusionReasonsForTesting(
753       {CookieInclusionStatus::EXCLUDE_INVALID_PARTITIONED}));
754 
755   // Partitioned attribute: No Path attribute.
756   status = CookieInclusionStatus();
757   cookie =
758       CanonicalCookie::Create(url, "A=2; Partitioned; Secure", creation_time,
759                               server_time, partition_key, &status);
760   EXPECT_TRUE(cookie.get());
761   EXPECT_TRUE(status.IsInclude());
762   EXPECT_TRUE(cookie->IsPartitioned());
763   EXPECT_EQ(partition_key, cookie->PartitionKey());
764 
765   // Partitioned attribute: Path attribute not equal to "/".
766   status = CookieInclusionStatus();
767   cookie = CanonicalCookie::Create(
768       url, "A=2; Partitioned; Path=/foobar; Secure", creation_time, server_time,
769       partition_key, &status);
770   EXPECT_TRUE(cookie.get());
771   EXPECT_TRUE(status.IsInclude());
772   EXPECT_TRUE(cookie->IsPartitioned());
773   EXPECT_EQ(partition_key, cookie->PartitionKey());
774 
775   // Partitioned attribute: Domain cookie.
776   status = CookieInclusionStatus();
777   cookie = CanonicalCookie::Create(
778       url, "A=2; Partitioned; Path=/; Secure; Domain=example.com",
779       creation_time, server_time, partition_key, &status);
780   EXPECT_TRUE(cookie.get());
781   LOG(ERROR) << status;
782   EXPECT_TRUE(status.IsInclude());
783   EXPECT_TRUE(cookie->IsPartitioned());
784   EXPECT_EQ(partition_key, cookie->PartitionKey());
785 
786   // No Partitioned attribute but with a nonce.
787   status = CookieInclusionStatus();
788   auto partition_key_with_nonce =
789       absl::make_optional(CookiePartitionKey::FromURLForTesting(
790           GURL("https://toplevelsite.com"), base::UnguessableToken::Create()));
791   cookie =
792       CanonicalCookie::Create(url, "__Host-A=2; Path=/; Secure", creation_time,
793                               server_time, partition_key_with_nonce, &status);
794   EXPECT_TRUE(cookie.get());
795   EXPECT_TRUE(status.IsInclude());
796   EXPECT_TRUE(cookie->IsPartitioned());
797   EXPECT_EQ(partition_key_with_nonce, cookie->PartitionKey());
798 }
799 
TEST(CanonicalCookieTest,CreateWithPartitioned_Localhost)800 TEST(CanonicalCookieTest, CreateWithPartitioned_Localhost) {
801   GURL url("http://localhost:8000/foo/bar.html");
802   base::Time creation_time = base::Time::Now();
803   absl::optional<base::Time> server_time = absl::nullopt;
804   auto partition_key =
805       CookiePartitionKey::FromURLForTesting(GURL("http://localhost:8000"));
806   CookieInclusionStatus status;
807 
808   std::unique_ptr<CanonicalCookie> cookie = CanonicalCookie::Create(
809       url, "foo=bar; Path=/; Secure; Partitioned", creation_time, server_time,
810       partition_key, &status);
811   ASSERT_TRUE(cookie.get());
812   EXPECT_TRUE(status.IsInclude());
813   EXPECT_TRUE(cookie->IsSecure());
814   EXPECT_TRUE(cookie->IsPartitioned());
815   EXPECT_EQ(partition_key, cookie->PartitionKey());
816   EXPECT_EQ(CookieSameSite::UNSPECIFIED, cookie->SameSite());
817 }
818 
TEST_P(CanonicalCookieWithClampingTest,CreateWithMaxAge)819 TEST_P(CanonicalCookieWithClampingTest, CreateWithMaxAge) {
820   GURL url("http://www.example.com/test/foo.html");
821   base::Time creation_time = base::Time::Now();
822   absl::optional<base::Time> server_time = absl::nullopt;
823 
824   // Max-age with positive integer.
825   std::unique_ptr<CanonicalCookie> cookie = CanonicalCookie::Create(
826       url, "A=1; max-age=60", creation_time, server_time,
827       absl::nullopt /* cookie_partition_key */);
828   EXPECT_TRUE(cookie.get());
829   EXPECT_TRUE(cookie->IsPersistent());
830   EXPECT_FALSE(cookie->IsExpired(creation_time));
831   EXPECT_EQ(base::Seconds(60) + creation_time, cookie->ExpiryDate());
832   EXPECT_TRUE(cookie->IsCanonical());
833 
834   // Max-age with expires (max-age should take precedence).
835   cookie = CanonicalCookie::Create(
836       url, "A=1; expires=01-Jan-1970, 00:00:00 GMT; max-age=60", creation_time,
837       server_time, absl::nullopt /* cookie_partition_key */);
838   EXPECT_TRUE(cookie.get());
839   EXPECT_TRUE(cookie->IsPersistent());
840   EXPECT_FALSE(cookie->IsExpired(creation_time));
841   EXPECT_EQ(base::Seconds(60) + creation_time, cookie->ExpiryDate());
842   EXPECT_TRUE(cookie->IsCanonical());
843 
844   // Max-age=0 should create an expired cookie with expiry equal to the earliest
845   // representable time.
846   cookie =
847       CanonicalCookie::Create(url, "A=1; max-age=0", creation_time, server_time,
848                               absl::nullopt /* cookie_partition_key */);
849   EXPECT_TRUE(cookie.get());
850   EXPECT_TRUE(cookie->IsPersistent());
851   EXPECT_TRUE(cookie->IsExpired(creation_time));
852   EXPECT_EQ(base::Time::Min(), cookie->ExpiryDate());
853   EXPECT_TRUE(cookie->IsCanonical());
854 
855   // Negative max-age should create an expired cookie with expiry equal to the
856   // earliest representable time.
857   cookie = CanonicalCookie::Create(url, "A=1; max-age=-1", creation_time,
858                                    server_time,
859                                    absl::nullopt /* cookie_partition_key */);
860   EXPECT_TRUE(cookie.get());
861   EXPECT_TRUE(cookie->IsPersistent());
862   EXPECT_TRUE(cookie->IsExpired(creation_time));
863   EXPECT_EQ(base::Time::Min(), cookie->ExpiryDate());
864   EXPECT_TRUE(cookie->IsCanonical());
865 
866   // Max-age with whitespace (should be trimmed out).
867   cookie = CanonicalCookie::Create(url, "A=1; max-age = 60  ; Secure",
868                                    creation_time, server_time,
869                                    absl::nullopt /* cookie_partition_key */);
870   EXPECT_TRUE(cookie.get());
871   EXPECT_TRUE(cookie->IsPersistent());
872   EXPECT_FALSE(cookie->IsExpired(creation_time));
873   EXPECT_EQ(base::Seconds(60) + creation_time, cookie->ExpiryDate());
874   EXPECT_TRUE(cookie->IsCanonical());
875 
876   // Max-age with non-integer should be ignored.
877   cookie = CanonicalCookie::Create(url, "A=1; max-age=abcd", creation_time,
878                                    server_time,
879                                    absl::nullopt /* cookie_partition_key */);
880   EXPECT_TRUE(cookie.get());
881   EXPECT_FALSE(cookie->IsPersistent());
882   EXPECT_FALSE(cookie->IsExpired(creation_time));
883   EXPECT_TRUE(cookie->IsCanonical());
884 
885   // Overflow max-age should be clipped.
886   cookie = CanonicalCookie::Create(url,
887                                    "A=1; "
888                                    "max-age="
889                                    "9999999999999999999999999999999999999999999"
890                                    "999999999999999999999999999999999999999999",
891                                    creation_time, server_time,
892                                    absl::nullopt /* cookie_partition_key */);
893   EXPECT_TRUE(cookie.get());
894   EXPECT_TRUE(cookie->IsPersistent());
895   EXPECT_FALSE(cookie->IsExpired(creation_time));
896   if (IsClampCookieExpiryTo400DaysEnabled()) {
897     EXPECT_EQ(creation_time + base::Days(400), cookie->ExpiryDate());
898   } else {
899     EXPECT_EQ(base::Time::Max(), cookie->ExpiryDate());
900   }
901   EXPECT_TRUE(cookie->IsCanonical());
902 
903   // Underflow max-age should be clipped.
904   cookie = CanonicalCookie::Create(url,
905                                    "A=1; "
906                                    "max-age=-"
907                                    "9999999999999999999999999999999999999999999"
908                                    "999999999999999999999999999999999999999999",
909                                    creation_time, server_time,
910                                    absl::nullopt /* cookie_partition_key */);
911   EXPECT_TRUE(cookie.get());
912   EXPECT_TRUE(cookie->IsPersistent());
913   EXPECT_TRUE(cookie->IsExpired(creation_time));
914   EXPECT_EQ(base::Time::Min(), cookie->ExpiryDate());
915   EXPECT_TRUE(cookie->IsCanonical());
916 }
917 
TEST_P(CanonicalCookieWithClampingTest,CreateWithExpires)918 TEST_P(CanonicalCookieWithClampingTest, CreateWithExpires) {
919   GURL url("http://www.example.com/test/foo.html");
920   base::Time creation_time = base::Time::Now();
921   absl::optional<base::Time> server_time = absl::nullopt;
922 
923   // Expires in the past
924   base::Time past_date = base::Time::Now() - base::Days(10);
925   std::unique_ptr<CanonicalCookie> cookie = CanonicalCookie::Create(
926       url, "A=1; expires=" + base::TimeFormatHTTP(past_date), creation_time,
927       server_time, absl::nullopt /* cookie_partition_key */);
928   EXPECT_TRUE(cookie.get());
929   EXPECT_TRUE(cookie->IsPersistent());
930   EXPECT_TRUE(cookie->IsExpired(creation_time));
931   EXPECT_TRUE((past_date - cookie->ExpiryDate()).magnitude() <
932               base::Seconds(1));
933   EXPECT_TRUE(cookie->IsCanonical());
934 
935   // Expires in the future
936   base::Time future_date = base::Time::Now() + base::Days(10);
937   cookie = CanonicalCookie::Create(
938       url, "A=1; expires=" + base::TimeFormatHTTP(future_date), creation_time,
939       server_time, absl::nullopt /* cookie_partition_key */);
940   EXPECT_TRUE(cookie.get());
941   EXPECT_TRUE(cookie->IsPersistent());
942   EXPECT_FALSE(cookie->IsExpired(creation_time));
943   EXPECT_TRUE((future_date - cookie->ExpiryDate()).magnitude() <
944               base::Seconds(1));
945   EXPECT_TRUE(cookie->IsCanonical());
946 
947   // Expires in the far future
948   future_date = base::Time::Now() + base::Days(800);
949   cookie = CanonicalCookie::Create(
950       url, "A=1; expires=" + base::TimeFormatHTTP(future_date), creation_time,
951       server_time, absl::nullopt /* cookie_partition_key */);
952   EXPECT_TRUE(cookie.get());
953   EXPECT_TRUE(cookie->IsPersistent());
954   EXPECT_FALSE(cookie->IsExpired(creation_time));
955   if (IsClampCookieExpiryTo400DaysEnabled()) {
956     EXPECT_TRUE(
957         (cookie->ExpiryDate() - creation_time - base::Days(400)).magnitude() <
958         base::Seconds(1));
959   } else {
960     EXPECT_TRUE((future_date - cookie->ExpiryDate()).magnitude() <
961                 base::Seconds(1));
962   }
963   EXPECT_TRUE(cookie->IsCanonical());
964 
965   // Expires in the far future using CreateUnsafeCookieForTesting.
966   cookie = CanonicalCookie::CreateUnsafeCookieForTesting(
967       "A", "1", url.host(), url.path(), creation_time, base::Time::Max(),
968       base::Time(), base::Time(), true, false, CookieSameSite::UNSPECIFIED,
969       COOKIE_PRIORITY_HIGH, false, absl::nullopt /* cookie_partition_key */,
970       CookieSourceScheme::kSecure, 443);
971   EXPECT_TRUE(cookie.get());
972   EXPECT_TRUE(cookie->IsPersistent());
973   EXPECT_FALSE(cookie->IsExpired(creation_time));
974   EXPECT_EQ(base::Time::Max(), cookie->ExpiryDate());
975   EXPECT_EQ(base::Time(), cookie->LastUpdateDate());
976   if (IsClampCookieExpiryTo400DaysEnabled()) {
977     EXPECT_FALSE(cookie->IsCanonical());
978   } else {
979     EXPECT_TRUE(cookie->IsCanonical());
980   }
981 
982   // Expires in the far future using FromStorage.
983   cookie = CanonicalCookie::FromStorage(
984       "A", "B", "www.foo.com", "/bar", creation_time, base::Time::Max(),
985       base::Time(), base::Time(), false /*secure*/, false /*httponly*/,
986       CookieSameSite::NO_RESTRICTION, COOKIE_PRIORITY_DEFAULT,
987       false /*same_party*/, absl::nullopt /*partition_key*/,
988       CookieSourceScheme::kSecure, 443);
989   EXPECT_TRUE(cookie.get());
990   EXPECT_TRUE(cookie->IsPersistent());
991   EXPECT_FALSE(cookie->IsExpired(creation_time));
992   EXPECT_EQ(base::Time::Max(), cookie->ExpiryDate());
993   EXPECT_EQ(base::Time(), cookie->LastUpdateDate());
994   if (IsClampCookieExpiryTo400DaysEnabled()) {
995     EXPECT_FALSE(cookie->IsCanonical());
996   } else {
997     EXPECT_TRUE(cookie->IsCanonical());
998   }
999 }
1000 
TEST(CanonicalCookieTest,EmptyExpiry)1001 TEST(CanonicalCookieTest, EmptyExpiry) {
1002   GURL url("http://www7.ipdl.inpit.go.jp/Tokujitu/tjkta.ipdl?N0000=108");
1003   base::Time creation_time = base::Time::Now();
1004   absl::optional<base::Time> server_time = absl::nullopt;
1005 
1006   std::string cookie_line =
1007       "ACSTM=20130308043820420042; path=/; domain=ipdl.inpit.go.jp; Expires=";
1008   std::unique_ptr<CanonicalCookie> cookie(
1009       CanonicalCookie::Create(url, cookie_line, creation_time, server_time,
1010                               absl::nullopt /* cookie_partition_key */));
1011   EXPECT_TRUE(cookie.get());
1012   EXPECT_FALSE(cookie->IsPersistent());
1013   EXPECT_FALSE(cookie->IsExpired(creation_time));
1014   EXPECT_EQ(base::Time(), cookie->ExpiryDate());
1015 
1016   // With a stale server time
1017   server_time = creation_time - base::Hours(1);
1018   cookie = CanonicalCookie::Create(url, cookie_line, creation_time, server_time,
1019                                    absl::nullopt /* cookie_partition_key */);
1020   EXPECT_TRUE(cookie.get());
1021   EXPECT_FALSE(cookie->IsPersistent());
1022   EXPECT_FALSE(cookie->IsExpired(creation_time));
1023   EXPECT_EQ(base::Time(), cookie->ExpiryDate());
1024 
1025   // With a future server time
1026   server_time = creation_time + base::Hours(1);
1027   cookie = CanonicalCookie::Create(url, cookie_line, creation_time, server_time,
1028                                    absl::nullopt /* cookie_partition_key */);
1029   EXPECT_TRUE(cookie.get());
1030   EXPECT_FALSE(cookie->IsPersistent());
1031   EXPECT_FALSE(cookie->IsExpired(creation_time));
1032   EXPECT_EQ(base::Time(), cookie->ExpiryDate());
1033 }
1034 
TEST_P(CanonicalCookieWithClampingTest,CreateWithLastUpdate)1035 TEST_P(CanonicalCookieWithClampingTest, CreateWithLastUpdate) {
1036   GURL url("http://www.example.com/test/foo.html");
1037   base::Time creation_time = base::Time::Now() - base::Days(1);
1038   base::Time last_update_time = base::Time::Now() - base::Hours(1);
1039   absl::optional<base::Time> server_time = absl::nullopt;
1040 
1041   // Creating a cookie sets the last update date as now.
1042   std::unique_ptr<CanonicalCookie> cookie =
1043       CanonicalCookie::Create(url, "A=1", creation_time, server_time,
1044                               /*cookie_partition_key=*/absl::nullopt);
1045   ASSERT_TRUE(cookie.get());
1046   EXPECT_TRUE((base::Time::Now() - cookie->LastUpdateDate()).magnitude() <
1047               base::Seconds(1));
1048 
1049   // Creating a sanitized cookie sets the last update date as now.
1050   cookie = CanonicalCookie::CreateSanitizedCookie(
1051       url, "A", "1", url.host(), url.path(), creation_time, base::Time(),
1052       creation_time, /*secure=*/true,
1053       /*http_only=*/false, CookieSameSite::NO_RESTRICTION,
1054       COOKIE_PRIORITY_DEFAULT, /*same_party=*/false,
1055       /*partition_key=*/absl::nullopt);
1056   ASSERT_TRUE(cookie.get());
1057   EXPECT_TRUE((base::Time::Now() - cookie->LastUpdateDate()).magnitude() <
1058               base::Seconds(1));
1059 
1060   // Creating an unsafe cookie allows us to set the last update date.
1061   cookie = CanonicalCookie::CreateUnsafeCookieForTesting(
1062       "A", "1", url.host(), url.path(), creation_time, base::Time(),
1063       base::Time(), last_update_time, /*secure=*/true,
1064       /*httponly=*/false, CookieSameSite::NO_RESTRICTION,
1065       COOKIE_PRIORITY_DEFAULT, /*same_party=*/false,
1066       /*partition_key=*/absl::nullopt, CookieSourceScheme::kSecure,
1067       /*source_port=*/443);
1068   ASSERT_TRUE(cookie.get());
1069   EXPECT_EQ(last_update_time, cookie->LastUpdateDate());
1070 
1071   // Loading a cookie from storage allows us to set the last update date.
1072   cookie = CanonicalCookie::FromStorage(
1073       "A", "1", url.host(), url.path(), creation_time, base::Time(),
1074       base::Time(), last_update_time, /*secure=*/true,
1075       /*httponly=*/false, CookieSameSite::NO_RESTRICTION,
1076       COOKIE_PRIORITY_DEFAULT, /*same_party=*/false,
1077       /*partition_key=*/absl::nullopt, CookieSourceScheme::kSecure,
1078       /*source_port=*/443);
1079   ASSERT_TRUE(cookie.get());
1080   EXPECT_EQ(last_update_time, cookie->LastUpdateDate());
1081 }
1082 
TEST(CanonicalCookieTest,IsEquivalent)1083 TEST(CanonicalCookieTest, IsEquivalent) {
1084   GURL url("https://www.example.com/");
1085   std::string cookie_name = "A";
1086   std::string cookie_value = "2EDA-EF";
1087   std::string cookie_domain = ".www.example.com";
1088   std::string cookie_path = "/path";
1089   base::Time creation_time = base::Time::Now();
1090   base::Time expiration_time = creation_time + base::Days(2);
1091   base::Time update_time = creation_time + base::Days(1);
1092   bool secure = false;
1093   bool httponly = false;
1094   CookieSameSite same_site = CookieSameSite::NO_RESTRICTION;
1095   bool same_party = false;
1096 
1097   // Test that a cookie is equivalent to itself.
1098   auto cookie = CanonicalCookie::CreateUnsafeCookieForTesting(
1099       cookie_name, cookie_value, cookie_domain, cookie_path, creation_time,
1100       expiration_time, base::Time(), update_time, secure, httponly, same_site,
1101       COOKIE_PRIORITY_MEDIUM, same_party);
1102   EXPECT_TRUE(cookie->IsEquivalent(*cookie));
1103   EXPECT_TRUE(cookie->IsEquivalentForSecureCookieMatching(*cookie));
1104 
1105   // Test that two identical cookies are equivalent.
1106   auto other_cookie = CanonicalCookie::CreateUnsafeCookieForTesting(
1107       cookie_name, cookie_value, cookie_domain, cookie_path, creation_time,
1108       expiration_time, base::Time(), update_time, secure, httponly, same_site,
1109       COOKIE_PRIORITY_MEDIUM, same_party);
1110   EXPECT_TRUE(cookie->IsEquivalent(*other_cookie));
1111   EXPECT_TRUE(other_cookie->IsEquivalentForSecureCookieMatching(*cookie));
1112 
1113   // Tests that use different variations of attribute values that
1114   // DON'T affect cookie equivalence.
1115   other_cookie = CanonicalCookie::CreateUnsafeCookieForTesting(
1116       cookie_name, "2", cookie_domain, cookie_path, creation_time,
1117       expiration_time, base::Time(), update_time, secure, httponly, same_site,
1118       COOKIE_PRIORITY_HIGH, same_party);
1119   EXPECT_TRUE(cookie->IsEquivalent(*other_cookie));
1120   EXPECT_TRUE(cookie->IsEquivalentForSecureCookieMatching(*other_cookie));
1121   EXPECT_TRUE(other_cookie->IsEquivalentForSecureCookieMatching(*cookie));
1122 
1123   base::Time other_creation_time = creation_time + base::Minutes(2);
1124   other_cookie = CanonicalCookie::CreateUnsafeCookieForTesting(
1125       cookie_name, "2", cookie_domain, cookie_path, other_creation_time,
1126       expiration_time, base::Time(), update_time, secure, httponly, same_site,
1127       COOKIE_PRIORITY_MEDIUM, same_party);
1128   EXPECT_TRUE(cookie->IsEquivalent(*other_cookie));
1129   EXPECT_TRUE(cookie->IsEquivalentForSecureCookieMatching(*other_cookie));
1130   EXPECT_TRUE(other_cookie->IsEquivalentForSecureCookieMatching(*cookie));
1131 
1132   other_cookie = CanonicalCookie::CreateUnsafeCookieForTesting(
1133       cookie_name, cookie_name, cookie_domain, cookie_path, creation_time,
1134       expiration_time, base::Time(), update_time, true, httponly, same_site,
1135       COOKIE_PRIORITY_LOW, same_party);
1136   EXPECT_TRUE(cookie->IsEquivalent(*other_cookie));
1137   EXPECT_TRUE(cookie->IsEquivalentForSecureCookieMatching(*other_cookie));
1138   EXPECT_TRUE(other_cookie->IsEquivalentForSecureCookieMatching(*cookie));
1139 
1140   other_cookie = CanonicalCookie::CreateUnsafeCookieForTesting(
1141       cookie_name, cookie_name, cookie_domain, cookie_path, creation_time,
1142       expiration_time, base::Time(), update_time, secure, true, same_site,
1143       COOKIE_PRIORITY_LOW, same_party);
1144   EXPECT_TRUE(cookie->IsEquivalent(*other_cookie));
1145   EXPECT_TRUE(cookie->IsEquivalentForSecureCookieMatching(*other_cookie));
1146   EXPECT_TRUE(other_cookie->IsEquivalentForSecureCookieMatching(*cookie));
1147 
1148   other_cookie = CanonicalCookie::CreateUnsafeCookieForTesting(
1149       cookie_name, cookie_name, cookie_domain, cookie_path, creation_time,
1150       expiration_time, base::Time(), update_time, secure, httponly,
1151       CookieSameSite::STRICT_MODE, COOKIE_PRIORITY_LOW, same_party);
1152   EXPECT_TRUE(cookie->IsEquivalent(*other_cookie));
1153   EXPECT_TRUE(cookie->IsEquivalentForSecureCookieMatching(*other_cookie));
1154   EXPECT_TRUE(other_cookie->IsEquivalentForSecureCookieMatching(*cookie));
1155 
1156   // Test the effect of a differing last_update_time on equivalency.
1157   other_cookie = CanonicalCookie::CreateUnsafeCookieForTesting(
1158       cookie_name, cookie_name, cookie_domain, cookie_path, creation_time,
1159       expiration_time, base::Time(), base::Time(), secure, httponly, same_site,
1160       COOKIE_PRIORITY_LOW, same_party);
1161   EXPECT_TRUE(cookie->IsEquivalent(*other_cookie));
1162   EXPECT_TRUE(cookie->IsEquivalentForSecureCookieMatching(*other_cookie));
1163   EXPECT_TRUE(other_cookie->IsEquivalentForSecureCookieMatching(*cookie));
1164   EXPECT_FALSE(cookie->HasEquivalentDataMembers(*other_cookie));
1165 
1166   // Cookies whose names mismatch are not equivalent.
1167   other_cookie = CanonicalCookie::CreateUnsafeCookieForTesting(
1168       "B", cookie_value, cookie_domain, cookie_path, creation_time,
1169       expiration_time, base::Time(), update_time, secure, httponly, same_site,
1170       COOKIE_PRIORITY_MEDIUM, same_party);
1171   EXPECT_FALSE(cookie->IsEquivalent(*other_cookie));
1172   EXPECT_FALSE(cookie->IsEquivalentForSecureCookieMatching(*other_cookie));
1173   EXPECT_FALSE(other_cookie->IsEquivalentForSecureCookieMatching(*cookie));
1174 
1175   // A domain cookie at 'www.example.com' is not equivalent to a host cookie
1176   // at the same domain. These are, however, equivalent according to the laxer
1177   // rules of 'IsEquivalentForSecureCookieMatching'.
1178   other_cookie = CanonicalCookie::CreateUnsafeCookieForTesting(
1179       cookie_name, cookie_value, "www.example.com", cookie_path, creation_time,
1180       expiration_time, base::Time(), update_time, secure, httponly, same_site,
1181       COOKIE_PRIORITY_MEDIUM, same_party);
1182   EXPECT_TRUE(cookie->IsDomainCookie());
1183   EXPECT_FALSE(other_cookie->IsDomainCookie());
1184   EXPECT_FALSE(cookie->IsEquivalent(*other_cookie));
1185   EXPECT_TRUE(cookie->IsEquivalentForSecureCookieMatching(*other_cookie));
1186   EXPECT_TRUE(other_cookie->IsEquivalentForSecureCookieMatching(*cookie));
1187 
1188   // Likewise, a cookie on 'example.com' is not equivalent to a cookie on
1189   // 'www.example.com', but they are equivalent for secure cookie matching.
1190   other_cookie = CanonicalCookie::CreateUnsafeCookieForTesting(
1191       cookie_name, cookie_value, ".example.com", cookie_path, creation_time,
1192       expiration_time, base::Time(), update_time, secure, httponly, same_site,
1193       COOKIE_PRIORITY_MEDIUM, same_party);
1194   EXPECT_FALSE(cookie->IsEquivalent(*other_cookie));
1195   EXPECT_TRUE(cookie->IsEquivalentForSecureCookieMatching(*other_cookie));
1196   EXPECT_TRUE(other_cookie->IsEquivalentForSecureCookieMatching(*cookie));
1197 
1198   // Paths are a bit more complicated. 'IsEquivalent' requires an exact path
1199   // match, while secure cookie matching uses a more relaxed 'IsOnPath' check.
1200   // That is, |cookie| set on '/path' is not equivalent in either way to
1201   // |other_cookie| set on '/test' or '/path/subpath'. It is, however,
1202   // equivalent for secure cookie matching to |other_cookie| set on '/'.
1203   other_cookie = CanonicalCookie::CreateUnsafeCookieForTesting(
1204       cookie_name, cookie_value, cookie_domain, "/test", creation_time,
1205       expiration_time, base::Time(), update_time, secure, httponly, same_site,
1206       COOKIE_PRIORITY_MEDIUM, same_party);
1207   EXPECT_FALSE(cookie->IsEquivalent(*other_cookie));
1208   EXPECT_FALSE(cookie->IsEquivalentForSecureCookieMatching(*other_cookie));
1209   EXPECT_FALSE(other_cookie->IsEquivalentForSecureCookieMatching(*cookie));
1210 
1211   other_cookie = CanonicalCookie::CreateUnsafeCookieForTesting(
1212       cookie_name, cookie_value, cookie_domain, cookie_path + "/subpath",
1213       creation_time, expiration_time, base::Time(), update_time, secure,
1214       httponly, same_site, COOKIE_PRIORITY_MEDIUM, same_party);
1215   EXPECT_FALSE(cookie->IsEquivalent(*other_cookie));
1216   // The path comparison is asymmetric
1217   EXPECT_FALSE(cookie->IsEquivalentForSecureCookieMatching(*other_cookie));
1218   EXPECT_TRUE(other_cookie->IsEquivalentForSecureCookieMatching(*cookie));
1219 
1220   other_cookie = CanonicalCookie::CreateUnsafeCookieForTesting(
1221       cookie_name, cookie_value, cookie_domain, "/", creation_time,
1222       expiration_time, base::Time(), update_time, secure, httponly, same_site,
1223       COOKIE_PRIORITY_MEDIUM, same_party);
1224   EXPECT_FALSE(cookie->IsEquivalent(*other_cookie));
1225   EXPECT_TRUE(cookie->IsEquivalentForSecureCookieMatching(*other_cookie));
1226   EXPECT_FALSE(other_cookie->IsEquivalentForSecureCookieMatching(*cookie));
1227 
1228   // Partitioned cookies are not equivalent to unpartitioned cookies.
1229   other_cookie = CanonicalCookie::CreateUnsafeCookieForTesting(
1230       cookie_name, cookie_value, cookie_domain, cookie_path, creation_time,
1231       expiration_time, base::Time(), update_time, secure, httponly, same_site,
1232       COOKIE_PRIORITY_MEDIUM, same_party,
1233       CookiePartitionKey::FromURLForTesting(GURL("https://foo.com")));
1234   EXPECT_FALSE(cookie->IsEquivalent(*other_cookie));
1235   EXPECT_FALSE(cookie->IsEquivalentForSecureCookieMatching(*other_cookie));
1236 
1237   // Partitioned cookies are equal if they have the same partition key.
1238   auto paritioned_cookie = CanonicalCookie::CreateUnsafeCookieForTesting(
1239       cookie_name, cookie_value, cookie_domain, cookie_path, creation_time,
1240       expiration_time, base::Time(), update_time, secure, httponly, same_site,
1241       COOKIE_PRIORITY_MEDIUM, same_party,
1242       CookiePartitionKey::FromURLForTesting(GURL("https://foo.com")));
1243   EXPECT_TRUE(paritioned_cookie->IsEquivalent(*other_cookie));
1244   EXPECT_TRUE(
1245       paritioned_cookie->IsEquivalentForSecureCookieMatching(*other_cookie));
1246 
1247   // Partitioned cookies with different partition keys are not equal
1248   other_cookie = CanonicalCookie::CreateUnsafeCookieForTesting(
1249       cookie_name, cookie_value, cookie_domain, cookie_path, creation_time,
1250       expiration_time, base::Time(), update_time, secure, httponly, same_site,
1251       COOKIE_PRIORITY_MEDIUM, same_party,
1252       CookiePartitionKey::FromURLForTesting(GURL("https://bar.com")));
1253   EXPECT_FALSE(paritioned_cookie->IsEquivalent(*other_cookie));
1254   EXPECT_FALSE(
1255       paritioned_cookie->IsEquivalentForSecureCookieMatching(*other_cookie));
1256 }
1257 
TEST(CanonicalCookieTest,IsEquivalentForSecureCookieMatching)1258 TEST(CanonicalCookieTest, IsEquivalentForSecureCookieMatching) {
1259   struct {
1260     struct {
1261       const char* name;
1262       const char* domain;
1263       const char* path;
1264       absl::optional<CookiePartitionKey> cookie_partition_key = absl::nullopt;
1265     } cookie, secure_cookie;
1266     bool equivalent;
1267     bool is_symmetric;  // Whether the reverse comparison has the same result.
1268   } kTests[] = {
1269       // Equivalent to itself
1270       {{"A", "a.foo.com", "/"}, {"A", "a.foo.com", "/"}, true, true},
1271       {{"A", ".a.foo.com", "/"}, {"A", ".a.foo.com", "/"}, true, true},
1272       // Names are different
1273       {{"A", "a.foo.com", "/"}, {"B", "a.foo.com", "/"}, false, true},
1274       // Host cookie and domain cookie with same hostname match
1275       {{"A", "a.foo.com", "/"}, {"A", ".a.foo.com", "/"}, true, true},
1276       // Subdomains and superdomains match
1277       {{"A", "a.foo.com", "/"}, {"A", ".foo.com", "/"}, true, true},
1278       {{"A", ".a.foo.com", "/"}, {"A", ".foo.com", "/"}, true, true},
1279       {{"A", "a.foo.com", "/"}, {"A", "foo.com", "/"}, true, true},
1280       {{"A", ".a.foo.com", "/"}, {"A", "foo.com", "/"}, true, true},
1281       // Different domains don't match
1282       {{"A", "a.foo.com", "/"}, {"A", "b.foo.com", "/"}, false, true},
1283       {{"A", "a.foo.com", "/"}, {"A", "ba.foo.com", "/"}, false, true},
1284       // Path attribute matches if it is a subdomain, but not vice versa.
1285       {{"A", "a.foo.com", "/sub"}, {"A", "a.foo.com", "/"}, true, false},
1286       // Different paths don't match
1287       {{"A", "a.foo.com", "/sub"}, {"A", "a.foo.com", "/other"}, false, true},
1288       {{"A", "a.foo.com", "/a/b"}, {"A", "a.foo.com", "/a/c"}, false, true},
1289       // Partitioned cookies are not equivalent to unpartitioned cookies.
1290       {{"A", ".a.foo.com", "/"},
1291        {"A", ".a.foo.com", "/",
1292         CookiePartitionKey::FromURLForTesting(GURL("https://bar.com"))},
1293        false,
1294        true},
1295       // Partitioned cookies are equivalent if they have the same partition key.
1296       {{"A", "a.foo.com", "/",
1297         CookiePartitionKey::FromURLForTesting(GURL("https://bar.com"))},
1298        {"A", "a.foo.com", "/",
1299         CookiePartitionKey::FromURLForTesting(GURL("https://bar.com"))},
1300        true,
1301        true},
1302       // Partitioned cookies are *not* equivalent if they have the different
1303       // partition keys.
1304       {{"A", "a.foo.com", "/",
1305         CookiePartitionKey::FromURLForTesting(GURL("https://bar.com"))},
1306        {"A", "a.foo.com", "/",
1307         CookiePartitionKey::FromURLForTesting(GURL("https://baz.com"))},
1308        false,
1309        true},
1310   };
1311 
1312   for (auto test : kTests) {
1313     auto cookie = CanonicalCookie::CreateUnsafeCookieForTesting(
1314         test.cookie.name, "value1", test.cookie.domain, test.cookie.path,
1315         base::Time(), base::Time(), base::Time(), base::Time(),
1316         false /* secure */, false /* httponly */, CookieSameSite::LAX_MODE,
1317         COOKIE_PRIORITY_MEDIUM, false /* sameparty */,
1318         test.cookie.cookie_partition_key);
1319     auto secure_cookie = CanonicalCookie::CreateUnsafeCookieForTesting(
1320         test.secure_cookie.name, "value2", test.secure_cookie.domain,
1321         test.secure_cookie.path, base::Time(), base::Time(), base::Time(),
1322         base::Time(), true /* secure */, false /* httponly */,
1323         CookieSameSite::LAX_MODE, COOKIE_PRIORITY_MEDIUM, false /* sameparty */,
1324         test.secure_cookie.cookie_partition_key);
1325 
1326     EXPECT_EQ(test.equivalent,
1327               cookie->IsEquivalentForSecureCookieMatching(*secure_cookie));
1328     EXPECT_EQ(test.equivalent == test.is_symmetric,
1329               secure_cookie->IsEquivalentForSecureCookieMatching(*cookie));
1330   }
1331 }
1332 
TEST(CanonicalCookieTest,IsDomainMatch)1333 TEST(CanonicalCookieTest, IsDomainMatch) {
1334   GURL url("http://www.example.com/test/foo.html");
1335   base::Time creation_time = base::Time::Now();
1336   absl::optional<base::Time> server_time = absl::nullopt;
1337 
1338   std::unique_ptr<CanonicalCookie> cookie(
1339       CanonicalCookie::Create(url, "A=2", creation_time, server_time,
1340                               absl::nullopt /* cookie_partition_key */));
1341   EXPECT_TRUE(cookie->IsHostCookie());
1342   EXPECT_TRUE(cookie->IsDomainMatch("www.example.com"));
1343   EXPECT_TRUE(cookie->IsDomainMatch("www.example.com"));
1344   EXPECT_FALSE(cookie->IsDomainMatch("foo.www.example.com"));
1345   EXPECT_FALSE(cookie->IsDomainMatch("www0.example.com"));
1346   EXPECT_FALSE(cookie->IsDomainMatch("example.com"));
1347 
1348   cookie = CanonicalCookie::Create(url, "A=2; Domain=www.example.com",
1349                                    creation_time, server_time,
1350                                    absl::nullopt /* cookie_partition_key */);
1351   EXPECT_TRUE(cookie->IsDomainCookie());
1352   EXPECT_TRUE(cookie->IsDomainMatch("www.example.com"));
1353   EXPECT_TRUE(cookie->IsDomainMatch("www.example.com"));
1354   EXPECT_TRUE(cookie->IsDomainMatch("foo.www.example.com"));
1355   EXPECT_FALSE(cookie->IsDomainMatch("www0.example.com"));
1356   EXPECT_FALSE(cookie->IsDomainMatch("example.com"));
1357 
1358   cookie = CanonicalCookie::Create(url, "A=2; Domain=.www.example.com",
1359                                    creation_time, server_time,
1360                                    absl::nullopt /* cookie_partition_key */);
1361   EXPECT_TRUE(cookie->IsDomainMatch("www.example.com"));
1362   EXPECT_TRUE(cookie->IsDomainMatch("www.example.com"));
1363   EXPECT_TRUE(cookie->IsDomainMatch("foo.www.example.com"));
1364   EXPECT_FALSE(cookie->IsDomainMatch("www0.example.com"));
1365   EXPECT_FALSE(cookie->IsDomainMatch("example.com"));
1366 }
1367 
TEST(CanonicalCookieTest,IsOnPath)1368 TEST(CanonicalCookieTest, IsOnPath) {
1369   base::Time creation_time = base::Time::Now();
1370   absl::optional<base::Time> server_time = absl::nullopt;
1371 
1372   std::unique_ptr<CanonicalCookie> cookie(CanonicalCookie::Create(
1373       GURL("http://www.example.com"), "A=2", creation_time, server_time,
1374       absl::nullopt /* cookie_partition_key */));
1375   EXPECT_TRUE(cookie->IsOnPath("/"));
1376   EXPECT_TRUE(cookie->IsOnPath("/test"));
1377   EXPECT_TRUE(cookie->IsOnPath("/test/bar.html"));
1378 
1379   // Test the empty string edge case.
1380   EXPECT_FALSE(cookie->IsOnPath(std::string()));
1381 
1382   cookie = CanonicalCookie::Create(GURL("http://www.example.com/test/foo.html"),
1383                                    "A=2", creation_time, server_time,
1384                                    absl::nullopt /* cookie_partition_key */);
1385   EXPECT_FALSE(cookie->IsOnPath("/"));
1386   EXPECT_TRUE(cookie->IsOnPath("/test"));
1387   EXPECT_TRUE(cookie->IsOnPath("/test/bar.html"));
1388   EXPECT_TRUE(cookie->IsOnPath("/test/sample/bar.html"));
1389 }
1390 
TEST(CanonicalCookieTest,GetEffectiveSameSite)1391 TEST(CanonicalCookieTest, GetEffectiveSameSite) {
1392   struct {
1393     CookieSameSite same_site;
1394     CookieEffectiveSameSite expected_effective_same_site;
1395     // nullopt for following members indicates same effective SameSite result
1396     // for all possible values.
1397     absl::optional<CookieAccessSemantics> access_semantics = absl::nullopt;
1398     absl::optional<bool> is_cookie_recent = absl::nullopt;
1399   } kTestCases[] = {
1400       // Explicitly specified SameSite always has the same effective SameSite
1401       // regardless of the access semantics.
1402       {CookieSameSite::NO_RESTRICTION, CookieEffectiveSameSite::NO_RESTRICTION},
1403       {CookieSameSite::LAX_MODE, CookieEffectiveSameSite::LAX_MODE},
1404       {CookieSameSite::STRICT_MODE, CookieEffectiveSameSite::STRICT_MODE},
1405       {CookieSameSite::NO_RESTRICTION, CookieEffectiveSameSite::NO_RESTRICTION},
1406 
1407       // UNSPECIFIED always maps to NO_RESTRICTION if LEGACY access semantics.
1408       {CookieSameSite::UNSPECIFIED, CookieEffectiveSameSite::NO_RESTRICTION,
1409        CookieAccessSemantics::LEGACY},
1410 
1411       // UNSPECIFIED with non-LEGACY access semantics depends on whether cookie
1412       // is recently created.
1413       {CookieSameSite::UNSPECIFIED,
1414        CookieEffectiveSameSite::LAX_MODE_ALLOW_UNSAFE,
1415        CookieAccessSemantics::NONLEGACY, true},
1416       {CookieSameSite::UNSPECIFIED,
1417        CookieEffectiveSameSite::LAX_MODE_ALLOW_UNSAFE,
1418        CookieAccessSemantics::UNKNOWN, true},
1419       {CookieSameSite::UNSPECIFIED, CookieEffectiveSameSite::LAX_MODE,
1420        CookieAccessSemantics::NONLEGACY, false},
1421       {CookieSameSite::UNSPECIFIED, CookieEffectiveSameSite::LAX_MODE,
1422        CookieAccessSemantics::UNKNOWN, false},
1423   };
1424 
1425   for (const auto& test : kTestCases) {
1426     std::vector<std::unique_ptr<CanonicalCookie>> cookies;
1427 
1428     base::Time now = base::Time::Now();
1429     base::Time recent_creation_time = now - (kLaxAllowUnsafeMaxAge / 4);
1430     base::Time not_recent_creation_time = now - (kLaxAllowUnsafeMaxAge * 4);
1431     base::Time expiry_time = now + (kLaxAllowUnsafeMaxAge / 4);
1432 
1433     if (!test.is_cookie_recent.has_value() || *test.is_cookie_recent) {
1434       // Recent session cookie.
1435       cookies.push_back(CanonicalCookie::CreateUnsafeCookieForTesting(
1436           "A", "2", "example.test", "/", recent_creation_time, base::Time(),
1437           base::Time(), base::Time(), true /* secure */, false /* httponly */,
1438           test.same_site, COOKIE_PRIORITY_DEFAULT, false));
1439       // Recent persistent cookie.
1440       cookies.push_back(CanonicalCookie::CreateUnsafeCookieForTesting(
1441           "A", "2", "example.test", "/", recent_creation_time, expiry_time,
1442           base::Time(), base::Time(), true /* secure */, false /* httponly */,
1443           test.same_site, COOKIE_PRIORITY_DEFAULT, false));
1444     }
1445     if (!test.is_cookie_recent.has_value() || !(*test.is_cookie_recent)) {
1446       // Not-recent session cookie.
1447       cookies.push_back(CanonicalCookie::CreateUnsafeCookieForTesting(
1448           "A", "2", "example.test", "/", not_recent_creation_time, base::Time(),
1449           base::Time(), base::Time(), true /* secure */, false /* httponly */,
1450           test.same_site, COOKIE_PRIORITY_DEFAULT, false));
1451       // Not-recent persistent cookie.
1452       cookies.push_back(CanonicalCookie::CreateUnsafeCookieForTesting(
1453           "A", "2", "example.test", "/", not_recent_creation_time, expiry_time,
1454           base::Time(), base::Time(), true /* secure */, false /* httponly */,
1455           test.same_site, COOKIE_PRIORITY_DEFAULT, false));
1456     }
1457 
1458     std::vector<CookieAccessSemantics> access_semantics = {
1459         CookieAccessSemantics::UNKNOWN, CookieAccessSemantics::LEGACY,
1460         CookieAccessSemantics::NONLEGACY};
1461     if (test.access_semantics.has_value())
1462       access_semantics = {*test.access_semantics};
1463 
1464     for (const auto& cookie : cookies) {
1465       for (const auto semantics : access_semantics) {
1466         EXPECT_EQ(test.expected_effective_same_site,
1467                   cookie->GetEffectiveSameSiteForTesting(semantics));
1468       }
1469     }
1470   }
1471 }
1472 
TEST(CanonicalCookieTest,IncludeForRequestURL)1473 TEST(CanonicalCookieTest, IncludeForRequestURL) {
1474   GURL url("http://www.example.com");
1475   base::Time creation_time = base::Time::Now();
1476   CookieOptions options = CookieOptions::MakeAllInclusive();
1477   absl::optional<base::Time> server_time = absl::nullopt;
1478 
1479   std::unique_ptr<CanonicalCookie> cookie(
1480       CanonicalCookie::Create(url, "A=2", creation_time, server_time,
1481                               absl::nullopt /* cookie_partition_key */));
1482   EXPECT_TRUE(cookie
1483                   ->IncludeForRequestURL(
1484                       url, options,
1485                       CookieAccessParams{
1486                           net::CookieAccessSemantics::UNKNOWN,
1487                           /*delegate_treats_url_as_trustworthy=*/false,
1488                           CookieSamePartyStatus::kNoSamePartyEnforcement})
1489                   .status.IsInclude());
1490   EXPECT_TRUE(cookie
1491                   ->IncludeForRequestURL(
1492                       GURL("http://www.example.com/foo/bar"), options,
1493                       CookieAccessParams{
1494                           net::CookieAccessSemantics::UNKNOWN,
1495                           /*delegate_treats_url_as_trustworthy=*/false,
1496                           CookieSamePartyStatus::kNoSamePartyEnforcement})
1497                   .status.IsInclude());
1498   EXPECT_TRUE(cookie
1499                   ->IncludeForRequestURL(
1500                       GURL("https://www.example.com/foo/bar"), options,
1501                       CookieAccessParams{
1502                           net::CookieAccessSemantics::UNKNOWN,
1503                           /*delegate_treats_url_as_trustworthy=*/false,
1504                           CookieSamePartyStatus::kNoSamePartyEnforcement})
1505                   .status.IsInclude());
1506   EXPECT_TRUE(cookie
1507                   ->IncludeForRequestURL(
1508                       GURL("https://sub.example.com"), options,
1509                       CookieAccessParams{
1510                           net::CookieAccessSemantics::UNKNOWN,
1511                           /*delegate_treats_url_as_trustworthy=*/false,
1512                           CookieSamePartyStatus::kNoSamePartyEnforcement})
1513                   .status.HasExactlyExclusionReasonsForTesting(
1514                       {CookieInclusionStatus::EXCLUDE_DOMAIN_MISMATCH}));
1515   EXPECT_TRUE(cookie
1516                   ->IncludeForRequestURL(
1517                       GURL("https://sub.www.example.com"), options,
1518                       CookieAccessParams{
1519                           net::CookieAccessSemantics::UNKNOWN,
1520                           /*delegate_treats_url_as_trustworthy=*/false,
1521                           CookieSamePartyStatus::kNoSamePartyEnforcement})
1522                   .status.HasExactlyExclusionReasonsForTesting(
1523                       {CookieInclusionStatus::EXCLUDE_DOMAIN_MISMATCH}));
1524 
1525   // Test that cookie with a cookie path that does not match the url path are
1526   // not included.
1527   cookie = CanonicalCookie::Create(url, "A=2; Path=/foo/bar", creation_time,
1528                                    server_time,
1529                                    absl::nullopt /* cookie_partition_key */);
1530   EXPECT_TRUE(cookie
1531                   ->IncludeForRequestURL(
1532                       url, options,
1533                       CookieAccessParams{
1534                           net::CookieAccessSemantics::UNKNOWN,
1535                           /*delegate_treats_url_as_trustworthy=*/false,
1536                           CookieSamePartyStatus::kNoSamePartyEnforcement})
1537                   .status.HasExactlyExclusionReasonsForTesting(
1538                       {CookieInclusionStatus::EXCLUDE_NOT_ON_PATH}));
1539   EXPECT_TRUE(cookie
1540                   ->IncludeForRequestURL(
1541                       GURL("http://www.example.com/foo/bar/index.html"),
1542                       options,
1543                       CookieAccessParams{
1544                           net::CookieAccessSemantics::UNKNOWN,
1545                           /*delegate_treats_url_as_trustworthy=*/false,
1546                           CookieSamePartyStatus::kNoSamePartyEnforcement})
1547                   .status.IsInclude());
1548 
1549   // Test that a secure cookie is not included for a non secure URL.
1550   GURL secure_url("https://www.example.com");
1551   cookie = CanonicalCookie::Create(secure_url, "A=2; Secure", creation_time,
1552                                    server_time,
1553                                    absl::nullopt /* cookie_partition_key */);
1554   EXPECT_TRUE(cookie->IsSecure());
1555   EXPECT_TRUE(cookie
1556                   ->IncludeForRequestURL(
1557                       secure_url, options,
1558                       CookieAccessParams{
1559                           net::CookieAccessSemantics::UNKNOWN,
1560                           /*delegate_treats_url_as_trustworthy=*/false,
1561                           CookieSamePartyStatus::kNoSamePartyEnforcement})
1562                   .status.IsInclude());
1563   EXPECT_TRUE(cookie
1564                   ->IncludeForRequestURL(
1565                       url, options,
1566                       CookieAccessParams{
1567                           net::CookieAccessSemantics::UNKNOWN,
1568                           /*delegate_treats_url_as_trustworthy=*/false,
1569                           CookieSamePartyStatus::kNoSamePartyEnforcement})
1570                   .status.HasExactlyExclusionReasonsForTesting(
1571                       {CookieInclusionStatus::EXCLUDE_SECURE_ONLY}));
1572 
1573   // Test that a delegate can make an exception, however, and ask for a
1574   // non-secure URL to be treated as trustworthy... with a warning.
1575   cookie =
1576       CanonicalCookie::Create(url, "A=2; Secure", creation_time, server_time,
1577                               absl::nullopt /* cookie_partition_key */);
1578   ASSERT_TRUE(cookie);
1579   EXPECT_TRUE(cookie->IsSecure());
1580   CookieAccessResult result = cookie->IncludeForRequestURL(
1581       url, options,
1582       CookieAccessParams{net::CookieAccessSemantics::UNKNOWN,
1583                          /*delegate_treats_url_as_trustworthy=*/true,
1584                          CookieSamePartyStatus::kNoSamePartyEnforcement});
1585   EXPECT_TRUE(result.status.IsInclude());
1586   EXPECT_TRUE(result.status.HasWarningReason(
1587       CookieInclusionStatus::WARN_SECURE_ACCESS_GRANTED_NON_CRYPTOGRAPHIC));
1588 
1589   // The same happens for localhost even w/o delegate intervention.
1590   GURL localhost_url("http://localhost/");
1591   cookie = CanonicalCookie::Create(localhost_url, "A=2; Secure", creation_time,
1592                                    server_time,
1593                                    absl::nullopt /* cookie_partition_key */);
1594   ASSERT_TRUE(cookie);
1595   EXPECT_TRUE(cookie->IsSecure());
1596   result = cookie->IncludeForRequestURL(
1597       localhost_url, options,
1598       CookieAccessParams{net::CookieAccessSemantics::UNKNOWN,
1599                          /*delegate_treats_url_as_trustworthy=*/false,
1600                          CookieSamePartyStatus::kNoSamePartyEnforcement});
1601   EXPECT_TRUE(result.status.IsInclude());
1602   EXPECT_TRUE(result.status.HasWarningReason(
1603       CookieInclusionStatus::WARN_SECURE_ACCESS_GRANTED_NON_CRYPTOGRAPHIC));
1604 
1605   // An unneeded exception doesn't add a warning, however.
1606   cookie = CanonicalCookie::Create(secure_url, "A=2; Secure", creation_time,
1607                                    server_time,
1608                                    absl::nullopt /* cookie_partition_key */);
1609   ASSERT_TRUE(cookie);
1610   EXPECT_TRUE(cookie->IsSecure());
1611   result = cookie->IncludeForRequestURL(
1612       secure_url, options,
1613       CookieAccessParams{net::CookieAccessSemantics::UNKNOWN,
1614                          /*delegate_treats_url_as_trustworthy=*/true,
1615                          CookieSamePartyStatus::kNoSamePartyEnforcement});
1616   EXPECT_TRUE(result.status.IsInclude());
1617   EXPECT_FALSE(result.status.ShouldWarn());
1618 
1619   //
1620 
1621   // Test that http only cookies are only included if the include httponly flag
1622   // is set on the cookie options.
1623   options.set_include_httponly();
1624   cookie =
1625       CanonicalCookie::Create(url, "A=2; HttpOnly", creation_time, server_time,
1626                               absl::nullopt /* cookie_partition_key */);
1627   EXPECT_TRUE(cookie->IsHttpOnly());
1628   EXPECT_TRUE(cookie
1629                   ->IncludeForRequestURL(
1630                       url, options,
1631                       CookieAccessParams{
1632                           net::CookieAccessSemantics::UNKNOWN,
1633                           /*delegate_treats_url_as_trustworthy=*/false,
1634                           CookieSamePartyStatus::kNoSamePartyEnforcement})
1635                   .status.IsInclude());
1636   options.set_exclude_httponly();
1637   EXPECT_TRUE(cookie
1638                   ->IncludeForRequestURL(
1639                       url, options,
1640                       CookieAccessParams{
1641                           net::CookieAccessSemantics::UNKNOWN,
1642                           /*delegate_treats_url_as_trustworthy=*/false,
1643                           CookieSamePartyStatus::kNoSamePartyEnforcement})
1644                   .status.HasExactlyExclusionReasonsForTesting(
1645                       {CookieInclusionStatus::EXCLUDE_HTTP_ONLY}));
1646 }
1647 
1648 struct IncludeForRequestURLTestCase {
1649   std::string cookie_line;
1650   CookieSameSite expected_samesite;
1651   CookieEffectiveSameSite expected_effective_samesite;
1652   CookieOptions::SameSiteCookieContext request_options_samesite_context;
1653   CookieInclusionStatus expected_inclusion_status;
1654   base::TimeDelta creation_time_delta = base::TimeDelta();
1655 };
1656 
VerifyIncludeForRequestURLTestCases(CookieAccessSemantics access_semantics,std::vector<IncludeForRequestURLTestCase> test_cases)1657 void VerifyIncludeForRequestURLTestCases(
1658     CookieAccessSemantics access_semantics,
1659     std::vector<IncludeForRequestURLTestCase> test_cases) {
1660   GURL url("https://example.test");
1661 
1662   for (const auto& test : test_cases) {
1663     base::Time creation_time = base::Time::Now() - test.creation_time_delta;
1664     std::unique_ptr<CanonicalCookie> cookie = CanonicalCookie::Create(
1665         url, test.cookie_line, creation_time, absl::nullopt /* server_time */,
1666         absl::nullopt /* cookie_partition_key */);
1667     EXPECT_EQ(test.expected_samesite, cookie->SameSite());
1668 
1669     CookieOptions request_options;
1670     request_options.set_same_site_cookie_context(
1671         test.request_options_samesite_context);
1672 
1673     EXPECT_THAT(
1674         cookie->IncludeForRequestURL(
1675             url, request_options,
1676             CookieAccessParams{access_semantics,
1677                                /*delegate_treats_url_as_trustworthy=*/false,
1678                                CookieSamePartyStatus::kNoSamePartyEnforcement}),
1679         MatchesCookieAccessResult(test.expected_inclusion_status,
1680                                   test.expected_effective_samesite,
1681                                   access_semantics, true))
1682         << cookie->Name() << "=" << cookie->Value();
1683   }
1684 }
1685 
TEST(CanonicalCookieTest,IncludeForRequestURLSameSite)1686 TEST(CanonicalCookieTest, IncludeForRequestURLSameSite) {
1687   const base::TimeDelta kLongAge = kLaxAllowUnsafeMaxAge * 4;
1688   const base::TimeDelta kShortAge = kLaxAllowUnsafeMaxAge / 4;
1689 
1690   using SameSiteCookieContext = CookieOptions::SameSiteCookieContext;
1691 
1692   // Test cases that are the same regardless of feature status or access
1693   // semantics. For Schemeful Same-Site this means that the context downgrade is
1694   // a no-op (such as for NO_RESTRICTION cookies) or that there is no downgrade:
1695   std::vector<IncludeForRequestURLTestCase> common_test_cases = {
1696       // Strict cookies:
1697       {"Common=1;SameSite=Strict", CookieSameSite::STRICT_MODE,
1698        CookieEffectiveSameSite::STRICT_MODE,
1699        SameSiteCookieContext(SameSiteCookieContext::ContextType::CROSS_SITE),
1700        CookieInclusionStatus(CookieInclusionStatus::EXCLUDE_SAMESITE_STRICT)},
1701       {"Common=2;SameSite=Strict", CookieSameSite::STRICT_MODE,
1702        CookieEffectiveSameSite::STRICT_MODE,
1703        SameSiteCookieContext(
1704            SameSiteCookieContext::ContextType::SAME_SITE_LAX_METHOD_UNSAFE),
1705        CookieInclusionStatus(CookieInclusionStatus::EXCLUDE_SAMESITE_STRICT)},
1706       {"Common=3;SameSite=Strict", CookieSameSite::STRICT_MODE,
1707        CookieEffectiveSameSite::STRICT_MODE,
1708        SameSiteCookieContext(SameSiteCookieContext::ContextType::SAME_SITE_LAX),
1709        CookieInclusionStatus(CookieInclusionStatus::EXCLUDE_SAMESITE_STRICT)},
1710       {"Common=4;SameSite=Strict", CookieSameSite::STRICT_MODE,
1711        CookieEffectiveSameSite::STRICT_MODE,
1712        SameSiteCookieContext(
1713            SameSiteCookieContext::ContextType::SAME_SITE_STRICT),
1714        CookieInclusionStatus()},
1715       // Lax cookies:
1716       {"Common=5;SameSite=Lax", CookieSameSite::LAX_MODE,
1717        CookieEffectiveSameSite::LAX_MODE,
1718        SameSiteCookieContext(SameSiteCookieContext::ContextType::CROSS_SITE),
1719        CookieInclusionStatus(CookieInclusionStatus::EXCLUDE_SAMESITE_LAX)},
1720       {"Common=6;SameSite=Lax", CookieSameSite::LAX_MODE,
1721        CookieEffectiveSameSite::LAX_MODE,
1722        SameSiteCookieContext(
1723            SameSiteCookieContext::ContextType::SAME_SITE_LAX_METHOD_UNSAFE),
1724        CookieInclusionStatus(CookieInclusionStatus::EXCLUDE_SAMESITE_LAX)},
1725       {"Common=7;SameSite=Lax", CookieSameSite::LAX_MODE,
1726        CookieEffectiveSameSite::LAX_MODE,
1727        SameSiteCookieContext(SameSiteCookieContext::ContextType::SAME_SITE_LAX),
1728        CookieInclusionStatus()},
1729       {"Common=8;SameSite=Lax", CookieSameSite::LAX_MODE,
1730        CookieEffectiveSameSite::LAX_MODE,
1731        SameSiteCookieContext(
1732            SameSiteCookieContext::ContextType::SAME_SITE_STRICT),
1733        CookieInclusionStatus()},
1734       // Lax cookies with downgrade:
1735       {"Common=9;SameSite=Lax", CookieSameSite::LAX_MODE,
1736        CookieEffectiveSameSite::LAX_MODE,
1737        SameSiteCookieContext(
1738            SameSiteCookieContext::ContextType::SAME_SITE_STRICT,
1739            SameSiteCookieContext::ContextType::SAME_SITE_LAX),
1740        CookieInclusionStatus()},
1741       // None and Secure cookies:
1742       {"Common=10;SameSite=None;Secure", CookieSameSite::NO_RESTRICTION,
1743        CookieEffectiveSameSite::NO_RESTRICTION,
1744        SameSiteCookieContext(SameSiteCookieContext::ContextType::CROSS_SITE),
1745        CookieInclusionStatus()},
1746       {"Common=11;SameSite=None;Secure", CookieSameSite::NO_RESTRICTION,
1747        CookieEffectiveSameSite::NO_RESTRICTION,
1748        SameSiteCookieContext(
1749            SameSiteCookieContext::ContextType::SAME_SITE_LAX_METHOD_UNSAFE),
1750        CookieInclusionStatus()},
1751       {"Common=12;SameSite=None;Secure", CookieSameSite::NO_RESTRICTION,
1752        CookieEffectiveSameSite::NO_RESTRICTION,
1753        SameSiteCookieContext(SameSiteCookieContext::ContextType::SAME_SITE_LAX),
1754        CookieInclusionStatus()},
1755       {"Common=13;SameSite=None;Secure", CookieSameSite::NO_RESTRICTION,
1756        CookieEffectiveSameSite::NO_RESTRICTION,
1757        SameSiteCookieContext(
1758            SameSiteCookieContext::ContextType::SAME_SITE_STRICT),
1759        CookieInclusionStatus()},
1760       // Because NO_RESTRICTION cookies are always sent, the schemeful context
1761       // downgrades shouldn't matter.
1762       {"Common=14;SameSite=None;Secure", CookieSameSite::NO_RESTRICTION,
1763        CookieEffectiveSameSite::NO_RESTRICTION,
1764        SameSiteCookieContext(
1765            SameSiteCookieContext::ContextType::SAME_SITE_STRICT,
1766            SameSiteCookieContext::ContextType::SAME_SITE_LAX),
1767        CookieInclusionStatus()},
1768       {"Common=15;SameSite=None;Secure", CookieSameSite::NO_RESTRICTION,
1769        CookieEffectiveSameSite::NO_RESTRICTION,
1770        SameSiteCookieContext(
1771            SameSiteCookieContext::ContextType::SAME_SITE_STRICT,
1772            SameSiteCookieContext::ContextType::SAME_SITE_LAX_METHOD_UNSAFE),
1773        CookieInclusionStatus()},
1774       {"Common=16;SameSite=None;Secure", CookieSameSite::NO_RESTRICTION,
1775        CookieEffectiveSameSite::NO_RESTRICTION,
1776        SameSiteCookieContext(
1777            SameSiteCookieContext::ContextType::SAME_SITE_STRICT,
1778            SameSiteCookieContext::ContextType::CROSS_SITE),
1779        CookieInclusionStatus()},
1780       {"Common=17;SameSite=None;Secure", CookieSameSite::NO_RESTRICTION,
1781        CookieEffectiveSameSite::NO_RESTRICTION,
1782        SameSiteCookieContext(SameSiteCookieContext::ContextType::SAME_SITE_LAX,
1783                              SameSiteCookieContext::ContextType::CROSS_SITE),
1784        CookieInclusionStatus()},
1785       {"Common=18;SameSite=None;Secure", CookieSameSite::NO_RESTRICTION,
1786        CookieEffectiveSameSite::NO_RESTRICTION,
1787        SameSiteCookieContext(
1788            SameSiteCookieContext::ContextType::SAME_SITE_LAX_METHOD_UNSAFE,
1789            SameSiteCookieContext::ContextType::CROSS_SITE),
1790        CookieInclusionStatus()},
1791   };
1792 
1793   // Test cases where the unspecified-SameSite cookie defaults to SameSite=None
1794   // due to LEGACY access semantics):
1795   std::vector<IncludeForRequestURLTestCase> default_none_test_cases = {
1796       {"DefaultNone=1", CookieSameSite::UNSPECIFIED,
1797        CookieEffectiveSameSite::NO_RESTRICTION,
1798        SameSiteCookieContext(SameSiteCookieContext::ContextType::CROSS_SITE),
1799        CookieInclusionStatus::MakeFromReasonsForTesting(
1800            std::vector<CookieInclusionStatus::ExclusionReason>(),
1801            {CookieInclusionStatus::
1802                 WARN_SAMESITE_UNSPECIFIED_CROSS_SITE_CONTEXT})},
1803       {"DefaultNone=2", CookieSameSite::UNSPECIFIED,
1804        CookieEffectiveSameSite::NO_RESTRICTION,
1805        SameSiteCookieContext(
1806            SameSiteCookieContext::ContextType::SAME_SITE_LAX_METHOD_UNSAFE),
1807        CookieInclusionStatus::MakeFromReasonsForTesting(
1808            std::vector<CookieInclusionStatus::ExclusionReason>(),
1809            {CookieInclusionStatus::
1810                 WARN_SAMESITE_UNSPECIFIED_CROSS_SITE_CONTEXT})},
1811 
1812       {"DefaultNone=3", CookieSameSite::UNSPECIFIED,
1813        CookieEffectiveSameSite::NO_RESTRICTION,
1814        SameSiteCookieContext(SameSiteCookieContext::ContextType::SAME_SITE_LAX),
1815        CookieInclusionStatus()},
1816       {"DefaultNone=4", CookieSameSite::UNSPECIFIED,
1817        CookieEffectiveSameSite::NO_RESTRICTION,
1818        SameSiteCookieContext(
1819            SameSiteCookieContext::ContextType::SAME_SITE_STRICT),
1820        CookieInclusionStatus()}};
1821 
1822   // Test cases where the unspecified-SameSite cookie defaults to SameSite=Lax:
1823   std::vector<IncludeForRequestURLTestCase> default_lax_test_cases = {
1824       // Unspecified recently-created cookies (with SameSite-by-default):
1825       {"DefaultLax=1", CookieSameSite::UNSPECIFIED,
1826        CookieEffectiveSameSite::LAX_MODE_ALLOW_UNSAFE,
1827        SameSiteCookieContext(SameSiteCookieContext::ContextType::CROSS_SITE),
1828        CookieInclusionStatus(
1829            CookieInclusionStatus::EXCLUDE_SAMESITE_UNSPECIFIED_TREATED_AS_LAX,
1830            CookieInclusionStatus::WARN_SAMESITE_UNSPECIFIED_CROSS_SITE_CONTEXT),
1831        kShortAge},
1832       {"DefaultLax=2", CookieSameSite::UNSPECIFIED,
1833        CookieEffectiveSameSite::LAX_MODE_ALLOW_UNSAFE,
1834        SameSiteCookieContext(
1835            SameSiteCookieContext::ContextType::SAME_SITE_LAX_METHOD_UNSAFE),
1836        CookieInclusionStatus::MakeFromReasonsForTesting(
1837            std::vector<CookieInclusionStatus::ExclusionReason>(),
1838            {CookieInclusionStatus::WARN_SAMESITE_UNSPECIFIED_LAX_ALLOW_UNSAFE}),
1839        kShortAge},
1840       {"DefaultLax=3", CookieSameSite::UNSPECIFIED,
1841        CookieEffectiveSameSite::LAX_MODE_ALLOW_UNSAFE,
1842        SameSiteCookieContext(SameSiteCookieContext::ContextType::SAME_SITE_LAX),
1843        CookieInclusionStatus(), kShortAge},
1844       {"DefaultLax=4", CookieSameSite::UNSPECIFIED,
1845        CookieEffectiveSameSite::LAX_MODE_ALLOW_UNSAFE,
1846        SameSiteCookieContext(
1847            SameSiteCookieContext::ContextType::SAME_SITE_STRICT),
1848        CookieInclusionStatus(), kShortAge},
1849       // Unspecified not-recently-created cookies (with SameSite-by-default):
1850       {"DefaultLax=5", CookieSameSite::UNSPECIFIED,
1851        CookieEffectiveSameSite::LAX_MODE,
1852        SameSiteCookieContext(SameSiteCookieContext::ContextType::CROSS_SITE),
1853        CookieInclusionStatus(
1854            CookieInclusionStatus::EXCLUDE_SAMESITE_UNSPECIFIED_TREATED_AS_LAX,
1855            CookieInclusionStatus::WARN_SAMESITE_UNSPECIFIED_CROSS_SITE_CONTEXT),
1856        kLongAge},
1857       {"DefaultLax=6", CookieSameSite::UNSPECIFIED,
1858        CookieEffectiveSameSite::LAX_MODE,
1859        SameSiteCookieContext(
1860            SameSiteCookieContext::ContextType::SAME_SITE_LAX_METHOD_UNSAFE),
1861        CookieInclusionStatus(
1862            CookieInclusionStatus::EXCLUDE_SAMESITE_UNSPECIFIED_TREATED_AS_LAX,
1863            CookieInclusionStatus::WARN_SAMESITE_UNSPECIFIED_CROSS_SITE_CONTEXT),
1864        kLongAge},
1865       {"DefaultLax=7", CookieSameSite::UNSPECIFIED,
1866        CookieEffectiveSameSite::LAX_MODE,
1867        SameSiteCookieContext(SameSiteCookieContext::ContextType::SAME_SITE_LAX),
1868        CookieInclusionStatus(), kLongAge},
1869       {"DefaultLax=8", CookieSameSite::UNSPECIFIED,
1870        CookieEffectiveSameSite::LAX_MODE,
1871        SameSiteCookieContext(
1872            SameSiteCookieContext::ContextType::SAME_SITE_STRICT),
1873        CookieInclusionStatus(), kLongAge},
1874   };
1875 
1876   // Test cases that require LEGACY semantics or Schemeful Same-Site to be
1877   // disabled.
1878   std::vector<IncludeForRequestURLTestCase> schemeful_disabled_test_cases = {
1879       {"LEGACY_Schemeful=1;SameSite=Strict", CookieSameSite::STRICT_MODE,
1880        CookieEffectiveSameSite::STRICT_MODE,
1881        SameSiteCookieContext(
1882            SameSiteCookieContext::ContextType::SAME_SITE_STRICT,
1883            SameSiteCookieContext::ContextType::SAME_SITE_LAX),
1884        CookieInclusionStatus::MakeFromReasonsForTesting(
1885            std::vector<CookieInclusionStatus::ExclusionReason>(),
1886            {CookieInclusionStatus::WARN_STRICT_LAX_DOWNGRADE_STRICT_SAMESITE})},
1887       {"LEGACY_Schemeful=2;SameSite=Strict", CookieSameSite::STRICT_MODE,
1888        CookieEffectiveSameSite::STRICT_MODE,
1889        SameSiteCookieContext(
1890            SameSiteCookieContext::ContextType::SAME_SITE_STRICT,
1891            SameSiteCookieContext::ContextType::SAME_SITE_LAX_METHOD_UNSAFE),
1892        CookieInclusionStatus::MakeFromReasonsForTesting(
1893            std::vector<CookieInclusionStatus::ExclusionReason>(),
1894            {CookieInclusionStatus::
1895                 WARN_STRICT_CROSS_DOWNGRADE_STRICT_SAMESITE})},
1896       {"LEGACY_Schemeful=3;SameSite=Strict", CookieSameSite::STRICT_MODE,
1897        CookieEffectiveSameSite::STRICT_MODE,
1898        SameSiteCookieContext(
1899            SameSiteCookieContext::ContextType::SAME_SITE_STRICT,
1900            SameSiteCookieContext::ContextType::CROSS_SITE),
1901        CookieInclusionStatus::MakeFromReasonsForTesting(
1902            std::vector<CookieInclusionStatus::ExclusionReason>(),
1903            {CookieInclusionStatus::
1904                 WARN_STRICT_CROSS_DOWNGRADE_STRICT_SAMESITE})},
1905       {"LEGACY_Schemeful=4;SameSite=Lax", CookieSameSite::LAX_MODE,
1906        CookieEffectiveSameSite::LAX_MODE,
1907        SameSiteCookieContext(
1908            SameSiteCookieContext::ContextType::SAME_SITE_STRICT,
1909            SameSiteCookieContext::ContextType::SAME_SITE_LAX_METHOD_UNSAFE),
1910        CookieInclusionStatus::MakeFromReasonsForTesting(
1911            std::vector<CookieInclusionStatus::ExclusionReason>(),
1912            {CookieInclusionStatus::WARN_STRICT_CROSS_DOWNGRADE_LAX_SAMESITE})},
1913       {"LEGACY_Schemeful=5;SameSite=Lax", CookieSameSite::LAX_MODE,
1914        CookieEffectiveSameSite::LAX_MODE,
1915        SameSiteCookieContext(
1916            SameSiteCookieContext::ContextType::SAME_SITE_STRICT,
1917            SameSiteCookieContext::ContextType::CROSS_SITE),
1918        CookieInclusionStatus::MakeFromReasonsForTesting(
1919            std::vector<CookieInclusionStatus::ExclusionReason>(),
1920            {CookieInclusionStatus::WARN_STRICT_CROSS_DOWNGRADE_LAX_SAMESITE})},
1921       {"LEGACY_Schemeful=6;SameSite=Lax", CookieSameSite::LAX_MODE,
1922        CookieEffectiveSameSite::LAX_MODE,
1923        SameSiteCookieContext(SameSiteCookieContext::ContextType::SAME_SITE_LAX,
1924                              SameSiteCookieContext::ContextType::CROSS_SITE),
1925        CookieInclusionStatus::MakeFromReasonsForTesting(
1926            std::vector<CookieInclusionStatus::ExclusionReason>(),
1927            {CookieInclusionStatus::WARN_LAX_CROSS_DOWNGRADE_LAX_SAMESITE})},
1928   };
1929 
1930   // Test cases that require NONLEGACY or UNKNOWN semantics with Schemeful
1931   // Same-Site enabled
1932   std::vector<IncludeForRequestURLTestCase> schemeful_enabled_test_cases = {
1933       {"NONLEGACY_Schemeful=1;SameSite=Strict", CookieSameSite::STRICT_MODE,
1934        CookieEffectiveSameSite::STRICT_MODE,
1935        SameSiteCookieContext(
1936            SameSiteCookieContext::ContextType::SAME_SITE_STRICT,
1937            SameSiteCookieContext::ContextType::SAME_SITE_LAX),
1938        CookieInclusionStatus::MakeFromReasonsForTesting(
1939            {CookieInclusionStatus::EXCLUDE_SAMESITE_STRICT},
1940            {CookieInclusionStatus::WARN_STRICT_LAX_DOWNGRADE_STRICT_SAMESITE})},
1941       {"NONLEGACY_Schemeful=2;SameSite=Strict", CookieSameSite::STRICT_MODE,
1942        CookieEffectiveSameSite::STRICT_MODE,
1943        SameSiteCookieContext(
1944            SameSiteCookieContext::ContextType::SAME_SITE_STRICT,
1945            SameSiteCookieContext::ContextType::SAME_SITE_LAX_METHOD_UNSAFE),
1946        CookieInclusionStatus::MakeFromReasonsForTesting(
1947            {CookieInclusionStatus::EXCLUDE_SAMESITE_STRICT},
1948            {CookieInclusionStatus::
1949                 WARN_STRICT_CROSS_DOWNGRADE_STRICT_SAMESITE})},
1950       {"NONLEGACY_Schemeful=3;SameSite=Strict", CookieSameSite::STRICT_MODE,
1951        CookieEffectiveSameSite::STRICT_MODE,
1952        SameSiteCookieContext(
1953            SameSiteCookieContext::ContextType::SAME_SITE_STRICT,
1954            SameSiteCookieContext::ContextType::CROSS_SITE),
1955        CookieInclusionStatus::MakeFromReasonsForTesting(
1956            {CookieInclusionStatus::EXCLUDE_SAMESITE_STRICT},
1957            {CookieInclusionStatus::
1958                 WARN_STRICT_CROSS_DOWNGRADE_STRICT_SAMESITE})},
1959       {"NONLEGACY_Schemeful=4;SameSite=Lax", CookieSameSite::LAX_MODE,
1960        CookieEffectiveSameSite::LAX_MODE,
1961        SameSiteCookieContext(
1962            SameSiteCookieContext::ContextType::SAME_SITE_STRICT,
1963            SameSiteCookieContext::ContextType::SAME_SITE_LAX_METHOD_UNSAFE),
1964        CookieInclusionStatus::MakeFromReasonsForTesting(
1965            {CookieInclusionStatus::EXCLUDE_SAMESITE_LAX},
1966            {CookieInclusionStatus::WARN_STRICT_CROSS_DOWNGRADE_LAX_SAMESITE})},
1967       {"NONLEGACY_Schemeful=5;SameSite=Lax", CookieSameSite::LAX_MODE,
1968        CookieEffectiveSameSite::LAX_MODE,
1969        SameSiteCookieContext(
1970            SameSiteCookieContext::ContextType::SAME_SITE_STRICT,
1971            SameSiteCookieContext::ContextType::CROSS_SITE),
1972        CookieInclusionStatus::MakeFromReasonsForTesting(
1973            {CookieInclusionStatus::EXCLUDE_SAMESITE_LAX},
1974            {CookieInclusionStatus::WARN_STRICT_CROSS_DOWNGRADE_LAX_SAMESITE})},
1975       {"NONLEGACY_Schemeful=6;SameSite=Lax", CookieSameSite::LAX_MODE,
1976        CookieEffectiveSameSite::LAX_MODE,
1977        SameSiteCookieContext(SameSiteCookieContext::ContextType::SAME_SITE_LAX,
1978                              SameSiteCookieContext::ContextType::CROSS_SITE),
1979        CookieInclusionStatus::MakeFromReasonsForTesting(
1980            {CookieInclusionStatus::EXCLUDE_SAMESITE_LAX},
1981            {CookieInclusionStatus::WARN_LAX_CROSS_DOWNGRADE_LAX_SAMESITE})},
1982   };
1983 
1984   auto SchemefulIndependentCases = [&]() {
1985     // Run the test cases that are independent of Schemeful Same-Site.
1986     VerifyIncludeForRequestURLTestCases(CookieAccessSemantics::UNKNOWN,
1987                                         common_test_cases);
1988     VerifyIncludeForRequestURLTestCases(CookieAccessSemantics::UNKNOWN,
1989                                         default_lax_test_cases);
1990     VerifyIncludeForRequestURLTestCases(CookieAccessSemantics::LEGACY,
1991                                         common_test_cases);
1992     VerifyIncludeForRequestURLTestCases(CookieAccessSemantics::LEGACY,
1993                                         default_none_test_cases);
1994     VerifyIncludeForRequestURLTestCases(CookieAccessSemantics::NONLEGACY,
1995                                         common_test_cases);
1996     VerifyIncludeForRequestURLTestCases(CookieAccessSemantics::NONLEGACY,
1997                                         default_lax_test_cases);
1998   };
1999 
2000   {
2001     // Schemeful Same-Site disabled.
2002     base::test::ScopedFeatureList feature_list;
2003     feature_list.InitAndDisableFeature(features::kSchemefulSameSite);
2004 
2005     SchemefulIndependentCases();
2006 
2007     VerifyIncludeForRequestURLTestCases(CookieAccessSemantics::LEGACY,
2008                                         schemeful_disabled_test_cases);
2009     VerifyIncludeForRequestURLTestCases(CookieAccessSemantics::NONLEGACY,
2010                                         schemeful_disabled_test_cases);
2011     VerifyIncludeForRequestURLTestCases(CookieAccessSemantics::UNKNOWN,
2012                                         schemeful_disabled_test_cases);
2013   }
2014   {
2015     // Schemeful Same-Site enabled.
2016     base::test::ScopedFeatureList feature_list;
2017     feature_list.InitAndEnableFeature(features::kSchemefulSameSite);
2018 
2019     SchemefulIndependentCases();
2020 
2021     // With LEGACY access the cases should act as if schemeful is disabled, even
2022     // when it's not.
2023     VerifyIncludeForRequestURLTestCases(CookieAccessSemantics::LEGACY,
2024                                         schemeful_disabled_test_cases);
2025 
2026     VerifyIncludeForRequestURLTestCases(CookieAccessSemantics::NONLEGACY,
2027                                         schemeful_enabled_test_cases);
2028     VerifyIncludeForRequestURLTestCases(CookieAccessSemantics::UNKNOWN,
2029                                         schemeful_enabled_test_cases);
2030   }
2031 }
2032 
2033 // Test that SameSite=None requires Secure.
TEST(CanonicalCookieTest,IncludeCookiesWithoutSameSiteMustBeSecure)2034 TEST(CanonicalCookieTest, IncludeCookiesWithoutSameSiteMustBeSecure) {
2035   GURL url("https://www.example.com");
2036   base::Time creation_time = base::Time::Now();
2037   absl::optional<base::Time> server_time = absl::nullopt;
2038   CookieOptions options;
2039 
2040   // Make a SameSite=None, *not* Secure cookie.
2041   std::unique_ptr<CanonicalCookie> cookie = CanonicalCookie::Create(
2042       url, "A=2; SameSite=None", creation_time, server_time,
2043       absl::nullopt /* cookie_partition_key */);
2044   ASSERT_TRUE(cookie.get());
2045   EXPECT_FALSE(cookie->IsSecure());
2046   EXPECT_EQ(CookieSameSite::NO_RESTRICTION, cookie->SameSite());
2047   EXPECT_EQ(CookieEffectiveSameSite::NO_RESTRICTION,
2048             cookie->GetEffectiveSameSiteForTesting());
2049 
2050   // UKNOWN semantics results in modern behavior (requiring Secure).
2051   EXPECT_TRUE(cookie
2052                   ->IncludeForRequestURL(
2053                       url, options,
2054                       CookieAccessParams{
2055                           CookieAccessSemantics::UNKNOWN,
2056                           /*delegate_treats_url_as_trustworthy=*/false,
2057                           CookieSamePartyStatus::kNoSamePartyEnforcement})
2058                   .status.HasExactlyExclusionReasonsForTesting(
2059                       {CookieInclusionStatus::EXCLUDE_SAMESITE_NONE_INSECURE}));
2060 
2061   // LEGACY semantics does not require Secure for SameSite=None cookies.
2062   EXPECT_TRUE(cookie
2063                   ->IncludeForRequestURL(
2064                       url, options,
2065                       CookieAccessParams{
2066                           CookieAccessSemantics::LEGACY,
2067                           /*delegate_treats_url_as_trustworthy=*/false,
2068                           CookieSamePartyStatus::kNoSamePartyEnforcement})
2069                   .status.IsInclude());
2070 
2071   // NONLEGACY semantics results in modern behavior (requiring Secure).
2072   EXPECT_TRUE(cookie
2073                   ->IncludeForRequestURL(
2074                       url, options,
2075                       CookieAccessParams{
2076                           CookieAccessSemantics::NONLEGACY,
2077                           /*delegate_treats_url_as_trustworthy=*/false,
2078                           CookieSamePartyStatus::kNoSamePartyEnforcement})
2079                   .status.HasExactlyExclusionReasonsForTesting(
2080                       {CookieInclusionStatus::EXCLUDE_SAMESITE_NONE_INSECURE}));
2081 }
2082 
TEST(CanonicalCookieTest,IncludeForRequestURLSameParty)2083 TEST(CanonicalCookieTest, IncludeForRequestURLSameParty) {
2084   GURL url("https://www.example.com");
2085   base::Time creation_time = base::Time::Now();
2086   absl::optional<base::Time> server_time = absl::nullopt;
2087   CookieOptions options;
2088 
2089   // SameSite is not specified.
2090   std::unique_ptr<CanonicalCookie> cookie_samesite_unspecified =
2091       CanonicalCookie::Create(url, "A=2; SameParty; Secure", creation_time,
2092                               server_time,
2093                               absl::nullopt /* cookie_partition_key */);
2094   ASSERT_TRUE(cookie_samesite_unspecified.get());
2095   EXPECT_TRUE(cookie_samesite_unspecified->IsSecure());
2096   EXPECT_EQ(CookieSameSite::UNSPECIFIED,
2097             cookie_samesite_unspecified->SameSite());
2098   EXPECT_EQ(CookieEffectiveSameSite::LAX_MODE_ALLOW_UNSAFE,
2099             cookie_samesite_unspecified->GetEffectiveSameSiteForTesting());
2100   EXPECT_TRUE(cookie_samesite_unspecified->IsSameParty());
2101 
2102   // SameSite=None.
2103   std::unique_ptr<CanonicalCookie> cookie_samesite_none =
2104       CanonicalCookie::Create(url, "A=2; SameSite=None; SameParty; Secure",
2105                               creation_time, server_time,
2106                               absl::nullopt /* cookie_partition_key */);
2107   ASSERT_TRUE(cookie_samesite_none.get());
2108   EXPECT_TRUE(cookie_samesite_none->IsSecure());
2109   EXPECT_EQ(CookieSameSite::NO_RESTRICTION, cookie_samesite_none->SameSite());
2110   EXPECT_EQ(CookieEffectiveSameSite::NO_RESTRICTION,
2111             cookie_samesite_none->GetEffectiveSameSiteForTesting());
2112   EXPECT_TRUE(cookie_samesite_none->IsSameParty());
2113 
2114   // SameSite=Lax.
2115   std::unique_ptr<CanonicalCookie> cookie_samesite_lax =
2116       CanonicalCookie::Create(url, "A=2; SameSite=Lax; SameParty; Secure",
2117                               creation_time, server_time,
2118                               absl::nullopt /* cookie_partition_key */);
2119   ASSERT_TRUE(cookie_samesite_lax.get());
2120   EXPECT_TRUE(cookie_samesite_lax->IsSecure());
2121   EXPECT_EQ(CookieSameSite::LAX_MODE, cookie_samesite_lax->SameSite());
2122   EXPECT_EQ(CookieEffectiveSameSite::LAX_MODE,
2123             cookie_samesite_lax->GetEffectiveSameSiteForTesting());
2124   EXPECT_TRUE(cookie_samesite_lax->IsSameParty());
2125 
2126   for (const CanonicalCookie* cookie : {
2127            cookie_samesite_unspecified.get(),
2128            cookie_samesite_none.get(),
2129            cookie_samesite_lax.get(),
2130        }) {
2131     // SameParty cookies that should be excluded result in the appropriate
2132     // exclusion reason, and removes SAMESITE exclusion reasons.
2133     for (CookieAccessSemantics access_semantics : {
2134              CookieAccessSemantics::UNKNOWN,
2135              CookieAccessSemantics::LEGACY,
2136              CookieAccessSemantics::NONLEGACY,
2137          }) {
2138       EXPECT_THAT(cookie->IncludeForRequestURL(
2139                       url, options,
2140                       CookieAccessParams{
2141                           access_semantics,
2142                           /*delegate_treats_url_as_trustworthy=*/false,
2143                           CookieSamePartyStatus::kEnforceSamePartyExclude}),
2144                   MatchesCookieAccessResult(
2145                       HasExactlyExclusionReasonsForTesting(
2146                           std::vector<CookieInclusionStatus::ExclusionReason>(
2147                               {CookieInclusionStatus::
2148                                    EXCLUDE_SAMEPARTY_CROSS_PARTY_CONTEXT})),
2149                       _, _, true))
2150           << "SameSite = " << static_cast<int>(cookie->SameSite())
2151           << ", access_semantics = " << static_cast<int>(access_semantics);
2152     }
2153   }
2154 }
2155 
TEST(CanonicalCookieTest,IncludeForRequestURL_SameSiteNone_Metrics)2156 TEST(CanonicalCookieTest, IncludeForRequestURL_SameSiteNone_Metrics) {
2157   using SamePartyContextType = SamePartyContext::Type;
2158 
2159   constexpr bool delegate_treats_url_as_trustworthy = false;
2160   const base::Time now = base::Time::Now();
2161   const auto make_cookie = [now](CookieSameSite same_site, bool same_party) {
2162     return CanonicalCookie::CreateUnsafeCookieForTesting(
2163         "A", "1", "www.example.com", "/test", now, base::Time(), base::Time(),
2164         base::Time(), true /* secure */, false /*httponly*/, same_site,
2165         COOKIE_PRIORITY_DEFAULT, same_party);
2166   };
2167   GURL url("https://www.example.com/test");
2168 
2169   const std::unique_ptr<CanonicalCookie> same_site_none_cookie =
2170       make_cookie(CookieSameSite::NO_RESTRICTION, false /* same_party */);
2171   const std::unique_ptr<CanonicalCookie> same_party_cookie =
2172       make_cookie(CookieSameSite::NO_RESTRICTION, true /* same_party */);
2173   const std::unique_ptr<CanonicalCookie> same_site_lax_cookie =
2174       make_cookie(CookieSameSite::LAX_MODE, false /* same_party */);
2175   const std::unique_ptr<CanonicalCookie> same_site_strict_cookie =
2176       make_cookie(CookieSameSite::STRICT_MODE, false /* same_party */);
2177   CookieOptions options;
2178   options.set_same_site_cookie_context(CookieOptions::SameSiteCookieContext(
2179       CookieOptions::SameSiteCookieContext::ContextType::CROSS_SITE));
2180   // Same as default, but just to be explicit:
2181   options.set_same_party_context(
2182       SamePartyContext(SamePartyContext::Type::kCrossParty));
2183 
2184   // Check that the most restrictive context is recognized and enforced.
2185   EXPECT_THAT(
2186       same_site_none_cookie->IncludeForRequestURL(
2187           url, options,
2188           CookieAccessParams(CookieAccessSemantics::LEGACY,
2189                              delegate_treats_url_as_trustworthy,
2190                              CookieSamePartyStatus::kNoSamePartyEnforcement)),
2191       MatchesCookieAccessResult(CookieInclusionStatus(), _, _, true));
2192   EXPECT_THAT(
2193       same_party_cookie->IncludeForRequestURL(
2194           url, options,
2195           CookieAccessParams(CookieAccessSemantics::LEGACY,
2196                              delegate_treats_url_as_trustworthy,
2197                              CookieSamePartyStatus::kEnforceSamePartyExclude)),
2198       MatchesCookieAccessResult(Not(net::IsInclude()), _, _, true));
2199 
2200   // Now tweak the context to allow a SameParty cookie (using the top&resource
2201   // definition) and make sure we get the right warning. (Note: we make the
2202   // "real" same-partyness value match the value computed for the metric, even
2203   // though they would differ unless we changed the real definition.) Then
2204   // check that if we modify the cookie as indicated, the set would be allowed,
2205   // but the next-most-restrictive variation would still be blocked.
2206   options.set_same_party_context(
2207       SamePartyContext(SamePartyContextType::kSameParty));
2208   EXPECT_THAT(
2209       same_site_none_cookie->IncludeForRequestURL(
2210           url, options,
2211           CookieAccessParams(CookieAccessSemantics::LEGACY,
2212                              delegate_treats_url_as_trustworthy,
2213                              CookieSamePartyStatus::kNoSamePartyEnforcement)),
2214       MatchesCookieAccessResult(CookieInclusionStatus(), _, _, true));
2215   EXPECT_THAT(
2216       same_party_cookie->IncludeForRequestURL(
2217           url, options,
2218           CookieAccessParams(CookieAccessSemantics::LEGACY,
2219                              delegate_treats_url_as_trustworthy,
2220                              CookieSamePartyStatus::kEnforceSamePartyInclude)),
2221       MatchesCookieAccessResult(net::IsInclude(), _, _, true));
2222   EXPECT_THAT(
2223       same_site_lax_cookie->IncludeForRequestURL(
2224           url, options,
2225           CookieAccessParams(CookieAccessSemantics::LEGACY,
2226                              delegate_treats_url_as_trustworthy,
2227                              CookieSamePartyStatus::kNoSamePartyEnforcement)),
2228       MatchesCookieAccessResult(Not(net::IsInclude()), _, _, true));
2229 
2230   // Next: allow a SameParty cookie (using both definitions).
2231   options.set_same_party_context(SamePartyContext::MakeInclusive());
2232   EXPECT_THAT(
2233       same_site_none_cookie->IncludeForRequestURL(
2234           url, options,
2235           CookieAccessParams(CookieAccessSemantics::LEGACY,
2236                              delegate_treats_url_as_trustworthy,
2237                              CookieSamePartyStatus::kNoSamePartyEnforcement)),
2238       MatchesCookieAccessResult(CookieInclusionStatus(), _, _, true));
2239   EXPECT_THAT(
2240       same_party_cookie->IncludeForRequestURL(
2241           url, options,
2242           CookieAccessParams(CookieAccessSemantics::LEGACY,
2243                              delegate_treats_url_as_trustworthy,
2244                              CookieSamePartyStatus::kNoSamePartyEnforcement)),
2245       MatchesCookieAccessResult(net::IsInclude(), _, _, true));
2246   EXPECT_THAT(
2247       same_site_lax_cookie->IncludeForRequestURL(
2248           url, options,
2249           CookieAccessParams(CookieAccessSemantics::LEGACY,
2250                              delegate_treats_url_as_trustworthy,
2251                              CookieSamePartyStatus::kNoSamePartyEnforcement)),
2252       MatchesCookieAccessResult(Not(net::IsInclude()), _, _, true));
2253 
2254   // Next: allow a SameSite=Lax cookie.
2255   options.set_same_site_cookie_context(CookieOptions::SameSiteCookieContext(
2256       CookieOptions::SameSiteCookieContext::ContextType::SAME_SITE_LAX));
2257   EXPECT_THAT(
2258       same_site_none_cookie->IncludeForRequestURL(
2259           url, options,
2260           CookieAccessParams(CookieAccessSemantics::LEGACY,
2261                              delegate_treats_url_as_trustworthy,
2262                              CookieSamePartyStatus::kNoSamePartyEnforcement)),
2263       MatchesCookieAccessResult(CookieInclusionStatus(), _, _, true));
2264   EXPECT_THAT(
2265       same_site_lax_cookie->IncludeForRequestURL(
2266           url, options,
2267           CookieAccessParams(CookieAccessSemantics::LEGACY,
2268                              delegate_treats_url_as_trustworthy,
2269                              CookieSamePartyStatus::kNoSamePartyEnforcement)),
2270       MatchesCookieAccessResult(net::IsInclude(), _, _, true));
2271   EXPECT_THAT(
2272       same_site_strict_cookie->IncludeForRequestURL(
2273           url, options,
2274           CookieAccessParams(CookieAccessSemantics::LEGACY,
2275                              delegate_treats_url_as_trustworthy,
2276                              CookieSamePartyStatus::kNoSamePartyEnforcement)),
2277       MatchesCookieAccessResult(Not(net::IsInclude()), _, _, true));
2278 
2279   // Next: allow a SameSite=Strict cookie.
2280   options.set_same_site_cookie_context(CookieOptions::SameSiteCookieContext(
2281       CookieOptions::SameSiteCookieContext::ContextType::SAME_SITE_STRICT));
2282   EXPECT_THAT(
2283       same_site_none_cookie->IncludeForRequestURL(
2284           url, options,
2285           CookieAccessParams(CookieAccessSemantics::LEGACY,
2286                              delegate_treats_url_as_trustworthy,
2287                              CookieSamePartyStatus::kNoSamePartyEnforcement)),
2288       MatchesCookieAccessResult(CookieInclusionStatus(), _, _, true));
2289   EXPECT_THAT(
2290       same_site_strict_cookie->IncludeForRequestURL(
2291           url, options,
2292           CookieAccessParams(CookieAccessSemantics::LEGACY,
2293                              delegate_treats_url_as_trustworthy,
2294                              CookieSamePartyStatus::kNoSamePartyEnforcement)),
2295       MatchesCookieAccessResult(net::IsInclude(), _, _, true));
2296 }
2297 
2298 // Test that the CookieInclusionStatus warning for inclusion changed by
2299 // cross-site redirect context downgrade is applied correctly.
TEST(CanonicalCookieTest,IncludeForRequestURL_RedirectDowngradeWarning)2300 TEST(CanonicalCookieTest, IncludeForRequestURL_RedirectDowngradeWarning) {
2301   using Context = CookieOptions::SameSiteCookieContext;
2302   using ContextType = Context::ContextType;
2303 
2304   Context::ContextMetadata strict_lax_downgrade_metadata,
2305       strict_cross_downgrade_metadata;
2306   strict_lax_downgrade_metadata.cross_site_redirect_downgrade =
2307       Context::ContextMetadata::ContextDowngradeType::kStrictToLax;
2308   strict_cross_downgrade_metadata.cross_site_redirect_downgrade =
2309       Context::ContextMetadata::ContextDowngradeType::kStrictToCross;
2310 
2311   // Because there are downgrades we need to set the HTTP method as well, since
2312   // some metrics code expects that. The actual method doesn't matter here.
2313   strict_lax_downgrade_metadata.http_method_bug_1221316 =
2314       Context::ContextMetadata::HttpMethod::kGet;
2315   strict_cross_downgrade_metadata.http_method_bug_1221316 =
2316       Context::ContextMetadata::HttpMethod::kGet;
2317 
2318   GURL url("https://www.example.test/test");
2319   GURL insecure_url("http://www.example.test/test");
2320 
2321   const struct {
2322     ContextType context_type;
2323     Context::ContextMetadata metadata;
2324     CookieSameSite samesite;
2325     bool expect_cross_site_redirect_warning;
2326   } kTestCases[] = {
2327       // Strict-to-lax downgrade.
2328       {ContextType::SAME_SITE_STRICT, strict_lax_downgrade_metadata,
2329        CookieSameSite::STRICT_MODE, true},
2330       {ContextType::SAME_SITE_LAX, strict_lax_downgrade_metadata,
2331        CookieSameSite::STRICT_MODE, true},
2332       {ContextType::SAME_SITE_STRICT, strict_lax_downgrade_metadata,
2333        CookieSameSite::LAX_MODE, false},
2334       {ContextType::SAME_SITE_LAX, strict_lax_downgrade_metadata,
2335        CookieSameSite::LAX_MODE, false},
2336       {ContextType::SAME_SITE_STRICT, strict_lax_downgrade_metadata,
2337        CookieSameSite::NO_RESTRICTION, false},
2338       {ContextType::SAME_SITE_LAX, strict_lax_downgrade_metadata,
2339        CookieSameSite::NO_RESTRICTION, false},
2340 
2341       // Strict-to-cross downgrade.
2342       {ContextType::SAME_SITE_STRICT, strict_cross_downgrade_metadata,
2343        CookieSameSite::STRICT_MODE, true},
2344       {ContextType::CROSS_SITE, strict_cross_downgrade_metadata,
2345        CookieSameSite::STRICT_MODE, true},
2346       {ContextType::SAME_SITE_STRICT, strict_cross_downgrade_metadata,
2347        CookieSameSite::LAX_MODE, true},
2348       {ContextType::CROSS_SITE, strict_cross_downgrade_metadata,
2349        CookieSameSite::LAX_MODE, true},
2350       {ContextType::SAME_SITE_STRICT, strict_cross_downgrade_metadata,
2351        CookieSameSite::NO_RESTRICTION, false},
2352       {ContextType::CROSS_SITE, strict_cross_downgrade_metadata,
2353        CookieSameSite::NO_RESTRICTION, false},
2354   };
2355 
2356   for (bool consider_redirects : {true, false}) {
2357     base::test::ScopedFeatureList feature_list;
2358     feature_list.InitWithFeatureState(
2359         features::kCookieSameSiteConsidersRedirectChain, consider_redirects);
2360 
2361     for (CookieAccessSemantics semantics :
2362          {CookieAccessSemantics::LEGACY, CookieAccessSemantics::NONLEGACY}) {
2363       // There are no downgrade warnings for undowngraded contexts.
2364       for (ContextType context_type :
2365            {ContextType::SAME_SITE_STRICT, ContextType::SAME_SITE_LAX,
2366             ContextType::SAME_SITE_LAX_METHOD_UNSAFE,
2367             ContextType::CROSS_SITE}) {
2368         for (CookieSameSite samesite :
2369              {CookieSameSite::UNSPECIFIED, CookieSameSite::NO_RESTRICTION,
2370               CookieSameSite::LAX_MODE, CookieSameSite::STRICT_MODE}) {
2371           std::unique_ptr<CanonicalCookie> cookie =
2372               CanonicalCookie::CreateUnsafeCookieForTesting(
2373                   "A", "1", "www.example.test", "/test", base::Time::Now(),
2374                   base::Time(), base::Time(), base::Time(), /*secure=*/true,
2375                   /*httponly=*/false, samesite, COOKIE_PRIORITY_DEFAULT,
2376                   /*same_party=*/false);
2377 
2378           CookieOptions options;
2379           options.set_same_site_cookie_context(Context(context_type));
2380 
2381           EXPECT_FALSE(
2382               cookie
2383                   ->IncludeForRequestURL(
2384                       url, options,
2385                       CookieAccessParams(
2386                           semantics,
2387                           /*delegate_treats_url_as_trustworthy=*/false,
2388                           CookieSamePartyStatus::kNoSamePartyEnforcement))
2389                   .status.HasWarningReason(
2390                       CookieInclusionStatus::
2391                           WARN_CROSS_SITE_REDIRECT_DOWNGRADE_CHANGES_INCLUSION));
2392         }
2393       }
2394 
2395       for (const auto& test : kTestCases) {
2396         std::unique_ptr<CanonicalCookie> cookie =
2397             CanonicalCookie::CreateUnsafeCookieForTesting(
2398                 "A", "1", "www.example.test", "/test", base::Time::Now(),
2399                 base::Time(), base::Time(), base::Time(), /*secure=*/true,
2400                 /*httponly=*/false, test.samesite, COOKIE_PRIORITY_DEFAULT,
2401                 /*same_party=*/false);
2402 
2403         CookieOptions options;
2404         options.set_same_site_cookie_context(
2405             Context(test.context_type, test.context_type, test.metadata,
2406                     test.metadata));
2407         EXPECT_EQ(
2408             cookie
2409                 ->IncludeForRequestURL(
2410                     url, options,
2411                     CookieAccessParams(
2412                         semantics,
2413                         /*delegate_treats_url_as_trustworthy=*/false,
2414                         CookieSamePartyStatus::kNoSamePartyEnforcement))
2415                 .status.HasWarningReason(
2416                     CookieInclusionStatus::
2417                         WARN_CROSS_SITE_REDIRECT_DOWNGRADE_CHANGES_INCLUSION),
2418             test.expect_cross_site_redirect_warning);
2419 
2420         // SameSite warnings not applied if other exclusion reasons apply (e.g.
2421         // non-https with Secure attribute).
2422         EXPECT_FALSE(
2423             cookie
2424                 ->IncludeForRequestURL(
2425                     insecure_url, options,
2426                     CookieAccessParams(
2427                         semantics,
2428                         /*delegate_treats_url_as_trustworthy=*/false,
2429                         CookieSamePartyStatus::kNoSamePartyEnforcement))
2430                 .status.HasWarningReason(
2431                     CookieInclusionStatus::
2432                         WARN_CROSS_SITE_REDIRECT_DOWNGRADE_CHANGES_INCLUSION));
2433       }
2434     }
2435   }
2436 }
2437 
TEST(CanonicalCookieTest,MultipleExclusionReasons)2438 TEST(CanonicalCookieTest, MultipleExclusionReasons) {
2439   GURL url("http://www.not-secure.com/foo");
2440   base::Time creation_time = base::Time::Now();
2441   absl::optional<base::Time> server_time = absl::nullopt;
2442   CookieOptions options;
2443   options.set_exclude_httponly();
2444   options.set_same_site_cookie_context(CookieOptions::SameSiteCookieContext(
2445       CookieOptions::SameSiteCookieContext::ContextType::CROSS_SITE));
2446 
2447   // Test IncludeForRequestURL()
2448   // Note: This is a cookie that should never exist normally, because Create()
2449   // would weed it out.
2450   auto cookie1 = CanonicalCookie::CreateUnsafeCookieForTesting(
2451       "name", "value", "other-domain.com", "/bar", creation_time, base::Time(),
2452       base::Time(), base::Time(), true /* secure */, true /* httponly */,
2453       CookieSameSite::STRICT_MODE, COOKIE_PRIORITY_DEFAULT, false);
2454   EXPECT_THAT(
2455       cookie1->IncludeForRequestURL(
2456           url, options,
2457           CookieAccessParams{CookieAccessSemantics::UNKNOWN,
2458                              /*delegate_treats_url_as_trustworthy=*/false,
2459                              CookieSamePartyStatus::kNoSamePartyEnforcement}),
2460       MatchesCookieAccessResult(
2461           CookieInclusionStatus::MakeFromReasonsForTesting({
2462               CookieInclusionStatus::EXCLUDE_HTTP_ONLY,
2463               CookieInclusionStatus::EXCLUDE_SECURE_ONLY,
2464               CookieInclusionStatus::EXCLUDE_DOMAIN_MISMATCH,
2465               CookieInclusionStatus::EXCLUDE_NOT_ON_PATH,
2466               CookieInclusionStatus::EXCLUDE_SAMESITE_STRICT,
2467           }),
2468           _, _, false));
2469 
2470   // Test Create()
2471   CookieInclusionStatus create_status;
2472   auto cookie2 = CanonicalCookie::Create(
2473       url, "__Secure-notactuallysecure=value;Domain=some-other-domain.com",
2474       creation_time, server_time, absl::nullopt /* cookie_partition_key */,
2475       &create_status);
2476   ASSERT_FALSE(cookie2);
2477   EXPECT_TRUE(create_status.HasExactlyExclusionReasonsForTesting(
2478       {CookieInclusionStatus::EXCLUDE_INVALID_PREFIX,
2479        CookieInclusionStatus::EXCLUDE_INVALID_DOMAIN}));
2480 
2481   // Test IsSetPermittedInContext()
2482   auto cookie3 = CanonicalCookie::Create(
2483       url, "name=value;HttpOnly;SameSite=Lax", creation_time, server_time,
2484       absl::nullopt /* cookie_partition_key */);
2485   ASSERT_TRUE(cookie3);
2486   EXPECT_THAT(
2487       cookie3->IsSetPermittedInContext(
2488           url, options,
2489           CookieAccessParams(CookieAccessSemantics::UNKNOWN,
2490                              false /* delegate_treats_url_as_trustworthy */,
2491                              CookieSamePartyStatus::kNoSamePartyEnforcement),
2492           kCookieableSchemes),
2493       MatchesCookieAccessResult(
2494           CookieInclusionStatus::MakeFromReasonsForTesting(
2495               {CookieInclusionStatus::EXCLUDE_HTTP_ONLY,
2496                CookieInclusionStatus::EXCLUDE_SAMESITE_LAX}),
2497           _, _, false));
2498 }
2499 
TEST(CanonicalCookieTest,PartialCompare)2500 TEST(CanonicalCookieTest, PartialCompare) {
2501   GURL url("http://www.example.com");
2502   base::Time creation_time = base::Time::Now();
2503   absl::optional<base::Time> server_time = absl::nullopt;
2504   std::unique_ptr<CanonicalCookie> cookie(
2505       CanonicalCookie::Create(url, "a=b", creation_time, server_time,
2506                               absl::nullopt /* cookie_partition_key */));
2507   std::unique_ptr<CanonicalCookie> cookie_different_path(
2508       CanonicalCookie::Create(url, "a=b; path=/foo", creation_time, server_time,
2509                               absl::nullopt /* cookie_partition_key */));
2510   std::unique_ptr<CanonicalCookie> cookie_different_value(
2511       CanonicalCookie::Create(url, "a=c", creation_time, server_time,
2512                               absl::nullopt /* cookie_partition_key */));
2513 
2514   // Cookie is equivalent to itself.
2515   EXPECT_FALSE(cookie->PartialCompare(*cookie));
2516 
2517   // Changing the path affects the ordering.
2518   EXPECT_TRUE(cookie->PartialCompare(*cookie_different_path));
2519   EXPECT_FALSE(cookie_different_path->PartialCompare(*cookie));
2520 
2521   // Changing the value does not affect the ordering.
2522   EXPECT_FALSE(cookie->PartialCompare(*cookie_different_value));
2523   EXPECT_FALSE(cookie_different_value->PartialCompare(*cookie));
2524 
2525   // Cookies identical for PartialCompare() are equivalent.
2526   EXPECT_TRUE(cookie->IsEquivalent(*cookie_different_value));
2527   EXPECT_TRUE(cookie->IsEquivalent(*cookie));
2528 }
2529 
TEST(CanonicalCookieTest,SecureCookiePrefix)2530 TEST(CanonicalCookieTest, SecureCookiePrefix) {
2531   GURL https_url("https://www.example.test");
2532   GURL http_url("http://www.example.test");
2533   base::Time creation_time = base::Time::Now();
2534   absl::optional<base::Time> server_time = absl::nullopt;
2535   CookieInclusionStatus status;
2536 
2537   // A __Secure- cookie must be Secure.
2538   EXPECT_FALSE(CanonicalCookie::Create(
2539       https_url, "__Secure-A=B", creation_time, server_time,
2540       absl::nullopt /* cookie_partition_key */, &status));
2541   EXPECT_TRUE(status.HasExactlyExclusionReasonsForTesting(
2542       {CookieInclusionStatus::EXCLUDE_INVALID_PREFIX}));
2543   EXPECT_FALSE(CanonicalCookie::Create(
2544       https_url, "__Secure-A=B; httponly", creation_time, server_time,
2545       absl::nullopt /* cookie_partition_key */, &status));
2546   // (EXCLUDE_HTTP_ONLY would be fine, too)
2547   EXPECT_TRUE(status.HasExactlyExclusionReasonsForTesting(
2548       {CookieInclusionStatus::EXCLUDE_INVALID_PREFIX}));
2549 
2550   // Prefixes are case insensitive.
2551   EXPECT_FALSE(CanonicalCookie::Create(
2552       https_url, "__secure-A=C;", creation_time, server_time,
2553       absl::nullopt /* cookie_partition_key */));
2554   EXPECT_TRUE(status.HasExactlyExclusionReasonsForTesting(
2555       {CookieInclusionStatus::EXCLUDE_INVALID_PREFIX}));
2556   EXPECT_FALSE(CanonicalCookie::Create(
2557       https_url, "__SECURE-A=C;", creation_time, server_time,
2558       absl::nullopt /* cookie_partition_key */));
2559   EXPECT_TRUE(status.HasExactlyExclusionReasonsForTesting(
2560       {CookieInclusionStatus::EXCLUDE_INVALID_PREFIX}));
2561   EXPECT_FALSE(CanonicalCookie::Create(
2562       https_url, "__SeCuRe-A=C;", creation_time, server_time,
2563       absl::nullopt /* cookie_partition_key */));
2564   EXPECT_TRUE(status.HasExactlyExclusionReasonsForTesting(
2565       {CookieInclusionStatus::EXCLUDE_INVALID_PREFIX}));
2566 
2567   {
2568     base::test::ScopedFeatureList scope_feature_list;
2569     scope_feature_list.InitAndDisableFeature(
2570         features::kCaseInsensitiveCookiePrefix);
2571 
2572     EXPECT_TRUE(CanonicalCookie::Create(
2573         https_url, "__secure-A=C;", creation_time, server_time,
2574         absl::nullopt /* cookie_partition_key */));
2575     EXPECT_TRUE(CanonicalCookie::Create(
2576         https_url, "__SECURE-A=C;", creation_time, server_time,
2577         absl::nullopt /* cookie_partition_key */));
2578     EXPECT_TRUE(CanonicalCookie::Create(
2579         https_url, "__SeCuRe-A=C;", creation_time, server_time,
2580         absl::nullopt /* cookie_partition_key */));
2581   }
2582 
2583   // A typoed prefix does not have to be Secure.
2584   EXPECT_TRUE(CanonicalCookie::Create(
2585       https_url, "__SecureA=B; Secure", creation_time, server_time,
2586       absl::nullopt /* cookie_partition_key */));
2587   EXPECT_TRUE(CanonicalCookie::Create(
2588       https_url, "__SecureA=C;", creation_time, server_time,
2589       absl::nullopt /* cookie_partition_key */));
2590   EXPECT_TRUE(CanonicalCookie::Create(
2591       https_url, "_Secure-A=C;", creation_time, server_time,
2592       absl::nullopt /* cookie_partition_key */));
2593   EXPECT_TRUE(CanonicalCookie::Create(
2594       https_url, "Secure-A=C;", creation_time, server_time,
2595       absl::nullopt /* cookie_partition_key */));
2596 
2597   // A __Secure- cookie can't be set on a non-secure origin.
2598   EXPECT_FALSE(CanonicalCookie::Create(
2599       http_url, "__Secure-A=B; Secure", creation_time, server_time,
2600       absl::nullopt /* cookie_partition_key */, &status));
2601   EXPECT_TRUE(status.HasExactlyExclusionReasonsForTesting(
2602       {CookieInclusionStatus::EXCLUDE_INVALID_PREFIX}));
2603 
2604   // Hidden __Secure- prefixes should be rejected.
2605   EXPECT_FALSE(CanonicalCookie::Create(
2606       https_url, "=__Secure-A=B; Secure", creation_time, server_time,
2607       absl::nullopt /* cookie_partition_key */, &status));
2608   EXPECT_TRUE(status.HasExactlyExclusionReasonsForTesting(
2609       {CookieInclusionStatus::EXCLUDE_INVALID_PREFIX}));
2610   EXPECT_FALSE(CanonicalCookie::Create(
2611       https_url, "=__Secure-A; Secure", creation_time, server_time,
2612       absl::nullopt /* cookie_partition_key */, &status));
2613   EXPECT_TRUE(status.HasExactlyExclusionReasonsForTesting(
2614       {CookieInclusionStatus::EXCLUDE_INVALID_PREFIX}));
2615 
2616   // While tricky, this isn't considered hidden and is fine.
2617   EXPECT_TRUE(CanonicalCookie::Create(
2618       https_url, "A=__Secure-A=B; Secure", creation_time, server_time,
2619       absl::nullopt /* cookie_partition_key */));
2620 }
2621 
TEST(CanonicalCookieTest,HostCookiePrefix)2622 TEST(CanonicalCookieTest, HostCookiePrefix) {
2623   GURL https_url("https://www.example.test");
2624   GURL http_url("http://www.example.test");
2625   base::Time creation_time = base::Time::Now();
2626   absl::optional<base::Time> server_time = absl::nullopt;
2627   std::string domain = https_url.host();
2628   CookieInclusionStatus status;
2629 
2630   // A __Host- cookie must be Secure.
2631   EXPECT_FALSE(CanonicalCookie::Create(
2632       https_url, "__Host-A=B;", creation_time, server_time,
2633       absl::nullopt /* cookie_partition_key */, &status));
2634   EXPECT_TRUE(status.HasExactlyExclusionReasonsForTesting(
2635       {CookieInclusionStatus::EXCLUDE_INVALID_PREFIX}));
2636   EXPECT_FALSE(CanonicalCookie::Create(
2637       https_url, "__Host-A=B; Domain=" + domain + "; Path=/;", creation_time,
2638       server_time, absl::nullopt /* cookie_partition_key */, &status));
2639   EXPECT_TRUE(status.HasExactlyExclusionReasonsForTesting(
2640       {CookieInclusionStatus::EXCLUDE_INVALID_PREFIX}));
2641   EXPECT_TRUE(CanonicalCookie::Create(
2642       https_url, "__Host-A=B; Path=/; Secure;", creation_time, server_time,
2643       absl::nullopt /* cookie_partition_key */));
2644 
2645   // A __Host- cookie must be set from a secure scheme.
2646   EXPECT_FALSE(CanonicalCookie::Create(
2647       http_url, "__Host-A=B; Domain=" + domain + "; Path=/; Secure;",
2648       creation_time, server_time, absl::nullopt /* cookie_partition_key */,
2649       &status));
2650   EXPECT_TRUE(status.HasExactlyExclusionReasonsForTesting(
2651       {CookieInclusionStatus::EXCLUDE_INVALID_PREFIX}));
2652   EXPECT_TRUE(CanonicalCookie::Create(
2653       https_url, "__Host-A=B; Path=/; Secure;", creation_time, server_time,
2654       absl::nullopt /* cookie_partition_key */));
2655 
2656   // A __Host- cookie can't have a Domain.
2657   EXPECT_FALSE(CanonicalCookie::Create(
2658       https_url, "__Host-A=B; Domain=" + domain + "; Path=/; Secure;",
2659       creation_time, server_time, absl::nullopt /* cookie_partition_key */,
2660       &status));
2661   EXPECT_TRUE(status.HasExactlyExclusionReasonsForTesting(
2662       {CookieInclusionStatus::EXCLUDE_INVALID_PREFIX}));
2663   EXPECT_FALSE(CanonicalCookie::Create(
2664       https_url, "__Host-A=B; Domain=" + domain + "; Secure;", creation_time,
2665       server_time, absl::nullopt /* cookie_partition_key */, &status));
2666   EXPECT_TRUE(status.HasExactlyExclusionReasonsForTesting(
2667       {CookieInclusionStatus::EXCLUDE_INVALID_PREFIX}));
2668 
2669   // A __Host- cookie may have a domain if it's an IP address that matches the
2670   // URL.
2671   EXPECT_TRUE(CanonicalCookie::Create(
2672       GURL("https://127.0.0.1"),
2673       "__Host-A=B; Domain=127.0.0.1; Path=/; Secure;", creation_time,
2674       server_time, absl::nullopt /* cookie_partition_key */, &status));
2675   // A __Host- cookie with an IP address domain does not need the domain
2676   // attribute specified explicitly (just like a normal domain).
2677   EXPECT_TRUE(CanonicalCookie::Create(
2678       GURL("https://127.0.0.1"), "__Host-A=B; Domain=; Path=/; Secure;",
2679       creation_time, server_time, absl::nullopt /* cookie_partition_key */,
2680       &status));
2681 
2682   // A __Host- cookie must have a Path of "/".
2683   EXPECT_FALSE(CanonicalCookie::Create(
2684       https_url, "__Host-A=B; Path=/foo; Secure;", creation_time, server_time,
2685       absl::nullopt /* cookie_partition_key */, &status));
2686   EXPECT_TRUE(status.HasExactlyExclusionReasonsForTesting(
2687       {CookieInclusionStatus::EXCLUDE_INVALID_PREFIX}));
2688   EXPECT_FALSE(CanonicalCookie::Create(
2689       https_url, "__Host-A=B; Secure;", creation_time, server_time,
2690       absl::nullopt /* cookie_partition_key */, &status));
2691   EXPECT_TRUE(status.HasExactlyExclusionReasonsForTesting(
2692       {CookieInclusionStatus::EXCLUDE_INVALID_PREFIX}));
2693   EXPECT_TRUE(CanonicalCookie::Create(
2694       https_url, "__Host-A=B; Secure; Path=/;", creation_time, server_time,
2695       absl::nullopt /* cookie_partition_key */));
2696 
2697   // Prefixes are case insensitive.
2698   EXPECT_FALSE(CanonicalCookie::Create(
2699       http_url, "__host-A=B; Domain=" + domain + "; Path=/;", creation_time,
2700       server_time, absl::nullopt /* cookie_partition_key */, &status));
2701   EXPECT_TRUE(status.HasExactlyExclusionReasonsForTesting(
2702       {CookieInclusionStatus::EXCLUDE_INVALID_PREFIX}));
2703 
2704   EXPECT_FALSE(CanonicalCookie::Create(
2705       http_url, "__HOST-A=B; Domain=" + domain + "; Path=/;", creation_time,
2706       server_time, absl::nullopt /* cookie_partition_key */, &status));
2707   EXPECT_TRUE(status.HasExactlyExclusionReasonsForTesting(
2708       {CookieInclusionStatus::EXCLUDE_INVALID_PREFIX}));
2709 
2710   EXPECT_FALSE(CanonicalCookie::Create(
2711       http_url, "__HoSt-A=B; Domain=" + domain + "; Path=/;", creation_time,
2712       server_time, absl::nullopt /* cookie_partition_key */, &status));
2713   EXPECT_TRUE(status.HasExactlyExclusionReasonsForTesting(
2714       {CookieInclusionStatus::EXCLUDE_INVALID_PREFIX}));
2715 
2716   {
2717     base::test::ScopedFeatureList scope_feature_list;
2718     scope_feature_list.InitAndDisableFeature(
2719         features::kCaseInsensitiveCookiePrefix);
2720 
2721     EXPECT_TRUE(CanonicalCookie::Create(
2722         http_url, "__host-A=B; Domain=" + domain + "; Path=/;", creation_time,
2723         server_time, absl::nullopt /* cookie_partition_key */, &status));
2724 
2725     EXPECT_TRUE(CanonicalCookie::Create(
2726         http_url, "__HOST-A=B; Domain=" + domain + "; Path=/;", creation_time,
2727         server_time, absl::nullopt /* cookie_partition_key */, &status));
2728 
2729     EXPECT_TRUE(CanonicalCookie::Create(
2730         http_url, "__HoSt-A=B; Domain=" + domain + "; Path=/;", creation_time,
2731         server_time, absl::nullopt /* cookie_partition_key */, &status));
2732   }
2733 
2734   // Rules don't apply for a typoed prefix.
2735   EXPECT_TRUE(CanonicalCookie::Create(
2736       https_url, "__HostA=B; Domain=" + domain + "; Secure;", creation_time,
2737       server_time, absl::nullopt /* cookie_partition_key */));
2738 
2739   EXPECT_TRUE(CanonicalCookie::Create(
2740       https_url, "_Host-A=B; Domain=" + domain + "; Secure;", creation_time,
2741       server_time, absl::nullopt /* cookie_partition_key */));
2742 
2743   EXPECT_TRUE(CanonicalCookie::Create(
2744       https_url, "Host-A=B; Domain=" + domain + "; Secure;", creation_time,
2745       server_time, absl::nullopt /* cookie_partition_key */));
2746 
2747   // Hidden __Host- prefixes should be rejected.
2748   EXPECT_FALSE(CanonicalCookie::Create(
2749       https_url, "=__Host-A=B; Path=/; Secure;", creation_time, server_time,
2750       absl::nullopt /* cookie_partition_key */, &status));
2751   EXPECT_TRUE(status.HasExactlyExclusionReasonsForTesting(
2752       {CookieInclusionStatus::EXCLUDE_INVALID_PREFIX}));
2753   EXPECT_FALSE(CanonicalCookie::Create(
2754       https_url, "=__Host-A; Path=/; Secure;", creation_time, server_time,
2755       absl::nullopt /* cookie_partition_key */, &status));
2756   EXPECT_TRUE(status.HasExactlyExclusionReasonsForTesting(
2757       {CookieInclusionStatus::EXCLUDE_INVALID_PREFIX}));
2758 
2759   // While tricky, this isn't considered hidden and is fine.
2760   EXPECT_TRUE(CanonicalCookie::Create(
2761       https_url, "A=__Host-A=B; Path=/; Secure;", creation_time, server_time,
2762       absl::nullopt /* cookie_partition_key */));
2763 }
2764 
TEST(CanonicalCookieTest,CanCreateSecureCookiesFromAnyScheme)2765 TEST(CanonicalCookieTest, CanCreateSecureCookiesFromAnyScheme) {
2766   GURL http_url("http://www.example.com");
2767   GURL https_url("https://www.example.com");
2768   base::Time creation_time = base::Time::Now();
2769   absl::optional<base::Time> server_time = absl::nullopt;
2770 
2771   std::unique_ptr<CanonicalCookie> http_cookie_no_secure(
2772       CanonicalCookie::Create(http_url, "a=b", creation_time, server_time,
2773                               absl::nullopt /* cookie_partition_key */));
2774   std::unique_ptr<CanonicalCookie> http_cookie_secure(CanonicalCookie::Create(
2775       http_url, "a=b; Secure", creation_time, server_time,
2776       absl::nullopt /* cookie_partition_key */));
2777   std::unique_ptr<CanonicalCookie> https_cookie_no_secure(
2778       CanonicalCookie::Create(https_url, "a=b", creation_time, server_time,
2779                               absl::nullopt /* cookie_partition_key */));
2780   std::unique_ptr<CanonicalCookie> https_cookie_secure(CanonicalCookie::Create(
2781       https_url, "a=b; Secure", creation_time, server_time,
2782       absl::nullopt /* cookie_partition_key */));
2783 
2784   EXPECT_TRUE(http_cookie_no_secure.get());
2785   EXPECT_TRUE(http_cookie_secure.get());
2786   EXPECT_TRUE(https_cookie_no_secure.get());
2787   EXPECT_TRUE(https_cookie_secure.get());
2788 }
2789 
TEST(CanonicalCookieTest,IsCanonical)2790 TEST(CanonicalCookieTest, IsCanonical) {
2791   // Base correct template.
2792   EXPECT_TRUE(CanonicalCookie::CreateUnsafeCookieForTesting(
2793                   "A", "B", "x.y", "/path", base::Time(), base::Time(),
2794                   base::Time(), base::Time(), false, false,
2795                   CookieSameSite::NO_RESTRICTION, COOKIE_PRIORITY_LOW, false)
2796                   ->IsCanonical());
2797 
2798   // Newline in name.
2799   EXPECT_FALSE(CanonicalCookie::CreateUnsafeCookieForTesting(
2800                    "A\n", "B", "x.y", "/path", base::Time(), base::Time(),
2801                    base::Time(), base::Time(), false, false,
2802                    CookieSameSite::NO_RESTRICTION, COOKIE_PRIORITY_LOW, false)
2803                    ->IsCanonical());
2804 
2805   // Carriage return in name.
2806   EXPECT_FALSE(CanonicalCookie::CreateUnsafeCookieForTesting(
2807                    "A\r", "B", "x.y", "/path", base::Time(), base::Time(),
2808                    base::Time(), base::Time(), false, false,
2809                    CookieSameSite::NO_RESTRICTION, COOKIE_PRIORITY_LOW, false)
2810                    ->IsCanonical());
2811 
2812   // Null character in name.
2813   EXPECT_FALSE(CanonicalCookie::CreateUnsafeCookieForTesting(
2814                    std::string("A\0Z", 3), "B", "x.y", "/path", base::Time(),
2815                    base::Time(), base::Time(), base::Time(), false, false,
2816                    CookieSameSite::NO_RESTRICTION, COOKIE_PRIORITY_LOW, false)
2817                    ->IsCanonical());
2818 
2819   // Name begins with whitespace.
2820   EXPECT_FALSE(CanonicalCookie::CreateUnsafeCookieForTesting(
2821                    " A", "B", "x.y", "/path", base::Time(), base::Time(),
2822                    base::Time(), base::Time(), false, false,
2823                    CookieSameSite::NO_RESTRICTION, COOKIE_PRIORITY_LOW, false)
2824                    ->IsCanonical());
2825 
2826   // Name ends with whitespace.
2827   EXPECT_FALSE(CanonicalCookie::CreateUnsafeCookieForTesting(
2828                    "A ", "B", "x.y", "/path", base::Time(), base::Time(),
2829                    base::Time(), base::Time(), false, false,
2830                    CookieSameSite::NO_RESTRICTION, COOKIE_PRIORITY_LOW, false)
2831                    ->IsCanonical());
2832 
2833   // Empty name.  (Note this is against the spec but compatible with other
2834   // browsers.)
2835   EXPECT_TRUE(CanonicalCookie::CreateUnsafeCookieForTesting(
2836                   "", "B", "x.y", "/path", base::Time(), base::Time(),
2837                   base::Time(), base::Time(), false, false,
2838                   CookieSameSite::NO_RESTRICTION, COOKIE_PRIORITY_LOW, false)
2839                   ->IsCanonical());
2840 
2841   // Space in name
2842   EXPECT_TRUE(CanonicalCookie::CreateUnsafeCookieForTesting(
2843                   "A C", "B", "x.y", "/path", base::Time(), base::Time(),
2844                   base::Time(), base::Time(), false, false,
2845                   CookieSameSite::NO_RESTRICTION, COOKIE_PRIORITY_LOW, false)
2846                   ->IsCanonical());
2847 
2848   // Extra space suffixing name.
2849   EXPECT_FALSE(CanonicalCookie::CreateUnsafeCookieForTesting(
2850                    "A ", "B", "x.y", "/path", base::Time(), base::Time(),
2851                    base::Time(), base::Time(), false, false,
2852                    CookieSameSite::NO_RESTRICTION, COOKIE_PRIORITY_LOW, false)
2853                    ->IsCanonical());
2854 
2855   // '=' character in name.
2856   EXPECT_FALSE(CanonicalCookie::CreateUnsafeCookieForTesting(
2857                    "A=", "B", "x.y", "/path", base::Time(), base::Time(),
2858                    base::Time(), base::Time(), false, false,
2859                    CookieSameSite::NO_RESTRICTION, COOKIE_PRIORITY_LOW, false)
2860                    ->IsCanonical());
2861 
2862   // Separator in name.
2863   EXPECT_FALSE(CanonicalCookie::CreateUnsafeCookieForTesting(
2864                    "A;", "B", "x.y", "/path", base::Time(), base::Time(),
2865                    base::Time(), base::Time(), false, false,
2866                    CookieSameSite::NO_RESTRICTION, COOKIE_PRIORITY_LOW, false)
2867                    ->IsCanonical());
2868 
2869   // '=' character in value.
2870   EXPECT_TRUE(CanonicalCookie::CreateUnsafeCookieForTesting(
2871                   "A", "B=", "x.y", "/path", base::Time(), base::Time(),
2872                   base::Time(), base::Time(), false, false,
2873                   CookieSameSite::NO_RESTRICTION, COOKIE_PRIORITY_LOW, false)
2874                   ->IsCanonical());
2875 
2876   // Separator in value.
2877   EXPECT_FALSE(CanonicalCookie::CreateUnsafeCookieForTesting(
2878                    "A", "B;", "x.y", "/path", base::Time(), base::Time(),
2879                    base::Time(), base::Time(), false, false,
2880                    CookieSameSite::NO_RESTRICTION, COOKIE_PRIORITY_LOW, false)
2881                    ->IsCanonical());
2882 
2883   // Separator in domain.
2884   EXPECT_FALSE(CanonicalCookie::CreateUnsafeCookieForTesting(
2885                    "A", "B", ";x.y", "/path", base::Time(), base::Time(),
2886                    base::Time(), base::Time(), false, false,
2887                    CookieSameSite::NO_RESTRICTION, COOKIE_PRIORITY_LOW, false)
2888                    ->IsCanonical());
2889 
2890   // Garbage in domain.
2891   EXPECT_FALSE(CanonicalCookie::CreateUnsafeCookieForTesting(
2892                    "A", "B", "@:&", "/path", base::Time(), base::Time(),
2893                    base::Time(), base::Time(), false, false,
2894                    CookieSameSite::NO_RESTRICTION, COOKIE_PRIORITY_LOW, false)
2895                    ->IsCanonical());
2896 
2897   // Space in domain.
2898   EXPECT_FALSE(CanonicalCookie::CreateUnsafeCookieForTesting(
2899                    "A", "B", "x.y ", "/path", base::Time(), base::Time(),
2900                    base::Time(), base::Time(), false, false,
2901                    CookieSameSite::NO_RESTRICTION, COOKIE_PRIORITY_LOW, false)
2902                    ->IsCanonical());
2903 
2904   // Empty domain.  (This is against cookie spec, but needed for Chrome's
2905   // out-of-spec use of cookies for extensions; see http://crbug.com/730633.
2906   EXPECT_TRUE(CanonicalCookie::CreateUnsafeCookieForTesting(
2907                   "A", "B", "", "/path", base::Time(), base::Time(),
2908                   base::Time(), base::Time(), false, false,
2909                   CookieSameSite::NO_RESTRICTION, COOKIE_PRIORITY_LOW, false)
2910                   ->IsCanonical());
2911 
2912   // Path does not start with a "/".
2913   EXPECT_FALSE(CanonicalCookie::CreateUnsafeCookieForTesting(
2914                    "A", "B", "x.y", "path", base::Time(), base::Time(),
2915                    base::Time(), base::Time(), false, false,
2916                    CookieSameSite::NO_RESTRICTION, COOKIE_PRIORITY_LOW, false)
2917                    ->IsCanonical());
2918 
2919   // Empty path.
2920   EXPECT_FALSE(CanonicalCookie::CreateUnsafeCookieForTesting(
2921                    "A", "B", "x.y", "", base::Time(), base::Time(),
2922                    base::Time(), base::Time(), false, false,
2923                    CookieSameSite::NO_RESTRICTION, COOKIE_PRIORITY_LOW, false)
2924                    ->IsCanonical());
2925 
2926   // "localhost" as domain.
2927   EXPECT_TRUE(CanonicalCookie::CreateUnsafeCookieForTesting(
2928                   "A", "B", "localhost", "/path", base::Time(), base::Time(),
2929                   base::Time(), base::Time(), false, false,
2930                   CookieSameSite::NO_RESTRICTION, COOKIE_PRIORITY_LOW, false)
2931                   ->IsCanonical());
2932 
2933   // non-ASCII domain.
2934   EXPECT_FALSE(CanonicalCookie::CreateUnsafeCookieForTesting(
2935                    "A", "B", "\xC3\xA9xample.com", "/path", base::Time(),
2936                    base::Time(), base::Time(), base::Time(), false, false,
2937                    CookieSameSite::NO_RESTRICTION, COOKIE_PRIORITY_LOW, false)
2938                    ->IsCanonical());
2939 
2940   // punycode domain.
2941   EXPECT_TRUE(CanonicalCookie::CreateUnsafeCookieForTesting(
2942                   "A", "B", "xn--xample-9ua.com", "/path", base::Time(),
2943                   base::Time(), base::Time(), base::Time(), false, false,
2944                   CookieSameSite::NO_RESTRICTION, COOKIE_PRIORITY_LOW, false)
2945                   ->IsCanonical());
2946 
2947   // Localhost IPv4 address as domain.
2948   EXPECT_TRUE(CanonicalCookie::CreateUnsafeCookieForTesting(
2949                   "A", "B", "127.0.0.1", "/path", base::Time(), base::Time(),
2950                   base::Time(), base::Time(), false, false,
2951                   CookieSameSite::NO_RESTRICTION, COOKIE_PRIORITY_LOW, false)
2952                   ->IsCanonical());
2953 
2954   // Simple IPv4 address as domain.
2955   EXPECT_TRUE(CanonicalCookie::CreateUnsafeCookieForTesting(
2956                   "A", "B", "1.2.3.4", "/path", base::Time(), base::Time(),
2957                   base::Time(), base::Time(), false, false,
2958                   CookieSameSite::NO_RESTRICTION, COOKIE_PRIORITY_LOW, false)
2959                   ->IsCanonical());
2960 
2961   // period-prefixed IPv4 address as domain.
2962   EXPECT_FALSE(CanonicalCookie::CreateUnsafeCookieForTesting(
2963                    "A", "B", ".1.3.2.4", "/path", base::Time(), base::Time(),
2964                    base::Time(), base::Time(), false, false,
2965                    CookieSameSite::NO_RESTRICTION, COOKIE_PRIORITY_LOW, false)
2966                    ->IsCanonical());
2967 
2968   // period-prefixed truncated IPv4 address as domain.
2969   EXPECT_FALSE(CanonicalCookie::CreateUnsafeCookieForTesting(
2970                    "A", "B", ".3.2.4", "/path", base::Time(), base::Time(),
2971                    base::Time(), base::Time(), true, false,
2972                    CookieSameSite::NO_RESTRICTION, COOKIE_PRIORITY_LOW, false)
2973                    ->IsCanonical());
2974 
2975   // truncated IPv4 address as domain.
2976   EXPECT_FALSE(CanonicalCookie::CreateUnsafeCookieForTesting(
2977                    "A", "B", "3.2.4", "/path", base::Time(), base::Time(),
2978                    base::Time(), base::Time(), true, false,
2979                    CookieSameSite::NO_RESTRICTION, COOKIE_PRIORITY_LOW, false)
2980                    ->IsCanonical());
2981 
2982   // Non-canonical IPv4 address as domain.
2983   EXPECT_FALSE(CanonicalCookie::CreateUnsafeCookieForTesting(
2984                    "A", "B", "01.2.03.4", "/path", base::Time(), base::Time(),
2985                    base::Time(), base::Time(), false, false,
2986                    CookieSameSite::NO_RESTRICTION, COOKIE_PRIORITY_LOW, false)
2987                    ->IsCanonical());
2988 
2989   // Non-canonical IPv4 address as domain.
2990   EXPECT_FALSE(CanonicalCookie::CreateUnsafeCookieForTesting(
2991                    "A", "B", "16843009", "/path", base::Time(), base::Time(),
2992                    base::Time(), base::Time(), false, false,
2993                    CookieSameSite::NO_RESTRICTION, COOKIE_PRIORITY_LOW, false)
2994                    ->IsCanonical());
2995 
2996   // Non-canonical IPv4 address as domain.
2997   EXPECT_FALSE(CanonicalCookie::CreateUnsafeCookieForTesting(
2998                    "A", "B", "0x1010101", "/path", base::Time(), base::Time(),
2999                    base::Time(), base::Time(), false, false,
3000                    CookieSameSite::NO_RESTRICTION, COOKIE_PRIORITY_LOW, false)
3001                    ->IsCanonical());
3002 
3003   // Null IPv6 address as domain.
3004   EXPECT_TRUE(CanonicalCookie::CreateUnsafeCookieForTesting(
3005                   "A", "B", "[::]", "/path", base::Time(), base::Time(),
3006                   base::Time(), base::Time(), false, false,
3007                   CookieSameSite::NO_RESTRICTION, COOKIE_PRIORITY_LOW, false)
3008                   ->IsCanonical());
3009 
3010   // Localhost IPv6 address as domain.
3011   EXPECT_TRUE(CanonicalCookie::CreateUnsafeCookieForTesting(
3012                   "A", "B", "[::1]", "/path", base::Time(), base::Time(),
3013                   base::Time(), base::Time(), false, false,
3014                   CookieSameSite::NO_RESTRICTION, COOKIE_PRIORITY_LOW, false)
3015                   ->IsCanonical());
3016 
3017   // Fully speced IPv6 address as domain.
3018   EXPECT_FALSE(CanonicalCookie::CreateUnsafeCookieForTesting(
3019                    "A", "B", "[2001:0DB8:AC10:FE01:0000:0000:0000:0000]",
3020                    "/path", base::Time(), base::Time(), base::Time(),
3021                    base::Time(), false, false, CookieSameSite::NO_RESTRICTION,
3022                    COOKIE_PRIORITY_LOW, false)
3023                    ->IsCanonical());
3024 
3025   // Zero abbreviated IPv6 address as domain.  Not canonical because of leading
3026   // zeros & uppercase hex letters.
3027   EXPECT_FALSE(CanonicalCookie::CreateUnsafeCookieForTesting(
3028                    "A", "B", "[2001:0DB8:AC10:FE01::]", "/path", base::Time(),
3029                    base::Time(), base::Time(), base::Time(), false, false,
3030                    CookieSameSite::NO_RESTRICTION, COOKIE_PRIORITY_LOW, false)
3031                    ->IsCanonical());
3032 
3033   // Zero prefixes removed IPv6 address as domain.  Not canoncial because of
3034   // uppercase hex letters.
3035   EXPECT_FALSE(CanonicalCookie::CreateUnsafeCookieForTesting(
3036                    "A", "B", "[2001:DB8:AC10:FE01::]", "/path", base::Time(),
3037                    base::Time(), base::Time(), base::Time(), false, false,
3038                    CookieSameSite::NO_RESTRICTION, COOKIE_PRIORITY_LOW, false)
3039                    ->IsCanonical());
3040 
3041   // Lowercased hex IPv6 address as domain.
3042   EXPECT_TRUE(CanonicalCookie::CreateUnsafeCookieForTesting(
3043                   "A", "B", "[2001:db8:ac10:fe01::]", "/path", base::Time(),
3044                   base::Time(), base::Time(), base::Time(), false, false,
3045                   CookieSameSite::NO_RESTRICTION, COOKIE_PRIORITY_LOW, false)
3046                   ->IsCanonical());
3047 
3048   // Lowercased hex IPv6 address as domain for domain cookie.
3049   EXPECT_FALSE(CanonicalCookie::CreateUnsafeCookieForTesting(
3050                    "A", "B", ".[2001:db8:ac10:fe01::]", "/path", base::Time(),
3051                    base::Time(), base::Time(), base::Time(), false, false,
3052                    CookieSameSite::NO_RESTRICTION, COOKIE_PRIORITY_LOW, false)
3053                    ->IsCanonical());
3054 
3055   // Incomplete lowercased hex IPv6 address as domain.
3056   EXPECT_FALSE(CanonicalCookie::CreateUnsafeCookieForTesting(
3057                    "A", "B", "[2001:db8:ac10:fe01:]", "/path", base::Time(),
3058                    base::Time(), base::Time(), base::Time(), false, false,
3059                    CookieSameSite::NO_RESTRICTION, COOKIE_PRIORITY_LOW, false)
3060                    ->IsCanonical());
3061 
3062   // Missing square brackets in IPv6 address as domain.
3063   EXPECT_FALSE(CanonicalCookie::CreateUnsafeCookieForTesting(
3064                    "A", "B", "2606:2800:220:1:248:1893:25c8:1946", "/path",
3065                    base::Time(), base::Time(), base::Time(), base::Time(),
3066                    false, false, CookieSameSite::NO_RESTRICTION,
3067                    COOKIE_PRIORITY_LOW, false)
3068                    ->IsCanonical());
3069 
3070   // Properly formatted host cookie.
3071   EXPECT_TRUE(CanonicalCookie::CreateUnsafeCookieForTesting(
3072                   "__Host-A", "B", "x.y", "/", base::Time(), base::Time(),
3073                   base::Time(), base::Time(), true, false,
3074                   CookieSameSite::NO_RESTRICTION, COOKIE_PRIORITY_LOW, false)
3075                   ->IsCanonical());
3076 
3077   // Insecure host cookie.
3078   EXPECT_FALSE(CanonicalCookie::CreateUnsafeCookieForTesting(
3079                    "__Host-A", "B", "x.y", "/", base::Time(), base::Time(),
3080                    base::Time(), base::Time(), false, false,
3081                    CookieSameSite::NO_RESTRICTION, COOKIE_PRIORITY_LOW, false)
3082                    ->IsCanonical());
3083 
3084   // Host cookie with non-null path.
3085   EXPECT_FALSE(CanonicalCookie::CreateUnsafeCookieForTesting(
3086                    "__Host-A", "B", "x.y", "/path", base::Time(), base::Time(),
3087                    base::Time(), base::Time(), true, false,
3088                    CookieSameSite::NO_RESTRICTION, COOKIE_PRIORITY_LOW, false)
3089                    ->IsCanonical());
3090 
3091   // Host cookie with empty domain.
3092   EXPECT_FALSE(CanonicalCookie::CreateUnsafeCookieForTesting(
3093                    "__Host-A", "B", "", "/", base::Time(), base::Time(),
3094                    base::Time(), base::Time(), true, false,
3095                    CookieSameSite::NO_RESTRICTION, COOKIE_PRIORITY_LOW, false)
3096                    ->IsCanonical());
3097 
3098   // Host cookie with period prefixed domain.
3099   EXPECT_FALSE(CanonicalCookie::CreateUnsafeCookieForTesting(
3100                    "__Host-A", "B", ".x.y", "/", base::Time(), base::Time(),
3101                    base::Time(), base::Time(), true, false,
3102                    CookieSameSite::NO_RESTRICTION, COOKIE_PRIORITY_LOW, false)
3103                    ->IsCanonical());
3104 
3105   // Properly formatted secure cookie.
3106   EXPECT_TRUE(CanonicalCookie::CreateUnsafeCookieForTesting(
3107                   "__Secure-A", "B", "x.y", "/", base::Time(), base::Time(),
3108                   base::Time(), base::Time(), true, false,
3109                   CookieSameSite::NO_RESTRICTION, COOKIE_PRIORITY_LOW, false)
3110                   ->IsCanonical());
3111 
3112   // Insecure secure cookie.
3113   EXPECT_FALSE(CanonicalCookie::CreateUnsafeCookieForTesting(
3114                    "__Secure-A", "B", "x.y", "/", base::Time(), base::Time(),
3115                    base::Time(), base::Time(), false, false,
3116                    CookieSameSite::NO_RESTRICTION, COOKIE_PRIORITY_LOW, false)
3117                    ->IsCanonical());
3118 
3119   // SameParty attribute used correctly (with Secure and non-Strict SameSite).
3120   EXPECT_TRUE(CanonicalCookie::CreateUnsafeCookieForTesting(
3121                   "A", "B", "x.y", "/", base::Time(), base::Time(),
3122                   base::Time(), base::Time(), true, false,
3123                   CookieSameSite::NO_RESTRICTION, COOKIE_PRIORITY_LOW, true)
3124                   ->IsCanonical());
3125   EXPECT_TRUE(CanonicalCookie::CreateUnsafeCookieForTesting(
3126                   "A", "B", "x.y", "/", base::Time(), base::Time(),
3127                   base::Time(), base::Time(), true, false,
3128                   CookieSameSite::UNSPECIFIED, COOKIE_PRIORITY_LOW, true)
3129                   ->IsCanonical());
3130   EXPECT_TRUE(CanonicalCookie::CreateUnsafeCookieForTesting(
3131                   "A", "B", "x.y", "/", base::Time(), base::Time(),
3132                   base::Time(), base::Time(), true, false,
3133                   CookieSameSite::LAX_MODE, COOKIE_PRIORITY_LOW, true)
3134                   ->IsCanonical());
3135 
3136   // SameParty without Secure is not canonical.
3137   EXPECT_FALSE(CanonicalCookie::CreateUnsafeCookieForTesting(
3138                    "A", "B", "x.y", "/", base::Time(), base::Time(),
3139                    base::Time(), base::Time(), false, false,
3140                    CookieSameSite::LAX_MODE, COOKIE_PRIORITY_LOW, true)
3141                    ->IsCanonical());
3142 
3143   // SameParty with SameSite=Strict is not canonical.
3144   EXPECT_FALSE(CanonicalCookie::CreateUnsafeCookieForTesting(
3145                    "A", "B", "x.y", "/", base::Time(), base::Time(),
3146                    base::Time(), base::Time(), true, false,
3147                    CookieSameSite::STRICT_MODE, COOKIE_PRIORITY_LOW, true)
3148                    ->IsCanonical());
3149 
3150   // Partitioned attribute used correctly (__Host- prefix, no SameParty).
3151   EXPECT_TRUE(CanonicalCookie::CreateUnsafeCookieForTesting(
3152                   "__Host-A", "B", "x.y", "/", base::Time(), base::Time(),
3153                   base::Time(), base::Time(), /*secure=*/true,
3154                   /*httponly=*/false, CookieSameSite::UNSPECIFIED,
3155                   COOKIE_PRIORITY_LOW,
3156                   /*same_party=*/false,
3157                   CookiePartitionKey::FromURLForTesting(
3158                       GURL("https://toplevelsite.com")))
3159                   ->IsCanonical());
3160 
3161   // Partitioned attribute with no __Host- prefix is still valid if it has
3162   // Secure, Path=/, and no Domain.
3163   EXPECT_TRUE(CanonicalCookie::CreateUnsafeCookieForTesting(
3164                   "A", "B", "x.y", "/", base::Time(), base::Time(),
3165                   base::Time(), base::Time(), /*secure=*/true,
3166                   /*httponly=*/false, CookieSameSite::UNSPECIFIED,
3167                   COOKIE_PRIORITY_LOW,
3168                   /*same_party=*/false,
3169                   CookiePartitionKey::FromURLForTesting(
3170                       GURL("https://toplevelsite.com")))
3171                   ->IsCanonical());
3172 
3173   // Partitioned attribute invalid, not Secure.
3174   EXPECT_FALSE(CanonicalCookie::CreateUnsafeCookieForTesting(
3175                    "A", "B", "x.y", "/", base::Time(), base::Time(),
3176                    base::Time(), base::Time(), /*secure=*/false,
3177                    /*httponly=*/false, CookieSameSite::UNSPECIFIED,
3178                    COOKIE_PRIORITY_LOW,
3179                    /*same_party=*/false,
3180                    CookiePartitionKey::FromURLForTesting(
3181                        GURL("https://toplevelsite.com")))
3182                    ->IsCanonical());
3183 
3184   // Partitioned attribute is valid when Path != "/".
3185   EXPECT_TRUE(CanonicalCookie::CreateUnsafeCookieForTesting(
3186                   "A", "B", "x.y", "/foo/bar", base::Time(), base::Time(),
3187                   base::Time(), base::Time(), /*secure=*/true,
3188                   /*httponly=*/false, CookieSameSite::UNSPECIFIED,
3189                   COOKIE_PRIORITY_LOW,
3190                   /*same_party=*/false,
3191                   CookiePartitionKey::FromURLForTesting(
3192                       GURL("https://toplevelsite.com")))
3193                   ->IsCanonical());
3194 
3195   // Partitioned attribute is valid when Domain attribute also included.
3196   EXPECT_TRUE(CanonicalCookie::CreateUnsafeCookieForTesting(
3197                   "A", "B", ".x.y", "/", base::Time(), base::Time(),
3198                   base::Time(), base::Time(), /*secure=*/true,
3199                   /*httponly=*/false, CookieSameSite::UNSPECIFIED,
3200                   COOKIE_PRIORITY_LOW,
3201                   /*same_party=*/false,
3202                   CookiePartitionKey::FromURLForTesting(
3203                       GURL("https://toplevelsite.com")))
3204                   ->IsCanonical());
3205 
3206   // Hidden cookie prefixes.
3207   EXPECT_FALSE(CanonicalCookie::CreateUnsafeCookieForTesting(
3208                    "", "__Secure-a=b", "x.y", "/", base::Time(), base::Time(),
3209                    base::Time(), base::Time(), true, false,
3210                    CookieSameSite::NO_RESTRICTION, COOKIE_PRIORITY_LOW, false)
3211                    ->IsCanonical());
3212 
3213   EXPECT_FALSE(CanonicalCookie::CreateUnsafeCookieForTesting(
3214                    "", "__Secure-a", "x.y", "/", base::Time(), base::Time(),
3215                    base::Time(), base::Time(), true, false,
3216                    CookieSameSite::NO_RESTRICTION, COOKIE_PRIORITY_LOW, false)
3217                    ->IsCanonical());
3218 
3219   EXPECT_FALSE(CanonicalCookie::CreateUnsafeCookieForTesting(
3220                    "", "__Host-a=b", "x.y", "/", base::Time(), base::Time(),
3221                    base::Time(), base::Time(), true, false,
3222                    CookieSameSite::NO_RESTRICTION, COOKIE_PRIORITY_LOW, false)
3223                    ->IsCanonical());
3224 
3225   EXPECT_FALSE(CanonicalCookie::CreateUnsafeCookieForTesting(
3226                    "", "__Host-a", "x.y", "/", base::Time(), base::Time(),
3227                    base::Time(), base::Time(), true, false,
3228                    CookieSameSite::NO_RESTRICTION, COOKIE_PRIORITY_LOW, false)
3229                    ->IsCanonical());
3230 
3231   EXPECT_TRUE(CanonicalCookie::CreateUnsafeCookieForTesting(
3232                   "a", "__Secure-a=b", "x.y", "/", base::Time(), base::Time(),
3233                   base::Time(), base::Time(), true, false,
3234                   CookieSameSite::NO_RESTRICTION, COOKIE_PRIORITY_LOW, false)
3235                   ->IsCanonical());
3236 
3237   EXPECT_TRUE(CanonicalCookie::CreateUnsafeCookieForTesting(
3238                   "a", "__Host-a=b", "x.y", "/", base::Time(), base::Time(),
3239                   base::Time(), base::Time(), true, false,
3240                   CookieSameSite::NO_RESTRICTION, COOKIE_PRIORITY_LOW, false)
3241                   ->IsCanonical());
3242 }
3243 
TEST(CanonicalCookieTest,TestSetCreationDate)3244 TEST(CanonicalCookieTest, TestSetCreationDate) {
3245   auto cookie = CanonicalCookie::CreateUnsafeCookieForTesting(
3246       "A", "B", "x.y", "/path", base::Time(), base::Time(), base::Time(),
3247       base::Time(), false, false, CookieSameSite::NO_RESTRICTION,
3248       COOKIE_PRIORITY_LOW, false);
3249   EXPECT_TRUE(cookie->CreationDate().is_null());
3250 
3251   base::Time now(base::Time::Now());
3252   cookie->SetCreationDate(now);
3253   EXPECT_EQ(now, cookie->CreationDate());
3254 }
3255 
TEST(CanonicalCookieTest,TestPrefixHistograms)3256 TEST(CanonicalCookieTest, TestPrefixHistograms) {
3257   base::HistogramTester histograms;
3258   const char kCookiePrefixHistogram[] = "Cookie.CookiePrefix";
3259   const char kCookiePrefixVariantHistogram[] =
3260       "Cookie.CookiePrefix.CaseVariant";
3261   const char kVariantValidHistogram[] = "Cookie.CookiePrefix.CaseVariantValid";
3262   const char kVariantCountHistogram[] = "Cookie.CookiePrefix.CaseVariantCount";
3263   GURL https_url("https://www.example.test");
3264   base::Time creation_time = base::Time::Now();
3265   absl::optional<base::Time> server_time = absl::nullopt;
3266 
3267   EXPECT_FALSE(CanonicalCookie::Create(
3268       https_url, "__Host-A=B;", creation_time, server_time,
3269       absl::nullopt /* cookie_partition_key */));
3270 
3271   histograms.ExpectBucketCount(kCookiePrefixHistogram,
3272                                CanonicalCookie::COOKIE_PREFIX_HOST, 1);
3273 
3274   EXPECT_TRUE(CanonicalCookie::Create(
3275       https_url, "__Host-A=B; Path=/; Secure", creation_time, server_time,
3276       absl::nullopt /* cookie_partition_key */));
3277   histograms.ExpectBucketCount(kCookiePrefixHistogram,
3278                                CanonicalCookie::COOKIE_PREFIX_HOST, 2);
3279   EXPECT_TRUE(CanonicalCookie::Create(
3280       https_url, "__HostA=B; Path=/; Secure", creation_time, server_time,
3281       absl::nullopt /* cookie_partition_key */));
3282   histograms.ExpectBucketCount(kCookiePrefixHistogram,
3283                                CanonicalCookie::COOKIE_PREFIX_HOST, 2);
3284 
3285   EXPECT_FALSE(CanonicalCookie::Create(
3286       https_url, "__Secure-A=B;", creation_time, server_time,
3287       absl::nullopt /* cookie_partition_key */));
3288 
3289   histograms.ExpectBucketCount(kCookiePrefixHistogram,
3290                                CanonicalCookie::COOKIE_PREFIX_SECURE, 1);
3291   EXPECT_TRUE(CanonicalCookie::Create(
3292       https_url, "__Secure-A=B; Path=/; Secure", creation_time, server_time,
3293       absl::nullopt /* cookie_partition_key */));
3294   histograms.ExpectBucketCount(kCookiePrefixHistogram,
3295                                CanonicalCookie::COOKIE_PREFIX_SECURE, 2);
3296   EXPECT_TRUE(CanonicalCookie::Create(
3297       https_url, "__SecureA=B; Path=/; Secure", creation_time, server_time,
3298       absl::nullopt /* cookie_partition_key */));
3299   histograms.ExpectBucketCount(kCookiePrefixHistogram,
3300                                CanonicalCookie::COOKIE_PREFIX_SECURE, 2);
3301 
3302   // Test prefix case variants
3303   const int sensitive_value_host = histograms.GetBucketCount(
3304       kCookiePrefixHistogram, CanonicalCookie::COOKIE_PREFIX_HOST);
3305   const int sensitive_value_secure = histograms.GetBucketCount(
3306       kCookiePrefixHistogram, CanonicalCookie::COOKIE_PREFIX_SECURE);
3307 
3308   EXPECT_TRUE(CanonicalCookie::Create(
3309       https_url, "__SECURE-A=B; Path=/; Secure", creation_time, server_time,
3310       absl::nullopt /* cookie_partition_key */));
3311   histograms.ExpectBucketCount(kCookiePrefixVariantHistogram,
3312                                CanonicalCookie::COOKIE_PREFIX_SECURE, 1);
3313   histograms.ExpectBucketCount(kCookiePrefixHistogram,
3314                                CanonicalCookie::COOKIE_PREFIX_SECURE,
3315                                sensitive_value_secure);
3316 
3317   EXPECT_TRUE(CanonicalCookie::Create(
3318       https_url, "__HOST-A=B; Path=/; Secure", creation_time, server_time,
3319       absl::nullopt /* cookie_partition_key */));
3320   histograms.ExpectBucketCount(kCookiePrefixVariantHistogram,
3321                                CanonicalCookie::COOKIE_PREFIX_HOST, 1);
3322   histograms.ExpectBucketCount(kCookiePrefixHistogram,
3323                                CanonicalCookie::COOKIE_PREFIX_HOST,
3324                                sensitive_value_host);
3325 
3326   // True indicates a variant
3327   histograms.ExpectBucketCount(kVariantCountHistogram, true, 2);
3328   histograms.ExpectBucketCount(kVariantCountHistogram, false, 4);
3329 
3330   // Invalid variants
3331   EXPECT_FALSE(CanonicalCookie::Create(
3332       https_url, "__SECURE-A=B", creation_time, server_time,
3333       absl::nullopt /* cookie_partition_key */));
3334 
3335   EXPECT_FALSE(CanonicalCookie::Create(
3336       https_url, "__HOST-A=B;", creation_time, server_time,
3337       absl::nullopt /* cookie_partition_key */));
3338 
3339   histograms.ExpectBucketCount(kVariantValidHistogram, true, 2);
3340   histograms.ExpectBucketCount(kVariantValidHistogram, false, 2);
3341 }
3342 
TEST(CanonicalCookieTest,TestHasNonASCIIHistograms)3343 TEST(CanonicalCookieTest, TestHasNonASCIIHistograms) {
3344   base::HistogramTester histograms;
3345   const char kCookieNonASCIINameHistogram[] = "Cookie.HasNonASCII.Name";
3346   const char kCookieNonASCIIValueHistogram[] = "Cookie.HasNonASCII.Value";
3347   const GURL test_url("https://www.example.test");
3348   int expected_name_true = 0;
3349   int expected_name_false = 0;
3350   int expected_value_true = 0;
3351   int expected_value_false = 0;
3352 
3353   auto create_for_test = [&](const std::string& name,
3354                              const std::string& value) {
3355     return CanonicalCookie::Create(
3356         test_url, name + "=" + value, /*creation_time=*/base::Time::Now(),
3357         /*server_time=*/absl::nullopt, /*cookie_partition_key=*/absl::nullopt);
3358   };
3359 
3360   auto check_histograms = [&]() {
3361     histograms.ExpectBucketCount(kCookieNonASCIINameHistogram, true,
3362                                  expected_name_true);
3363     histograms.ExpectBucketCount(kCookieNonASCIINameHistogram, false,
3364                                  expected_name_false);
3365     histograms.ExpectBucketCount(kCookieNonASCIIValueHistogram, true,
3366                                  expected_value_true);
3367     histograms.ExpectBucketCount(kCookieNonASCIIValueHistogram, false,
3368                                  expected_value_false);
3369   };
3370 
3371   EXPECT_TRUE(create_for_test("foo", "bar"));
3372   expected_name_false++;
3373   expected_value_false++;
3374   check_histograms();
3375 
3376   EXPECT_TRUE(create_for_test("Uni\xf0\x9f\x8d\xaa", "bar"));
3377   expected_name_true++;
3378   expected_value_false++;
3379   check_histograms();
3380 
3381   EXPECT_TRUE(create_for_test("foo", "Uni\xf0\x9f\x8d\xaa"));
3382   expected_name_false++;
3383   expected_value_true++;
3384   check_histograms();
3385 
3386   EXPECT_TRUE(create_for_test("Uni\xf0\x9f\x8d\xaa", "Uni\xf0\x9f\x8d\xaa"));
3387   expected_name_true++;
3388   expected_value_true++;
3389   check_histograms();
3390 }
3391 
TEST(CanonicalCookieTest,BuildCookieLine)3392 TEST(CanonicalCookieTest, BuildCookieLine) {
3393   std::vector<std::unique_ptr<CanonicalCookie>> cookies;
3394   GURL url("https://example.com/");
3395   base::Time now = base::Time::Now();
3396   absl::optional<base::Time> server_time = absl::nullopt;
3397   MatchCookieLineToVector("", cookies);
3398 
3399   cookies.push_back(CanonicalCookie::Create(
3400       url, "A=B", now, server_time, absl::nullopt /* cookie_partition_key */));
3401   MatchCookieLineToVector("A=B", cookies);
3402   // Nameless cookies are sent back without a prefixed '='.
3403   cookies.push_back(CanonicalCookie::Create(
3404       url, "C", now, server_time, absl::nullopt /* cookie_partition_key */));
3405   MatchCookieLineToVector("A=B; C", cookies);
3406   // Cookies separated by ';'.
3407   cookies.push_back(CanonicalCookie::Create(
3408       url, "D=E", now, server_time, absl::nullopt /* cookie_partition_key */));
3409   MatchCookieLineToVector("A=B; C; D=E", cookies);
3410   // BuildCookieLine doesn't reorder the list, it relies on the caller to do so.
3411   cookies.push_back(
3412       CanonicalCookie::Create(url, "F=G", now - base::Seconds(1), server_time,
3413                               absl::nullopt /* cookie_partition_key */));
3414   MatchCookieLineToVector("A=B; C; D=E; F=G", cookies);
3415   // BuildCookieLine doesn't deduplicate.
3416   cookies.push_back(
3417       CanonicalCookie::Create(url, "D=E", now - base::Seconds(2), server_time,
3418                               absl::nullopt /* cookie_partition_key */));
3419   MatchCookieLineToVector("A=B; C; D=E; F=G; D=E", cookies);
3420   // BuildCookieLine should match the spec in the case of an empty name with a
3421   // value containing an equal sign (even if it currently produces "invalid"
3422   // cookie lines).
3423   cookies.push_back(CanonicalCookie::Create(
3424       url, "=H=I", now, server_time, absl::nullopt /* cookie_partition_key */));
3425   MatchCookieLineToVector("A=B; C; D=E; F=G; D=E; H=I", cookies);
3426 }
3427 
TEST(CanonicalCookieTest,BuildCookieAttributesLine)3428 TEST(CanonicalCookieTest, BuildCookieAttributesLine) {
3429   std::unique_ptr<CanonicalCookie> cookie;
3430   GURL url("https://example.com/");
3431   base::Time now = base::Time::Now();
3432   absl::optional<base::Time> server_time = absl::nullopt;
3433 
3434   cookie = CanonicalCookie::Create(url, "A=B", now, server_time,
3435                                    absl::nullopt /* cookie_partition_key */);
3436   EXPECT_EQ("A=B; domain=example.com; path=/",
3437             CanonicalCookie::BuildCookieAttributesLine(*cookie));
3438   // Nameless cookies are sent back without a prefixed '='.
3439   cookie = CanonicalCookie::Create(url, "C", now, server_time,
3440                                    absl::nullopt /* cookie_partition_key */);
3441   EXPECT_EQ("C; domain=example.com; path=/",
3442             CanonicalCookie::BuildCookieAttributesLine(*cookie));
3443   // BuildCookieAttributesLine should match the spec in the case of an empty
3444   // name with a value containing an equal sign (even if it currently produces
3445   // "invalid" cookie lines).
3446   cookie = CanonicalCookie::Create(url, "=H=I", now, server_time,
3447                                    absl::nullopt /* cookie_partition_key */);
3448   EXPECT_EQ("H=I; domain=example.com; path=/",
3449             CanonicalCookie::BuildCookieAttributesLine(*cookie));
3450   // BuildCookieAttributesLine should include all attributes.
3451   cookie = CanonicalCookie::Create(
3452       url, "A=B; domain=.example.com; path=/; secure; httponly; samesite=lax",
3453       now, server_time, absl::nullopt /* cookie_partition_key */);
3454   EXPECT_EQ("A=B; domain=.example.com; path=/; secure; httponly; samesite=lax",
3455             CanonicalCookie::BuildCookieAttributesLine(*cookie));
3456 }
3457 
3458 // Confirm that input arguments are reflected in the output cookie.
TEST(CanonicalCookieTest,CreateSanitizedCookie_Inputs)3459 TEST(CanonicalCookieTest, CreateSanitizedCookie_Inputs) {
3460   base::Time two_hours_ago = base::Time::Now() - base::Hours(2);
3461   base::Time one_hour_ago = base::Time::Now() - base::Hours(1);
3462   base::Time one_hour_from_now = base::Time::Now() + base::Hours(1);
3463   CookieInclusionStatus status;
3464   std::unique_ptr<CanonicalCookie> cc;
3465 
3466   cc = CanonicalCookie::CreateSanitizedCookie(
3467       GURL("https://www.foo.com"), "A", "B", std::string(), "/foo",
3468       base::Time(), base::Time(), base::Time(), false /*secure*/,
3469       false /*httponly*/, CookieSameSite::NO_RESTRICTION,
3470       COOKIE_PRIORITY_DEFAULT, false /*same_party*/,
3471       absl::nullopt /*partition_key*/, &status);
3472   EXPECT_TRUE(cc);
3473   EXPECT_EQ("A", cc->Name());
3474   EXPECT_EQ("B", cc->Value());
3475   EXPECT_EQ("www.foo.com", cc->Domain());
3476   EXPECT_EQ("/foo", cc->Path());
3477   EXPECT_EQ(base::Time(), cc->CreationDate());
3478   EXPECT_EQ(base::Time(), cc->LastAccessDate());
3479   EXPECT_EQ(base::Time(), cc->ExpiryDate());
3480   EXPECT_FALSE(cc->IsSecure());
3481   EXPECT_FALSE(cc->IsHttpOnly());
3482   EXPECT_EQ(CookieSameSite::NO_RESTRICTION, cc->SameSite());
3483   EXPECT_EQ(COOKIE_PRIORITY_MEDIUM, cc->Priority());
3484   EXPECT_FALSE(cc->IsSameParty());
3485   EXPECT_FALSE(cc->IsPartitioned());
3486   EXPECT_FALSE(cc->IsDomainCookie());
3487   EXPECT_TRUE(status.IsInclude());
3488 
3489   // Creation date
3490   cc = CanonicalCookie::CreateSanitizedCookie(
3491       GURL("https://www.foo.com"), "A", "B", std::string(), "/foo",
3492       two_hours_ago, base::Time(), base::Time(), false /*secure*/,
3493       false /*httponly*/, CookieSameSite::NO_RESTRICTION,
3494       COOKIE_PRIORITY_DEFAULT, false /*same_party*/,
3495       absl::nullopt /*partition_key*/, &status);
3496   EXPECT_TRUE(cc);
3497   EXPECT_EQ(two_hours_ago, cc->CreationDate());
3498   EXPECT_TRUE(status.IsInclude());
3499 
3500   // Last access date
3501   cc = CanonicalCookie::CreateSanitizedCookie(
3502       GURL("https://www.foo.com"), "A", "B", std::string(), "/foo",
3503       two_hours_ago, base::Time(), one_hour_ago, false /*secure*/,
3504       false /*httponly*/, CookieSameSite::NO_RESTRICTION,
3505       COOKIE_PRIORITY_DEFAULT, false /*same_party*/,
3506       absl::nullopt /*partition_key*/, &status);
3507   EXPECT_TRUE(cc);
3508   EXPECT_EQ(one_hour_ago, cc->LastAccessDate());
3509   EXPECT_TRUE(status.IsInclude());
3510 
3511   // Expiry
3512   cc = CanonicalCookie::CreateSanitizedCookie(
3513       GURL("https://www.foo.com"), "A", "B", std::string(), "/foo",
3514       base::Time(), one_hour_from_now, base::Time(), false /*secure*/,
3515       false /*httponly*/, CookieSameSite::NO_RESTRICTION,
3516       COOKIE_PRIORITY_DEFAULT, false /*same_party*/,
3517       absl::nullopt /*partition_key*/, &status);
3518   EXPECT_TRUE(cc);
3519   EXPECT_EQ(one_hour_from_now, cc->ExpiryDate());
3520   EXPECT_TRUE(status.IsInclude());
3521 
3522   // Secure
3523   cc = CanonicalCookie::CreateSanitizedCookie(
3524       GURL("https://www.foo.com"), "A", "B", std::string(), "/foo",
3525       base::Time(), base::Time(), base::Time(), true /*secure*/,
3526       false /*httponly*/, CookieSameSite::NO_RESTRICTION,
3527       COOKIE_PRIORITY_DEFAULT, false /*same_party*/,
3528       absl::nullopt /*partition_key*/, &status);
3529   EXPECT_TRUE(cc);
3530   EXPECT_TRUE(cc->IsSecure());
3531   EXPECT_TRUE(status.IsInclude());
3532 
3533   // Httponly
3534   cc = CanonicalCookie::CreateSanitizedCookie(
3535       GURL("https://www.foo.com"), "A", "B", std::string(), "/foo",
3536       base::Time(), base::Time(), base::Time(), false /*secure*/,
3537       true /*httponly*/, CookieSameSite::NO_RESTRICTION,
3538       COOKIE_PRIORITY_DEFAULT, false /*same_party*/,
3539       absl::nullopt /*partition_key*/, &status);
3540   EXPECT_TRUE(cc);
3541   EXPECT_TRUE(cc->IsHttpOnly());
3542   EXPECT_TRUE(status.IsInclude());
3543 
3544   // Same site
3545   cc = CanonicalCookie::CreateSanitizedCookie(
3546       GURL("https://www.foo.com"), "A", "B", std::string(), "/foo",
3547       base::Time(), base::Time(), base::Time(), false /*secure*/,
3548       false /*httponly*/, CookieSameSite::LAX_MODE, COOKIE_PRIORITY_DEFAULT,
3549       false /*same_party*/, absl::nullopt /*partition_key*/, &status);
3550   EXPECT_TRUE(cc);
3551   EXPECT_EQ(CookieSameSite::LAX_MODE, cc->SameSite());
3552   EXPECT_TRUE(status.IsInclude());
3553 
3554   // Priority
3555   cc = CanonicalCookie::CreateSanitizedCookie(
3556       GURL("https://www.foo.com"), "A", "B", std::string(), "/foo",
3557       base::Time(), base::Time(), base::Time(), false /*secure*/,
3558       false /*httponly*/, CookieSameSite::NO_RESTRICTION, COOKIE_PRIORITY_LOW,
3559       false /*same_party*/, absl::nullopt /*partition_key*/, &status);
3560   EXPECT_TRUE(cc);
3561   EXPECT_EQ(COOKIE_PRIORITY_LOW, cc->Priority());
3562   EXPECT_TRUE(status.IsInclude());
3563 
3564   // Domain cookie
3565   cc = CanonicalCookie::CreateSanitizedCookie(
3566       GURL("https://www.foo.com"), "A", "B", "www.foo.com", "/foo",
3567       base::Time(), base::Time(), base::Time(), false /*secure*/,
3568       false /*httponly*/, CookieSameSite::NO_RESTRICTION,
3569       COOKIE_PRIORITY_DEFAULT, false /*same_party*/,
3570       absl::nullopt /*partition_key*/, &status);
3571   EXPECT_TRUE(cc);
3572   EXPECT_TRUE(cc->IsDomainCookie());
3573   EXPECT_TRUE(status.IsInclude());
3574 
3575   // SameParty
3576   cc = CanonicalCookie::CreateSanitizedCookie(
3577       GURL("https://www.foo.com"), "A", "B", std::string(), "/foo",
3578       base::Time(), base::Time(), base::Time(), true /*secure*/,
3579       false /*httponly*/, CookieSameSite::NO_RESTRICTION, COOKIE_PRIORITY_LOW,
3580       true /*same_party*/, absl::nullopt /*partition_key*/, &status);
3581   EXPECT_TRUE(cc);
3582   EXPECT_TRUE(cc->IsSameParty());
3583   EXPECT_TRUE(status.IsInclude());
3584 
3585   // Partitioned
3586   cc = CanonicalCookie::CreateSanitizedCookie(
3587       GURL("https://www.foo.com"), "__Host-A", "B", std::string(), "/",
3588       base::Time(), base::Time(), base::Time(), true /*secure*/,
3589       false /*httponly*/, CookieSameSite::NO_RESTRICTION, COOKIE_PRIORITY_LOW,
3590       false /*same_party*/,
3591       CookiePartitionKey::FromURLForTesting(GURL("https://toplevelsite.com")),
3592       &status);
3593   EXPECT_TRUE(cc);
3594   EXPECT_TRUE(cc->IsPartitioned());
3595   EXPECT_TRUE(status.IsInclude());
3596 }
3597 
3598 // Make sure sanitization and blocking of cookies works correctly.
TEST(CanonicalCookieTest,CreateSanitizedCookie_Logic)3599 TEST(CanonicalCookieTest, CreateSanitizedCookie_Logic) {
3600   base::Time two_hours_ago = base::Time::Now() - base::Hours(2);
3601   base::Time one_hour_ago = base::Time::Now() - base::Hours(1);
3602   base::Time one_hour_from_now = base::Time::Now() + base::Hours(1);
3603   CookieInclusionStatus status;
3604 
3605   // Simple path and domain variations.
3606   EXPECT_TRUE(CanonicalCookie::CreateSanitizedCookie(
3607       GURL("http://www.foo.com/foo"), "A", "B", std::string(), "/foo",
3608       one_hour_ago, one_hour_from_now, base::Time(), false /*secure*/,
3609       false /*httponly*/, CookieSameSite::NO_RESTRICTION,
3610       COOKIE_PRIORITY_DEFAULT, false /*same_party*/,
3611       absl::nullopt /*partition_key*/, &status));
3612   EXPECT_TRUE(status.IsInclude());
3613   EXPECT_TRUE(CanonicalCookie::CreateSanitizedCookie(
3614       GURL("http://www.foo.com/bar"), "C", "D", "www.foo.com", "/",
3615       two_hours_ago, base::Time(), one_hour_ago, false /*secure*/,
3616       true /*httponly*/, CookieSameSite::NO_RESTRICTION,
3617       COOKIE_PRIORITY_DEFAULT, false /*same_party*/,
3618       absl::nullopt /*partition_key*/, &status));
3619   EXPECT_TRUE(status.IsInclude());
3620   EXPECT_TRUE(CanonicalCookie::CreateSanitizedCookie(
3621       GURL("https://www.foo.com"), "E", "F", std::string(), std::string(),
3622       base::Time(), base::Time(), base::Time(), true /*secure*/,
3623       false /*httponly*/, CookieSameSite::NO_RESTRICTION,
3624       COOKIE_PRIORITY_DEFAULT, false /*same_party*/,
3625       absl::nullopt /*partition_key*/, &status));
3626   EXPECT_TRUE(status.IsInclude());
3627 
3628   // Test the file:// protocol.
3629   EXPECT_TRUE(CanonicalCookie::CreateSanitizedCookie(
3630       GURL("file:///"), "A", "B", std::string(), "/foo", one_hour_ago,
3631       one_hour_from_now, base::Time(), false /*secure*/, false /*httponly*/,
3632       CookieSameSite::NO_RESTRICTION, COOKIE_PRIORITY_DEFAULT,
3633       false /*same_party*/, absl::nullopt /*partition_key*/, &status));
3634   EXPECT_TRUE(status.IsInclude());
3635   EXPECT_TRUE(CanonicalCookie::CreateSanitizedCookie(
3636       GURL("file:///home/user/foo.txt"), "A", "B", std::string(), "/foo",
3637       one_hour_ago, one_hour_from_now, base::Time(), false /*secure*/,
3638       false /*httponly*/, CookieSameSite::NO_RESTRICTION,
3639       COOKIE_PRIORITY_DEFAULT, false /*same_party*/,
3640       absl::nullopt /*partition_key*/, &status));
3641   EXPECT_TRUE(status.IsInclude());
3642   EXPECT_FALSE(CanonicalCookie::CreateSanitizedCookie(
3643       GURL("file:///home/user/foo.txt"), "A", "B", "home", "/foo", one_hour_ago,
3644       one_hour_from_now, base::Time(), false /*secure*/, false /*httponly*/,
3645       CookieSameSite::NO_RESTRICTION, COOKIE_PRIORITY_DEFAULT,
3646       false /*same_party*/, absl::nullopt /*partition_key*/, &status));
3647   EXPECT_TRUE(status.HasExactlyExclusionReasonsForTesting(
3648       {CookieInclusionStatus::EXCLUDE_INVALID_DOMAIN}));
3649 
3650   // Test that malformed attributes fail to set the cookie.
3651   EXPECT_FALSE(CanonicalCookie::CreateSanitizedCookie(
3652       GURL("http://www.foo.com/foo"), " A", "B", std::string(), "/foo",
3653       base::Time(), base::Time(), base::Time(), false /*secure*/,
3654       false /*httponly*/, CookieSameSite::NO_RESTRICTION,
3655       COOKIE_PRIORITY_DEFAULT, false /*same_party*/,
3656       absl::nullopt /*partition_key*/, &status));
3657   EXPECT_TRUE(status.HasExactlyExclusionReasonsForTesting(
3658       {CookieInclusionStatus::EXCLUDE_FAILURE_TO_STORE}));
3659   EXPECT_FALSE(CanonicalCookie::CreateSanitizedCookie(
3660       GURL("http://www.foo.com/foo"), "A;", "B", std::string(), "/foo",
3661       base::Time(), base::Time(), base::Time(), false /*secure*/,
3662       false /*httponly*/, CookieSameSite::NO_RESTRICTION,
3663       COOKIE_PRIORITY_DEFAULT, false /*same_party*/,
3664       absl::nullopt /*partition_key*/, &status));
3665   EXPECT_TRUE(status.HasExactlyExclusionReasonsForTesting(
3666       {CookieInclusionStatus::EXCLUDE_FAILURE_TO_STORE}));
3667   EXPECT_FALSE(CanonicalCookie::CreateSanitizedCookie(
3668       GURL("http://www.foo.com/foo"), "A=", "B", std::string(), "/foo",
3669       base::Time(), base::Time(), base::Time(), false /*secure*/,
3670       false /*httponly*/, CookieSameSite::NO_RESTRICTION,
3671       COOKIE_PRIORITY_DEFAULT, false /*same_party*/,
3672       absl::nullopt /*partition_key*/, &status));
3673   EXPECT_TRUE(status.HasExactlyExclusionReasonsForTesting(
3674       {CookieInclusionStatus::EXCLUDE_FAILURE_TO_STORE}));
3675   EXPECT_FALSE(CanonicalCookie::CreateSanitizedCookie(
3676       GURL("http://www.foo.com/foo"), "A\x07", "B", std::string(), "/foo",
3677       one_hour_ago, one_hour_from_now, base::Time(), false /*secure*/,
3678       false /*httponly*/, CookieSameSite::NO_RESTRICTION,
3679       COOKIE_PRIORITY_DEFAULT, false /*same_party*/,
3680       absl::nullopt /*partition_key*/, &status));
3681   EXPECT_TRUE(status.HasExactlyExclusionReasonsForTesting(
3682       {CookieInclusionStatus::EXCLUDE_FAILURE_TO_STORE}));
3683   EXPECT_FALSE(CanonicalCookie::CreateSanitizedCookie(
3684       GURL("http://www.foo.com"), "A", " B", std::string(), "/foo",
3685       base::Time(), base::Time(), base::Time(), false /*secure*/,
3686       false /*httponly*/, CookieSameSite::NO_RESTRICTION,
3687       COOKIE_PRIORITY_DEFAULT, false /*same_party*/,
3688       absl::nullopt /*partition_key*/, &status));
3689   EXPECT_TRUE(status.HasExactlyExclusionReasonsForTesting(
3690       {CookieInclusionStatus::EXCLUDE_FAILURE_TO_STORE}));
3691   EXPECT_FALSE(CanonicalCookie::CreateSanitizedCookie(
3692       GURL("http://www.foo.com"), "A", "\x0fZ", std::string(), "/foo",
3693       base::Time(), base::Time(), base::Time(), false /*secure*/,
3694       false /*httponly*/, CookieSameSite::NO_RESTRICTION,
3695       COOKIE_PRIORITY_DEFAULT, false /*same_party*/,
3696       absl::nullopt /*partition_key*/, &status));
3697   EXPECT_TRUE(status.HasExactlyExclusionReasonsForTesting(
3698       {CookieInclusionStatus::EXCLUDE_FAILURE_TO_STORE}));
3699   EXPECT_FALSE(CanonicalCookie::CreateSanitizedCookie(
3700       GURL("http://www.foo.com"), "A", "B", "www.foo.com ", "/foo",
3701       base::Time(), base::Time(), base::Time(), false /*secure*/,
3702       false /*httponly*/, CookieSameSite::NO_RESTRICTION,
3703       COOKIE_PRIORITY_DEFAULT, false /*same_party*/,
3704       absl::nullopt /*partition_key*/, &status));
3705   EXPECT_TRUE(status.HasExactlyExclusionReasonsForTesting(
3706       {CookieInclusionStatus::EXCLUDE_INVALID_DOMAIN}));
3707   EXPECT_FALSE(CanonicalCookie::CreateSanitizedCookie(
3708       GURL("http://www.foo.com/foo"), "A", "B", "foo.ozzzzzzle", "/foo",
3709       base::Time(), base::Time(), base::Time(), false /*secure*/,
3710       false /*httponly*/, CookieSameSite::NO_RESTRICTION,
3711       COOKIE_PRIORITY_DEFAULT, false /*same_party*/,
3712       absl::nullopt /*partition_key*/, &status));
3713   EXPECT_TRUE(status.HasExactlyExclusionReasonsForTesting(
3714       {CookieInclusionStatus::EXCLUDE_INVALID_DOMAIN}));
3715   EXPECT_FALSE(CanonicalCookie::CreateSanitizedCookie(
3716       GURL("http://www.foo.com/foo"), "A", "B", std::string(), "foo",
3717       base::Time(), base::Time(), base::Time(), false /*secure*/,
3718       false /*httponly*/, CookieSameSite::NO_RESTRICTION,
3719       COOKIE_PRIORITY_DEFAULT, false /*same_party*/,
3720       absl::nullopt /*partition_key*/, &status));
3721   EXPECT_TRUE(status.HasExactlyExclusionReasonsForTesting(
3722       {CookieInclusionStatus::EXCLUDE_FAILURE_TO_STORE}));
3723   EXPECT_FALSE(CanonicalCookie::CreateSanitizedCookie(
3724       GURL("http://www.foo.com"), "A", "B", std::string(), "/foo ",
3725       base::Time(), base::Time(), base::Time(), false /*secure*/,
3726       false /*httponly*/, CookieSameSite::NO_RESTRICTION,
3727       COOKIE_PRIORITY_DEFAULT, false /*same_party*/,
3728       absl::nullopt /*partition_key*/, &status));
3729   EXPECT_TRUE(status.HasExactlyExclusionReasonsForTesting(
3730       {CookieInclusionStatus::EXCLUDE_FAILURE_TO_STORE}));
3731   EXPECT_FALSE(CanonicalCookie::CreateSanitizedCookie(
3732       GURL("http://www.foo.com/foo"), "A", "B", "%2Efoo.com", "/foo",
3733       one_hour_ago, one_hour_from_now, base::Time(), false /*secure*/,
3734       false /*httponly*/, CookieSameSite::NO_RESTRICTION,
3735       COOKIE_PRIORITY_DEFAULT, false /*same_party*/,
3736       absl::nullopt /*partition_key*/, &status));
3737   EXPECT_TRUE(status.HasExactlyExclusionReasonsForTesting(
3738       {CookieInclusionStatus::EXCLUDE_INVALID_DOMAIN}));
3739   EXPECT_FALSE(CanonicalCookie::CreateSanitizedCookie(
3740       GURL("http://domaintest.%E3%81%BF%E3%82%93%E3%81%AA"), "A", "B",
3741       "domaintest.%E3%81%BF%E3%82%93%E3%81%AA", "/foo", base::Time(),
3742       base::Time(), base::Time(), false /*secure*/, false /*httponly*/,
3743       CookieSameSite::NO_RESTRICTION, COOKIE_PRIORITY_DEFAULT,
3744       false /*same_party*/, absl::nullopt /*partition_key*/, &status));
3745   EXPECT_TRUE(status.HasExactlyExclusionReasonsForTesting(
3746       {CookieInclusionStatus::EXCLUDE_INVALID_DOMAIN}));
3747 
3748   std::unique_ptr<CanonicalCookie> cc;
3749 
3750   // Confirm that setting domain cookies with or without leading periods,
3751   // or on domains different from the URL's, functions correctly.
3752   cc = CanonicalCookie::CreateSanitizedCookie(
3753       GURL("http://www.foo.com/foo"), "A", "B", "www.foo.com", "/foo",
3754       one_hour_ago, one_hour_from_now, base::Time(), false /*secure*/,
3755       false /*httponly*/, CookieSameSite::NO_RESTRICTION,
3756       COOKIE_PRIORITY_DEFAULT, false /*same_party*/,
3757       absl::nullopt /*partition_key*/, &status);
3758   ASSERT_TRUE(cc);
3759   EXPECT_TRUE(cc->IsDomainCookie());
3760   EXPECT_EQ(".www.foo.com", cc->Domain());
3761   EXPECT_TRUE(status.IsInclude());
3762 
3763   cc = CanonicalCookie::CreateSanitizedCookie(
3764       GURL("http://www.foo.com/foo"), "A", "B", ".www.foo.com", "/foo",
3765       one_hour_ago, one_hour_from_now, base::Time(), false /*secure*/,
3766       false /*httponly*/, CookieSameSite::NO_RESTRICTION,
3767       COOKIE_PRIORITY_DEFAULT, false /*same_party*/,
3768       absl::nullopt /*partition_key*/, &status);
3769   ASSERT_TRUE(cc);
3770   EXPECT_TRUE(cc->IsDomainCookie());
3771   EXPECT_EQ(".www.foo.com", cc->Domain());
3772   EXPECT_TRUE(status.IsInclude());
3773 
3774   cc = CanonicalCookie::CreateSanitizedCookie(
3775       GURL("http://www.foo.com/foo"), "A", "B", ".foo.com", "/foo",
3776       one_hour_ago, one_hour_from_now, base::Time(), false /*secure*/,
3777       false /*httponly*/, CookieSameSite::NO_RESTRICTION,
3778       COOKIE_PRIORITY_DEFAULT, false /*same_party*/,
3779       absl::nullopt /*partition_key*/, &status);
3780   ASSERT_TRUE(cc);
3781   EXPECT_TRUE(cc->IsDomainCookie());
3782   EXPECT_EQ(".foo.com", cc->Domain());
3783   EXPECT_TRUE(status.IsInclude());
3784 
3785   cc = CanonicalCookie::CreateSanitizedCookie(
3786       GURL("http://www.foo.com/foo"), "A", "B", ".www2.www.foo.com", "/foo",
3787       one_hour_ago, one_hour_from_now, base::Time(), false /*secure*/,
3788       false /*httponly*/, CookieSameSite::NO_RESTRICTION,
3789       COOKIE_PRIORITY_DEFAULT, false /*same_party*/,
3790       absl::nullopt /*partition_key*/, &status);
3791   EXPECT_FALSE(cc);
3792   EXPECT_TRUE(status.HasExactlyExclusionReasonsForTesting(
3793       {CookieInclusionStatus::EXCLUDE_INVALID_DOMAIN}));
3794 
3795   // Secure/URL Scheme mismatch.
3796   EXPECT_FALSE(CanonicalCookie::CreateSanitizedCookie(
3797       GURL("http://www.foo.com"), "A", "B", std::string(), "/foo ",
3798       base::Time(), base::Time(), base::Time(), true /*secure*/,
3799       false /*httponly*/, CookieSameSite::NO_RESTRICTION,
3800       COOKIE_PRIORITY_DEFAULT, false /*same_party*/,
3801       absl::nullopt /*partition_key*/, &status));
3802   EXPECT_TRUE(status.HasExactlyExclusionReasonsForTesting(
3803       {CookieInclusionStatus::EXCLUDE_FAILURE_TO_STORE}));
3804 
3805   // Null creation date/non-null last access date conflict.
3806   EXPECT_FALSE(CanonicalCookie::CreateSanitizedCookie(
3807       GURL("http://www.foo.com"), "A", "B", std::string(), "/foo", base::Time(),
3808       base::Time(), base::Time::Now(), false /*secure*/, false /*httponly*/,
3809       CookieSameSite::NO_RESTRICTION, COOKIE_PRIORITY_DEFAULT,
3810       false /*same_party*/, absl::nullopt /*partition_key*/, &status));
3811   EXPECT_TRUE(status.HasExactlyExclusionReasonsForTesting(
3812       {CookieInclusionStatus::EXCLUDE_FAILURE_TO_STORE}));
3813 
3814   // Domain doesn't match URL
3815   EXPECT_FALSE(CanonicalCookie::CreateSanitizedCookie(
3816       GURL("http://www.foo.com"), "A", "B", "www.bar.com", "/", base::Time(),
3817       base::Time(), base::Time(), false /*secure*/, false /*httponly*/,
3818       CookieSameSite::NO_RESTRICTION, COOKIE_PRIORITY_DEFAULT,
3819       false /*same_party*/, absl::nullopt /*partition_key*/, &status));
3820   EXPECT_TRUE(status.HasExactlyExclusionReasonsForTesting(
3821       {CookieInclusionStatus::EXCLUDE_INVALID_DOMAIN}));
3822 
3823   // Path with unusual characters escaped.
3824   cc = CanonicalCookie::CreateSanitizedCookie(
3825       GURL("http://www.foo.com"), "A", "B", std::string(), "/foo\x7F",
3826       base::Time(), base::Time(), base::Time(), false /*secure*/,
3827       false /*httponly*/, CookieSameSite::NO_RESTRICTION,
3828       COOKIE_PRIORITY_DEFAULT, false /*same_party*/,
3829       absl::nullopt /*partition_key*/, &status);
3830   ASSERT_TRUE(cc);
3831   EXPECT_EQ("/foo%7F", cc->Path());
3832   EXPECT_TRUE(status.IsInclude());
3833 
3834   // Ensure that all characters get escaped the same on all platforms. This is
3835   // also useful for visualizing which characters will actually be escaped.
3836   std::stringstream ss;
3837   ss << "/";
3838   for (uint8_t character = 0; character < 0xFF; character++) {
3839     // Skip any "terminating characters" that CreateSanitizedCookie does not
3840     // allow to be in `path`.
3841     if (character == '\0' || character == '\n' || character == '\r' ||
3842         character == ';') {
3843       continue;
3844     }
3845     ss << character;
3846   }
3847   ss << "\xFF";
3848   std::string initial(ss.str());
3849   std::string expected =
3850       "/%01%02%03%04%05%06%07%08%09%0B%0C%0E%0F%10%11%12%13%14%15%16%17%18%19%"
3851       "1A%1B%1C%1D%1E%1F%20!%22%23$%&'()*+,-./"
3852       "0123456789:%3C=%3E%3F@ABCDEFGHIJKLMNOPQRSTUVWXYZ[/"
3853       "]%5E_%60abcdefghijklmnopqrstuvwxyz%7B%7C%7D~%7F%80%81%82%83%84%85%86%87%"
3854       "88%89%8A%8B%8C%8D%8E%8F%90%91%92%93%94%95%96%97%98%99%9A%9B%9C%9D%9E%9F%"
3855       "A0%A1%A2%A3%A4%A5%A6%A7%A8%A9%AA%AB%AC%AD%AE%AF%B0%B1%B2%B3%B4%B5%B6%B7%"
3856       "B8%B9%BA%BB%BC%BD%BE%BF%C0%C1%C2%C3%C4%C5%C6%C7%C8%C9%CA%CB%CC%CD%CE%CF%"
3857       "D0%D1%D2%D3%D4%D5%D6%D7%D8%D9%DA%DB%DC%DD%DE%DF%E0%E1%E2%E3%E4%E5%E6%E7%"
3858       "E8%E9%EA%EB%EC%ED%EE%EF%F0%F1%F2%F3%F4%F5%F6%F7%F8%F9%FA%FB%FC%FD%FE%FF";
3859   cc = CanonicalCookie::CreateSanitizedCookie(
3860       GURL("http://www.foo.com"), "A", "B", std::string(), initial,
3861       base::Time(), base::Time(), base::Time(), false /*secure*/,
3862       false /*httponly*/, CookieSameSite::NO_RESTRICTION,
3863       COOKIE_PRIORITY_DEFAULT, false /*same_party*/,
3864       absl::nullopt /*partition_key*/, &status);
3865   ASSERT_TRUE(cc);
3866   EXPECT_EQ(expected, cc->Path());
3867   EXPECT_TRUE(status.IsInclude());
3868 
3869   // Empty name and value.
3870   EXPECT_FALSE(CanonicalCookie::CreateSanitizedCookie(
3871       GURL("http://www.foo.com"), "", "", std::string(), "/", base::Time(),
3872       base::Time(), base::Time(), false /*secure*/, false /*httponly*/,
3873       CookieSameSite::NO_RESTRICTION, COOKIE_PRIORITY_DEFAULT,
3874       false /*same_party*/, absl::nullopt /*partition_key*/, &status));
3875   EXPECT_TRUE(status.HasExactlyExclusionReasonsForTesting(
3876       {CookieInclusionStatus::EXCLUDE_FAILURE_TO_STORE}));
3877 
3878   // Check that value can contain an equal sign, even when no name is present.
3879   // Note that in newer drafts of RFC6265bis, it is specified that a cookie with
3880   // an empty name and a value containing an equal sign should result in a
3881   // corresponding cookie line that omits the preceding equal sign. This means
3882   // that the cookie line won't be deserialized into the original cookie in this
3883   // case. For now, we'll test for compliance with the spec here, but we aim to
3884   // collect metrics and hopefully fix this in the spec (and then in
3885   // CanonicalCookie) at some point.
3886   // For reference, see: https://github.com/httpwg/http-extensions/pull/1592
3887   cc = CanonicalCookie::CreateSanitizedCookie(
3888       GURL("http://www.foo.com"), "", "ambiguous=value", std::string(),
3889       std::string(), base::Time(), base::Time(), base::Time(), false /*secure*/,
3890       false /*httponly*/, CookieSameSite::NO_RESTRICTION,
3891       COOKIE_PRIORITY_DEFAULT, false /*same_party*/,
3892       absl::nullopt /*partition_key*/, &status);
3893   EXPECT_TRUE(cc);
3894   std::vector<std::unique_ptr<CanonicalCookie>> cookies;
3895   cookies.push_back(std::move(cc));
3896   MatchCookieLineToVector("ambiguous=value", cookies);
3897 
3898   // Check that name can't contain an equal sign ("ambiguous=name=value" should
3899   // correctly be parsed as name: "ambiguous" and value "name=value", so
3900   // allowing this case would result in cookies that can't serialize correctly).
3901   EXPECT_FALSE(CanonicalCookie::CreateSanitizedCookie(
3902       GURL("http://www.foo.com"), "ambiguous=name", "value", std::string(),
3903       std::string(), base::Time(), base::Time(), base::Time(), false /*secure*/,
3904       false /*httponly*/, CookieSameSite::NO_RESTRICTION,
3905       COOKIE_PRIORITY_DEFAULT, false /*same_party*/,
3906       absl::nullopt /*partition_key*/, &status));
3907   EXPECT_TRUE(status.HasExactlyExclusionReasonsForTesting(
3908       {CookieInclusionStatus::EXCLUDE_FAILURE_TO_STORE}));
3909 
3910   // A __Secure- cookie must be Secure.
3911   EXPECT_TRUE(CanonicalCookie::CreateSanitizedCookie(
3912       GURL("https://www.foo.com"), "__Secure-A", "B", ".www.foo.com", "/",
3913       two_hours_ago, one_hour_from_now, one_hour_ago, true, false,
3914       CookieSameSite::NO_RESTRICTION, CookiePriority::COOKIE_PRIORITY_DEFAULT,
3915       false /*same_party*/, absl::nullopt /*partition_key*/, &status));
3916   EXPECT_TRUE(status.IsInclude());
3917   EXPECT_FALSE(CanonicalCookie::CreateSanitizedCookie(
3918       GURL("https://www.foo.com"), "__Secure-A", "B", ".www.foo.com", "/",
3919       two_hours_ago, one_hour_from_now, one_hour_ago, false, false,
3920       CookieSameSite::NO_RESTRICTION, CookiePriority::COOKIE_PRIORITY_DEFAULT,
3921       false /*same_party*/, absl::nullopt /*partition_key*/, &status));
3922   EXPECT_TRUE(status.HasExactlyExclusionReasonsForTesting(
3923       {CookieInclusionStatus::EXCLUDE_INVALID_PREFIX}));
3924 
3925   // A __Host- cookie must be Secure.
3926   EXPECT_TRUE(CanonicalCookie::CreateSanitizedCookie(
3927       GURL("https://www.foo.com"), "__Host-A", "B", std::string(), "/",
3928       two_hours_ago, one_hour_from_now, one_hour_ago, true, false,
3929       CookieSameSite::NO_RESTRICTION, CookiePriority::COOKIE_PRIORITY_DEFAULT,
3930       false /*same_party*/, absl::nullopt /*partition_key*/, &status));
3931   EXPECT_TRUE(status.IsInclude());
3932   EXPECT_FALSE(CanonicalCookie::CreateSanitizedCookie(
3933       GURL("https://www.foo.com"), "__Host-A", "B", std::string(), "/",
3934       two_hours_ago, one_hour_from_now, one_hour_ago, false, false,
3935       CookieSameSite::NO_RESTRICTION, CookiePriority::COOKIE_PRIORITY_DEFAULT,
3936       false /*same_party*/, absl::nullopt /*partition_key*/, &status));
3937   EXPECT_TRUE(status.HasExactlyExclusionReasonsForTesting(
3938       {CookieInclusionStatus::EXCLUDE_INVALID_PREFIX}));
3939 
3940   // A __Host- cookie must have path "/".
3941   EXPECT_TRUE(CanonicalCookie::CreateSanitizedCookie(
3942       GURL("https://www.foo.com"), "__Host-A", "B", std::string(), "/",
3943       two_hours_ago, one_hour_from_now, one_hour_ago, true, false,
3944       CookieSameSite::NO_RESTRICTION, CookiePriority::COOKIE_PRIORITY_DEFAULT,
3945       false /*same_party*/, absl::nullopt /*partition_key*/, &status));
3946   EXPECT_TRUE(status.IsInclude());
3947   EXPECT_FALSE(CanonicalCookie::CreateSanitizedCookie(
3948       GURL("https://www.foo.com"), "__Host-A", "B", std::string(), "/foo",
3949       two_hours_ago, one_hour_from_now, one_hour_ago, true, false,
3950       CookieSameSite::NO_RESTRICTION, CookiePriority::COOKIE_PRIORITY_DEFAULT,
3951       false /*same_party*/, absl::nullopt /*partition_key*/, &status));
3952   EXPECT_TRUE(status.HasExactlyExclusionReasonsForTesting(
3953       {CookieInclusionStatus::EXCLUDE_INVALID_PREFIX}));
3954 
3955   // A __Host- cookie must not specify a domain.
3956   EXPECT_TRUE(CanonicalCookie::CreateSanitizedCookie(
3957       GURL("https://www.foo.com"), "__Host-A", "B", std::string(), "/",
3958       two_hours_ago, one_hour_from_now, one_hour_ago, true, false,
3959       CookieSameSite::NO_RESTRICTION, CookiePriority::COOKIE_PRIORITY_DEFAULT,
3960       false /*same_party*/, absl::nullopt /*partition_key*/, &status));
3961   EXPECT_TRUE(status.IsInclude());
3962   EXPECT_FALSE(CanonicalCookie::CreateSanitizedCookie(
3963       GURL("https://www.foo.com"), "__Host-A", "B", ".www.foo.com", "/",
3964       two_hours_ago, one_hour_from_now, one_hour_ago, true, false,
3965       CookieSameSite::NO_RESTRICTION, CookiePriority::COOKIE_PRIORITY_DEFAULT,
3966       false /*same_party*/, absl::nullopt /*partition_key*/, &status));
3967   EXPECT_TRUE(status.HasExactlyExclusionReasonsForTesting(
3968       {CookieInclusionStatus::EXCLUDE_INVALID_PREFIX}));
3969 
3970   // Without __Host- prefix, this is a valid host cookie because it does not
3971   // specify a domain.
3972   EXPECT_TRUE(CanonicalCookie::CreateSanitizedCookie(
3973       GURL("https://www.foo.com"), "A", "B", std::string(), "/", two_hours_ago,
3974       one_hour_from_now, one_hour_ago, true, false,
3975       CookieSameSite::NO_RESTRICTION, CookiePriority::COOKIE_PRIORITY_DEFAULT,
3976       false /*same_party*/, absl::nullopt /*partition_key*/, &status));
3977   EXPECT_TRUE(status.IsInclude());
3978 
3979   // Without __Host- prefix, this is a valid domain (not host) cookie.
3980   EXPECT_TRUE(CanonicalCookie::CreateSanitizedCookie(
3981       GURL("https://www.foo.com"), "A", "B", ".www.foo.com", "/", two_hours_ago,
3982       one_hour_from_now, one_hour_ago, true, false,
3983       CookieSameSite::NO_RESTRICTION, CookiePriority::COOKIE_PRIORITY_DEFAULT,
3984       false /*same_party*/, absl::nullopt /*partition_key*/, &status));
3985   EXPECT_TRUE(status.IsInclude());
3986 
3987   // The __Host- prefix should not prevent otherwise-valid host cookies from
3988   // being accepted.
3989   EXPECT_TRUE(CanonicalCookie::CreateSanitizedCookie(
3990       GURL("https://127.0.0.1"), "A", "B", std::string(), "/", two_hours_ago,
3991       one_hour_from_now, one_hour_ago, true, false,
3992       CookieSameSite::NO_RESTRICTION, CookiePriority::COOKIE_PRIORITY_DEFAULT,
3993       false /*same_party*/, absl::nullopt /*partition_key*/, &status));
3994   EXPECT_TRUE(status.IsInclude());
3995   EXPECT_TRUE(CanonicalCookie::CreateSanitizedCookie(
3996       GURL("https://127.0.0.1"), "__Host-A", "B", std::string(), "/",
3997       two_hours_ago, one_hour_from_now, one_hour_ago, true, false,
3998       CookieSameSite::NO_RESTRICTION, CookiePriority::COOKIE_PRIORITY_DEFAULT,
3999       false /*same_party*/, absl::nullopt /*partition_key*/, &status));
4000   EXPECT_TRUE(status.IsInclude());
4001 
4002   // Host cookies should not specify domain unless it is an IP address that
4003   // matches the URL.
4004   EXPECT_TRUE(CanonicalCookie::CreateSanitizedCookie(
4005       GURL("https://127.0.0.1"), "A", "B", "127.0.0.1", "/", two_hours_ago,
4006       one_hour_from_now, one_hour_ago, true, false,
4007       CookieSameSite::NO_RESTRICTION, CookiePriority::COOKIE_PRIORITY_DEFAULT,
4008       false /*same_party*/, absl::nullopt /*partition_key*/, &status));
4009   EXPECT_TRUE(status.IsInclude());
4010   EXPECT_TRUE(CanonicalCookie::CreateSanitizedCookie(
4011       GURL("https://127.0.0.1"), "__Host-A", "B", "127.0.0.1", "/",
4012       two_hours_ago, one_hour_from_now, one_hour_ago, true, false,
4013       CookieSameSite::NO_RESTRICTION, CookiePriority::COOKIE_PRIORITY_DEFAULT,
4014       false /*same_party*/, absl::nullopt /*partition_key*/, &status));
4015   EXPECT_TRUE(status.IsInclude());
4016 
4017   // Cookies with hidden prefixes should be rejected.
4018 
4019   EXPECT_FALSE(CanonicalCookie::CreateSanitizedCookie(
4020       GURL("https://www.foo.com"), "", "__Host-A=B", "", "/", two_hours_ago,
4021       one_hour_from_now, one_hour_ago, true, false,
4022       CookieSameSite::NO_RESTRICTION, CookiePriority::COOKIE_PRIORITY_DEFAULT,
4023       false /*same_party*/, absl::nullopt /*partition_key*/, &status));
4024   EXPECT_TRUE(status.HasExactlyExclusionReasonsForTesting(
4025       {CookieInclusionStatus::EXCLUDE_INVALID_PREFIX}));
4026 
4027   EXPECT_FALSE(CanonicalCookie::CreateSanitizedCookie(
4028       GURL("https://www.foo.com"), "", "__Host-A", "", "/", two_hours_ago,
4029       one_hour_from_now, one_hour_ago, true, false,
4030       CookieSameSite::NO_RESTRICTION, CookiePriority::COOKIE_PRIORITY_DEFAULT,
4031       false /*same_party*/, absl::nullopt /*partition_key*/, &status));
4032   EXPECT_TRUE(status.HasExactlyExclusionReasonsForTesting(
4033       {CookieInclusionStatus::EXCLUDE_INVALID_PREFIX}));
4034 
4035   EXPECT_FALSE(CanonicalCookie::CreateSanitizedCookie(
4036       GURL("https://www.foo.com"), "", "__Secure-A=B", "", "/", two_hours_ago,
4037       one_hour_from_now, one_hour_ago, true, false,
4038       CookieSameSite::NO_RESTRICTION, CookiePriority::COOKIE_PRIORITY_DEFAULT,
4039       false /*same_party*/, absl::nullopt /*partition_key*/, &status));
4040   EXPECT_TRUE(status.HasExactlyExclusionReasonsForTesting(
4041       {CookieInclusionStatus::EXCLUDE_INVALID_PREFIX}));
4042 
4043   EXPECT_FALSE(CanonicalCookie::CreateSanitizedCookie(
4044       GURL("https://www.foo.com"), "", "__Secure-A", "", "/", two_hours_ago,
4045       one_hour_from_now, one_hour_ago, true, false,
4046       CookieSameSite::NO_RESTRICTION, CookiePriority::COOKIE_PRIORITY_DEFAULT,
4047       false /*same_party*/, absl::nullopt /*partition_key*/, &status));
4048   EXPECT_TRUE(status.HasExactlyExclusionReasonsForTesting(
4049       {CookieInclusionStatus::EXCLUDE_INVALID_PREFIX}));
4050 
4051   // While tricky, this aren't considered hidden prefixes and should succeed.
4052   EXPECT_TRUE(CanonicalCookie::CreateSanitizedCookie(
4053       GURL("https://www.foo.com"), "A", "__Host-A=B", "", "/", two_hours_ago,
4054       one_hour_from_now, one_hour_ago, true, false,
4055       CookieSameSite::NO_RESTRICTION, CookiePriority::COOKIE_PRIORITY_DEFAULT,
4056       false /*same_party*/, absl::nullopt /*partition_key*/, &status));
4057   EXPECT_TRUE(status.IsInclude());
4058 
4059   EXPECT_TRUE(CanonicalCookie::CreateSanitizedCookie(
4060       GURL("https://www.foo.com"), "A", "__Secure-A=B", "", "/", two_hours_ago,
4061       one_hour_from_now, one_hour_ago, true, false,
4062       CookieSameSite::NO_RESTRICTION, CookiePriority::COOKIE_PRIORITY_DEFAULT,
4063       false /*same_party*/, absl::nullopt /*partition_key*/, &status));
4064   EXPECT_TRUE(status.IsInclude());
4065 
4066   // SameParty attribute requires Secure and forbids SameSite=Strict.
4067   EXPECT_TRUE(CanonicalCookie::CreateSanitizedCookie(
4068       GURL("https://www.foo.com"), "A", "B", ".www.foo.com", "/", two_hours_ago,
4069       one_hour_from_now, one_hour_ago, true /*secure*/, false,
4070       CookieSameSite::NO_RESTRICTION, CookiePriority::COOKIE_PRIORITY_DEFAULT,
4071       true /*same_party*/, absl::nullopt /*partition_key*/, &status));
4072   EXPECT_TRUE(status.IsInclude());
4073   EXPECT_FALSE(CanonicalCookie::CreateSanitizedCookie(
4074       GURL("https://www.foo.com"), "A", "B", ".www.foo.com", "/", two_hours_ago,
4075       one_hour_from_now, one_hour_ago, false /*secure*/, false,
4076       CookieSameSite::LAX_MODE, CookiePriority::COOKIE_PRIORITY_DEFAULT,
4077       true /*same_party*/, absl::nullopt /*partition_key*/, &status));
4078   EXPECT_TRUE(status.HasExactlyExclusionReasonsForTesting(
4079       {CookieInclusionStatus::EXCLUDE_INVALID_SAMEPARTY}));
4080   EXPECT_FALSE(CanonicalCookie::CreateSanitizedCookie(
4081       GURL("https://www.foo.com"), "A", "B", ".www.foo.com", "/", two_hours_ago,
4082       one_hour_from_now, one_hour_ago, true /*secure*/, false,
4083       CookieSameSite::STRICT_MODE, CookiePriority::COOKIE_PRIORITY_DEFAULT,
4084       true /*same_party*/, absl::nullopt /*partition_key*/, &status));
4085   EXPECT_TRUE(status.HasExactlyExclusionReasonsForTesting(
4086       {CookieInclusionStatus::EXCLUDE_INVALID_SAMEPARTY}));
4087   EXPECT_FALSE(CanonicalCookie::CreateSanitizedCookie(
4088       GURL("https://www.foo.com"), "A", "B", ".www.foo.com", "/", two_hours_ago,
4089       one_hour_from_now, one_hour_ago, false /*secure*/, false,
4090       CookieSameSite::STRICT_MODE, CookiePriority::COOKIE_PRIORITY_DEFAULT,
4091       true /*same_party*/, absl::nullopt /*partition_key*/, &status));
4092   EXPECT_TRUE(status.HasExactlyExclusionReasonsForTesting(
4093       {CookieInclusionStatus::EXCLUDE_INVALID_SAMEPARTY}));
4094 
4095   // Partitioned attribute requires __Host- and forbids SameParty.
4096   status = CookieInclusionStatus();
4097   EXPECT_TRUE(CanonicalCookie::CreateSanitizedCookie(
4098       GURL("https://www.foo.com"), "__Host-A", "B", std::string(), "/",
4099       two_hours_ago, one_hour_from_now, one_hour_ago, true /*secure*/, false,
4100       CookieSameSite::NO_RESTRICTION, CookiePriority::COOKIE_PRIORITY_DEFAULT,
4101       false /*same_party*/,
4102       absl::optional<CookiePartitionKey>(CookiePartitionKey::FromURLForTesting(
4103           GURL("https://toplevelsite.com"))),
4104       &status));
4105   EXPECT_TRUE(status.IsInclude());
4106   // No __Host- prefix is still valid if the cookie still has Secure, Path=/,
4107   // and no Domain.
4108   EXPECT_TRUE(CanonicalCookie::CreateSanitizedCookie(
4109       GURL("https://www.foo.com"), "A", "B", std::string(), "/", two_hours_ago,
4110       one_hour_from_now, one_hour_ago, true /*secure*/, false,
4111       CookieSameSite::NO_RESTRICTION, CookiePriority::COOKIE_PRIORITY_DEFAULT,
4112       false /*same_party*/,
4113       absl::optional<CookiePartitionKey>(CookiePartitionKey::FromURLForTesting(
4114           GURL("https://toplevelsite.com"))),
4115       &status));
4116   EXPECT_TRUE(status.IsInclude());
4117   status = CookieInclusionStatus();
4118   // Invalid: Not Secure.
4119   status = CookieInclusionStatus();
4120   EXPECT_FALSE(CanonicalCookie::CreateSanitizedCookie(
4121       GURL("https://www.foo.com"), "A", "B", std::string(), "/", two_hours_ago,
4122       one_hour_from_now, one_hour_ago, /*secure=*/false, /*http_only=*/false,
4123       CookieSameSite::LAX_MODE, CookiePriority::COOKIE_PRIORITY_DEFAULT,
4124       /*same_party=*/false,
4125       absl::optional<CookiePartitionKey>(CookiePartitionKey::FromURLForTesting(
4126           GURL("https://toplevelsite.com"))),
4127       &status));
4128   EXPECT_TRUE(status.HasExactlyExclusionReasonsForTesting(
4129       {CookieInclusionStatus::EXCLUDE_INVALID_PARTITIONED}));
4130   // Invalid: invalid Path.
4131   status = CookieInclusionStatus();
4132   EXPECT_TRUE(CanonicalCookie::CreateSanitizedCookie(
4133       GURL("https://www.foo.com"), "A", "B", std::string(), "/foobar",
4134       two_hours_ago, one_hour_from_now, one_hour_ago, /*secure=*/true,
4135       /*http_only=*/false, CookieSameSite::NO_RESTRICTION,
4136       CookiePriority::COOKIE_PRIORITY_DEFAULT,
4137       /*same_party=*/false,
4138       absl::optional<CookiePartitionKey>(CookiePartitionKey::FromURLForTesting(
4139           GURL("https://toplevelsite.com"))),
4140       &status));
4141   EXPECT_TRUE(status.IsInclude());
4142   // Domain attribute present is still valid.
4143   status = CookieInclusionStatus();
4144   EXPECT_TRUE(CanonicalCookie::CreateSanitizedCookie(
4145       GURL("https://www.foo.com"), "A", "B", ".foo.com", "/", two_hours_ago,
4146       one_hour_from_now, one_hour_ago, /*secure=*/true, /*http_only=*/false,
4147       CookieSameSite::NO_RESTRICTION, CookiePriority::COOKIE_PRIORITY_DEFAULT,
4148       /*same_party=*/false,
4149       absl::optional<CookiePartitionKey>(CookiePartitionKey::FromURLForTesting(
4150           GURL("https://toplevelsite.com"))),
4151       &status));
4152   EXPECT_TRUE(status.IsInclude());
4153 
4154   status = CookieInclusionStatus();
4155 
4156   // Check that CreateSanitizedCookie can gracefully fail on inputs that would
4157   // crash cookie_util::GetCookieDomainWithString due to failing
4158   // DCHECKs. Specifically, GetCookieDomainWithString requires that if the
4159   // domain is empty or the URL's host matches the domain, then the URL's host
4160   // must pass DomainIsHostOnly; it must not begin with a period.
4161   EXPECT_FALSE(CanonicalCookie::CreateSanitizedCookie(
4162       GURL("http://..."), "A", "B", "...", "/", base::Time(), base::Time(),
4163       base::Time(), false /*secure*/, false /*httponly*/,
4164       CookieSameSite::NO_RESTRICTION, COOKIE_PRIORITY_DEFAULT,
4165       false /*same_party*/, absl::nullopt /*partition_key*/, &status));
4166   EXPECT_TRUE(status.HasExactlyExclusionReasonsForTesting(
4167       {CookieInclusionStatus::EXCLUDE_INVALID_DOMAIN}));
4168   EXPECT_FALSE(CanonicalCookie::CreateSanitizedCookie(
4169       GURL("http://."), "A", "B", std::string(), "/", base::Time(),
4170       base::Time(), base::Time(), false /*secure*/, false /*httponly*/,
4171       CookieSameSite::NO_RESTRICTION, COOKIE_PRIORITY_DEFAULT,
4172       false /*same_party*/, absl::nullopt /*partition_key*/, &status));
4173   EXPECT_TRUE(status.HasExactlyExclusionReasonsForTesting(
4174       {CookieInclusionStatus::EXCLUDE_INVALID_DOMAIN}));
4175   EXPECT_FALSE(CanonicalCookie::CreateSanitizedCookie(
4176       GURL("http://.chromium.org"), "A", "B", ".chromium.org", "/",
4177       base::Time(), base::Time(), base::Time(), false /*secure*/,
4178       false /*httponly*/, CookieSameSite::NO_RESTRICTION,
4179       COOKIE_PRIORITY_DEFAULT, false /*same_party*/,
4180       absl::nullopt /*partition_key*/, &status));
4181   EXPECT_TRUE(status.HasExactlyExclusionReasonsForTesting(
4182       {CookieInclusionStatus::EXCLUDE_INVALID_DOMAIN}));
4183 
4184   // Check that a file URL with an IPv6 host, and matching IPv6 domain, are
4185   // valid.
4186   EXPECT_TRUE(CanonicalCookie::CreateSanitizedCookie(
4187       GURL("file://[A::]"), "A", "B", "[A::]", "", base::Time(), base::Time(),
4188       base::Time(), false /*secure*/, false /*httponly*/,
4189       CookieSameSite::NO_RESTRICTION, COOKIE_PRIORITY_DEFAULT,
4190       false /*same_party*/, absl::nullopt /*partition_key*/, &status));
4191   EXPECT_TRUE(status.IsInclude());
4192 
4193   // On Windows, URLs beginning with two backslashes are considered file
4194   // URLs. On other platforms, they are invalid.
4195   auto double_backslash_ipv6_cookie = CanonicalCookie::CreateSanitizedCookie(
4196       GURL("\\\\[A::]"), "A", "B", "[A::]", "", base::Time(), base::Time(),
4197       base::Time(), false /*secure*/, false /*httponly*/,
4198       CookieSameSite::NO_RESTRICTION, COOKIE_PRIORITY_DEFAULT,
4199       false /*same_party*/, absl::nullopt /*partition_key*/, &status);
4200 #if BUILDFLAG(IS_WIN)
4201   EXPECT_TRUE(double_backslash_ipv6_cookie);
4202   EXPECT_TRUE(double_backslash_ipv6_cookie->IsCanonical());
4203   EXPECT_TRUE(status.IsInclude());
4204 #else
4205   EXPECT_FALSE(double_backslash_ipv6_cookie);
4206   EXPECT_TRUE(status.HasExactlyExclusionReasonsForTesting(
4207       {CookieInclusionStatus::EXCLUDE_INVALID_DOMAIN}));
4208 #endif
4209 
4210   // Confirm multiple error types can be set.
4211   EXPECT_FALSE(CanonicalCookie::CreateSanitizedCookie(
4212       GURL(""), "", "", "", "", base::Time(), base::Time(), base::Time::Now(),
4213       true /*secure*/, true /*httponly*/, CookieSameSite::STRICT_MODE,
4214       COOKIE_PRIORITY_DEFAULT, true /*same_party*/,
4215       absl::nullopt /*partition_key*/, &status));
4216   EXPECT_TRUE(status.HasExactlyExclusionReasonsForTesting(
4217       {CookieInclusionStatus::EXCLUDE_FAILURE_TO_STORE,
4218        CookieInclusionStatus::EXCLUDE_INVALID_DOMAIN,
4219        CookieInclusionStatus::EXCLUDE_INVALID_SAMEPARTY}));
4220 
4221   // Check that RFC6265bis name + value string length limits are enforced.
4222   std::string max_name(ParsedCookie::kMaxCookieNamePlusValueSize, 'a');
4223   std::string max_value(ParsedCookie::kMaxCookieNamePlusValueSize, 'b');
4224   std::string almost_max_name = max_name.substr(1, std::string::npos);
4225   std::string almost_max_value = max_value.substr(1, std::string::npos);
4226 
4227   EXPECT_TRUE(CanonicalCookie::CreateSanitizedCookie(
4228       GURL("http://www.foo.com/foo"), max_name, "", std::string(), "/foo",
4229       one_hour_ago, one_hour_from_now, base::Time(), false /*secure*/,
4230       false /*httponly*/, CookieSameSite::NO_RESTRICTION,
4231       COOKIE_PRIORITY_DEFAULT, false /*same_party*/,
4232       absl::nullopt /*partition_key*/, &status));
4233   EXPECT_TRUE(status.IsInclude());
4234   EXPECT_TRUE(CanonicalCookie::CreateSanitizedCookie(
4235       GURL("http://www.foo.com/foo"), "", max_value, std::string(), "/foo",
4236       one_hour_ago, one_hour_from_now, base::Time(), false /*secure*/,
4237       false /*httponly*/, CookieSameSite::NO_RESTRICTION,
4238       COOKIE_PRIORITY_DEFAULT, false /*same_party*/,
4239       absl::nullopt /*partition_key*/, &status));
4240   EXPECT_TRUE(status.IsInclude());
4241   EXPECT_TRUE(CanonicalCookie::CreateSanitizedCookie(
4242       GURL("http://www.foo.com/foo"), almost_max_name, "b", std::string(),
4243       "/foo", one_hour_ago, one_hour_from_now, base::Time(), false /*secure*/,
4244       false /*httponly*/, CookieSameSite::NO_RESTRICTION,
4245       COOKIE_PRIORITY_DEFAULT, false /*same_party*/,
4246       absl::nullopt /*partition_key*/, &status));
4247   EXPECT_TRUE(status.IsInclude());
4248   EXPECT_TRUE(CanonicalCookie::CreateSanitizedCookie(
4249       GURL("http://www.foo.com/foo"), "a", almost_max_value, std::string(),
4250       "/foo", one_hour_ago, one_hour_from_now, base::Time(), false /*secure*/,
4251       false /*httponly*/, CookieSameSite::NO_RESTRICTION,
4252       COOKIE_PRIORITY_DEFAULT, false /*same_party*/,
4253       absl::nullopt /*partition_key*/, &status));
4254   EXPECT_TRUE(status.IsInclude());
4255 
4256   cc = CanonicalCookie::CreateSanitizedCookie(
4257       GURL("http://www.foo.com/foo"), max_name, "X", std::string(), "/foo",
4258       one_hour_ago, one_hour_from_now, base::Time(), false /*secure*/,
4259       false /*httponly*/, CookieSameSite::NO_RESTRICTION,
4260       COOKIE_PRIORITY_DEFAULT, false /*same_party*/,
4261       absl::nullopt /*partition_key*/, &status);
4262   EXPECT_FALSE(cc);
4263   EXPECT_TRUE(status.HasExactlyExclusionReasonsForTesting(
4264       {CookieInclusionStatus::EXCLUDE_NAME_VALUE_PAIR_EXCEEDS_MAX_SIZE}));
4265 
4266   cc = CanonicalCookie::CreateSanitizedCookie(
4267       GURL("http://www.foo.com/foo"), "X", max_value, std::string(), "/foo",
4268       one_hour_ago, one_hour_from_now, base::Time(), false /*secure*/,
4269       false /*httponly*/, CookieSameSite::NO_RESTRICTION,
4270       COOKIE_PRIORITY_DEFAULT, false /*same_party*/,
4271       absl::nullopt /*partition_key*/, &status);
4272   EXPECT_FALSE(cc);
4273   EXPECT_TRUE(status.HasExactlyExclusionReasonsForTesting(
4274       {CookieInclusionStatus::EXCLUDE_NAME_VALUE_PAIR_EXCEEDS_MAX_SIZE}));
4275 
4276   // Check that the RFC6265bis attribute value size limits apply to the Path
4277   // attribute value.
4278   std::string almost_max_path(ParsedCookie::kMaxCookieAttributeValueSize - 1,
4279                               'c');
4280   std::string max_path = "/" + almost_max_path;
4281   std::string too_long_path = "/X" + almost_max_path;
4282 
4283   cc = CanonicalCookie::CreateSanitizedCookie(
4284       GURL("http://www.foo.com" + max_path), "name", "value", std::string(),
4285       max_path, one_hour_ago, one_hour_from_now, base::Time(), false /*secure*/,
4286       false /*httponly*/, CookieSameSite::NO_RESTRICTION,
4287       COOKIE_PRIORITY_DEFAULT, false /*same_party*/,
4288       absl::nullopt /*partition_key*/, &status);
4289   EXPECT_TRUE(cc);
4290   EXPECT_EQ(max_path, cc->Path());
4291   EXPECT_TRUE(status.IsInclude());
4292 
4293   cc = CanonicalCookie::CreateSanitizedCookie(
4294       GURL("http://www.foo.com/path-attr-from-url/"), "name", "value",
4295       std::string(), too_long_path, one_hour_ago, one_hour_from_now,
4296       base::Time(), false /*secure*/, false /*httponly*/,
4297       CookieSameSite::NO_RESTRICTION, COOKIE_PRIORITY_DEFAULT,
4298       false /*same_party*/, absl::nullopt /*partition_key*/, &status);
4299   EXPECT_FALSE(cc);
4300   EXPECT_TRUE(status.HasExactlyExclusionReasonsForTesting(
4301       {CookieInclusionStatus::EXCLUDE_ATTRIBUTE_VALUE_EXCEEDS_MAX_SIZE}));
4302 
4303   // Check that length limits on the Path attribute value are not enforced
4304   // in the case where no Path attribute is specified and the path value is
4305   // implicitly set from the URL.
4306   cc = CanonicalCookie::CreateSanitizedCookie(
4307       GURL("http://www.foo.com" + too_long_path + "/"), "name", "value",
4308       std::string(), std::string(), one_hour_ago, one_hour_from_now,
4309       base::Time(), false /*secure*/, false /*httponly*/,
4310       CookieSameSite::NO_RESTRICTION, COOKIE_PRIORITY_DEFAULT,
4311       false /*same_party*/, absl::nullopt /*partition_key*/, &status);
4312   EXPECT_TRUE(cc);
4313   EXPECT_EQ(too_long_path, cc->Path());
4314   EXPECT_TRUE(status.IsInclude());
4315 
4316   // The Path attribute value gets URL-encoded, so ensure that the size
4317   // limit is enforced after this (to avoid setting cookies where the Path
4318   // attribute value would otherwise exceed the lengths specified in the
4319   // RFC).
4320   std::string expanding_path(ParsedCookie::kMaxCookieAttributeValueSize / 2,
4321                              '#');
4322   expanding_path = "/" + expanding_path;
4323 
4324   cc = CanonicalCookie::CreateSanitizedCookie(
4325       GURL("http://www.foo.com/path-attr-from-url/"), "name", "value",
4326       std::string(), expanding_path, one_hour_ago, one_hour_from_now,
4327       base::Time(), false /*secure*/, false /*httponly*/,
4328       CookieSameSite::NO_RESTRICTION, COOKIE_PRIORITY_DEFAULT,
4329       false /*same_party*/, absl::nullopt /*partition_key*/, &status);
4330   EXPECT_FALSE(cc);
4331   EXPECT_TRUE(status.HasExactlyExclusionReasonsForTesting(
4332       {CookieInclusionStatus::EXCLUDE_ATTRIBUTE_VALUE_EXCEEDS_MAX_SIZE}));
4333 
4334   // Check that the RFC6265bis attribute value size limits apply to the Domain
4335   // attribute value.
4336   std::string max_domain(ParsedCookie::kMaxCookieAttributeValueSize, 'd');
4337   max_domain.replace(ParsedCookie::kMaxCookieAttributeValueSize - 4, 4, ".com");
4338   std::string too_long_domain = "x" + max_domain;
4339 
4340   cc = CanonicalCookie::CreateSanitizedCookie(
4341       GURL("http://" + max_domain + "/"), "name", "value", max_domain, "/",
4342       one_hour_ago, one_hour_from_now, base::Time(), false /*secure*/,
4343       false /*httponly*/, CookieSameSite::NO_RESTRICTION,
4344       COOKIE_PRIORITY_DEFAULT, false /*same_party*/,
4345       absl::nullopt /*partition_key*/, &status);
4346   EXPECT_TRUE(cc);
4347   EXPECT_EQ(max_domain, cc->DomainWithoutDot());
4348   EXPECT_TRUE(status.IsInclude());
4349   cc = CanonicalCookie::CreateSanitizedCookie(
4350       GURL("http://www.domain-from-url.com/"), "name", "value", too_long_domain,
4351       "/", one_hour_ago, one_hour_from_now, base::Time(), false /*secure*/,
4352       false /*httponly*/, CookieSameSite::NO_RESTRICTION,
4353       COOKIE_PRIORITY_DEFAULT, false /*same_party*/,
4354       absl::nullopt /*partition_key*/, &status);
4355   EXPECT_FALSE(cc);
4356   EXPECT_TRUE(status.HasExactlyExclusionReasonsForTesting(
4357       {CookieInclusionStatus::EXCLUDE_ATTRIBUTE_VALUE_EXCEEDS_MAX_SIZE}));
4358   // Check that length limits on the Domain attribute value are not enforced
4359   // in the case where no Domain attribute is specified and the domain value
4360   // is implicitly set from the URL.
4361   cc = CanonicalCookie::CreateSanitizedCookie(
4362       GURL("http://" + too_long_domain + "/"), "name", "value", std::string(),
4363       "/", one_hour_ago, one_hour_from_now, base::Time(), false /*secure*/,
4364       false /*httponly*/, CookieSameSite::NO_RESTRICTION,
4365       COOKIE_PRIORITY_DEFAULT, false /*same_party*/,
4366       absl::nullopt /*partition_key*/, &status);
4367   EXPECT_TRUE(cc);
4368   EXPECT_EQ(too_long_domain, cc->DomainWithoutDot());
4369   EXPECT_TRUE(status.IsInclude());
4370 }
4371 
TEST(CanonicalCookieTest,FromStorage)4372 TEST(CanonicalCookieTest, FromStorage) {
4373   base::Time two_hours_ago = base::Time::Now() - base::Hours(2);
4374   base::Time one_hour_ago = base::Time::Now() - base::Hours(1);
4375   base::Time one_hour_from_now = base::Time::Now() + base::Hours(1);
4376 
4377   std::unique_ptr<CanonicalCookie> cc = CanonicalCookie::FromStorage(
4378       "A", "B", "www.foo.com", "/bar", two_hours_ago, one_hour_from_now,
4379       one_hour_ago, one_hour_ago, false /*secure*/, false /*httponly*/,
4380       CookieSameSite::NO_RESTRICTION, COOKIE_PRIORITY_DEFAULT,
4381       false /*same_party*/, absl::nullopt /*partition_key*/,
4382       CookieSourceScheme::kSecure, 87);
4383   EXPECT_TRUE(cc);
4384   EXPECT_EQ("A", cc->Name());
4385   EXPECT_EQ("B", cc->Value());
4386   EXPECT_EQ("www.foo.com", cc->Domain());
4387   EXPECT_EQ("/bar", cc->Path());
4388   EXPECT_EQ(two_hours_ago, cc->CreationDate());
4389   EXPECT_EQ(one_hour_ago, cc->LastAccessDate());
4390   EXPECT_EQ(one_hour_from_now, cc->ExpiryDate());
4391   EXPECT_EQ(one_hour_ago, cc->LastUpdateDate());
4392   EXPECT_FALSE(cc->IsSecure());
4393   EXPECT_FALSE(cc->IsHttpOnly());
4394   EXPECT_EQ(CookieSameSite::NO_RESTRICTION, cc->SameSite());
4395   EXPECT_EQ(COOKIE_PRIORITY_MEDIUM, cc->Priority());
4396   EXPECT_EQ(CookieSourceScheme::kSecure, cc->SourceScheme());
4397   EXPECT_FALSE(cc->IsDomainCookie());
4398   EXPECT_EQ(cc->SourcePort(), 87);
4399 
4400   // Should return nullptr when the cookie is not canonical.
4401   // In this case the cookie is not canonical because its name attribute
4402   // contains a newline character.
4403   EXPECT_FALSE(CanonicalCookie::FromStorage(
4404       "A\n", "B", "www.foo.com", "/bar", two_hours_ago, one_hour_from_now,
4405       one_hour_ago, one_hour_ago, false /*secure*/, false /*httponly*/,
4406       CookieSameSite::NO_RESTRICTION, COOKIE_PRIORITY_DEFAULT,
4407       false /*same_party*/, absl::nullopt /*partition_key*/,
4408       CookieSourceScheme::kSecure, 80));
4409 
4410   // If the port information gets corrupted out of the valid range
4411   // FromStorage() should result in a PORT_INVALID.
4412   std::unique_ptr<CanonicalCookie> cc2 = CanonicalCookie::FromStorage(
4413       "A", "B", "www.foo.com", "/bar", two_hours_ago, one_hour_from_now,
4414       one_hour_ago, one_hour_ago, false /*secure*/, false /*httponly*/,
4415       CookieSameSite::NO_RESTRICTION, COOKIE_PRIORITY_DEFAULT,
4416       false /*same_party*/, absl::nullopt /*partition_key*/,
4417       CookieSourceScheme::kSecure, 80000);
4418 
4419   EXPECT_EQ(cc2->SourcePort(), url::PORT_INVALID);
4420 
4421   // Test port edge cases: unspecified.
4422   std::unique_ptr<CanonicalCookie> cc3 = CanonicalCookie::FromStorage(
4423       "A", "B", "www.foo.com", "/bar", two_hours_ago, one_hour_from_now,
4424       one_hour_ago, one_hour_ago, false /*secure*/, false /*httponly*/,
4425       CookieSameSite::NO_RESTRICTION, COOKIE_PRIORITY_DEFAULT,
4426       false /*same_party*/, absl::nullopt /*partition_key*/,
4427       CookieSourceScheme::kSecure, url::PORT_UNSPECIFIED);
4428   EXPECT_EQ(cc3->SourcePort(), url::PORT_UNSPECIFIED);
4429 
4430   // Test port edge cases: invalid.
4431   std::unique_ptr<CanonicalCookie> cc4 = CanonicalCookie::FromStorage(
4432       "A", "B", "www.foo.com", "/bar", two_hours_ago, one_hour_from_now,
4433       one_hour_ago, one_hour_ago, false /*secure*/, false /*httponly*/,
4434       CookieSameSite::NO_RESTRICTION, COOKIE_PRIORITY_DEFAULT,
4435       false /*same_party*/, absl::nullopt /*partition_key*/,
4436       CookieSourceScheme::kSecure, url::PORT_INVALID);
4437   EXPECT_EQ(cc4->SourcePort(), url::PORT_INVALID);
4438 }
4439 
TEST(CanonicalCookieTest,IsSetPermittedInContext)4440 TEST(CanonicalCookieTest, IsSetPermittedInContext) {
4441   GURL url("https://www.example.com/test");
4442   GURL insecure_url("http://www.example.com/test");
4443   base::Time current_time = base::Time::Now();
4444 
4445   auto cookie_scriptable = CanonicalCookie::CreateUnsafeCookieForTesting(
4446       "A", "2", "www.example.com", "/test", current_time, base::Time(),
4447       base::Time(), base::Time(), true /*secure*/, false /*httponly*/,
4448       CookieSameSite::NO_RESTRICTION, COOKIE_PRIORITY_DEFAULT, false);
4449   auto cookie_httponly = CanonicalCookie::CreateUnsafeCookieForTesting(
4450       "A", "2", "www.example.com", "/test", current_time, base::Time(),
4451       base::Time(), base::Time(), true /*secure*/, true /*httponly*/,
4452       CookieSameSite::NO_RESTRICTION, COOKIE_PRIORITY_DEFAULT, false);
4453 
4454   CookieOptions context_script;
4455   CookieOptions context_network;
4456   context_network.set_include_httponly();
4457 
4458   EXPECT_THAT(
4459       cookie_scriptable->IsSetPermittedInContext(
4460           GURL("file://foo/bar.txt"), context_network,
4461           CookieAccessParams(CookieAccessSemantics::UNKNOWN,
4462                              false /* delegate_treats_url_as_trustworthy */,
4463                              CookieSamePartyStatus::kNoSamePartyEnforcement),
4464           kCookieableSchemes),
4465       MatchesCookieAccessResult(
4466           CookieInclusionStatus::MakeFromReasonsForTesting({
4467               CookieInclusionStatus::EXCLUDE_NONCOOKIEABLE_SCHEME,
4468               CookieInclusionStatus::EXCLUDE_SECURE_ONLY,
4469           }),
4470           _, _, false));
4471 
4472   EXPECT_THAT(
4473       cookie_scriptable->IsSetPermittedInContext(
4474           insecure_url, context_network,
4475           CookieAccessParams(CookieAccessSemantics::UNKNOWN,
4476                              false /* delegate_treats_url_as_trustworthy */,
4477                              CookieSamePartyStatus::kNoSamePartyEnforcement),
4478           kCookieableSchemes),
4479       MatchesCookieAccessResult(
4480           CookieInclusionStatus::MakeFromReasonsForTesting(
4481               {CookieInclusionStatus::EXCLUDE_SECURE_ONLY}),
4482           _, _, false));
4483   EXPECT_THAT(
4484       cookie_scriptable->IsSetPermittedInContext(
4485           url, context_network,
4486           CookieAccessParams(CookieAccessSemantics::UNKNOWN,
4487                              false /* delegate_treats_url_as_trustworthy */,
4488                              CookieSamePartyStatus::kNoSamePartyEnforcement),
4489           kCookieableSchemes),
4490       MatchesCookieAccessResult(IsInclude(), _, _, true));
4491   EXPECT_THAT(
4492       cookie_scriptable->IsSetPermittedInContext(
4493           url, context_script,
4494           CookieAccessParams(CookieAccessSemantics::UNKNOWN,
4495                              false /* delegate_treats_url_as_trustworthy */,
4496                              CookieSamePartyStatus::kNoSamePartyEnforcement),
4497           kCookieableSchemes),
4498       MatchesCookieAccessResult(IsInclude(), _, _, true));
4499 
4500   EXPECT_THAT(
4501       cookie_httponly->IsSetPermittedInContext(
4502           url, context_network,
4503           CookieAccessParams(CookieAccessSemantics::UNKNOWN,
4504                              false /* delegate_treats_url_as_trustworthy */,
4505                              CookieSamePartyStatus::kNoSamePartyEnforcement),
4506           kCookieableSchemes),
4507       MatchesCookieAccessResult(IsInclude(), _, _, true));
4508   EXPECT_THAT(
4509       cookie_httponly->IsSetPermittedInContext(
4510           url, context_script,
4511           CookieAccessParams(CookieAccessSemantics::UNKNOWN,
4512                              false /* delegate_treats_url_as_trustworthy */,
4513                              CookieSamePartyStatus::kNoSamePartyEnforcement),
4514           kCookieableSchemes),
4515       MatchesCookieAccessResult(
4516           CookieInclusionStatus::MakeFromReasonsForTesting(
4517               {CookieInclusionStatus::EXCLUDE_HTTP_ONLY}),
4518           _, _, true));
4519 
4520   CookieOptions context_cross_site;
4521   CookieOptions context_same_site_lax;
4522   context_same_site_lax.set_same_site_cookie_context(
4523       CookieOptions::SameSiteCookieContext(
4524           CookieOptions::SameSiteCookieContext::ContextType::SAME_SITE_LAX));
4525   CookieOptions context_same_site_strict;
4526   context_same_site_strict.set_same_site_cookie_context(
4527       CookieOptions::SameSiteCookieContext(
4528           CookieOptions::SameSiteCookieContext::ContextType::SAME_SITE_STRICT));
4529 
4530   CookieOptions context_same_site_strict_to_lax;
4531   context_same_site_strict_to_lax.set_same_site_cookie_context(
4532       CookieOptions::SameSiteCookieContext(
4533           CookieOptions::SameSiteCookieContext::ContextType::SAME_SITE_STRICT,
4534           CookieOptions::SameSiteCookieContext::ContextType::SAME_SITE_LAX));
4535 
4536   CookieOptions context_same_site_strict_to_cross;
4537   context_same_site_strict_to_cross.set_same_site_cookie_context(
4538       CookieOptions::SameSiteCookieContext(
4539           CookieOptions::SameSiteCookieContext::ContextType::SAME_SITE_STRICT,
4540           CookieOptions::SameSiteCookieContext::ContextType::CROSS_SITE));
4541 
4542   CookieOptions context_same_site_lax_to_cross;
4543   context_same_site_lax_to_cross.set_same_site_cookie_context(
4544       CookieOptions::SameSiteCookieContext(
4545           CookieOptions::SameSiteCookieContext::ContextType::SAME_SITE_LAX,
4546           CookieOptions::SameSiteCookieContext::ContextType::CROSS_SITE));
4547 
4548   {
4549     auto cookie_same_site_unrestricted =
4550         CanonicalCookie::CreateUnsafeCookieForTesting(
4551             "A", "2", "www.example.com", "/test", current_time, base::Time(),
4552             base::Time(), base::Time(), true /*secure*/, false /*httponly*/,
4553             CookieSameSite::NO_RESTRICTION, COOKIE_PRIORITY_DEFAULT, false);
4554 
4555     EXPECT_THAT(
4556         cookie_same_site_unrestricted->IsSetPermittedInContext(
4557             url, context_cross_site,
4558             CookieAccessParams(CookieAccessSemantics::UNKNOWN,
4559                                false /* delegate_treats_url_as_trustworthy */,
4560                                CookieSamePartyStatus::kNoSamePartyEnforcement),
4561             kCookieableSchemes),
4562         MatchesCookieAccessResult(IsInclude(), _, _, true));
4563     EXPECT_THAT(
4564         cookie_same_site_unrestricted->IsSetPermittedInContext(
4565             url, context_same_site_lax,
4566             CookieAccessParams(CookieAccessSemantics::UNKNOWN,
4567                                false /* delegate_treats_url_as_trustworthy */,
4568                                CookieSamePartyStatus::kNoSamePartyEnforcement),
4569             kCookieableSchemes),
4570         MatchesCookieAccessResult(IsInclude(), _, _, true));
4571     EXPECT_THAT(
4572         cookie_same_site_unrestricted->IsSetPermittedInContext(
4573             url, context_same_site_strict,
4574             CookieAccessParams(CookieAccessSemantics::UNKNOWN,
4575                                false /* delegate_treats_url_as_trustworthy */,
4576                                CookieSamePartyStatus::kNoSamePartyEnforcement),
4577             kCookieableSchemes),
4578         MatchesCookieAccessResult(IsInclude(), _, _, true));
4579 
4580     {
4581       // Schemeful Same-Site disabled.
4582       base::test::ScopedFeatureList feature_list;
4583       feature_list.InitAndDisableFeature(features::kSchemefulSameSite);
4584 
4585       EXPECT_THAT(cookie_same_site_unrestricted->IsSetPermittedInContext(
4586                       url, context_same_site_strict_to_lax,
4587                       CookieAccessParams(
4588                           CookieAccessSemantics::UNKNOWN,
4589                           false /* delegate_treats_url_as_trustworthy */,
4590                           CookieSamePartyStatus::kNoSamePartyEnforcement),
4591                       kCookieableSchemes),
4592                   MatchesCookieAccessResult(
4593                       AllOf(IsInclude(), Not(HasSchemefulDowngradeWarning())),
4594                       _, _, true));
4595       EXPECT_THAT(cookie_same_site_unrestricted->IsSetPermittedInContext(
4596                       url, context_same_site_strict_to_cross,
4597                       CookieAccessParams(
4598                           CookieAccessSemantics::UNKNOWN,
4599                           false /* delegate_treats_url_as_trustworthy */,
4600                           CookieSamePartyStatus::kNoSamePartyEnforcement),
4601                       kCookieableSchemes),
4602                   MatchesCookieAccessResult(
4603                       AllOf(IsInclude(), Not(HasSchemefulDowngradeWarning())),
4604                       _, _, true));
4605       EXPECT_THAT(cookie_same_site_unrestricted->IsSetPermittedInContext(
4606                       url, context_same_site_lax_to_cross,
4607                       CookieAccessParams(
4608                           CookieAccessSemantics::UNKNOWN,
4609                           false /* delegate_treats_url_as_trustworthy */,
4610                           CookieSamePartyStatus::kNoSamePartyEnforcement),
4611                       kCookieableSchemes),
4612                   MatchesCookieAccessResult(
4613                       AllOf(IsInclude(), Not(HasSchemefulDowngradeWarning())),
4614                       _, _, true));
4615     }
4616     {
4617       // Schemeful Same-Site enabled.
4618       base::test::ScopedFeatureList feature_list;
4619       feature_list.InitAndEnableFeature(features::kSchemefulSameSite);
4620 
4621       EXPECT_THAT(cookie_same_site_unrestricted->IsSetPermittedInContext(
4622                       url, context_same_site_strict_to_lax,
4623                       CookieAccessParams(
4624                           CookieAccessSemantics::UNKNOWN,
4625                           false /* delegate_treats_url_as_trustworthy */,
4626                           CookieSamePartyStatus::kNoSamePartyEnforcement),
4627                       kCookieableSchemes),
4628                   MatchesCookieAccessResult(
4629                       AllOf(IsInclude(), Not(HasSchemefulDowngradeWarning())),
4630                       _, _, true));
4631       EXPECT_THAT(cookie_same_site_unrestricted->IsSetPermittedInContext(
4632                       url, context_same_site_strict_to_cross,
4633                       CookieAccessParams(
4634                           CookieAccessSemantics::UNKNOWN,
4635                           false /* delegate_treats_url_as_trustworthy */,
4636                           CookieSamePartyStatus::kNoSamePartyEnforcement),
4637                       kCookieableSchemes),
4638                   MatchesCookieAccessResult(
4639                       AllOf(IsInclude(), Not(HasSchemefulDowngradeWarning())),
4640                       _, _, true));
4641       EXPECT_THAT(cookie_same_site_unrestricted->IsSetPermittedInContext(
4642                       url, context_same_site_lax_to_cross,
4643                       CookieAccessParams(
4644                           CookieAccessSemantics::UNKNOWN,
4645                           false /* delegate_treats_url_as_trustworthy */,
4646                           CookieSamePartyStatus::kNoSamePartyEnforcement),
4647                       kCookieableSchemes),
4648                   MatchesCookieAccessResult(
4649                       AllOf(IsInclude(), Not(HasSchemefulDowngradeWarning())),
4650                       _, _, true));
4651     }
4652   }
4653 
4654   {
4655     auto cookie_same_site_lax = CanonicalCookie::CreateUnsafeCookieForTesting(
4656         "A", "2", "www.example.com", "/test", current_time, base::Time(),
4657         base::Time(), base::Time(), true /*secure*/, false /*httponly*/,
4658         CookieSameSite::LAX_MODE, COOKIE_PRIORITY_DEFAULT, false);
4659 
4660     EXPECT_THAT(
4661         cookie_same_site_lax->IsSetPermittedInContext(
4662             url, context_cross_site,
4663             CookieAccessParams(CookieAccessSemantics::UNKNOWN,
4664                                false /* delegate_treats_url_as_trustworthy */,
4665                                CookieSamePartyStatus::kNoSamePartyEnforcement),
4666             kCookieableSchemes),
4667         MatchesCookieAccessResult(
4668             CookieInclusionStatus::MakeFromReasonsForTesting(
4669                 {CookieInclusionStatus::EXCLUDE_SAMESITE_LAX}),
4670             _, _, true));
4671     EXPECT_THAT(
4672         cookie_same_site_lax->IsSetPermittedInContext(
4673             url, context_same_site_lax,
4674             CookieAccessParams(CookieAccessSemantics::UNKNOWN,
4675                                false /* delegate_treats_url_as_trustworthy */,
4676                                CookieSamePartyStatus::kNoSamePartyEnforcement),
4677             kCookieableSchemes),
4678         MatchesCookieAccessResult(IsInclude(), _, _, true));
4679     EXPECT_THAT(
4680         cookie_same_site_lax->IsSetPermittedInContext(
4681             url, context_same_site_strict,
4682             CookieAccessParams(CookieAccessSemantics::UNKNOWN,
4683                                false /* delegate_treats_url_as_trustworthy */,
4684                                CookieSamePartyStatus::kNoSamePartyEnforcement),
4685             kCookieableSchemes),
4686         MatchesCookieAccessResult(IsInclude(), _, _, true));
4687 
4688     {
4689       // Schemeful Same-Site disabled.
4690       base::test::ScopedFeatureList feature_list;
4691       feature_list.InitAndDisableFeature(features::kSchemefulSameSite);
4692 
4693       EXPECT_THAT(cookie_same_site_lax->IsSetPermittedInContext(
4694                       url, context_same_site_strict_to_lax,
4695                       CookieAccessParams(
4696                           CookieAccessSemantics::UNKNOWN,
4697                           false /* delegate_treats_url_as_trustworthy */,
4698                           CookieSamePartyStatus::kNoSamePartyEnforcement),
4699                       kCookieableSchemes),
4700                   MatchesCookieAccessResult(
4701                       AllOf(IsInclude(), Not(HasSchemefulDowngradeWarning())),
4702                       _, _, true));
4703       EXPECT_THAT(cookie_same_site_lax->IsSetPermittedInContext(
4704                       url, context_same_site_strict_to_cross,
4705                       CookieAccessParams(
4706                           CookieAccessSemantics::UNKNOWN,
4707                           false /* delegate_treats_url_as_trustworthy */,
4708                           CookieSamePartyStatus::kNoSamePartyEnforcement),
4709                       kCookieableSchemes),
4710                   MatchesCookieAccessResult(
4711                       AllOf(IsInclude(),
4712                             HasWarningReason(
4713                                 CookieInclusionStatus::
4714                                     WARN_STRICT_CROSS_DOWNGRADE_LAX_SAMESITE)),
4715                       _, _, true));
4716       EXPECT_THAT(cookie_same_site_lax->IsSetPermittedInContext(
4717                       url, context_same_site_lax_to_cross,
4718                       CookieAccessParams(
4719                           CookieAccessSemantics::UNKNOWN,
4720                           false /* delegate_treats_url_as_trustworthy */,
4721                           CookieSamePartyStatus::kNoSamePartyEnforcement),
4722                       kCookieableSchemes),
4723                   MatchesCookieAccessResult(
4724                       AllOf(IsInclude(),
4725                             HasWarningReason(
4726                                 CookieInclusionStatus::
4727                                     WARN_LAX_CROSS_DOWNGRADE_LAX_SAMESITE)),
4728                       _, _, true));
4729     }
4730     {
4731       // Schemeful Same-Site enabled.
4732       base::test::ScopedFeatureList feature_list;
4733       feature_list.InitAndEnableFeature(features::kSchemefulSameSite);
4734 
4735       EXPECT_THAT(cookie_same_site_lax->IsSetPermittedInContext(
4736                       url, context_same_site_strict_to_lax,
4737                       CookieAccessParams(
4738                           CookieAccessSemantics::UNKNOWN,
4739                           false /* delegate_treats_url_as_trustworthy */,
4740                           CookieSamePartyStatus::kNoSamePartyEnforcement),
4741                       kCookieableSchemes),
4742                   MatchesCookieAccessResult(
4743                       AllOf(IsInclude(), Not(HasSchemefulDowngradeWarning())),
4744                       _, _, true));
4745       EXPECT_THAT(cookie_same_site_lax->IsSetPermittedInContext(
4746                       url, context_same_site_strict_to_cross,
4747                       CookieAccessParams(
4748                           CookieAccessSemantics::UNKNOWN,
4749                           false /* delegate_treats_url_as_trustworthy */,
4750                           CookieSamePartyStatus::kNoSamePartyEnforcement),
4751                       kCookieableSchemes),
4752                   MatchesCookieAccessResult(
4753                       AllOf(Not(IsInclude()),
4754                             HasWarningReason(
4755                                 CookieInclusionStatus::
4756                                     WARN_STRICT_CROSS_DOWNGRADE_LAX_SAMESITE),
4757                             HasExclusionReason(
4758                                 CookieInclusionStatus::EXCLUDE_SAMESITE_LAX)),
4759                       _, _, true));
4760       EXPECT_THAT(
4761           cookie_same_site_lax->IsSetPermittedInContext(
4762               url, context_same_site_lax_to_cross,
4763               CookieAccessParams(
4764                   CookieAccessSemantics::UNKNOWN,
4765                   false /* delegate_treats_url_as_trustworthy */,
4766                   CookieSamePartyStatus::kNoSamePartyEnforcement),
4767               kCookieableSchemes),
4768           MatchesCookieAccessResult(
4769               AllOf(Not(IsInclude()),
4770                     HasWarningReason(CookieInclusionStatus::
4771                                          WARN_LAX_CROSS_DOWNGRADE_LAX_SAMESITE),
4772                     HasExclusionReason(
4773                         CookieInclusionStatus::EXCLUDE_SAMESITE_LAX)),
4774               _, _, true));
4775     }
4776   }
4777 
4778   {
4779     auto cookie_same_site_strict =
4780         CanonicalCookie::CreateUnsafeCookieForTesting(
4781             "A", "2", "www.example.com", "/test", current_time, base::Time(),
4782             base::Time(), base::Time(), true /*secure*/, false /*httponly*/,
4783             CookieSameSite::STRICT_MODE, COOKIE_PRIORITY_DEFAULT, false);
4784 
4785     // TODO(morlovich): Do compatibility testing on whether set of strict in lax
4786     // context really should be accepted.
4787     EXPECT_THAT(
4788         cookie_same_site_strict->IsSetPermittedInContext(
4789             url, context_cross_site,
4790             CookieAccessParams(CookieAccessSemantics::UNKNOWN,
4791                                false /* delegate_treats_url_as_trustworthy */,
4792                                CookieSamePartyStatus::kNoSamePartyEnforcement),
4793             kCookieableSchemes),
4794         MatchesCookieAccessResult(
4795             CookieInclusionStatus::MakeFromReasonsForTesting(
4796                 {CookieInclusionStatus::EXCLUDE_SAMESITE_STRICT}),
4797             _, _, true));
4798     EXPECT_THAT(
4799         cookie_same_site_strict->IsSetPermittedInContext(
4800             url, context_same_site_lax,
4801             CookieAccessParams(CookieAccessSemantics::UNKNOWN,
4802                                false /* delegate_treats_url_as_trustworthy */,
4803                                CookieSamePartyStatus::kNoSamePartyEnforcement),
4804             kCookieableSchemes),
4805         MatchesCookieAccessResult(IsInclude(), _, _, true));
4806     EXPECT_THAT(
4807         cookie_same_site_strict->IsSetPermittedInContext(
4808             url, context_same_site_strict,
4809             CookieAccessParams(CookieAccessSemantics::UNKNOWN,
4810                                false /* delegate_treats_url_as_trustworthy */,
4811                                CookieSamePartyStatus::kNoSamePartyEnforcement),
4812             kCookieableSchemes),
4813         MatchesCookieAccessResult(IsInclude(), _, _, true));
4814 
4815     {
4816       // Schemeful Same-Site disabled.
4817       base::test::ScopedFeatureList feature_list;
4818       feature_list.InitAndDisableFeature(features::kSchemefulSameSite);
4819 
4820       EXPECT_THAT(cookie_same_site_strict->IsSetPermittedInContext(
4821                       url, context_same_site_strict_to_lax,
4822                       CookieAccessParams(
4823                           CookieAccessSemantics::UNKNOWN,
4824                           false /* delegate_treats_url_as_trustworthy */,
4825                           CookieSamePartyStatus::kNoSamePartyEnforcement),
4826                       kCookieableSchemes),
4827                   MatchesCookieAccessResult(
4828                       AllOf(IsInclude(), Not(HasSchemefulDowngradeWarning())),
4829                       _, _, true));
4830       EXPECT_THAT(
4831           cookie_same_site_strict->IsSetPermittedInContext(
4832               url, context_same_site_strict_to_cross,
4833               CookieAccessParams(
4834                   CookieAccessSemantics::UNKNOWN,
4835                   false /* delegate_treats_url_as_trustworthy */,
4836                   CookieSamePartyStatus::kNoSamePartyEnforcement),
4837               kCookieableSchemes),
4838           MatchesCookieAccessResult(
4839               AllOf(IsInclude(),
4840                     HasWarningReason(
4841                         CookieInclusionStatus::
4842                             WARN_STRICT_CROSS_DOWNGRADE_STRICT_SAMESITE)),
4843               _, _, true));
4844       EXPECT_THAT(cookie_same_site_strict->IsSetPermittedInContext(
4845                       url, context_same_site_lax_to_cross,
4846                       CookieAccessParams(
4847                           CookieAccessSemantics::UNKNOWN,
4848                           false /* delegate_treats_url_as_trustworthy */,
4849                           CookieSamePartyStatus::kNoSamePartyEnforcement),
4850                       kCookieableSchemes),
4851                   MatchesCookieAccessResult(
4852                       AllOf(IsInclude(),
4853                             HasWarningReason(
4854                                 CookieInclusionStatus::
4855                                     WARN_LAX_CROSS_DOWNGRADE_STRICT_SAMESITE)),
4856                       _, _, true));
4857     }
4858     {
4859       // Schemeful Same-Site enabled.
4860       base::test::ScopedFeatureList feature_list;
4861       feature_list.InitAndEnableFeature(features::kSchemefulSameSite);
4862 
4863       EXPECT_THAT(cookie_same_site_strict->IsSetPermittedInContext(
4864                       url, context_same_site_strict_to_lax,
4865                       CookieAccessParams(
4866                           CookieAccessSemantics::UNKNOWN,
4867                           false /* delegate_treats_url_as_trustworthy */,
4868                           CookieSamePartyStatus::kNoSamePartyEnforcement),
4869                       kCookieableSchemes),
4870                   MatchesCookieAccessResult(
4871                       AllOf(IsInclude(), Not(HasSchemefulDowngradeWarning())),
4872                       _, _, true));
4873       EXPECT_THAT(
4874           cookie_same_site_strict->IsSetPermittedInContext(
4875               url, context_same_site_strict_to_cross,
4876               CookieAccessParams(
4877                   CookieAccessSemantics::UNKNOWN,
4878                   false /* delegate_treats_url_as_trustworthy */,
4879                   CookieSamePartyStatus::kNoSamePartyEnforcement),
4880               kCookieableSchemes),
4881           MatchesCookieAccessResult(
4882               AllOf(Not(IsInclude()),
4883                     HasWarningReason(
4884                         CookieInclusionStatus::
4885                             WARN_STRICT_CROSS_DOWNGRADE_STRICT_SAMESITE),
4886                     HasExclusionReason(
4887                         CookieInclusionStatus::EXCLUDE_SAMESITE_STRICT)),
4888               _, _, true));
4889       EXPECT_THAT(
4890           cookie_same_site_strict->IsSetPermittedInContext(
4891               url, context_same_site_lax_to_cross,
4892               CookieAccessParams(
4893                   CookieAccessSemantics::UNKNOWN,
4894                   false /* delegate_treats_url_as_trustworthy */,
4895                   CookieSamePartyStatus::kNoSamePartyEnforcement),
4896               kCookieableSchemes),
4897           MatchesCookieAccessResult(
4898               AllOf(Not(IsInclude()),
4899                     HasWarningReason(
4900                         CookieInclusionStatus::
4901                             WARN_LAX_CROSS_DOWNGRADE_STRICT_SAMESITE),
4902                     HasExclusionReason(
4903                         CookieInclusionStatus::EXCLUDE_SAMESITE_STRICT)),
4904               _, _, true));
4905     }
4906 
4907     // Even with Schemeful Same-Site enabled, cookies semantics could change the
4908     // inclusion.
4909     {
4910       base::test::ScopedFeatureList feature_list;
4911       feature_list.InitAndEnableFeature(features::kSchemefulSameSite);
4912 
4913       EXPECT_THAT(cookie_same_site_strict->IsSetPermittedInContext(
4914                       url, context_same_site_strict_to_cross,
4915                       CookieAccessParams(
4916                           CookieAccessSemantics::UNKNOWN,
4917                           false /* delegate_treats_url_as_trustworthy */,
4918                           CookieSamePartyStatus::kNoSamePartyEnforcement),
4919                       kCookieableSchemes),
4920                   MatchesCookieAccessResult(Not(IsInclude()), _, _, true));
4921       EXPECT_THAT(cookie_same_site_strict->IsSetPermittedInContext(
4922                       url, context_same_site_strict_to_cross,
4923                       CookieAccessParams(
4924                           CookieAccessSemantics::NONLEGACY,
4925                           false /* delegate_treats_url_as_trustworthy */,
4926                           CookieSamePartyStatus::kNoSamePartyEnforcement),
4927                       kCookieableSchemes),
4928                   MatchesCookieAccessResult(Not(IsInclude()), _, _, true));
4929       // LEGACY semantics should allow cookies which Schemeful Same-Site would
4930       // normally block.
4931       EXPECT_THAT(cookie_same_site_strict->IsSetPermittedInContext(
4932                       url, context_same_site_strict_to_cross,
4933                       CookieAccessParams(
4934                           CookieAccessSemantics::LEGACY,
4935                           false /* delegate_treats_url_as_trustworthy */,
4936                           CookieSamePartyStatus::kNoSamePartyEnforcement),
4937                       kCookieableSchemes),
4938                   MatchesCookieAccessResult(IsInclude(), _, _, true));
4939     }
4940   }
4941 
4942   // Behavior of UNSPECIFIED depends on CookieAccessSemantics.
4943   auto cookie_same_site_unspecified =
4944       CanonicalCookie::CreateUnsafeCookieForTesting(
4945           "A", "2", "www.example.com", "/test", current_time, base::Time(),
4946           base::Time(), base::Time(), true /*secure*/, false /*httponly*/,
4947           CookieSameSite::UNSPECIFIED, COOKIE_PRIORITY_DEFAULT, false);
4948 
4949   EXPECT_THAT(
4950       cookie_same_site_unspecified->IsSetPermittedInContext(
4951           url, context_cross_site,
4952           CookieAccessParams(CookieAccessSemantics::UNKNOWN,
4953                              false /* delegate_treats_url_as_trustworthy */,
4954                              CookieSamePartyStatus::kNoSamePartyEnforcement),
4955           kCookieableSchemes),
4956       MatchesCookieAccessResult(
4957           HasExactlyExclusionReasonsForTesting(
4958               std::vector<CookieInclusionStatus::ExclusionReason>(
4959                   {CookieInclusionStatus::
4960                        EXCLUDE_SAMESITE_UNSPECIFIED_TREATED_AS_LAX})),
4961           _, _, true));
4962   EXPECT_THAT(
4963       cookie_same_site_unspecified->IsSetPermittedInContext(
4964           url, context_same_site_lax,
4965           CookieAccessParams(CookieAccessSemantics::UNKNOWN,
4966                              false /* delegate_treats_url_as_trustworthy */,
4967                              CookieSamePartyStatus::kNoSamePartyEnforcement),
4968           kCookieableSchemes),
4969       MatchesCookieAccessResult(IsInclude(), _, _, true));
4970   EXPECT_THAT(
4971       cookie_same_site_unspecified->IsSetPermittedInContext(
4972           url, context_same_site_strict,
4973           CookieAccessParams(CookieAccessSemantics::UNKNOWN,
4974                              false /* delegate_treats_url_as_trustworthy */,
4975                              CookieSamePartyStatus::kNoSamePartyEnforcement),
4976           kCookieableSchemes),
4977       MatchesCookieAccessResult(IsInclude(), _, _, true));
4978   EXPECT_THAT(
4979       cookie_same_site_unspecified->IsSetPermittedInContext(
4980           url, context_cross_site,
4981           CookieAccessParams(CookieAccessSemantics::LEGACY,
4982                              false /* delegate_treats_url_as_trustworthy */,
4983                              CookieSamePartyStatus::kNoSamePartyEnforcement),
4984           kCookieableSchemes),
4985       MatchesCookieAccessResult(IsInclude(), _, _, true));
4986   EXPECT_THAT(
4987       cookie_same_site_unspecified->IsSetPermittedInContext(
4988           url, context_same_site_lax,
4989           CookieAccessParams(CookieAccessSemantics::LEGACY,
4990                              false /* delegate_treats_url_as_trustworthy */,
4991                              CookieSamePartyStatus::kNoSamePartyEnforcement),
4992           kCookieableSchemes),
4993       MatchesCookieAccessResult(IsInclude(), _, _, true));
4994   EXPECT_THAT(
4995       cookie_same_site_unspecified->IsSetPermittedInContext(
4996           url, context_same_site_strict,
4997           CookieAccessParams(CookieAccessSemantics::LEGACY,
4998                              false /* delegate_treats_url_as_trustworthy */,
4999                              CookieSamePartyStatus::kNoSamePartyEnforcement),
5000           kCookieableSchemes),
5001       MatchesCookieAccessResult(IsInclude(), _, _, true));
5002   EXPECT_THAT(
5003       cookie_same_site_unspecified->IsSetPermittedInContext(
5004           url, context_cross_site,
5005           CookieAccessParams(CookieAccessSemantics::NONLEGACY,
5006                              false /* delegate_treats_url_as_trustworthy */,
5007                              CookieSamePartyStatus::kNoSamePartyEnforcement),
5008           kCookieableSchemes),
5009       MatchesCookieAccessResult(
5010           HasExactlyExclusionReasonsForTesting(
5011               std::vector<CookieInclusionStatus::ExclusionReason>(
5012                   {CookieInclusionStatus::
5013                        EXCLUDE_SAMESITE_UNSPECIFIED_TREATED_AS_LAX})),
5014           _, _, true));
5015   EXPECT_THAT(
5016       cookie_same_site_unspecified->IsSetPermittedInContext(
5017           url, context_same_site_lax,
5018           CookieAccessParams(CookieAccessSemantics::NONLEGACY,
5019                              false /* delegate_treats_url_as_trustworthy */,
5020                              CookieSamePartyStatus::kNoSamePartyEnforcement),
5021           kCookieableSchemes),
5022       MatchesCookieAccessResult(IsInclude(), _, _, true));
5023   EXPECT_THAT(
5024       cookie_same_site_unspecified->IsSetPermittedInContext(
5025           url, context_same_site_strict,
5026           CookieAccessParams(CookieAccessSemantics::NONLEGACY,
5027                              false /* delegate_treats_url_as_trustworthy */,
5028                              CookieSamePartyStatus::kNoSamePartyEnforcement),
5029           kCookieableSchemes),
5030       MatchesCookieAccessResult(IsInclude(), _, _, true));
5031 
5032   // Test IsSetPermittedInContext successfully chains warnings by passing
5033   // in a CookieAccessResult and expecting the result to have a
5034   // WARN_ATTRIBUTE_VALUE_EXCEEDS_MAX_SIZE
5035   CookieInclusionStatus status;
5036   std::string long_path(ParsedCookie::kMaxCookieAttributeValueSize, 'a');
5037 
5038   std::unique_ptr<CanonicalCookie> cookie_with_long_path =
5039       CanonicalCookie::Create(url, "A=B; Path=/" + long_path, current_time,
5040                               absl::nullopt, absl::nullopt, &status);
5041   CookieAccessResult cookie_access_result(status);
5042   CookieOptions cookie_with_long_path_options;
5043   EXPECT_THAT(
5044       cookie_with_long_path->IsSetPermittedInContext(
5045           url, cookie_with_long_path_options,
5046           CookieAccessParams(CookieAccessSemantics::UNKNOWN,
5047                              false /* delegate_treats_url_as_trustworthy */,
5048                              CookieSamePartyStatus::kNoSamePartyEnforcement),
5049           kCookieableSchemes, cookie_access_result),
5050       MatchesCookieAccessResult(
5051           HasWarningReason(
5052               CookieInclusionStatus::WARN_ATTRIBUTE_VALUE_EXCEEDS_MAX_SIZE),
5053           _, _, _));
5054 }
5055 
TEST(CanonicalCookieTest,IsSetPermittedEffectiveSameSite)5056 TEST(CanonicalCookieTest, IsSetPermittedEffectiveSameSite) {
5057   GURL url("http://www.example.com/test");
5058   base::Time current_time = base::Time::Now();
5059   CookieOptions options;
5060 
5061   // Test IsSetPermitted CookieEffectiveSameSite for
5062   // CanonicalCookie with CookieSameSite::NO_RESTRICTION.
5063   auto cookie_no_restriction = CanonicalCookie::CreateUnsafeCookieForTesting(
5064       "A", "2", "www.example.com", "/test", current_time, base::Time(),
5065       base::Time(), base::Time(), true /*secure*/, false /*httponly*/,
5066       CookieSameSite::NO_RESTRICTION, COOKIE_PRIORITY_DEFAULT, false);
5067 
5068   EXPECT_THAT(
5069       cookie_no_restriction->IsSetPermittedInContext(
5070           url, options,
5071           CookieAccessParams(CookieAccessSemantics::UNKNOWN,
5072                              false /* delegate_treats_url_as_trustworthy */,
5073                              CookieSamePartyStatus::kNoSamePartyEnforcement),
5074           kCookieableSchemes),
5075       MatchesCookieAccessResult(_, CookieEffectiveSameSite::NO_RESTRICTION, _,
5076                                 false));
5077 
5078   // Test IsSetPermitted CookieEffectiveSameSite for
5079   // CanonicalCookie with CookieSameSite::LAX_MODE.
5080   auto cookie_lax = CanonicalCookie::CreateUnsafeCookieForTesting(
5081       "A", "2", "www.example.com", "/test", current_time, base::Time(),
5082       base::Time(), base::Time(), true /*secure*/, false /*httponly*/,
5083       CookieSameSite::LAX_MODE, COOKIE_PRIORITY_DEFAULT, false);
5084 
5085   EXPECT_THAT(
5086       cookie_lax->IsSetPermittedInContext(
5087           url, options,
5088           CookieAccessParams(CookieAccessSemantics::UNKNOWN,
5089                              false /* delegate_treats_url_as_trustworthy */,
5090                              CookieSamePartyStatus::kNoSamePartyEnforcement),
5091           kCookieableSchemes),
5092       MatchesCookieAccessResult(_, CookieEffectiveSameSite::LAX_MODE, _,
5093                                 false));
5094 
5095   // Test IsSetPermitted CookieEffectiveSameSite for
5096   // CanonicalCookie with CookieSameSite::STRICT_MODE.
5097   auto cookie_strict = CanonicalCookie::CreateUnsafeCookieForTesting(
5098       "A", "2", "www.example.com", "/test", current_time, base::Time(),
5099       base::Time(), base::Time(), true /*secure*/, false /*httponly*/,
5100       CookieSameSite::STRICT_MODE, COOKIE_PRIORITY_DEFAULT, false);
5101 
5102   EXPECT_THAT(
5103       cookie_strict->IsSetPermittedInContext(
5104           url, options,
5105           CookieAccessParams(CookieAccessSemantics::UNKNOWN,
5106                              false /* delegate_treats_url_as_trustworthy */,
5107                              CookieSamePartyStatus::kNoSamePartyEnforcement),
5108           kCookieableSchemes),
5109       MatchesCookieAccessResult(_, CookieEffectiveSameSite::STRICT_MODE, _,
5110                                 false));
5111 
5112   // Test IsSetPermitted CookieEffectiveSameSite for
5113   // CanonicalCookie with CookieSameSite::UNSPECIFIED.
5114   base::Time creation_time = base::Time::Now() - (kLaxAllowUnsafeMaxAge * 4);
5115   auto cookie_old_unspecified = CanonicalCookie::CreateUnsafeCookieForTesting(
5116       "A", "2", "www.example.com", "/test", creation_time, base::Time(),
5117       base::Time(), base::Time(), true /*secure*/, false /*httponly*/,
5118       CookieSameSite::UNSPECIFIED, COOKIE_PRIORITY_DEFAULT, false);
5119   auto cookie_unspecified = CanonicalCookie::CreateUnsafeCookieForTesting(
5120       "A", "2", "www.example.com", "/test", current_time, base::Time(),
5121       base::Time(), base::Time(), true /*secure*/, false /*httponly*/,
5122       CookieSameSite::UNSPECIFIED, COOKIE_PRIORITY_DEFAULT, false);
5123 
5124   EXPECT_THAT(
5125       cookie_old_unspecified->IsSetPermittedInContext(
5126           url, options,
5127           CookieAccessParams(CookieAccessSemantics::UNKNOWN,
5128                              false /* delegate_treats_url_as_trustworthy */,
5129                              CookieSamePartyStatus::kNoSamePartyEnforcement),
5130           kCookieableSchemes),
5131       MatchesCookieAccessResult(_, CookieEffectiveSameSite::LAX_MODE, _,
5132                                 false));
5133 
5134   EXPECT_THAT(
5135       cookie_unspecified->IsSetPermittedInContext(
5136           url, options,
5137           CookieAccessParams(CookieAccessSemantics::UNKNOWN,
5138                              false /* delegate_treats_url_as_trustworthy */,
5139                              CookieSamePartyStatus::kNoSamePartyEnforcement),
5140           kCookieableSchemes),
5141       MatchesCookieAccessResult(
5142           _, CookieEffectiveSameSite::LAX_MODE_ALLOW_UNSAFE, _, false));
5143 
5144   EXPECT_THAT(
5145       cookie_unspecified->IsSetPermittedInContext(
5146           url, options,
5147           CookieAccessParams(CookieAccessSemantics::NONLEGACY,
5148                              false /* delegate_treats_url_as_trustworthy */,
5149                              CookieSamePartyStatus::kNoSamePartyEnforcement),
5150           kCookieableSchemes),
5151       MatchesCookieAccessResult(
5152           _, CookieEffectiveSameSite::LAX_MODE_ALLOW_UNSAFE, _, false));
5153 
5154   EXPECT_THAT(
5155       cookie_unspecified->IsSetPermittedInContext(
5156           url, options,
5157           CookieAccessParams(CookieAccessSemantics::LEGACY,
5158                              false /* delegate_treats_url_as_trustworthy */,
5159                              CookieSamePartyStatus::kNoSamePartyEnforcement),
5160           kCookieableSchemes),
5161       MatchesCookieAccessResult(_, CookieEffectiveSameSite::NO_RESTRICTION, _,
5162                                 false));
5163 }
5164 
TEST(CanonicalCookieTest,IsSetPermitted_AllowedToAccessSecureCookies)5165 TEST(CanonicalCookieTest, IsSetPermitted_AllowedToAccessSecureCookies) {
5166   GURL url("https://www.example.com/test");
5167   GURL insecure_url("http://www.example.com/test");
5168   GURL localhost_url("http://localhost/test");
5169   base::Time current_time = base::Time::Now();
5170   CookieOptions options;
5171 
5172   for (bool secure : {false, true}) {
5173     for (CookieSameSite same_site : {
5174              CookieSameSite::UNSPECIFIED,
5175              CookieSameSite::NO_RESTRICTION,
5176              CookieSameSite::LAX_MODE,
5177              CookieSameSite::STRICT_MODE,
5178          }) {
5179       for (bool same_party : {false, true}) {
5180         // Skip setting SameParty and SameSite=Strict, since that is invalid.
5181         if (same_party && same_site == CookieSameSite::STRICT_MODE)
5182           continue;
5183         auto cookie = CanonicalCookie::CreateUnsafeCookieForTesting(
5184             "A", "2", "www.example.com", "/test", current_time, base::Time(),
5185             base::Time(), base::Time(), secure, false /*httponly*/, same_site,
5186             COOKIE_PRIORITY_DEFAULT, same_party);
5187 
5188         for (bool delegate_treats_url_as_trustworthy : {false, true}) {
5189           for (CookieAccessSemantics access_semantics : {
5190                    CookieAccessSemantics::UNKNOWN,
5191                    CookieAccessSemantics::LEGACY,
5192                    CookieAccessSemantics::NONLEGACY,
5193                }) {
5194             for (CookieSamePartyStatus same_party_status : {
5195                      CookieSamePartyStatus::kNoSamePartyEnforcement,
5196                      CookieSamePartyStatus::kEnforceSamePartyInclude,
5197                      CookieSamePartyStatus::kEnforceSamePartyExclude,
5198                  }) {
5199               // Skip invalid combinations of `same_party` and
5200               // `same_party_status`.
5201               bool has_same_party_enforcement =
5202                   same_party_status !=
5203                   CookieSamePartyStatus::kNoSamePartyEnforcement;
5204               if (has_same_party_enforcement != same_party) {
5205                 continue;
5206               }
5207               EXPECT_THAT(
5208                   cookie->IsSetPermittedInContext(
5209                       url, options,
5210                       CookieAccessParams(access_semantics,
5211                                          delegate_treats_url_as_trustworthy,
5212                                          same_party_status),
5213                       kCookieableSchemes),
5214                   MatchesCookieAccessResult(_, _, _, true));
5215               EXPECT_THAT(
5216                   cookie->IsSetPermittedInContext(
5217                       insecure_url, options,
5218                       CookieAccessParams(access_semantics,
5219                                          delegate_treats_url_as_trustworthy,
5220                                          same_party_status),
5221                       kCookieableSchemes),
5222                   MatchesCookieAccessResult(
5223                       _, _, _, delegate_treats_url_as_trustworthy));
5224               EXPECT_THAT(
5225                   cookie->IsSetPermittedInContext(
5226                       localhost_url, options,
5227                       CookieAccessParams(access_semantics,
5228                                          delegate_treats_url_as_trustworthy,
5229                                          same_party_status),
5230                       kCookieableSchemes),
5231                   MatchesCookieAccessResult(_, _, _, true));
5232             }
5233           }
5234         }
5235       }
5236     }
5237   }
5238 }
5239 
TEST(CanonicalCookieTest,IsSetPermitted_SameSiteNone_Metrics)5240 TEST(CanonicalCookieTest, IsSetPermitted_SameSiteNone_Metrics) {
5241   using SamePartyContextType = SamePartyContext::Type;
5242 
5243   constexpr bool delegate_treats_url_as_trustworthy = false;
5244   const base::Time now = base::Time::Now();
5245   const auto make_cookie = [now](CookieSameSite same_site, bool same_party) {
5246     return CanonicalCookie::CreateUnsafeCookieForTesting(
5247         "A", "1", "www.example.com", "/test", now, base::Time(), base::Time(),
5248         base::Time(), true /* secure */, false /*httponly*/, same_site,
5249         COOKIE_PRIORITY_DEFAULT, same_party);
5250   };
5251   GURL url("https://www.example.com/test");
5252 
5253   const std::unique_ptr<CanonicalCookie> same_site_none_cookie =
5254       make_cookie(CookieSameSite::NO_RESTRICTION, false /* same_party */);
5255   const std::unique_ptr<CanonicalCookie> same_party_cookie =
5256       make_cookie(CookieSameSite::NO_RESTRICTION, true /* same_party */);
5257   const std::unique_ptr<CanonicalCookie> same_site_lax_cookie =
5258       make_cookie(CookieSameSite::LAX_MODE, false /* same_party */);
5259   const std::unique_ptr<CanonicalCookie> same_site_strict_cookie =
5260       make_cookie(CookieSameSite::STRICT_MODE, false /* same_party */);
5261   CookieOptions options;
5262 
5263   options.set_same_site_cookie_context(CookieOptions::SameSiteCookieContext(
5264       CookieOptions::SameSiteCookieContext::ContextType::CROSS_SITE));
5265   // Same as default, but just to be explicit:
5266   options.set_same_party_context(
5267       SamePartyContext(SamePartyContext::Type::kCrossParty));
5268   EXPECT_THAT(
5269       same_site_none_cookie->IsSetPermittedInContext(
5270           url, options,
5271           CookieAccessParams(CookieAccessSemantics::LEGACY,
5272                              delegate_treats_url_as_trustworthy,
5273                              CookieSamePartyStatus::kNoSamePartyEnforcement),
5274           kCookieableSchemes),
5275       MatchesCookieAccessResult(CookieInclusionStatus(), _, _, true));
5276   EXPECT_THAT(
5277       same_party_cookie->IsSetPermittedInContext(
5278           url, options,
5279           CookieAccessParams(CookieAccessSemantics::LEGACY,
5280                              delegate_treats_url_as_trustworthy,
5281                              CookieSamePartyStatus::kEnforceSamePartyExclude),
5282           kCookieableSchemes),
5283       MatchesCookieAccessResult(Not(net::IsInclude()), _, _, true));
5284 
5285   // Now tweak the context to allow a SameParty cookie (using the top&resource
5286   // definition) and make sure we get the right warning. (Note: we make the
5287   // "real" same-partyness value match the value computed for the metric, even
5288   // though they would differ unless we changed the real definition.) Then
5289   // check that if we modify the cookie as indicated, the set would be allowed.
5290   options.set_same_party_context(
5291       SamePartyContext(SamePartyContextType::kSameParty));
5292   EXPECT_THAT(
5293       same_site_none_cookie->IsSetPermittedInContext(
5294           url, options,
5295           CookieAccessParams(CookieAccessSemantics::LEGACY,
5296                              delegate_treats_url_as_trustworthy,
5297                              CookieSamePartyStatus::kNoSamePartyEnforcement),
5298           kCookieableSchemes),
5299       MatchesCookieAccessResult(CookieInclusionStatus(), _, _, true));
5300   EXPECT_THAT(
5301       same_party_cookie->IsSetPermittedInContext(
5302           url, options,
5303           CookieAccessParams(CookieAccessSemantics::LEGACY,
5304                              delegate_treats_url_as_trustworthy,
5305                              CookieSamePartyStatus::kEnforceSamePartyInclude),
5306           kCookieableSchemes),
5307       MatchesCookieAccessResult(net::IsInclude(), _, _, true));
5308   EXPECT_THAT(
5309       same_site_lax_cookie->IsSetPermittedInContext(
5310           url, options,
5311           CookieAccessParams(CookieAccessSemantics::LEGACY,
5312                              delegate_treats_url_as_trustworthy,
5313                              CookieSamePartyStatus::kNoSamePartyEnforcement),
5314           kCookieableSchemes),
5315       MatchesCookieAccessResult(Not(net::IsInclude()), _, _, true));
5316 
5317   // Next: allow a SameParty cookie (using both definitions).
5318   options.set_same_party_context(SamePartyContext::MakeInclusive());
5319   EXPECT_THAT(
5320       same_site_none_cookie->IsSetPermittedInContext(
5321           url, options,
5322           CookieAccessParams(CookieAccessSemantics::LEGACY,
5323                              delegate_treats_url_as_trustworthy,
5324                              CookieSamePartyStatus::kNoSamePartyEnforcement),
5325           kCookieableSchemes),
5326       MatchesCookieAccessResult(CookieInclusionStatus(), _, _, true));
5327   EXPECT_THAT(
5328       same_party_cookie->IsSetPermittedInContext(
5329           url, options,
5330           CookieAccessParams(CookieAccessSemantics::LEGACY,
5331                              delegate_treats_url_as_trustworthy,
5332                              CookieSamePartyStatus::kNoSamePartyEnforcement),
5333           kCookieableSchemes),
5334       MatchesCookieAccessResult(net::IsInclude(), _, _, true));
5335   EXPECT_THAT(
5336       same_site_lax_cookie->IsSetPermittedInContext(
5337           url, options,
5338           CookieAccessParams(CookieAccessSemantics::LEGACY,
5339                              delegate_treats_url_as_trustworthy,
5340                              CookieSamePartyStatus::kNoSamePartyEnforcement),
5341           kCookieableSchemes),
5342       MatchesCookieAccessResult(Not(net::IsInclude()), _, _, true));
5343 
5344   // Next: allow a SameSite=Lax or SameSite=Strict cookie.
5345   options.set_same_site_cookie_context(CookieOptions::SameSiteCookieContext(
5346       CookieOptions::SameSiteCookieContext::ContextType::SAME_SITE_LAX));
5347   EXPECT_THAT(
5348       same_site_none_cookie->IsSetPermittedInContext(
5349           url, options,
5350           CookieAccessParams(CookieAccessSemantics::LEGACY,
5351                              delegate_treats_url_as_trustworthy,
5352                              CookieSamePartyStatus::kNoSamePartyEnforcement),
5353           kCookieableSchemes),
5354       MatchesCookieAccessResult(CookieInclusionStatus(), _, _, true));
5355   EXPECT_THAT(
5356       same_site_lax_cookie->IsSetPermittedInContext(
5357           url, options,
5358           CookieAccessParams(CookieAccessSemantics::LEGACY,
5359                              delegate_treats_url_as_trustworthy,
5360                              CookieSamePartyStatus::kNoSamePartyEnforcement),
5361           kCookieableSchemes),
5362       MatchesCookieAccessResult(net::IsInclude(), _, _, true));
5363   EXPECT_THAT(
5364       same_site_strict_cookie->IsSetPermittedInContext(
5365           url, options,
5366           CookieAccessParams(CookieAccessSemantics::LEGACY,
5367                              delegate_treats_url_as_trustworthy,
5368                              CookieSamePartyStatus::kNoSamePartyEnforcement),
5369           kCookieableSchemes),
5370       MatchesCookieAccessResult(net::IsInclude(), _, _, true));
5371 }
5372 
TEST(CanonicalCookieTest,IsSetPermitted_SameParty)5373 TEST(CanonicalCookieTest, IsSetPermitted_SameParty) {
5374   GURL url("https://www.example.com/test");
5375   base::Time current_time = base::Time::Now();
5376   CookieOptions options;
5377   options.set_same_site_cookie_context(CookieOptions::SameSiteCookieContext(
5378       CookieOptions::SameSiteCookieContext::ContextType::CROSS_SITE));
5379   options.set_same_party_context(
5380       SamePartyContext(SamePartyContext::Type::kSameParty));
5381 
5382   {
5383     bool delegate_treats_url_as_trustworthy = false;
5384     auto cookie = CanonicalCookie::CreateUnsafeCookieForTesting(
5385         "A", "2", "www.example.com", "/test", current_time, base::Time(),
5386         base::Time(), base::Time(), true /* secure */, false /*httponly*/,
5387         CookieSameSite::LAX_MODE, COOKIE_PRIORITY_DEFAULT,
5388         true /* same_party */);
5389 
5390     // The following access would normally be excluded due to SameSite=Lax, but
5391     // SameParty overrides SameSite.
5392     EXPECT_THAT(
5393         cookie->IsSetPermittedInContext(
5394             url, options,
5395             CookieAccessParams(CookieAccessSemantics::LEGACY,
5396                                delegate_treats_url_as_trustworthy,
5397                                CookieSamePartyStatus::kEnforceSamePartyExclude),
5398             kCookieableSchemes),
5399         MatchesCookieAccessResult(
5400             CookieInclusionStatus::MakeFromReasonsForTesting(
5401                 {CookieInclusionStatus::EXCLUDE_SAMEPARTY_CROSS_PARTY_CONTEXT},
5402                 {CookieInclusionStatus::WARN_TREATED_AS_SAMEPARTY}),
5403             _, _, true));
5404   }
5405 
5406   for (CookieSameSite same_site : {
5407            CookieSameSite::UNSPECIFIED,
5408            CookieSameSite::NO_RESTRICTION,
5409            CookieSameSite::LAX_MODE,
5410        }) {
5411     auto cookie = CanonicalCookie::CreateUnsafeCookieForTesting(
5412         "A", "2", "www.example.com", "/test", current_time, base::Time(),
5413         base::Time(), base::Time(), true /* secure */, false /*httponly*/,
5414         same_site, COOKIE_PRIORITY_DEFAULT, true /* same_party */);
5415 
5416     for (bool delegate_treats_url_as_trustworthy : {false, true}) {
5417       for (CookieAccessSemantics access_semantics : {
5418                CookieAccessSemantics::UNKNOWN,
5419                CookieAccessSemantics::LEGACY,
5420                CookieAccessSemantics::NONLEGACY,
5421            }) {
5422         EXPECT_THAT(
5423             cookie->IsSetPermittedInContext(
5424                 url, options,
5425                 CookieAccessParams(
5426                     access_semantics, delegate_treats_url_as_trustworthy,
5427                     CookieSamePartyStatus::kEnforceSamePartyInclude),
5428                 kCookieableSchemes),
5429             MatchesCookieAccessResult(IsInclude(), _, _, true));
5430       }
5431     }
5432   }
5433 }
5434 
5435 // Test that the CookieInclusionStatus warning for inclusion changed by
5436 // cross-site redirect context downgrade is applied correctly.
TEST(CanonicalCookieTest,IsSetPermittedInContext_RedirectDowngradeWarning)5437 TEST(CanonicalCookieTest, IsSetPermittedInContext_RedirectDowngradeWarning) {
5438   using Context = CookieOptions::SameSiteCookieContext;
5439   using ContextType = Context::ContextType;
5440 
5441   GURL url("https://www.example.test/test");
5442   GURL insecure_url("http://www.example.test/test");
5443 
5444   // Test cases to be used with a lax-to-cross context downgrade.
5445   const struct {
5446     ContextType context_type;
5447     CookieSameSite samesite;
5448     bool expect_cross_site_redirect_warning;
5449   } kTestCases[] = {
5450       {ContextType::SAME_SITE_LAX, CookieSameSite::STRICT_MODE, true},
5451       {ContextType::CROSS_SITE, CookieSameSite::STRICT_MODE, true},
5452       {ContextType::SAME_SITE_LAX, CookieSameSite::LAX_MODE, true},
5453       {ContextType::CROSS_SITE, CookieSameSite::LAX_MODE, true},
5454       {ContextType::SAME_SITE_LAX, CookieSameSite::NO_RESTRICTION, false},
5455       {ContextType::CROSS_SITE, CookieSameSite::NO_RESTRICTION, false},
5456   };
5457 
5458   for (bool consider_redirects : {true, false}) {
5459     base::test::ScopedFeatureList feature_list;
5460     feature_list.InitWithFeatureState(
5461         features::kCookieSameSiteConsidersRedirectChain, consider_redirects);
5462 
5463     for (CookieAccessSemantics semantics :
5464          {CookieAccessSemantics::LEGACY, CookieAccessSemantics::NONLEGACY}) {
5465       // There are no downgrade warnings for undowngraded contexts.
5466       for (ContextType context_type : {ContextType::SAME_SITE_LAX,
5467                                        ContextType::SAME_SITE_LAX_METHOD_UNSAFE,
5468                                        ContextType::CROSS_SITE}) {
5469         for (CookieSameSite samesite :
5470              {CookieSameSite::UNSPECIFIED, CookieSameSite::NO_RESTRICTION,
5471               CookieSameSite::LAX_MODE, CookieSameSite::STRICT_MODE}) {
5472           std::unique_ptr<CanonicalCookie> cookie =
5473               CanonicalCookie::CreateUnsafeCookieForTesting(
5474                   "A", "1", "www.example.test", "/test", base::Time::Now(),
5475                   base::Time(), base::Time(), base::Time(), /*secure=*/true,
5476                   /*httponly=*/false, samesite, COOKIE_PRIORITY_DEFAULT,
5477                   /*same_party=*/false);
5478 
5479           CookieOptions options;
5480           options.set_same_site_cookie_context(Context(context_type));
5481 
5482           EXPECT_FALSE(
5483               cookie
5484                   ->IsSetPermittedInContext(
5485                       url, options,
5486                       CookieAccessParams(
5487                           semantics,
5488                           /*delegate_treats_url_as_trustworthy=*/false,
5489                           CookieSamePartyStatus::kNoSamePartyEnforcement),
5490                       kCookieableSchemes)
5491                   .status.HasWarningReason(
5492                       CookieInclusionStatus::
5493                           WARN_CROSS_SITE_REDIRECT_DOWNGRADE_CHANGES_INCLUSION));
5494         }
5495       }
5496 
5497       for (const auto& test : kTestCases) {
5498         std::unique_ptr<CanonicalCookie> cookie =
5499             CanonicalCookie::CreateUnsafeCookieForTesting(
5500                 "A", "1", "www.example.test", "/test", base::Time::Now(),
5501                 base::Time(), base::Time(), base::Time(), /*secure=*/true,
5502                 /*httponly=*/false, test.samesite, COOKIE_PRIORITY_DEFAULT,
5503                 /*same_party=*/false);
5504 
5505         Context::ContextMetadata lax_cross_downgrade_metadata;
5506         lax_cross_downgrade_metadata.cross_site_redirect_downgrade =
5507             Context::ContextMetadata::ContextDowngradeType::kLaxToCross;
5508         CookieOptions options;
5509         options.set_same_site_cookie_context(Context(
5510             test.context_type, test.context_type, lax_cross_downgrade_metadata,
5511             lax_cross_downgrade_metadata));
5512 
5513         EXPECT_EQ(
5514             cookie
5515                 ->IsSetPermittedInContext(
5516                     url, options,
5517                     CookieAccessParams(
5518                         semantics,
5519                         /*delegate_treats_url_as_trustworthy=*/false,
5520                         CookieSamePartyStatus::kNoSamePartyEnforcement),
5521                     kCookieableSchemes)
5522                 .status.HasWarningReason(
5523                     CookieInclusionStatus::
5524                         WARN_CROSS_SITE_REDIRECT_DOWNGRADE_CHANGES_INCLUSION),
5525             test.expect_cross_site_redirect_warning);
5526 
5527         // SameSite warnings not applied if other exclusion reasons apply (e.g.
5528         // non-https with Secure attribute).
5529         EXPECT_FALSE(
5530             cookie
5531                 ->IsSetPermittedInContext(
5532                     insecure_url, options,
5533                     CookieAccessParams(
5534                         semantics,
5535                         /*delegate_treats_url_as_trustworthy=*/false,
5536                         CookieSamePartyStatus::kNoSamePartyEnforcement),
5537                     kCookieableSchemes)
5538                 .status.HasWarningReason(
5539                     CookieInclusionStatus::
5540                         WARN_CROSS_SITE_REDIRECT_DOWNGRADE_CHANGES_INCLUSION));
5541       }
5542     }
5543   }
5544 }
5545 
TEST(CanonicalCookieTest,TestIsCanonicalWithInvalidSizeHistograms)5546 TEST(CanonicalCookieTest, TestIsCanonicalWithInvalidSizeHistograms) {
5547   base::HistogramTester histograms;
5548   const char kFromStorageWithValidLengthHistogram[] =
5549       "Cookie.FromStorageWithValidLength";
5550   const base::HistogramBase::Sample kInValid = 0;
5551   const base::HistogramBase::Sample kValid = 1;
5552 
5553   base::Time two_hours_ago = base::Time::Now() - base::Hours(2);
5554   base::Time one_hour_ago = base::Time::Now() - base::Hours(1);
5555   base::Time one_hour_from_now = base::Time::Now() + base::Hours(1);
5556 
5557   // Test a cookie that is canonical and valid size
5558   EXPECT_TRUE(CanonicalCookie::FromStorage(
5559       "A", "B", "www.foo.com", "/bar", two_hours_ago, one_hour_from_now,
5560       one_hour_ago, one_hour_ago, false /*secure*/, false /*httponly*/,
5561       CookieSameSite::NO_RESTRICTION, COOKIE_PRIORITY_DEFAULT,
5562       false /*same_party*/, absl::nullopt /*partition_key*/,
5563       CookieSourceScheme::kSecure, 87));
5564 
5565   histograms.ExpectBucketCount(kFromStorageWithValidLengthHistogram, kInValid,
5566                                0);
5567   histograms.ExpectBucketCount(kFromStorageWithValidLengthHistogram, kValid, 1);
5568 
5569   // Test loading a couple of cookies which are canonical but with an invalid
5570   // size
5571   const std::string kCookieBig(4096, 'a');
5572   EXPECT_TRUE(CanonicalCookie::FromStorage(
5573       kCookieBig, "B", "www.foo.com", "/bar", two_hours_ago, one_hour_from_now,
5574       one_hour_ago, one_hour_ago, false /*secure*/, false /*httponly*/,
5575       CookieSameSite::NO_RESTRICTION, COOKIE_PRIORITY_DEFAULT,
5576       false /*same_party*/, absl::nullopt /*partition_key*/,
5577       CookieSourceScheme::kSecure, 87));
5578   EXPECT_TRUE(CanonicalCookie::FromStorage(
5579       "A", kCookieBig, "www.foo.com", "/bar", two_hours_ago, one_hour_from_now,
5580       one_hour_ago, one_hour_ago, false /*secure*/, false /*httponly*/,
5581       CookieSameSite::NO_RESTRICTION, COOKIE_PRIORITY_DEFAULT,
5582       false /*same_party*/, absl::nullopt /*partition_key*/,
5583       CookieSourceScheme::kSecure, 87));
5584 
5585   histograms.ExpectBucketCount(kFromStorageWithValidLengthHistogram, kInValid,
5586                                2);
5587   histograms.ExpectBucketCount(kFromStorageWithValidLengthHistogram, kValid, 1);
5588 }
5589 
TEST(CanonicalCookieTest,TestHasHiddenPrefixName)5590 TEST(CanonicalCookieTest, TestHasHiddenPrefixName) {
5591   const struct {
5592     const char* value;
5593     bool result;
5594   } kTestCases[] = {
5595       {"", false},
5596       {"  ", false},
5597       {"foobar=", false},
5598       {"foo=bar", false},
5599       {" \t ", false},
5600       {"\t", false},
5601       {"__Secure=-", false},
5602       {"__Secure=-abc", false},
5603       {"__Secur=e-abc", false},
5604       {"__Secureabc", false},
5605       {"__Host=-", false},
5606       {"__Host=-abc", false},
5607       {"__Hos=t-abc", false},
5608       {"_Host", false},
5609       {"a__Host-abc=123", false},
5610       {"a__Secure-abc=123", false},
5611       {"__Secure-abc", true},
5612       {"__Host-abc", true},
5613       {"   __Secure-abc", true},
5614       {"\t__Host-", true},
5615       {"__Host-=", true},
5616       {"__Host-=123", true},
5617       {"__host-=123", true},
5618       {"__HOST-=123", true},
5619       {"__HoSt-=123", true},
5620       {"__Host-abc=", true},
5621       {"__Host-abc=123", true},
5622       {" __Host-abc=123", true},
5623       {"    __Host-abc=", true},
5624       {"\t\t\t\t\t__Host-abc=123", true},
5625       {"\t __Host-abc=", true},
5626       {"__Secure-=", true},
5627       {"__Secure-=123", true},
5628       {"__secure-=123", true},
5629       {"__SECURE-=123", true},
5630       {"__SeCuRe-=123", true},
5631       {"__Secure-abc=", true},
5632       {"__Secure-abc=123", true},
5633       {" __Secure-abc=123", true},
5634       {"    __Secure-abc=", true},
5635       {"\t\t\t\t\t__Secure-abc=123", true},
5636       {"\t __Secure-abc=", true},
5637       {"__Secure-abc=123=d=4=fg=", true},
5638   };
5639 
5640   for (auto test_case : kTestCases) {
5641     EXPECT_EQ(CanonicalCookie::HasHiddenPrefixName(test_case.value),
5642               test_case.result)
5643         << test_case.value << " failed check";
5644   }
5645 }
5646 
TEST(CanonicalCookieTest,TestDoubleUnderscorePrefixHistogram)5647 TEST(CanonicalCookieTest, TestDoubleUnderscorePrefixHistogram) {
5648   base::HistogramTester histograms;
5649   const char kDoubleUnderscorePrefixHistogram[] =
5650       "Cookie.DoubleUnderscorePrefixedName";
5651 
5652   CanonicalCookie::Create(
5653       GURL("https://www.example.com/"), "__Secure-abc=123; Secure",
5654       base::Time::Now() /* Creation time */, absl::nullopt /* Server Time */,
5655       absl::nullopt /* cookie_partition_key */);
5656 
5657   CanonicalCookie::Create(
5658       GURL("https://www.example.com/"), "__Host-abc=123; Secure; Path=/",
5659       base::Time::Now() /* Creation time */, absl::nullopt /* Server Time */,
5660       absl::nullopt /* cookie_partition_key */);
5661 
5662   // Cookie prefixes shouldn't count.
5663   histograms.ExpectTotalCount(kDoubleUnderscorePrefixHistogram, 2);
5664   histograms.ExpectBucketCount(kDoubleUnderscorePrefixHistogram, false, 2);
5665 
5666   CanonicalCookie::Create(GURL("https://www.example.com/"), "f__oo=bar",
5667                           base::Time::Now() /* Creation time */,
5668                           absl::nullopt /* Server Time */,
5669                           absl::nullopt /* cookie_partition_key */);
5670 
5671   CanonicalCookie::Create(GURL("https://www.example.com/"), "foo=__bar",
5672                           base::Time::Now() /* Creation time */,
5673                           absl::nullopt /* Server Time */,
5674                           absl::nullopt /* cookie_partition_key */);
5675 
5676   CanonicalCookie::Create(GURL("https://www.example.com/"), "_foo=bar",
5677                           base::Time::Now() /* Creation time */,
5678                           absl::nullopt /* Server Time */,
5679                           absl::nullopt /* cookie_partition_key */);
5680 
5681   CanonicalCookie::Create(GURL("https://www.example.com/"), "_f_oo=bar",
5682                           base::Time::Now() /* Creation time */,
5683                           absl::nullopt /* Server Time */,
5684                           absl::nullopt /* cookie_partition_key */);
5685 
5686   // These should be counted.
5687   CanonicalCookie::Create(GURL("https://www.example.com/"), "__foo=bar",
5688                           base::Time::Now() /* Creation time */,
5689                           absl::nullopt /* Server Time */,
5690                           absl::nullopt /* cookie_partition_key */);
5691 
5692   CanonicalCookie::Create(GURL("https://www.example.com/"), "___foo=bar",
5693                           base::Time::Now() /* Creation time */,
5694                           absl::nullopt /* Server Time */,
5695                           absl::nullopt /* cookie_partition_key */);
5696 
5697   histograms.ExpectTotalCount(kDoubleUnderscorePrefixHistogram, 8);
5698   histograms.ExpectBucketCount(kDoubleUnderscorePrefixHistogram, false, 6);
5699   histograms.ExpectBucketCount(kDoubleUnderscorePrefixHistogram, true, 2);
5700 }
5701 
5702 }  // namespace net
5703