xref: /aosp_15_r20/external/cronet/net/cookies/cookie_util_unittest.cc (revision 6777b5387eb2ff775bb5750e3f5d96f37fb7352b)
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/cookie_util.h"
6 
7 #include <memory>
8 #include <optional>
9 #include <string>
10 #include <tuple>
11 #include <utility>
12 #include <vector>
13 
14 #include "base/containers/contains.h"
15 #include "base/functional/callback.h"
16 #include "base/strings/strcat.h"
17 #include "base/strings/string_split.h"
18 #include "base/test/bind.h"
19 #include "base/test/scoped_feature_list.h"
20 #include "base/time/time.h"
21 #include "net/base/features.h"
22 #include "net/cookies/cookie_constants.h"
23 #include "net/cookies/cookie_options.h"
24 #include "testing/gmock/include/gmock/gmock.h"
25 #include "testing/gtest/include/gtest/gtest.h"
26 #include "url/origin.h"
27 
28 namespace net {
29 
30 namespace {
31 
32 struct RequestCookieParsingTest {
33   std::string str;
34   base::StringPairs parsed;
35   // Used for malformed cookies where the parsed-then-serialized string does not
36   // match the original string.
37   std::string serialized;
38 };
39 
CheckParse(const std::string & str,const base::StringPairs & parsed_expected)40 void CheckParse(const std::string& str,
41                 const base::StringPairs& parsed_expected) {
42   cookie_util::ParsedRequestCookies parsed;
43   cookie_util::ParseRequestCookieLine(str, &parsed);
44   EXPECT_EQ(parsed_expected, parsed);
45 }
46 
CheckSerialize(const base::StringPairs & parsed,const std::string & str_expected)47 void CheckSerialize(const base::StringPairs& parsed,
48                     const std::string& str_expected) {
49   EXPECT_EQ(str_expected, cookie_util::SerializeRequestCookieLine(parsed));
50 }
51 
TEST(CookieUtilTest,TestDomainIsHostOnly)52 TEST(CookieUtilTest, TestDomainIsHostOnly) {
53   const struct {
54     const char* str;
55     const bool is_host_only;
56   } tests[] = {{"", true}, {"www.foo.com", true}, {".foo.com", false}};
57 
58   for (const auto& test : tests) {
59     EXPECT_EQ(test.is_host_only, cookie_util::DomainIsHostOnly(test.str));
60   }
61 }
62 
63 // A cookie domain containing non-ASCII characters is not allowed, even if it
64 // matches the domain from the URL.
TEST(CookieUtilTest,GetCookieDomainWithString_NonASCII)65 TEST(CookieUtilTest, GetCookieDomainWithString_NonASCII) {
66   base::test::ScopedFeatureList feature_list;
67   feature_list.InitAndEnableFeature(features::kCookieDomainRejectNonASCII);
68 
69   CookieInclusionStatus status;
70   std::string result;
71   EXPECT_FALSE(cookie_util::GetCookieDomainWithString(
72       GURL("http://éxample.com"), xample.com", status, &result));
73   EXPECT_TRUE(status.HasExactlyExclusionReasonsForTesting(
74       {CookieInclusionStatus::EXCLUDE_DOMAIN_NON_ASCII}));
75 }
76 
77 // An empty domain string results in the domain from the URL.
TEST(CookieUtilTest,GetCookieDomainWithString_Empty)78 TEST(CookieUtilTest, GetCookieDomainWithString_Empty) {
79   CookieInclusionStatus status;
80   std::string result;
81   EXPECT_TRUE(cookie_util::GetCookieDomainWithString(GURL("http://example.com"),
82                                                      "", status, &result));
83   EXPECT_TRUE(status.IsInclude());
84   EXPECT_EQ(result, "example.com");
85 }
86 
87 // A cookie domain string equal to the URL host, when that is an IP, results in
88 // the IP.
TEST(CookieUtilTest,GetCookieDomainWithString_IP)89 TEST(CookieUtilTest, GetCookieDomainWithString_IP) {
90   CookieInclusionStatus status;
91   std::string result;
92   EXPECT_TRUE(cookie_util::GetCookieDomainWithString(
93       GURL("http://192.0.2.3"), "192.0.2.3", status, &result));
94   EXPECT_TRUE(status.IsInclude());
95   EXPECT_EQ(result, "192.0.2.3");
96 }
97 
98 // A cookie domain string equal to a dot prefixed to the URL host, when that is
99 // an IP, results in the IP, without the dot.
TEST(CookieUtilTest,GetCookieDomainWithString_DotIP)100 TEST(CookieUtilTest, GetCookieDomainWithString_DotIP) {
101   CookieInclusionStatus status;
102   std::string result;
103   EXPECT_TRUE(cookie_util::GetCookieDomainWithString(
104       GURL("http://192.0.2.3"), ".192.0.2.3", status, &result));
105   EXPECT_TRUE(status.IsInclude());
106   EXPECT_EQ(result, "192.0.2.3");
107 }
108 
109 // A cookie domain string containing %-encoding is not allowed.
TEST(CookieUtilTest,GetCookieDomainWithString_PercentEncoded)110 TEST(CookieUtilTest, GetCookieDomainWithString_PercentEncoded) {
111   CookieInclusionStatus status;
112   std::string result;
113   EXPECT_FALSE(cookie_util::GetCookieDomainWithString(
114       GURL("http://a.test"), "a%2Etest", status, &result));
115   EXPECT_TRUE(status.HasExactlyExclusionReasonsForTesting({}));
116 }
117 
118 // A cookie domain string that cannot be canonicalized is not allowed.
TEST(CookieUtilTest,GetCookieDomainWithString_UnCanonicalizable)119 TEST(CookieUtilTest, GetCookieDomainWithString_UnCanonicalizable) {
120   CookieInclusionStatus status;
121   std::string result;
122   EXPECT_FALSE(cookie_util::GetCookieDomainWithString(
123       GURL("http://a.test"), "a^test", status, &result));
124   EXPECT_TRUE(status.HasExactlyExclusionReasonsForTesting({}));
125 }
126 
127 // A cookie domain that is an eTLD but matches the URL results in a host cookie
128 // domain.
TEST(CookieUtilTest,GetCookieDomainWithString_ETldMatchesUrl)129 TEST(CookieUtilTest, GetCookieDomainWithString_ETldMatchesUrl) {
130   CookieInclusionStatus status;
131   std::string result;
132   EXPECT_TRUE(cookie_util::GetCookieDomainWithString(
133       GURL("http://gov.uk"), "gov.uk", status, &result));
134   EXPECT_TRUE(status.IsInclude());
135   EXPECT_EQ(result, "gov.uk");
136 }
137 
138 // A cookie domain that is an eTLD but matches the URL results in a host cookie
139 // domain, even if it is given with a dot prefix.
TEST(CookieUtilTest,GetCookieDomainWithString_ETldMatchesUrl_DotPrefix)140 TEST(CookieUtilTest, GetCookieDomainWithString_ETldMatchesUrl_DotPrefix) {
141   CookieInclusionStatus status;
142   std::string result;
143   EXPECT_TRUE(cookie_util::GetCookieDomainWithString(
144       GURL("http://gov.uk"), ".gov.uk", status, &result));
145   EXPECT_TRUE(status.IsInclude());
146   EXPECT_EQ(result, "gov.uk");
147 }
148 
149 // A cookie domain that is an eTLD but matches the URL results in a host cookie
150 // domain, even if its capitalization is non-canonical.
TEST(CookieUtilTest,GetCookieDomainWithString_ETldMatchesUrl_NonCanonical)151 TEST(CookieUtilTest, GetCookieDomainWithString_ETldMatchesUrl_NonCanonical) {
152   CookieInclusionStatus status;
153   std::string result;
154   EXPECT_TRUE(cookie_util::GetCookieDomainWithString(
155       GURL("http://gov.uk"), "GoV.Uk", status, &result));
156   EXPECT_TRUE(status.IsInclude());
157   EXPECT_EQ(result, "gov.uk");
158 }
159 
160 // A cookie domain that is an eTLD but does not match the URL is not allowed.
TEST(CookieUtilTest,GetCookieDomainWithString_ETldDifferentUrl)161 TEST(CookieUtilTest, GetCookieDomainWithString_ETldDifferentUrl) {
162   CookieInclusionStatus status;
163   std::string result;
164   EXPECT_FALSE(cookie_util::GetCookieDomainWithString(
165       GURL("http://nhs.gov.uk"), "gov.uk", status, &result));
166   EXPECT_TRUE(status.HasExactlyExclusionReasonsForTesting({}));
167 }
168 
169 // A cookie domain with a different eTLD+1 ("organization-identifying host")
170 // from the URL is not allowed.
TEST(CookieUtilTest,GetCookieDomainWithString_DifferentOrgHost)171 TEST(CookieUtilTest, GetCookieDomainWithString_DifferentOrgHost) {
172   CookieInclusionStatus status;
173   std::string result;
174   EXPECT_FALSE(cookie_util::GetCookieDomainWithString(
175       GURL("http://portal.globex.com"), "portal.initech.com", status, &result));
176   EXPECT_TRUE(status.HasExactlyExclusionReasonsForTesting({}));
177 }
178 
179 // A cookie domain that matches the URL results in a domain cookie domain.
TEST(CookieUtilTest,GetCookieDomainWithString_MatchesUrl)180 TEST(CookieUtilTest, GetCookieDomainWithString_MatchesUrl) {
181   CookieInclusionStatus status;
182   std::string result;
183   EXPECT_TRUE(cookie_util::GetCookieDomainWithString(
184       GURL("http://globex.com"), "globex.com", status, &result));
185   EXPECT_TRUE(status.IsInclude());
186   EXPECT_EQ(result, ".globex.com");
187 }
188 
189 // A cookie domain that matches the URL but has a `.` prefix results in a domain
190 // cookie domain.
TEST(CookieUtilTest,GetCookieDomainWithString_MatchesUrlWithDot)191 TEST(CookieUtilTest, GetCookieDomainWithString_MatchesUrlWithDot) {
192   CookieInclusionStatus status;
193   std::string result;
194   EXPECT_TRUE(cookie_util::GetCookieDomainWithString(
195       GURL("http://globex.com"), ".globex.com", status, &result));
196   EXPECT_TRUE(status.IsInclude());
197   EXPECT_EQ(result, ".globex.com");
198 }
199 
200 // A cookie domain that is a subdomain of the URL host is not allowed.
TEST(CookieUtilTest,GetCookieDomainWithString_Subdomain)201 TEST(CookieUtilTest, GetCookieDomainWithString_Subdomain) {
202   CookieInclusionStatus status;
203   std::string result;
204   EXPECT_FALSE(cookie_util::GetCookieDomainWithString(
205       GURL("http://globex.com"), "mail.globex.com", status, &result));
206   EXPECT_TRUE(status.HasExactlyExclusionReasonsForTesting({}));
207 }
208 
209 // A URL that is a subdomain of the cookie domain results in a domain cookie.
TEST(CookieUtilTest,GetCookieDomainWithString_UrlSubdomain)210 TEST(CookieUtilTest, GetCookieDomainWithString_UrlSubdomain) {
211   CookieInclusionStatus status;
212   std::string result;
213   EXPECT_TRUE(cookie_util::GetCookieDomainWithString(
214       GURL("http://mail.globex.com"), "globex.com", status, &result));
215   EXPECT_TRUE(status.IsInclude());
216   EXPECT_EQ(result, ".globex.com");
217 }
218 
219 // A URL of which the cookie domain is a substring, but not a dotted suffix,
220 // is not allowed.
TEST(CookieUtilTest,GetCookieDomainWithString_SubstringButUrlNotSubdomain)221 TEST(CookieUtilTest, GetCookieDomainWithString_SubstringButUrlNotSubdomain) {
222   CookieInclusionStatus status;
223   std::string result;
224   EXPECT_FALSE(cookie_util::GetCookieDomainWithString(
225       GURL("http://myglobex.com"), "globex.com", status, &result));
226   EXPECT_TRUE(status.HasExactlyExclusionReasonsForTesting({}));
227 }
228 
229 // A URL which has a different subdomain of the eTLD+1 than the cookie domain is
230 // not allowed, regardless of which hostname is longer.
TEST(CookieUtilTest,GetCookieDomainWithString_DifferentSubdomain)231 TEST(CookieUtilTest, GetCookieDomainWithString_DifferentSubdomain) {
232   CookieInclusionStatus status;
233   std::string result;
234   EXPECT_FALSE(cookie_util::GetCookieDomainWithString(
235       GURL("http://l.globex.com"), "portal.globex.com", status, &result));
236   EXPECT_TRUE(status.HasExactlyExclusionReasonsForTesting({}));
237   EXPECT_FALSE(cookie_util::GetCookieDomainWithString(
238       GURL("http://portal.globex.com"), "l.globex.com", status, &result));
239   EXPECT_TRUE(status.HasExactlyExclusionReasonsForTesting({}));
240 }
241 
242 // A URL without a host can set a "host" cookie with no cookie domain.
TEST(CookieUtilTest,GetCookieDomainWithString_NoUrlHost)243 TEST(CookieUtilTest, GetCookieDomainWithString_NoUrlHost) {
244   CookieInclusionStatus status;
245   std::string result;
246   EXPECT_TRUE(cookie_util::GetCookieDomainWithString(
247       GURL("file:///C:/bar.html"), "", status, &result));
248   EXPECT_EQ(result, "");
249 }
250 
251 // A URL with two trailing dots (which is an invalid hostname per
252 // rfc6265bis-11#5.1.2 and will cause GetDomainAndRegistry to return an empty
253 // string) is not allowed.
TEST(CookieUtilTest,GetCookieDomainWithString_TrailingDots)254 TEST(CookieUtilTest, GetCookieDomainWithString_TrailingDots) {
255   CookieInclusionStatus status;
256   std::string result;
257   EXPECT_FALSE(cookie_util::GetCookieDomainWithString(
258       GURL("http://foo.com../"), "foo.com..", status, &result));
259   EXPECT_TRUE(status.HasExactlyExclusionReasonsForTesting({}));
260 }
261 
262 // A "normal" URL does not match with a cookie containing two trailing dots (or
263 // just one).
TEST(CookieUtilTest,GetCookieDomainWithString_TrailingDots_NotMatchingUrlHost)264 TEST(CookieUtilTest,
265      GetCookieDomainWithString_TrailingDots_NotMatchingUrlHost) {
266   CookieInclusionStatus status;
267   std::string result;
268   EXPECT_FALSE(cookie_util::GetCookieDomainWithString(
269       GURL("http://foo.com/"), ".foo.com..", status, &result));
270   EXPECT_TRUE(status.HasExactlyExclusionReasonsForTesting({}));
271   EXPECT_FALSE(cookie_util::GetCookieDomainWithString(
272       GURL("http://foo.com/"), ".foo.com.", status, &result));
273   EXPECT_TRUE(status.HasExactlyExclusionReasonsForTesting({}));
274 }
275 
276 // A URL containing an IP address is allowed, if that IP matches the cookie
277 // domain.
TEST(CookieUtilTest,GetCookieDomainWithString_UrlHostIP)278 TEST(CookieUtilTest, GetCookieDomainWithString_UrlHostIP) {
279   CookieInclusionStatus status;
280   std::string result;
281   EXPECT_TRUE(cookie_util::GetCookieDomainWithString(
282       GURL("http://192.0.2.3/"), "192.0.2.3", status, &result));
283   EXPECT_EQ(result, "192.0.2.3");
284 }
285 
286 // A cookie domain with a dot-prefixed IP is allowed, if the IP matches
287 // the URL, but is transformed to a host cookie domain.
TEST(CookieUtilTest,GetCookieDomainWithString_UrlHostIP_DomainCookie)288 TEST(CookieUtilTest, GetCookieDomainWithString_UrlHostIP_DomainCookie) {
289   CookieInclusionStatus status;
290   std::string result;
291   EXPECT_TRUE(cookie_util::GetCookieDomainWithString(
292       GURL("http://192.0.2.3/"), ".192.0.2.3", status, &result));
293   EXPECT_EQ(result, "192.0.2.3");  // No dot.
294 }
295 
296 // A URL containing a TLD that is unknown as a registry is allowed, if it
297 // matches the cookie domain.
TEST(CookieUtilTest,GetCookieDomainWithString_UnknownRegistry)298 TEST(CookieUtilTest, GetCookieDomainWithString_UnknownRegistry) {
299   CookieInclusionStatus status;
300   std::string result;
301   EXPECT_TRUE(cookie_util::GetCookieDomainWithString(GURL("http://bar/"), "bar",
302                                                      status, &result));
303   EXPECT_EQ(result, "bar");
304 }
305 
TEST(CookieUtilTest,TestCookieDateParsing)306 TEST(CookieUtilTest, TestCookieDateParsing) {
307   const struct {
308     const char* str;
309     const bool valid;
310     const double epoch;
311   } tests[] = {
312       {"Sat, 15-Apr-17 21:01:22 GMT", true, 1492290082},
313       {"Thu, 19-Apr-2007 16:00:00 GMT", true, 1176998400},
314       {"Wed, 25 Apr 2007 21:02:13 GMT", true, 1177534933},
315       {"Thu, 19/Apr\\2007 16:00:00 GMT", true, 1176998400},
316       {"Fri, 1 Jan 2010 01:01:50 GMT", true, 1262307710},
317       {"Wednesday, 1-Jan-2003 00:00:00 GMT", true, 1041379200},
318       {", 1-Jan-2003 00:00:00 GMT", true, 1041379200},
319       {" 1-Jan-2003 00:00:00 GMT", true, 1041379200},
320       {"1-Jan-2003 00:00:00 GMT", true, 1041379200},
321       {"Wed,18-Apr-07 22:50:12 GMT", true, 1176936612},
322       {"WillyWonka  , 18-Apr-07 22:50:12 GMT", true, 1176936612},
323       {"WillyWonka  , 18-Apr-07 22:50:12", true, 1176936612},
324       {"WillyWonka  ,  18-apr-07   22:50:12", true, 1176936612},
325       {"Mon, 18-Apr-1977 22:50:13 GMT", true, 230251813},
326       {"Mon, 18-Apr-77 22:50:13 GMT", true, 230251813},
327       // If the cookie came in with the expiration quoted (which in terms of
328       // the RFC you shouldn't do), we will get string quoted.  Bug 1261605.
329       {"\"Sat, 15-Apr-17\\\"21:01:22\\\"GMT\"", true, 1492290082},
330       // Test with full month names and partial names.
331       {"Partyday, 18- April-07 22:50:12", true, 1176936612},
332       {"Partyday, 18 - Apri-07 22:50:12", true, 1176936612},
333       {"Wednes, 1-Januar-2003 00:00:00 GMT", true, 1041379200},
334       // Test that we always take GMT even with other time zones or bogus
335       // values.  The RFC says everything should be GMT, and in the worst case
336       // we are 24 hours off because of zone issues.
337       {"Sat, 15-Apr-17 21:01:22", true, 1492290082},
338       {"Sat, 15-Apr-17 21:01:22 GMT-2", true, 1492290082},
339       {"Sat, 15-Apr-17 21:01:22 GMT BLAH", true, 1492290082},
340       {"Sat, 15-Apr-17 21:01:22 GMT-0400", true, 1492290082},
341       {"Sat, 15-Apr-17 21:01:22 GMT-0400 (EDT)", true, 1492290082},
342       {"Sat, 15-Apr-17 21:01:22 DST", true, 1492290082},
343       {"Sat, 15-Apr-17 21:01:22 -0400", true, 1492290082},
344       {"Sat, 15-Apr-17 21:01:22 (hello there)", true, 1492290082},
345       // Test that if we encounter multiple : fields, that we take the first
346       // that correctly parses.
347       {"Sat, 15-Apr-17 21:01:22 11:22:33", true, 1492290082},
348       {"Sat, 15-Apr-17 ::00 21:01:22", true, 1492290082},
349       {"Sat, 15-Apr-17 boink:z 21:01:22", true, 1492290082},
350       // We take the first, which in this case is invalid.
351       {"Sat, 15-Apr-17 91:22:33 21:01:22", false, 0},
352       // amazon.com formats their cookie expiration like this.
353       {"Thu Apr 18 22:50:12 2007 GMT", true, 1176936612},
354       // Test that hh:mm:ss can occur anywhere.
355       {"22:50:12 Thu Apr 18 2007 GMT", true, 1176936612},
356       {"Thu 22:50:12 Apr 18 2007 GMT", true, 1176936612},
357       {"Thu Apr 22:50:12 18 2007 GMT", true, 1176936612},
358       {"Thu Apr 18 22:50:12 2007 GMT", true, 1176936612},
359       {"Thu Apr 18 2007 22:50:12 GMT", true, 1176936612},
360       {"Thu Apr 18 2007 GMT 22:50:12", true, 1176936612},
361       // Test that the day and year can be anywhere if they are unambigious.
362       {"Sat, 15-Apr-17 21:01:22 GMT", true, 1492290082},
363       {"15-Sat, Apr-17 21:01:22 GMT", true, 1492290082},
364       {"15-Sat, Apr 21:01:22 GMT 17", true, 1492290082},
365       {"15-Sat, Apr 21:01:22 GMT 2017", true, 1492290082},
366       {"15 Apr 21:01:22 2017", true, 1492290082},
367       {"15 17 Apr 21:01:22", true, 1492290082},
368       {"Apr 15 17 21:01:22", true, 1492290082},
369       {"Apr 15 21:01:22 17", true, 1492290082},
370       {"2017 April 15 21:01:22", true, 1492290082},
371       {"15 April 2017 21:01:22", true, 1492290082},
372       // Test two-digit abbreviated year numbers.
373       {"1-Jan-71 00:00:00 GMT" /* 1971 */, true, 31536000},
374       {"1-Jan-70 00:00:00 GMT" /* 1970 */, true, 0},
375       {"1-Jan-69 00:00:00 GMT" /* 2069 */, true, 3124224000},
376       {"1-Jan-68 00:00:00 GMT" /* 2068 */, true, 3092601600},
377       // Some invalid dates
378       {"98 April 17 21:01:22", false, 0},
379       {"Thu, 012-Aug-2008 20:49:07 GMT", false, 0},
380       {"Thu, 12-Aug-9999999999 20:49:07 GMT", false, 0},
381       {"Thu, 999999999999-Aug-2007 20:49:07 GMT", false, 0},
382       {"Thu, 12-Aug-2007 20:61:99999999999 GMT", false, 0},
383       {"IAintNoDateFool", false, 0},
384       {"1600 April 33 21:01:22", false, 0},
385       {"1970 April 33 21:01:22", false, 0},
386       {"Thu, 33-Aug-31841 20:49:07 GMT", false, 0},
387   };
388 
389   base::Time parsed_time;
390   for (const auto& test : tests) {
391     parsed_time = cookie_util::ParseCookieExpirationTime(test.str);
392     if (!test.valid) {
393       EXPECT_TRUE(parsed_time.is_null()) << test.str;
394       continue;
395     }
396     EXPECT_TRUE(!parsed_time.is_null()) << test.str;
397     EXPECT_EQ(test.epoch, parsed_time.InSecondsFSinceUnixEpoch()) << test.str;
398   }
399 }
400 
401 // Tests parsing dates that are beyond 2038. 32-bit (non-Mac) POSIX systems are
402 // incapable of doing this, however the expectation is for cookie parsing to
403 // succeed anyway (and return the minimum value Time::FromUTCExploded() can
404 // parse on the current platform). Also checks a date outside the limit on
405 // Windows, which is year 30827.
TEST(CookieUtilTest,ParseCookieExpirationTimeBeyond2038)406 TEST(CookieUtilTest, ParseCookieExpirationTimeBeyond2038) {
407   const char* kTests[] = {
408       "Thu, 12-Aug-31841 20:49:07 GMT", "2039 April 15 21:01:22",
409       "2039 April 15 21:01:22",         "2038 April 15 21:01:22",
410       "15 April 69 21:01:22",           "15 April 68, 21:01:22",
411   };
412 
413   for (auto* test : kTests) {
414     base::Time parsed_time = cookie_util::ParseCookieExpirationTime(test);
415     EXPECT_FALSE(parsed_time.is_null());
416 
417     // It should either have an exact value, or be base::Time::Max(). For
418     // simplicity just check that it is greater than an arbitray date.
419     base::Time almost_jan_2038 = base::Time::UnixEpoch() + base::Days(365 * 68);
420     EXPECT_LT(almost_jan_2038, parsed_time);
421   }
422 }
423 
424 // Tests parsing dates that are prior to (or around) 1970. Non-Mac POSIX systems
425 // are incapable of doing this, however the expectation is for cookie parsing to
426 // succeed anyway (and return a minimal base::Time).
TEST(CookieUtilTest,ParseCookieExpirationTimeBefore1970)427 TEST(CookieUtilTest, ParseCookieExpirationTimeBefore1970) {
428   const char* kTests[] = {
429       // Times around the Unix epoch.
430       "1970 Jan 1 00:00:00",
431       "1969 March 3 21:01:22",
432       // Two digit year abbreviations.
433       "1-Jan-70 00:00:00",
434       "Jan 1, 70 00:00:00",
435       // Times around the Windows epoch.
436       "1601 Jan 1 00:00:00",
437       "1600 April 15 21:01:22",
438       // Times around kExplodedMinYear on Mac.
439       "1902 Jan 1 00:00:00",
440       "1901 Jan 1 00:00:00",
441   };
442 
443   for (auto* test : kTests) {
444     base::Time parsed_time = cookie_util::ParseCookieExpirationTime(test);
445     EXPECT_FALSE(parsed_time.is_null()) << test;
446 
447     // It should either have an exact value, or should be base::Time(1)
448     // For simplicity just check that it is less than the unix epoch.
449     EXPECT_LE(parsed_time, base::Time::UnixEpoch()) << test;
450   }
451 }
452 
TEST(CookieUtilTest,TestRequestCookieParsing)453 TEST(CookieUtilTest, TestRequestCookieParsing) {
454   std::vector<RequestCookieParsingTest> tests;
455 
456   // Simple case.
457   tests.emplace_back();
458   tests.back().str = "key=value";
459   tests.back().parsed.emplace_back(std::string("key"), std::string("value"));
460   // Multiple key/value pairs.
461   tests.emplace_back();
462   tests.back().str = "key1=value1; key2=value2";
463   tests.back().parsed.emplace_back(std::string("key1"), std::string("value1"));
464   tests.back().parsed.emplace_back(std::string("key2"), std::string("value2"));
465   // Empty value.
466   tests.emplace_back();
467   tests.back().str = "key=; otherkey=1234";
468   tests.back().parsed.emplace_back(std::string("key"), std::string());
469   tests.back().parsed.emplace_back(std::string("otherkey"),
470                                    std::string("1234"));
471   // Special characters (including equals signs) in value.
472   tests.emplace_back();
473   tests.back().str = "key=; a2=s=(./&t=:&u=a#$; a3=+~";
474   tests.back().parsed.emplace_back(std::string("key"), std::string());
475   tests.back().parsed.emplace_back(std::string("a2"),
476                                    std::string("s=(./&t=:&u=a#$"));
477   tests.back().parsed.emplace_back(std::string("a3"), std::string("+~"));
478   // Quoted value.
479   tests.emplace_back();
480   tests.back().str = "key=\"abcdef\"; otherkey=1234";
481   tests.back().parsed.emplace_back(std::string("key"),
482                                    std::string("\"abcdef\""));
483   tests.back().parsed.emplace_back(std::string("otherkey"),
484                                    std::string("1234"));
485 
486   for (size_t i = 0; i < tests.size(); i++) {
487     SCOPED_TRACE(testing::Message() << "Test " << i);
488     CheckParse(tests[i].str, tests[i].parsed);
489     CheckSerialize(tests[i].parsed, tests[i].str);
490   }
491 }
492 
TEST(CookieUtilTest,TestRequestCookieParsing_Malformed)493 TEST(CookieUtilTest, TestRequestCookieParsing_Malformed) {
494   std::vector<RequestCookieParsingTest> tests;
495 
496   // Missing equal sign.
497   tests.emplace_back();
498   tests.back().str = "key";
499   tests.back().parsed.emplace_back(std::string("key"), std::string());
500   tests.back().serialized = "key=";
501 
502   // Quoted value with unclosed quote.
503   tests.emplace_back();
504   tests.back().str = "key=\"abcdef";
505 
506   // Quoted value with unclosed quote followed by regular value.
507   tests.emplace_back();
508   tests.back().str = "key=\"abcdef; otherkey=1234";
509 
510   // Quoted value with unclosed quote followed by another quoted value.
511   tests.emplace_back();
512   tests.back().str = "key=\"abcdef; otherkey=\"1234\"";
513   tests.back().parsed.emplace_back(std::string("key"),
514                                    std::string("\"abcdef; otherkey=\""));
515   tests.back().parsed.emplace_back(std::string("234\""), std::string());
516   tests.back().serialized = "key=\"abcdef; otherkey=\"; 234\"=";
517 
518   // Regular value followed by quoted value with unclosed quote.
519   tests.emplace_back();
520   tests.back().str = "key=abcdef; otherkey=\"1234";
521   tests.back().parsed.emplace_back(std::string("key"), std::string("abcdef"));
522   tests.back().serialized = "key=abcdef";
523 
524   for (size_t i = 0; i < tests.size(); i++) {
525     SCOPED_TRACE(testing::Message() << "Test " << i);
526     CheckParse(tests[i].str, tests[i].parsed);
527     CheckSerialize(tests[i].parsed, tests[i].serialized);
528   }
529 }
530 
TEST(CookieUtilTest,CookieDomainAndPathToURL)531 TEST(CookieUtilTest, CookieDomainAndPathToURL) {
532   struct {
533     std::string domain;
534     std::string path;
535     bool is_https;
536     std::string expected_url;
537   } kTests[]{
538       {"a.com", "/", true, "https://a.com/"},
539       {"a.com", "/", false, "http://a.com/"},
540       {".a.com", "/", true, "https://a.com/"},
541       {".a.com", "/", false, "http://a.com/"},
542       {"b.a.com", "/", true, "https://b.a.com/"},
543       {"b.a.com", "/", false, "http://b.a.com/"},
544       {"a.com", "/example/path", true, "https://a.com/example/path"},
545       {".a.com", "/example/path", false, "http://a.com/example/path"},
546       {"b.a.com", "/example/path", true, "https://b.a.com/example/path"},
547       {".b.a.com", "/example/path", false, "http://b.a.com/example/path"},
548   };
549 
550   for (auto& test : kTests) {
551     GURL url1 = cookie_util::CookieDomainAndPathToURL(test.domain, test.path,
552                                                       test.is_https);
553     GURL url2 = cookie_util::CookieDomainAndPathToURL(
554         test.domain, test.path, std::string(test.is_https ? "https" : "http"));
555     // Test both overloads for equality.
556     EXPECT_EQ(url1, url2);
557     EXPECT_EQ(url1, GURL(test.expected_url));
558   }
559 }
560 
TEST(CookieUtilTest,SimulatedCookieSource)561 TEST(CookieUtilTest, SimulatedCookieSource) {
562   GURL secure_url("https://b.a.com");
563   GURL insecure_url("http://b.a.com");
564 
565   struct {
566     std::string cookie;
567     std::string source_scheme;
568     std::string expected_simulated_source;
569   } kTests[]{
570       {"cookie=foo", "http", "http://b.a.com/"},
571       {"cookie=foo", "https", "https://b.a.com/"},
572       {"cookie=foo", "wss", "wss://b.a.com/"},
573       {"cookie=foo", "file", "file://b.a.com/"},
574       {"cookie=foo; Domain=b.a.com", "https", "https://b.a.com/"},
575       {"cookie=foo; Domain=a.com", "https", "https://a.com/"},
576       {"cookie=foo; Domain=.b.a.com", "https", "https://b.a.com/"},
577       {"cookie=foo; Domain=.a.com", "https", "https://a.com/"},
578       {"cookie=foo; Path=/", "https", "https://b.a.com/"},
579       {"cookie=foo; Path=/bar", "https", "https://b.a.com/bar"},
580       {"cookie=foo; Domain=b.a.com; Path=/", "https", "https://b.a.com/"},
581       {"cookie=foo; Domain=b.a.com; Path=/bar", "https", "https://b.a.com/bar"},
582       {"cookie=foo; Domain=a.com; Path=/", "https", "https://a.com/"},
583       {"cookie=foo; Domain=a.com; Path=/bar", "https", "https://a.com/bar"},
584   };
585 
586   for (const auto& test : kTests) {
587     std::vector<std::unique_ptr<CanonicalCookie>> cookies;
588     // It shouldn't depend on the cookie's secureness or actual source scheme.
589     cookies.push_back(CanonicalCookie::CreateForTesting(
590         insecure_url, test.cookie, base::Time::Now()));
591     cookies.push_back(CanonicalCookie::CreateForTesting(secure_url, test.cookie,
592                                                         base::Time::Now()));
593     cookies.push_back(CanonicalCookie::CreateForTesting(
594         secure_url, test.cookie + "; Secure", base::Time::Now()));
595     for (const auto& cookie : cookies) {
596       GURL simulated_source =
597           cookie_util::SimulatedCookieSource(*cookie, test.source_scheme);
598       EXPECT_EQ(GURL(test.expected_simulated_source), simulated_source);
599     }
600   }
601 }
602 
TEST(CookieUtilTest,TestGetEffectiveDomain)603 TEST(CookieUtilTest, TestGetEffectiveDomain) {
604   // Note: registry_controlled_domains::GetDomainAndRegistry is tested in its
605   // own unittests.
606   EXPECT_EQ("example.com",
607             cookie_util::GetEffectiveDomain("http", "www.example.com"));
608   EXPECT_EQ("example.com",
609             cookie_util::GetEffectiveDomain("https", "www.example.com"));
610   EXPECT_EQ("example.com",
611             cookie_util::GetEffectiveDomain("ws", "www.example.com"));
612   EXPECT_EQ("example.com",
613             cookie_util::GetEffectiveDomain("wss", "www.example.com"));
614   EXPECT_EQ("www.example.com",
615             cookie_util::GetEffectiveDomain("ftp", "www.example.com"));
616 }
617 
TEST(CookieUtilTest,TestIsDomainMatch)618 TEST(CookieUtilTest, TestIsDomainMatch) {
619   EXPECT_TRUE(cookie_util::IsDomainMatch("example.com", "example.com"));
620   EXPECT_FALSE(cookie_util::IsDomainMatch("www.example.com", "example.com"));
621 
622   EXPECT_TRUE(cookie_util::IsDomainMatch(".example.com", "example.com"));
623   EXPECT_TRUE(cookie_util::IsDomainMatch(".example.com", "www.example.com"));
624   EXPECT_FALSE(cookie_util::IsDomainMatch(".www.example.com", "example.com"));
625 
626   EXPECT_FALSE(cookie_util::IsDomainMatch("example.com", "example.de"));
627   EXPECT_FALSE(cookie_util::IsDomainMatch(".example.com", "example.de"));
628   EXPECT_FALSE(cookie_util::IsDomainMatch(".example.de", "example.de.vu"));
629 }
630 
TEST(CookieUtilTest,TestIsOnPath)631 TEST(CookieUtilTest, TestIsOnPath) {
632   EXPECT_TRUE(cookie_util::IsOnPath("/", "/"));
633   EXPECT_TRUE(cookie_util::IsOnPath("/", "/test"));
634   EXPECT_TRUE(cookie_util::IsOnPath("/", "/test/bar.html"));
635 
636   // Test the empty string edge case.
637   EXPECT_FALSE(cookie_util::IsOnPath("/", std::string()));
638 
639   EXPECT_FALSE(cookie_util::IsOnPath("/test", "/"));
640 
641   EXPECT_TRUE(cookie_util::IsOnPath("/test", "/test"));
642   EXPECT_FALSE(cookie_util::IsOnPath("/test", "/testtest/"));
643 
644   EXPECT_TRUE(cookie_util::IsOnPath("/test", "/test/bar.html"));
645   EXPECT_TRUE(cookie_util::IsOnPath("/test", "/test/sample/bar.html"));
646 }
647 
TEST(CookieUtilTest,TestIsOnPathCaseSensitive)648 TEST(CookieUtilTest, TestIsOnPathCaseSensitive) {
649   EXPECT_TRUE(cookie_util::IsOnPath("/test", "/test"));
650   EXPECT_FALSE(cookie_util::IsOnPath("/test", "/TEST"));
651   EXPECT_FALSE(cookie_util::IsOnPath("/TEST", "/test"));
652 }
653 
654 using ::testing::AllOf;
655 using SameSiteCookieContext = CookieOptions::SameSiteCookieContext;
656 using ContextType = CookieOptions::SameSiteCookieContext::ContextType;
657 using ContextRedirectTypeBug1221316 = CookieOptions::SameSiteCookieContext::
658     ContextMetadata::ContextRedirectTypeBug1221316;
659 using HttpMethod =
660     CookieOptions::SameSiteCookieContext::ContextMetadata::HttpMethod;
661 
662 MATCHER_P2(ContextTypeIsWithSchemefulMode, context_type, schemeful, "") {
663   return context_type == (schemeful ? arg.schemeful_context() : arg.context());
664 }
665 
666 // Checks for the expected metadata related to context downgrades from
667 // cross-site redirects.
668 MATCHER_P5(CrossSiteRedirectMetadataCorrectWithSchemefulMode,
669            method,
670            context_type_without_chain,
671            context_type_with_chain,
672            redirect_type_with_chain,
673            schemeful,
674            "") {
675   using ContextDowngradeType = CookieOptions::SameSiteCookieContext::
676       ContextMetadata::ContextDowngradeType;
677 
678   const auto& metadata = schemeful ? arg.schemeful_metadata() : arg.metadata();
679 
680   if (metadata.redirect_type_bug_1221316 != redirect_type_with_chain)
681     return false;
682 
683   // http_method_bug_1221316 is only set when there is a context downgrade.
684   if (metadata.cross_site_redirect_downgrade !=
685           ContextDowngradeType::kNoDowngrade &&
686       metadata.http_method_bug_1221316 != method) {
687     return false;
688   }
689 
690   switch (metadata.cross_site_redirect_downgrade) {
691     case ContextDowngradeType::kNoDowngrade:
692       return context_type_without_chain == context_type_with_chain;
693     case ContextDowngradeType::kStrictToLax:
694       return context_type_without_chain == ContextType::SAME_SITE_STRICT &&
695              (context_type_with_chain == ContextType::SAME_SITE_LAX ||
696               context_type_with_chain ==
697                   ContextType::SAME_SITE_LAX_METHOD_UNSAFE);
698     case ContextDowngradeType::kStrictToCross:
699       return context_type_without_chain == ContextType::SAME_SITE_STRICT &&
700              context_type_with_chain == ContextType::CROSS_SITE;
701     case ContextDowngradeType::kLaxToCross:
702       return (context_type_without_chain == ContextType::SAME_SITE_LAX ||
703               context_type_without_chain ==
704                   ContextType::SAME_SITE_LAX_METHOD_UNSAFE) &&
705              context_type_with_chain == ContextType::CROSS_SITE;
706   }
707 }
708 
UrlChainToString(const std::vector<GURL> & url_chain)709 std::string UrlChainToString(const std::vector<GURL>& url_chain) {
710   std::string s;
711   for (const GURL& url : url_chain) {
712     base::StrAppend(&s, {" ", url.spec()});
713   }
714   return s;
715 }
716 
717 // Tests for the various ComputeSameSiteContextFor*() functions. The first
718 // boolean test param is whether the results of the computations are evaluated
719 // schemefully. The second boolean param is whether SameSite considers redirect
720 // chains.
721 class CookieUtilComputeSameSiteContextTest
722     : public ::testing::TestWithParam<std::tuple<bool, bool>> {
723  public:
CookieUtilComputeSameSiteContextTest()724   CookieUtilComputeSameSiteContextTest() {
725     if (DoesSameSiteConsiderRedirectChain()) {
726       feature_list_.InitAndEnableFeature(
727           features::kCookieSameSiteConsidersRedirectChain);
728     } else {
729       // No need to explicitly disable the redirect chain feature because it
730       // is disabled by default.
731       feature_list_.Init();
732     }
733   }
734   ~CookieUtilComputeSameSiteContextTest() override = default;
735 
IsSchemeful() const736   bool IsSchemeful() const { return std::get<0>(GetParam()); }
737 
DoesSameSiteConsiderRedirectChain() const738   bool DoesSameSiteConsiderRedirectChain() const {
739     return std::get<1>(GetParam());
740   }
741 
742   // Returns the proper gtest matcher to use for the schemeless/schemeful mode.
ContextTypeIs(ContextType context_type) const743   auto ContextTypeIs(ContextType context_type) const {
744     return ContextTypeIsWithSchemefulMode(context_type, IsSchemeful());
745   }
746 
CrossSiteRedirectMetadataCorrect(HttpMethod method,ContextType context_type_without_chain,ContextType context_type_with_chain,ContextRedirectTypeBug1221316 redirect_type_with_chain) const747   auto CrossSiteRedirectMetadataCorrect(
748       HttpMethod method,
749       ContextType context_type_without_chain,
750       ContextType context_type_with_chain,
751       ContextRedirectTypeBug1221316 redirect_type_with_chain) const {
752     return CrossSiteRedirectMetadataCorrectWithSchemefulMode(
753         method, context_type_without_chain, context_type_with_chain,
754         redirect_type_with_chain, IsSchemeful());
755   }
756 
757   // The following methods return the sets of URLs/SiteForCookies/initiators/URL
758   // chains that are same-site or cross-site with respect to kSiteUrl.
759 
GetAllUrls() const760   std::vector<GURL> GetAllUrls() const {
761     return {kSiteUrl,
762             kSiteUrlWithPath,
763             kSecureSiteUrl,
764             kCrossSiteUrl,
765             kSecureCrossSiteUrl,
766             kSubdomainUrl,
767             kSecureSubdomainUrl,
768             kWsUrl,
769             kWssUrl};
770   }
771 
GetSameSiteUrls() const772   std::vector<GURL> GetSameSiteUrls() const {
773     // Same-site-same-scheme URLs are always same-site. (ws counts as
774     // same-scheme with http.)
775     std::vector<GURL> same_site_urls{kSiteUrl, kSiteUrlWithPath, kSubdomainUrl,
776                                      kWsUrl};
777     // If schemeless, the cross-scheme URLs are also same-site.
778     if (!IsSchemeful()) {
779       same_site_urls.push_back(kSecureSiteUrl);
780       same_site_urls.push_back(kSecureSubdomainUrl);
781       same_site_urls.push_back(kWssUrl);
782     }
783     return same_site_urls;
784   }
785 
GetCrossSiteUrls() const786   std::vector<GURL> GetCrossSiteUrls() const {
787     std::vector<GURL> cross_site_urls;
788     std::vector<GURL> same_site_urls = GetSameSiteUrls();
789     for (const GURL& url : GetAllUrls()) {
790       if (!base::Contains(same_site_urls, url))
791         cross_site_urls.push_back(url);
792     }
793     return cross_site_urls;
794   }
795 
GetAllSitesForCookies() const796   std::vector<SiteForCookies> GetAllSitesForCookies() const {
797     return {kNullSiteForCookies, kSiteForCookies, kSecureSiteForCookies,
798             kCrossSiteForCookies, kSecureCrossSiteForCookies};
799   }
800 
GetSameSiteSitesForCookies() const801   std::vector<SiteForCookies> GetSameSiteSitesForCookies() const {
802     std::vector<SiteForCookies> same_site_sfc = {kSiteForCookies};
803     // If schemeless, the cross-scheme SFC is also same-site.
804     if (!IsSchemeful())
805       same_site_sfc.push_back(kSecureSiteForCookies);
806     return same_site_sfc;
807   }
808 
GetCrossSiteSitesForCookies() const809   std::vector<SiteForCookies> GetCrossSiteSitesForCookies() const {
810     std::vector<SiteForCookies> cross_site_sfc;
811     std::vector<SiteForCookies> same_site_sfc = GetSameSiteSitesForCookies();
812     for (const SiteForCookies& sfc : GetAllSitesForCookies()) {
813       if (!base::Contains(same_site_sfc, sfc.RepresentativeUrl(),
814                           &SiteForCookies::RepresentativeUrl)) {
815         cross_site_sfc.push_back(sfc);
816       }
817     }
818     return cross_site_sfc;
819   }
820 
GetAllInitiators() const821   std::vector<std::optional<url::Origin>> GetAllInitiators() const {
822     return {kBrowserInitiated,   kOpaqueInitiator,
823             kSiteInitiator,      kSecureSiteInitiator,
824             kCrossSiteInitiator, kSecureCrossSiteInitiator,
825             kSubdomainInitiator, kSecureSubdomainInitiator,
826             kUnrelatedInitiator};
827   }
828 
GetSameSiteInitiators() const829   std::vector<std::optional<url::Origin>> GetSameSiteInitiators() const {
830     std::vector<std::optional<url::Origin>> same_site_initiators{
831         kBrowserInitiated, kSiteInitiator, kSubdomainInitiator};
832     // If schemeless, the cross-scheme origins are also same-site.
833     if (!IsSchemeful()) {
834       same_site_initiators.push_back(kSecureSiteInitiator);
835       same_site_initiators.push_back(kSecureSubdomainInitiator);
836     }
837     return same_site_initiators;
838   }
839 
GetCrossSiteInitiators() const840   std::vector<std::optional<url::Origin>> GetCrossSiteInitiators() const {
841     std::vector<std::optional<url::Origin>> cross_site_initiators;
842     std::vector<std::optional<url::Origin>> same_site_initiators =
843         GetSameSiteInitiators();
844     for (const std::optional<url::Origin>& initiator : GetAllInitiators()) {
845       if (!base::Contains(same_site_initiators, initiator))
846         cross_site_initiators.push_back(initiator);
847     }
848     return cross_site_initiators;
849   }
850 
851   // Returns an assortment of redirect chains that end in `url` as the
852   // current request URL, and are completely same-site. `url` is expected to be
853   // same-site to kSiteUrl.
GetSameSiteUrlChains(const GURL & url) const854   std::vector<std::vector<GURL>> GetSameSiteUrlChains(const GURL& url) const {
855     std::vector<std::vector<GURL>> same_site_url_chains;
856     for (const GURL& same_site_url : GetSameSiteUrls()) {
857       same_site_url_chains.push_back({same_site_url, url});
858       for (const GURL& other_same_site_url : GetSameSiteUrls()) {
859         same_site_url_chains.push_back(
860             {other_same_site_url, same_site_url, url});
861       }
862     }
863     return same_site_url_chains;
864   }
865 
866   // Returns an assortment of redirect chains that end in `url` as the
867   // current request URL, and are cross-site. `url` is expected to be same-site
868   // to kSiteUrl.
GetCrossSiteUrlChains(const GURL & url) const869   std::vector<std::vector<GURL>> GetCrossSiteUrlChains(const GURL& url) const {
870     std::vector<std::vector<GURL>> cross_site_url_chains;
871     for (const GURL& cross_site_url : GetCrossSiteUrls()) {
872       cross_site_url_chains.push_back({cross_site_url, url});
873       for (const GURL& same_site_url : GetSameSiteUrls()) {
874         cross_site_url_chains.push_back({cross_site_url, same_site_url, url});
875         cross_site_url_chains.push_back({same_site_url, cross_site_url, url});
876       }
877     }
878     return cross_site_url_chains;
879   }
880 
881   // Computes possible values of is_main_frame_navigation that are consistent
882   // with the DCHECKs.
CanBeMainFrameNavigation(const GURL & url,const SiteForCookies & site_for_cookies) const883   bool CanBeMainFrameNavigation(const GURL& url,
884                                 const SiteForCookies& site_for_cookies) const {
885     return (site_for_cookies.IsNull() ||
886             site_for_cookies.IsFirstPartyWithSchemefulMode(url, true)) &&
887            !url.SchemeIsWSOrWSS();
888   }
889 
IsMainFrameNavigationPossibleValues(const GURL & url,const SiteForCookies & site_for_cookies) const890   std::vector<bool> IsMainFrameNavigationPossibleValues(
891       const GURL& url,
892       const SiteForCookies& site_for_cookies) const {
893     return CanBeMainFrameNavigation(url, site_for_cookies)
894                ? std::vector<bool>{false, true}
895                : std::vector<bool>{false};
896   }
897 
898   // Request URL.
899   const GURL kSiteUrl{"http://example.test/"};
900   const GURL kSiteUrlWithPath{"http://example.test/path"};
901   const GURL kSecureSiteUrl{"https://example.test/"};
902   const GURL kCrossSiteUrl{"http://notexample.test/"};
903   const GURL kSecureCrossSiteUrl{"https://notexample.test/"};
904   const GURL kSubdomainUrl{"http://subdomain.example.test/"};
905   const GURL kSecureSubdomainUrl{"https://subdomain.example.test/"};
906   const GURL kWsUrl{"ws://example.test/"};
907   const GURL kWssUrl{"wss://example.test/"};
908   // Site for cookies.
909   const SiteForCookies kNullSiteForCookies;
910   const SiteForCookies kSiteForCookies = SiteForCookies::FromUrl(kSiteUrl);
911   const SiteForCookies kSecureSiteForCookies =
912       SiteForCookies::FromUrl(kSecureSiteUrl);
913   const SiteForCookies kCrossSiteForCookies =
914       SiteForCookies::FromUrl(kCrossSiteUrl);
915   const SiteForCookies kSecureCrossSiteForCookies =
916       SiteForCookies::FromUrl(kSecureCrossSiteUrl);
917   // Initiator origin.
918   const std::optional<url::Origin> kBrowserInitiated = std::nullopt;
919   const std::optional<url::Origin> kOpaqueInitiator =
920       std::make_optional(url::Origin());
921   const std::optional<url::Origin> kSiteInitiator =
922       std::make_optional(url::Origin::Create(kSiteUrl));
923   const std::optional<url::Origin> kSecureSiteInitiator =
924       std::make_optional(url::Origin::Create(kSecureSiteUrl));
925   const std::optional<url::Origin> kCrossSiteInitiator =
926       std::make_optional(url::Origin::Create(kCrossSiteUrl));
927   const std::optional<url::Origin> kSecureCrossSiteInitiator =
928       std::make_optional(url::Origin::Create(kSecureCrossSiteUrl));
929   const std::optional<url::Origin> kSubdomainInitiator =
930       std::make_optional(url::Origin::Create(kSubdomainUrl));
931   const std::optional<url::Origin> kSecureSubdomainInitiator =
932       std::make_optional(url::Origin::Create(kSecureSubdomainUrl));
933   const std::optional<url::Origin> kUnrelatedInitiator =
934       std::make_optional(url::Origin::Create(GURL("https://unrelated.test/")));
935 
936  protected:
937   base::test::ScopedFeatureList feature_list_;
938 };
939 
TEST_P(CookieUtilComputeSameSiteContextTest,UrlAndSiteForCookiesCrossSite)940 TEST_P(CookieUtilComputeSameSiteContextTest, UrlAndSiteForCookiesCrossSite) {
941   // If the SiteForCookies and URL are cross-site, then the context is always
942   // cross-site.
943   for (const GURL& url : GetSameSiteUrls()) {
944     for (const SiteForCookies& site_for_cookies :
945          GetCrossSiteSitesForCookies()) {
946       for (const std::optional<url::Origin>& initiator : GetAllInitiators()) {
947         for (const std::string& method : {"GET", "POST", "PUT", "HEAD"}) {
948           EXPECT_THAT(cookie_util::ComputeSameSiteContextForScriptGet(
949                           url, site_for_cookies, initiator,
950                           false /* force_ignore_site_for_cookies */),
951                       ContextTypeIs(ContextType::CROSS_SITE));
952           EXPECT_THAT(cookie_util::ComputeSameSiteContextForScriptSet(
953                           url, site_for_cookies,
954                           false /* force_ignore_site_for_cookies */),
955                       ContextTypeIs(ContextType::CROSS_SITE));
956           for (bool is_main_frame_navigation :
957                IsMainFrameNavigationPossibleValues(url, site_for_cookies)) {
958             EXPECT_THAT(cookie_util::ComputeSameSiteContextForRequest(
959                             method, {url}, site_for_cookies, initiator,
960                             is_main_frame_navigation,
961                             false /* force_ignore_site_for_cookies */),
962                         ContextTypeIs(ContextType::CROSS_SITE));
963             EXPECT_THAT(cookie_util::ComputeSameSiteContextForResponse(
964                             {url}, site_for_cookies, initiator,
965                             is_main_frame_navigation,
966                             false /* force_ignore_site_for_cookies */),
967                         ContextTypeIs(ContextType::CROSS_SITE));
968             // If the current request URL is cross-site to the site-for-cookies,
969             // the request context is always cross-site even if the URL chain
970             // contains members that are same-site to the site-for-cookies.
971             EXPECT_THAT(
972                 cookie_util::ComputeSameSiteContextForRequest(
973                     method, {site_for_cookies.RepresentativeUrl(), url},
974                     site_for_cookies, initiator, is_main_frame_navigation,
975                     false /* force_ignore_site_for_cookies */),
976                 ContextTypeIs(ContextType::CROSS_SITE));
977             EXPECT_THAT(
978                 cookie_util::ComputeSameSiteContextForResponse(
979                     {site_for_cookies.RepresentativeUrl(), url},
980                     site_for_cookies, initiator, is_main_frame_navigation,
981                     false /* force_ignore_site_for_cookies */),
982                 ContextTypeIs(ContextType::CROSS_SITE));
983           }
984           EXPECT_THAT(cookie_util::ComputeSameSiteContextForSubresource(
985                           url, site_for_cookies,
986                           false /* force_ignore_site_for_cookies */),
987                       ContextTypeIs(ContextType::CROSS_SITE));
988         }
989       }
990     }
991   }
992 }
993 
TEST_P(CookieUtilComputeSameSiteContextTest,SiteForCookiesNotSchemefullySame)994 TEST_P(CookieUtilComputeSameSiteContextTest, SiteForCookiesNotSchemefullySame) {
995   // If the SiteForCookies is not schemefully_same, even if its value is
996   // schemefully same-site, the schemeful context type will be cross-site.
997   if (!IsSchemeful())
998     return;
999 
1000   std::vector<SiteForCookies> sites_for_cookies = GetAllSitesForCookies();
1001   for (SiteForCookies& sfc : sites_for_cookies) {
1002     sfc.SetSchemefullySameForTesting(false);
1003   }
1004 
1005   for (const GURL& url : GetSameSiteUrls()) {
1006     for (const SiteForCookies& site_for_cookies : sites_for_cookies) {
1007       for (const std::optional<url::Origin>& initiator : GetAllInitiators()) {
1008         for (const std::string& method : {"GET", "POST", "PUT", "HEAD"}) {
1009           EXPECT_THAT(cookie_util::ComputeSameSiteContextForScriptGet(
1010                           url, site_for_cookies, initiator,
1011                           false /* force_ignore_site_for_cookies */),
1012                       ContextTypeIs(ContextType::CROSS_SITE));
1013           EXPECT_THAT(cookie_util::ComputeSameSiteContextForScriptSet(
1014                           url, site_for_cookies,
1015                           false /* force_ignore_site_for_cookies */),
1016                       ContextTypeIs(ContextType::CROSS_SITE));
1017 
1018           // If the site-for-cookies isn't schemefully_same, this cannot be a
1019           // main frame navigation.
1020           EXPECT_THAT(cookie_util::ComputeSameSiteContextForRequest(
1021                           method, {url}, site_for_cookies, initiator,
1022                           false /* is_main_frame_navigation */,
1023                           false /* force_ignore_site_for_cookies */),
1024                       ContextTypeIs(ContextType::CROSS_SITE));
1025           EXPECT_THAT(cookie_util::ComputeSameSiteContextForResponse(
1026                           {url}, site_for_cookies, initiator,
1027                           false /* is_main_frame_navigation */,
1028                           false /* force_ignore_site_for_cookies */),
1029                       ContextTypeIs(ContextType::CROSS_SITE));
1030 
1031           EXPECT_THAT(cookie_util::ComputeSameSiteContextForSubresource(
1032                           url, site_for_cookies,
1033                           false /* force_ignore_site_for_cookies */),
1034                       ContextTypeIs(ContextType::CROSS_SITE));
1035         }
1036       }
1037     }
1038   }
1039 }
1040 
TEST_P(CookieUtilComputeSameSiteContextTest,ForScriptGet)1041 TEST_P(CookieUtilComputeSameSiteContextTest, ForScriptGet) {
1042   for (const GURL& url : GetSameSiteUrls()) {
1043     // Same-site site-for-cookies.
1044     // (Cross-site cases covered above in UrlAndSiteForCookiesCrossSite test.)
1045     for (const SiteForCookies& site_for_cookies :
1046          GetSameSiteSitesForCookies()) {
1047       // Cross-site initiator -> it's same-site lax.
1048       for (const std::optional<url::Origin>& initiator :
1049            GetCrossSiteInitiators()) {
1050         EXPECT_THAT(cookie_util::ComputeSameSiteContextForScriptGet(
1051                         url, site_for_cookies, initiator,
1052                         false /* force_ignore_site_for_cookies */),
1053                     ContextTypeIs(ContextType::SAME_SITE_LAX));
1054       }
1055 
1056       // Same-site initiator -> it's same-site strict.
1057       for (const std::optional<url::Origin>& initiator :
1058            GetSameSiteInitiators()) {
1059         EXPECT_THAT(cookie_util::ComputeSameSiteContextForScriptGet(
1060                         url, site_for_cookies, initiator,
1061                         false /* force_ignore_site_for_cookies */),
1062                     ContextTypeIs(ContextType::SAME_SITE_STRICT));
1063       }
1064     }
1065   }
1066 }
1067 
TEST_P(CookieUtilComputeSameSiteContextTest,ForScriptGet_SchemefulDowngrade)1068 TEST_P(CookieUtilComputeSameSiteContextTest, ForScriptGet_SchemefulDowngrade) {
1069   // Some test cases where the context is downgraded when computed schemefully.
1070   // (Should already be covered above, but just to be explicit.)
1071   EXPECT_EQ(SameSiteCookieContext(ContextType::SAME_SITE_STRICT,
1072                                   ContextType::SAME_SITE_LAX),
1073             cookie_util::ComputeSameSiteContextForScriptGet(
1074                 kSiteUrl, kSiteForCookies, kSecureSiteInitiator,
1075                 false /* force_ignore_site_for_cookies */));
1076   EXPECT_EQ(SameSiteCookieContext(ContextType::SAME_SITE_STRICT,
1077                                   ContextType::SAME_SITE_LAX),
1078             cookie_util::ComputeSameSiteContextForScriptGet(
1079                 kSecureSiteUrl, kSecureSiteForCookies, kSiteInitiator,
1080                 false /* force_ignore_site_for_cookies */));
1081   EXPECT_EQ(SameSiteCookieContext(ContextType::SAME_SITE_LAX,
1082                                   ContextType::CROSS_SITE),
1083             cookie_util::ComputeSameSiteContextForScriptGet(
1084                 kSecureSiteUrl, kSiteForCookies, kCrossSiteInitiator,
1085                 false /* force_ignore_site_for_cookies */));
1086   EXPECT_EQ(SameSiteCookieContext(ContextType::SAME_SITE_LAX,
1087                                   ContextType::CROSS_SITE),
1088             cookie_util::ComputeSameSiteContextForScriptGet(
1089                 kSiteUrl, kSecureSiteForCookies, kCrossSiteInitiator,
1090                 false /* force_ignore_site_for_cookies */));
1091 }
1092 
TEST_P(CookieUtilComputeSameSiteContextTest,ForScriptGet_WebSocketSchemes)1093 TEST_P(CookieUtilComputeSameSiteContextTest, ForScriptGet_WebSocketSchemes) {
1094   // wss/https and http/ws are considered the same for schemeful purposes.
1095   EXPECT_THAT(cookie_util::ComputeSameSiteContextForScriptGet(
1096                   kWssUrl, kSecureSiteForCookies, kSecureSiteInitiator,
1097                   false /* force_ignore_site_for_cookies */),
1098               ContextTypeIs(ContextType::SAME_SITE_STRICT));
1099   EXPECT_THAT(cookie_util::ComputeSameSiteContextForScriptGet(
1100                   kWssUrl, kSecureSiteForCookies, kSecureCrossSiteInitiator,
1101                   false /* force_ignore_site_for_cookies */),
1102               ContextTypeIs(ContextType::SAME_SITE_LAX));
1103 
1104   EXPECT_THAT(cookie_util::ComputeSameSiteContextForScriptGet(
1105                   kWsUrl, kSiteForCookies, kSiteInitiator,
1106                   false /* force_ignore_site_for_cookies */),
1107               ContextTypeIs(ContextType::SAME_SITE_STRICT));
1108   EXPECT_THAT(cookie_util::ComputeSameSiteContextForScriptGet(
1109                   kWsUrl, kSiteForCookies, kCrossSiteInitiator,
1110                   false /* force_ignore_site_for_cookies */),
1111               ContextTypeIs(ContextType::SAME_SITE_LAX));
1112 }
1113 
1114 // Test cases where the URL chain has 1 member (i.e. no redirects).
TEST_P(CookieUtilComputeSameSiteContextTest,ForRequest)1115 TEST_P(CookieUtilComputeSameSiteContextTest, ForRequest) {
1116   for (const GURL& url : GetSameSiteUrls()) {
1117     // Same-site site-for-cookies.
1118     // (Cross-site cases covered above in UrlAndSiteForCookiesCrossSite test.)
1119     for (const SiteForCookies& site_for_cookies :
1120          GetSameSiteSitesForCookies()) {
1121       // Same-Site initiator -> it's same-site strict.
1122       for (const std::optional<url::Origin>& initiator :
1123            GetSameSiteInitiators()) {
1124         for (const std::string& method : {"GET", "POST", "PUT", "HEAD"}) {
1125           for (bool is_main_frame_navigation :
1126                IsMainFrameNavigationPossibleValues(url, site_for_cookies)) {
1127             EXPECT_THAT(cookie_util::ComputeSameSiteContextForRequest(
1128                             method, {url}, site_for_cookies, initiator,
1129                             is_main_frame_navigation,
1130                             false /* force_ignore_site_for_cookies */),
1131                         ContextTypeIs(ContextType::SAME_SITE_STRICT));
1132           }
1133         }
1134       }
1135 
1136       // Cross-Site initiator -> it's same-site lax iff the method is safe.
1137       for (const std::optional<url::Origin>& initiator :
1138            GetCrossSiteInitiators()) {
1139         // For main frame navigations, the context is Lax (or Lax-unsafe).
1140         for (const std::string& method : {"GET", "HEAD"}) {
1141           if (!CanBeMainFrameNavigation(url, site_for_cookies))
1142             break;
1143           EXPECT_THAT(cookie_util::ComputeSameSiteContextForRequest(
1144                           method, {url}, site_for_cookies, initiator,
1145                           true /* is_main_frame_navigation */,
1146                           false /* force_ignore_site_for_cookies */),
1147                       ContextTypeIs(ContextType::SAME_SITE_LAX));
1148         }
1149         for (const std::string& method : {"POST", "PUT"}) {
1150           if (!CanBeMainFrameNavigation(url, site_for_cookies))
1151             break;
1152           EXPECT_THAT(cookie_util::ComputeSameSiteContextForRequest(
1153                           method, {url}, site_for_cookies, initiator,
1154                           true /* is_main_frame_navigation */,
1155                           false /* force_ignore_site_for_cookies */),
1156                       ContextTypeIs(ContextType::SAME_SITE_LAX_METHOD_UNSAFE));
1157         }
1158 
1159         // For non-main-frame-navigation requests, the context should be
1160         // cross-site.
1161         for (const std::string& method : {"GET", "POST", "PUT", "HEAD"}) {
1162           EXPECT_THAT(cookie_util::ComputeSameSiteContextForRequest(
1163                           method, {url}, site_for_cookies, initiator,
1164                           false /* is_main_frame_navigation */,
1165                           false /* force_ignore_site_for_cookies */),
1166                       ContextTypeIs(ContextType::CROSS_SITE));
1167         }
1168       }
1169     }
1170   }
1171 }
1172 
TEST_P(CookieUtilComputeSameSiteContextTest,ForRequest_SchemefulDowngrade)1173 TEST_P(CookieUtilComputeSameSiteContextTest, ForRequest_SchemefulDowngrade) {
1174   // Some test cases where the context is downgraded when computed schemefully.
1175   // (Should already be covered above, but just to be explicit.)
1176 
1177   // Cross-scheme URL and site-for-cookies with (schemelessly) same-site
1178   // initiator.
1179   // (The request cannot be a main frame navigation if the site-for-cookies is
1180   // not schemefully same-site).
1181   for (const std::string& method : {"GET", "POST"}) {
1182     EXPECT_EQ(SameSiteCookieContext(ContextType::SAME_SITE_STRICT,
1183                                     ContextType::CROSS_SITE),
1184               cookie_util::ComputeSameSiteContextForRequest(
1185                   method, {kSecureSiteUrl}, kSiteForCookies, kSiteInitiator,
1186                   false /* is_main_frame_navigation */,
1187                   false /* force_ignore_site_for_cookies */));
1188     EXPECT_EQ(SameSiteCookieContext(ContextType::SAME_SITE_STRICT,
1189                                     ContextType::CROSS_SITE),
1190               cookie_util::ComputeSameSiteContextForRequest(
1191                   method, {kSiteUrl}, kSecureSiteForCookies, kSiteInitiator,
1192                   false /* is_main_frame_navigation */,
1193                   false /* force_ignore_site_for_cookies */));
1194   }
1195 
1196   // Schemefully same-site URL and site-for-cookies with cross-scheme
1197   // initiator.
1198   for (bool is_main_frame_navigation : {false, true}) {
1199     ContextType lax_if_main_frame = is_main_frame_navigation
1200                                         ? ContextType::SAME_SITE_LAX
1201                                         : ContextType::CROSS_SITE;
1202     ContextType lax_unsafe_if_main_frame =
1203         is_main_frame_navigation ? ContextType::SAME_SITE_LAX_METHOD_UNSAFE
1204                                  : ContextType::CROSS_SITE;
1205 
1206     EXPECT_EQ(
1207         SameSiteCookieContext(ContextType::SAME_SITE_STRICT, lax_if_main_frame),
1208         cookie_util::ComputeSameSiteContextForRequest(
1209             "GET", {kSecureSiteUrl}, kSecureSiteForCookies, kSiteInitiator,
1210             is_main_frame_navigation,
1211             false /* force_ignore_site_for_cookies */));
1212     EXPECT_EQ(
1213         SameSiteCookieContext(ContextType::SAME_SITE_STRICT, lax_if_main_frame),
1214         cookie_util::ComputeSameSiteContextForRequest(
1215             "GET", {kSiteUrl}, kSiteForCookies, kSecureSiteInitiator,
1216             is_main_frame_navigation,
1217             false /* force_ignore_site_for_cookies */));
1218     EXPECT_EQ(SameSiteCookieContext(ContextType::SAME_SITE_STRICT,
1219                                     lax_unsafe_if_main_frame),
1220               cookie_util::ComputeSameSiteContextForRequest(
1221                   "POST", {kSecureSiteUrl}, kSecureSiteForCookies,
1222                   kSiteInitiator, is_main_frame_navigation,
1223                   false /* force_ignore_site_for_cookies */));
1224     EXPECT_EQ(SameSiteCookieContext(ContextType::SAME_SITE_STRICT,
1225                                     lax_unsafe_if_main_frame),
1226               cookie_util::ComputeSameSiteContextForRequest(
1227                   "POST", {kSiteUrl}, kSiteForCookies, kSecureSiteInitiator,
1228                   is_main_frame_navigation,
1229                   false /* force_ignore_site_for_cookies */));
1230   }
1231 
1232   // Cross-scheme URL and site-for-cookies with cross-site initiator.
1233   // (The request cannot be a main frame navigation if the site-for-cookies is
1234   // not schemefully same-site).
1235   EXPECT_EQ(SameSiteCookieContext(ContextType::CROSS_SITE),
1236             cookie_util::ComputeSameSiteContextForRequest(
1237                 "GET", {kSiteUrl}, kSecureSiteForCookies, kCrossSiteInitiator,
1238                 false /* is_main_frame_navigation */,
1239                 false /* force_ignore_site_for_cookies */));
1240   EXPECT_EQ(SameSiteCookieContext(ContextType::CROSS_SITE),
1241             cookie_util::ComputeSameSiteContextForRequest(
1242                 "GET", {kSecureSiteUrl}, kSiteForCookies, kCrossSiteInitiator,
1243                 false /* is_main_frame_navigation */,
1244                 false /* force_ignore_site_for_cookies */));
1245   EXPECT_EQ(SameSiteCookieContext(ContextType::CROSS_SITE),
1246             cookie_util::ComputeSameSiteContextForRequest(
1247                 "POST", {kSiteUrl}, kSecureSiteForCookies, kCrossSiteInitiator,
1248                 false /* is_main_frame_navigation */,
1249                 false /* force_ignore_site_for_cookies */));
1250   EXPECT_EQ(SameSiteCookieContext(ContextType::CROSS_SITE),
1251             cookie_util::ComputeSameSiteContextForRequest(
1252                 "POST", {kSecureSiteUrl}, kSiteForCookies, kCrossSiteInitiator,
1253                 false /* is_main_frame_navigation */,
1254                 false /* force_ignore_site_for_cookies */));
1255 }
1256 
TEST_P(CookieUtilComputeSameSiteContextTest,ForRequest_WebSocketSchemes)1257 TEST_P(CookieUtilComputeSameSiteContextTest, ForRequest_WebSocketSchemes) {
1258   // wss/https and http/ws are considered the same for schemeful purposes.
1259   // (ws/wss requests cannot be main frame navigations.)
1260   EXPECT_THAT(cookie_util::ComputeSameSiteContextForRequest(
1261                   "GET", {kWssUrl}, kSecureSiteForCookies, kSecureSiteInitiator,
1262                   false /* is_main_frame_navigation */,
1263                   false /* force_ignore_site_for_cookies */),
1264               ContextTypeIs(ContextType::SAME_SITE_STRICT));
1265   EXPECT_THAT(
1266       cookie_util::ComputeSameSiteContextForRequest(
1267           "GET", {kWssUrl}, kSecureSiteForCookies, kSecureCrossSiteInitiator,
1268           false /* is_main_frame_navigation */,
1269           false /* force_ignore_site_for_cookies */),
1270       ContextTypeIs(ContextType::CROSS_SITE));
1271 
1272   EXPECT_THAT(cookie_util::ComputeSameSiteContextForRequest(
1273                   "GET", {kWsUrl}, kSiteForCookies, kSiteInitiator,
1274                   false /* is_main_frame_navigation */,
1275                   false /* force_ignore_site_for_cookies */),
1276               ContextTypeIs(ContextType::SAME_SITE_STRICT));
1277   EXPECT_THAT(cookie_util::ComputeSameSiteContextForRequest(
1278                   "GET", {kWsUrl}, kSiteForCookies, kCrossSiteInitiator,
1279                   false /* is_main_frame_navigation */,
1280                   false /* force_ignore_site_for_cookies */),
1281               ContextTypeIs(ContextType::CROSS_SITE));
1282 }
1283 
1284 // Test cases where the URL chain contains multiple members, where the last
1285 // member (current request URL) is same-site to kSiteUrl. (Everything is listed
1286 // as same-site or cross-site relative to kSiteUrl.)
TEST_P(CookieUtilComputeSameSiteContextTest,ForRequest_Redirect)1287 TEST_P(CookieUtilComputeSameSiteContextTest, ForRequest_Redirect) {
1288   struct {
1289     std::string method;
1290     bool url_chain_is_same_site;
1291     bool site_for_cookies_is_same_site;
1292     bool initiator_is_same_site;
1293     // These are the expected context types considering redirect chains:
1294     ContextType expected_context_type;  // for non-main-frame-nav requests.
1295     ContextType expected_context_type_for_main_frame_navigation;
1296     // These are the expected context types not considering redirect chains:
1297     ContextType expected_context_type_without_chain;
1298     ContextType expected_context_type_for_main_frame_navigation_without_chain;
1299     // The expected redirect type (only applicable for chains):
1300     ContextRedirectTypeBug1221316 expected_redirect_type_with_chain;
1301   } kTestCases[] = {
1302       // If the url chain is same-site, then the result is the same with or
1303       // without considering the redirect chain.
1304       {"GET", true, true, true, ContextType::SAME_SITE_STRICT,
1305        ContextType::SAME_SITE_STRICT, ContextType::SAME_SITE_STRICT,
1306        ContextType::SAME_SITE_STRICT,
1307        ContextRedirectTypeBug1221316::kAllSameSiteRedirect},
1308       {"GET", true, true, false, ContextType::CROSS_SITE,
1309        ContextType::SAME_SITE_LAX, ContextType::CROSS_SITE,
1310        ContextType::SAME_SITE_LAX,
1311        ContextRedirectTypeBug1221316::kCrossSiteRedirect},
1312       {"GET", true, false, true, ContextType::CROSS_SITE,
1313        ContextType::CROSS_SITE, ContextType::CROSS_SITE,
1314        ContextType::CROSS_SITE,
1315        ContextRedirectTypeBug1221316::kCrossSiteRedirect},
1316       {"GET", true, false, false, ContextType::CROSS_SITE,
1317        ContextType::CROSS_SITE, ContextType::CROSS_SITE,
1318        ContextType::CROSS_SITE,
1319        ContextRedirectTypeBug1221316::kCrossSiteRedirect},
1320       // If the url chain is cross-site, then the result will differ depending
1321       // on whether the redirect chain is considered, when the site-for-cookies
1322       // and initiator are both same-site.
1323       {"GET", false, true, true, ContextType::CROSS_SITE,
1324        ContextType::SAME_SITE_LAX, ContextType::SAME_SITE_STRICT,
1325        ContextType::SAME_SITE_STRICT,
1326        ContextRedirectTypeBug1221316::kPartialSameSiteRedirect},
1327       {"GET", false, true, false, ContextType::CROSS_SITE,
1328        ContextType::SAME_SITE_LAX, ContextType::CROSS_SITE,
1329        ContextType::SAME_SITE_LAX,
1330        ContextRedirectTypeBug1221316::kCrossSiteRedirect},
1331       {"GET", false, false, true, ContextType::CROSS_SITE,
1332        ContextType::CROSS_SITE, ContextType::CROSS_SITE,
1333        ContextType::CROSS_SITE,
1334        ContextRedirectTypeBug1221316::kCrossSiteRedirect},
1335       {"GET", false, false, false, ContextType::CROSS_SITE,
1336        ContextType::CROSS_SITE, ContextType::CROSS_SITE,
1337        ContextType::CROSS_SITE,
1338        ContextRedirectTypeBug1221316::kCrossSiteRedirect},
1339       // If the url chain is same-site, then the result is the same with or
1340       // without considering the redirect chain.
1341       {"POST", true, true, true, ContextType::SAME_SITE_STRICT,
1342        ContextType::SAME_SITE_STRICT, ContextType::SAME_SITE_STRICT,
1343        ContextType::SAME_SITE_STRICT,
1344        ContextRedirectTypeBug1221316::kAllSameSiteRedirect},
1345       {"POST", true, true, false, ContextType::CROSS_SITE,
1346        ContextType::SAME_SITE_LAX_METHOD_UNSAFE, ContextType::CROSS_SITE,
1347        ContextType::SAME_SITE_LAX_METHOD_UNSAFE,
1348        ContextRedirectTypeBug1221316::kCrossSiteRedirect},
1349       {"POST", true, false, true, ContextType::CROSS_SITE,
1350        ContextType::CROSS_SITE, ContextType::CROSS_SITE,
1351        ContextType::CROSS_SITE,
1352        ContextRedirectTypeBug1221316::kCrossSiteRedirect},
1353       {"POST", true, false, false, ContextType::CROSS_SITE,
1354        ContextType::CROSS_SITE, ContextType::CROSS_SITE,
1355        ContextType::CROSS_SITE,
1356        ContextRedirectTypeBug1221316::kCrossSiteRedirect},
1357       // If the url chain is cross-site, then the result will differ depending
1358       // on whether the redirect chain is considered, when the site-for-cookies
1359       // and initiator are both same-site.
1360       {"POST", false, true, true, ContextType::CROSS_SITE,
1361        ContextType::SAME_SITE_LAX_METHOD_UNSAFE, ContextType::SAME_SITE_STRICT,
1362        ContextType::SAME_SITE_STRICT,
1363        ContextRedirectTypeBug1221316::kPartialSameSiteRedirect},
1364       {"POST", false, true, false, ContextType::CROSS_SITE,
1365        ContextType::SAME_SITE_LAX_METHOD_UNSAFE, ContextType::CROSS_SITE,
1366        ContextType::SAME_SITE_LAX_METHOD_UNSAFE,
1367        ContextRedirectTypeBug1221316::kCrossSiteRedirect},
1368       {"POST", false, false, true, ContextType::CROSS_SITE,
1369        ContextType::CROSS_SITE, ContextType::CROSS_SITE,
1370        ContextType::CROSS_SITE,
1371        ContextRedirectTypeBug1221316::kCrossSiteRedirect},
1372       {"POST", false, false, false, ContextType::CROSS_SITE,
1373        ContextType::CROSS_SITE, ContextType::CROSS_SITE,
1374        ContextType::CROSS_SITE,
1375        ContextRedirectTypeBug1221316::kCrossSiteRedirect},
1376   };
1377 
1378   for (const auto& test_case : kTestCases) {
1379     std::vector<std::vector<GURL>> url_chains =
1380         test_case.url_chain_is_same_site ? GetSameSiteUrlChains(kSiteUrl)
1381                                          : GetCrossSiteUrlChains(kSiteUrl);
1382     std::vector<SiteForCookies> sites_for_cookies =
1383         test_case.site_for_cookies_is_same_site ? GetSameSiteSitesForCookies()
1384                                                 : GetCrossSiteSitesForCookies();
1385     std::vector<std::optional<url::Origin>> initiators =
1386         test_case.initiator_is_same_site ? GetSameSiteInitiators()
1387                                          : GetCrossSiteInitiators();
1388     ContextType expected_context_type =
1389         DoesSameSiteConsiderRedirectChain()
1390             ? test_case.expected_context_type
1391             : test_case.expected_context_type_without_chain;
1392     ContextType expected_context_type_for_main_frame_navigation =
1393         DoesSameSiteConsiderRedirectChain()
1394             ? test_case.expected_context_type_for_main_frame_navigation
1395             : test_case
1396                   .expected_context_type_for_main_frame_navigation_without_chain;
1397     for (const std::vector<GURL>& url_chain : url_chains) {
1398       for (const SiteForCookies& site_for_cookies : sites_for_cookies) {
1399         for (const std::optional<url::Origin>& initiator : initiators) {
1400           EXPECT_THAT(
1401               cookie_util::ComputeSameSiteContextForRequest(
1402                   test_case.method, url_chain, site_for_cookies, initiator,
1403                   false /* is_main_frame_navigation */,
1404                   false /* force_ignore_site_for_cookies */),
1405               AllOf(ContextTypeIs(expected_context_type),
1406                     CrossSiteRedirectMetadataCorrect(
1407                         cookie_util::HttpMethodStringToEnum(test_case.method),
1408                         test_case.expected_context_type_without_chain,
1409                         test_case.expected_context_type,
1410                         test_case.expected_redirect_type_with_chain)))
1411               << UrlChainToString(url_chain) << " "
1412               << site_for_cookies.ToDebugString() << " "
1413               << (initiator ? initiator->Serialize() : "nullopt");
1414           if (!CanBeMainFrameNavigation(url_chain.back(), site_for_cookies))
1415             continue;
1416           EXPECT_THAT(
1417               cookie_util::ComputeSameSiteContextForRequest(
1418                   test_case.method, url_chain, site_for_cookies, initiator,
1419                   true /* is_main_frame_navigation */,
1420                   false /* force_ignore_site_for_cookies */),
1421               AllOf(
1422                   ContextTypeIs(
1423                       expected_context_type_for_main_frame_navigation),
1424                   CrossSiteRedirectMetadataCorrect(
1425                       cookie_util::HttpMethodStringToEnum(test_case.method),
1426                       test_case
1427                           .expected_context_type_for_main_frame_navigation_without_chain,
1428                       test_case.expected_context_type_for_main_frame_navigation,
1429                       test_case.expected_redirect_type_with_chain)))
1430               << UrlChainToString(url_chain) << " "
1431               << site_for_cookies.ToDebugString() << " "
1432               << (initiator ? initiator->Serialize() : "nullopt");
1433         }
1434       }
1435     }
1436   }
1437 }
1438 
TEST_P(CookieUtilComputeSameSiteContextTest,ForScriptSet)1439 TEST_P(CookieUtilComputeSameSiteContextTest, ForScriptSet) {
1440   for (const GURL& url : GetSameSiteUrls()) {
1441     for (const SiteForCookies& site_for_cookies :
1442          GetSameSiteSitesForCookies()) {
1443       // Same-site site-for-cookies -> it's same-site lax.
1444       // (Cross-site cases covered above in UrlAndSiteForCookiesCrossSite test.)
1445       EXPECT_THAT(
1446           cookie_util::ComputeSameSiteContextForScriptSet(
1447               url, site_for_cookies, false /* force_ignore_site_for_cookies */),
1448           ContextTypeIs(ContextType::SAME_SITE_LAX));
1449     }
1450   }
1451 }
1452 
TEST_P(CookieUtilComputeSameSiteContextTest,ForScriptSet_SchemefulDowngrade)1453 TEST_P(CookieUtilComputeSameSiteContextTest, ForScriptSet_SchemefulDowngrade) {
1454   // Some test cases where the context is downgraded when computed schemefully.
1455   // (Should already be covered above, but just to be explicit.)
1456   EXPECT_EQ(SameSiteCookieContext(ContextType::SAME_SITE_LAX,
1457                                   ContextType::CROSS_SITE),
1458             cookie_util::ComputeSameSiteContextForScriptSet(
1459                 kSiteUrl, kSecureSiteForCookies,
1460                 false /* force_ignore_site_for_cookies */));
1461   EXPECT_EQ(SameSiteCookieContext(ContextType::SAME_SITE_LAX,
1462                                   ContextType::CROSS_SITE),
1463             cookie_util::ComputeSameSiteContextForScriptSet(
1464                 kSecureSiteUrl, kSiteForCookies,
1465                 false /* force_ignore_site_for_cookies */));
1466 }
1467 
TEST_P(CookieUtilComputeSameSiteContextTest,ForScriptSet_WebSocketSchemes)1468 TEST_P(CookieUtilComputeSameSiteContextTest, ForScriptSet_WebSocketSchemes) {
1469   // wss/https and http/ws are considered the same for schemeful purposes.
1470   EXPECT_THAT(cookie_util::ComputeSameSiteContextForScriptSet(
1471                   kWssUrl, kSecureSiteForCookies,
1472                   false /* force_ignore_site_for_cookies */),
1473               ContextTypeIs(ContextType::SAME_SITE_LAX));
1474   EXPECT_THAT(
1475       cookie_util::ComputeSameSiteContextForScriptSet(
1476           kWsUrl, kSiteForCookies, false /* force_ignore_site_for_cookies */),
1477       ContextTypeIs(ContextType::SAME_SITE_LAX));
1478 }
1479 
1480 // Test cases where the URL chain has 1 member (i.e. no redirects).
TEST_P(CookieUtilComputeSameSiteContextTest,ForResponse)1481 TEST_P(CookieUtilComputeSameSiteContextTest, ForResponse) {
1482   for (const GURL& url : GetSameSiteUrls()) {
1483     // Same-site site-for-cookies.
1484     // (Cross-site cases covered above in UrlAndSiteForCookiesCrossSite test.)
1485     for (const SiteForCookies& site_for_cookies :
1486          GetSameSiteSitesForCookies()) {
1487       // For main frame navigations, setting all SameSite cookies is allowed
1488       // regardless of initiator.
1489       for (const std::optional<url::Origin>& initiator : GetAllInitiators()) {
1490         if (!CanBeMainFrameNavigation(url, site_for_cookies))
1491           break;
1492         EXPECT_THAT(cookie_util::ComputeSameSiteContextForResponse(
1493                         {url}, site_for_cookies, initiator,
1494                         true /* is_main_frame_navigation */,
1495                         false /* force_ignore_site_for_cookies */),
1496                     ContextTypeIs(ContextType::SAME_SITE_LAX));
1497       }
1498 
1499       // For non-main-frame-navigation requests, the context should be lax iff
1500       // the initiator is same-site, and cross-site otherwise.
1501       for (const std::optional<url::Origin>& initiator :
1502            GetSameSiteInitiators()) {
1503         EXPECT_THAT(cookie_util::ComputeSameSiteContextForResponse(
1504                         {url}, site_for_cookies, initiator,
1505                         false /* is_main_frame_navigation */,
1506                         false /* force_ignore_site_for_cookies */),
1507                     ContextTypeIs(ContextType::SAME_SITE_LAX));
1508       }
1509       for (const std::optional<url::Origin>& initiator :
1510            GetCrossSiteInitiators()) {
1511         EXPECT_THAT(cookie_util::ComputeSameSiteContextForResponse(
1512                         {url}, site_for_cookies, initiator,
1513                         false /* is_main_frame_navigation */,
1514                         false /* force_ignore_site_for_cookies */),
1515                     ContextTypeIs(ContextType::CROSS_SITE));
1516       }
1517     }
1518   }
1519 }
1520 
TEST_P(CookieUtilComputeSameSiteContextTest,ForResponse_SchemefulDowngrade)1521 TEST_P(CookieUtilComputeSameSiteContextTest, ForResponse_SchemefulDowngrade) {
1522   // Some test cases where the context is downgraded when computed schemefully.
1523   // (Should already be covered above, but just to be explicit.)
1524 
1525   // URL and site-for-cookies are cross-scheme.
1526   // (If the URL and site-for-cookies are not schemefully same-site, this cannot
1527   // be a main frame navigation.)
1528   // With same-site initiator:
1529   EXPECT_EQ(SameSiteCookieContext(ContextType::SAME_SITE_LAX,
1530                                   ContextType::CROSS_SITE),
1531             cookie_util::ComputeSameSiteContextForResponse(
1532                 {kSiteUrl}, kSecureSiteForCookies, kSiteInitiator,
1533                 false /* is_main_frame_navigation */,
1534                 false /* force_ignore_site_for_cookies */));
1535   EXPECT_EQ(SameSiteCookieContext(ContextType::SAME_SITE_LAX,
1536                                   ContextType::CROSS_SITE),
1537             cookie_util::ComputeSameSiteContextForResponse(
1538                 {kSecureSiteUrl}, kSiteForCookies, kSecureSiteInitiator,
1539                 false /* is_main_frame_navigation */,
1540                 false /* force_ignore_site_for_cookies */));
1541   // With cross-site initiator:
1542   EXPECT_EQ(SameSiteCookieContext(ContextType::CROSS_SITE),
1543             cookie_util::ComputeSameSiteContextForResponse(
1544                 {kSiteUrl}, kSecureSiteForCookies, kCrossSiteInitiator,
1545                 false /* is_main_frame_navigation */,
1546                 false /* force_ignore_site_for_cookies */));
1547   EXPECT_EQ(SameSiteCookieContext(ContextType::CROSS_SITE),
1548             cookie_util::ComputeSameSiteContextForResponse(
1549                 {kSecureSiteUrl}, kSiteForCookies, kCrossSiteInitiator,
1550                 false /* is_main_frame_navigation */,
1551                 false /* force_ignore_site_for_cookies */));
1552 
1553   // Schemefully same-site URL and site-for-cookies with cross-scheme
1554   // initiator.
1555   for (bool is_main_frame_navigation : {false, true}) {
1556     ContextType lax_if_main_frame = is_main_frame_navigation
1557                                         ? ContextType::SAME_SITE_LAX
1558                                         : ContextType::CROSS_SITE;
1559     EXPECT_EQ(
1560         SameSiteCookieContext(ContextType::SAME_SITE_LAX, lax_if_main_frame),
1561         cookie_util::ComputeSameSiteContextForResponse(
1562             {kSiteUrl}, kSiteForCookies, kSecureSiteInitiator,
1563             is_main_frame_navigation,
1564             false /* force_ignore_site_for_cookies */));
1565     EXPECT_EQ(
1566         SameSiteCookieContext(ContextType::SAME_SITE_LAX, lax_if_main_frame),
1567         cookie_util::ComputeSameSiteContextForResponse(
1568             {kSecureSiteUrl}, kSecureSiteForCookies, kSiteInitiator,
1569             is_main_frame_navigation,
1570             false /* force_ignore_site_for_cookies */));
1571   }
1572 }
1573 
TEST_P(CookieUtilComputeSameSiteContextTest,ForResponse_WebSocketSchemes)1574 TEST_P(CookieUtilComputeSameSiteContextTest, ForResponse_WebSocketSchemes) {
1575   // wss/https and http/ws are considered the same for schemeful purposes.
1576   // (ws/wss requests cannot be main frame navigations.)
1577 
1578   // Same-site initiators.
1579   for (const std::optional<url::Origin>& initiator : GetSameSiteInitiators()) {
1580     EXPECT_THAT(cookie_util::ComputeSameSiteContextForResponse(
1581                     {kWsUrl}, kSiteForCookies, initiator,
1582                     false /* is_main_frame_navigation */,
1583                     false /* force_ignore_site_for_cookies */),
1584                 ContextTypeIs(ContextType::SAME_SITE_LAX));
1585   }
1586   // Cross-site initiators.
1587   for (const std::optional<url::Origin>& initiator : GetCrossSiteInitiators()) {
1588     EXPECT_THAT(cookie_util::ComputeSameSiteContextForResponse(
1589                     {kWsUrl}, kSiteForCookies, initiator,
1590                     false /* is_main_frame_navigation */,
1591                     false /* force_ignore_site_for_cookies */),
1592                 ContextTypeIs(ContextType::CROSS_SITE));
1593   }
1594 }
1595 
1596 // Test cases where the URL chain contains multiple members, where the last
1597 // member (current request URL) is same-site to kSiteUrl. (Everything is listed
1598 // as same-site or cross-site relative to kSiteUrl.)
TEST_P(CookieUtilComputeSameSiteContextTest,ForResponse_Redirect)1599 TEST_P(CookieUtilComputeSameSiteContextTest, ForResponse_Redirect) {
1600   struct {
1601     bool url_chain_is_same_site;
1602     bool site_for_cookies_is_same_site;
1603     bool initiator_is_same_site;
1604     // These are the expected context types considering redirect chains:
1605     ContextType expected_context_type;  // for non-main-frame-nav requests.
1606     ContextType expected_context_type_for_main_frame_navigation;
1607     // These are the expected context types not considering redirect chains:
1608     ContextType expected_context_type_without_chain;
1609     ContextType expected_context_type_for_main_frame_navigation_without_chain;
1610     // The expected redirect type (only applicable for chains):
1611     ContextRedirectTypeBug1221316 expected_redirect_type_with_chain;
1612   } kTestCases[] = {
1613       // If the url chain is same-site, then the result is the same with or
1614       // without considering the redirect chain.
1615       {true, true, true, ContextType::SAME_SITE_LAX, ContextType::SAME_SITE_LAX,
1616        ContextType::SAME_SITE_LAX, ContextType::SAME_SITE_LAX,
1617        ContextRedirectTypeBug1221316::kAllSameSiteRedirect},
1618       {true, true, false, ContextType::CROSS_SITE, ContextType::SAME_SITE_LAX,
1619        ContextType::CROSS_SITE, ContextType::SAME_SITE_LAX,
1620        ContextRedirectTypeBug1221316::kCrossSiteRedirect},
1621       {true, false, true, ContextType::CROSS_SITE, ContextType::CROSS_SITE,
1622        ContextType::CROSS_SITE, ContextType::CROSS_SITE,
1623        ContextRedirectTypeBug1221316::kCrossSiteRedirect},
1624       {true, false, false, ContextType::CROSS_SITE, ContextType::CROSS_SITE,
1625        ContextType::CROSS_SITE, ContextType::CROSS_SITE,
1626        ContextRedirectTypeBug1221316::kCrossSiteRedirect},
1627       // If the url chain is cross-site, then the result will differ depending
1628       // on whether the redirect chain is considered, when the site-for-cookies
1629       // and initiator are both same-site.
1630       {false, true, true, ContextType::CROSS_SITE, ContextType::SAME_SITE_LAX,
1631        ContextType::SAME_SITE_LAX, ContextType::SAME_SITE_LAX,
1632        ContextRedirectTypeBug1221316::kPartialSameSiteRedirect},
1633       {false, true, false, ContextType::CROSS_SITE, ContextType::SAME_SITE_LAX,
1634        ContextType::CROSS_SITE, ContextType::SAME_SITE_LAX,
1635        ContextRedirectTypeBug1221316::kCrossSiteRedirect},
1636       {false, false, true, ContextType::CROSS_SITE, ContextType::CROSS_SITE,
1637        ContextType::CROSS_SITE, ContextType::CROSS_SITE,
1638        ContextRedirectTypeBug1221316::kCrossSiteRedirect},
1639       {false, false, false, ContextType::CROSS_SITE, ContextType::CROSS_SITE,
1640        ContextType::CROSS_SITE, ContextType::CROSS_SITE,
1641        ContextRedirectTypeBug1221316::kCrossSiteRedirect},
1642   };
1643   for (const auto& test_case : kTestCases) {
1644     std::vector<std::vector<GURL>> url_chains =
1645         test_case.url_chain_is_same_site ? GetSameSiteUrlChains(kSiteUrl)
1646                                          : GetCrossSiteUrlChains(kSiteUrl);
1647     std::vector<SiteForCookies> sites_for_cookies =
1648         test_case.site_for_cookies_is_same_site ? GetSameSiteSitesForCookies()
1649                                                 : GetCrossSiteSitesForCookies();
1650     std::vector<std::optional<url::Origin>> initiators =
1651         test_case.initiator_is_same_site ? GetSameSiteInitiators()
1652                                          : GetCrossSiteInitiators();
1653     ContextType expected_context_type =
1654         DoesSameSiteConsiderRedirectChain()
1655             ? test_case.expected_context_type
1656             : test_case.expected_context_type_without_chain;
1657     ContextType expected_context_type_for_main_frame_navigation =
1658         DoesSameSiteConsiderRedirectChain()
1659             ? test_case.expected_context_type_for_main_frame_navigation
1660             : test_case
1661                   .expected_context_type_for_main_frame_navigation_without_chain;
1662     for (const std::vector<GURL>& url_chain : url_chains) {
1663       for (const SiteForCookies& site_for_cookies : sites_for_cookies) {
1664         for (const std::optional<url::Origin>& initiator : initiators) {
1665           EXPECT_THAT(cookie_util::ComputeSameSiteContextForResponse(
1666                           url_chain, site_for_cookies, initiator,
1667                           false /* is_main_frame_navigation */,
1668                           false /* force_ignore_site_for_cookies */),
1669                       AllOf(ContextTypeIs(expected_context_type),
1670                             // The 'method' field is kept empty because it's
1671                             // only used to check http_method_bug_1221316 which
1672                             // is always empty for responses.
1673                             CrossSiteRedirectMetadataCorrect(
1674                                 HttpMethod::kUnset,
1675                                 test_case.expected_context_type_without_chain,
1676                                 test_case.expected_context_type,
1677                                 test_case.expected_redirect_type_with_chain)))
1678               << UrlChainToString(url_chain) << " "
1679               << site_for_cookies.ToDebugString() << " "
1680               << (initiator ? initiator->Serialize() : "nullopt");
1681           if (!CanBeMainFrameNavigation(url_chain.back(), site_for_cookies))
1682             continue;
1683           EXPECT_THAT(
1684               cookie_util::ComputeSameSiteContextForResponse(
1685                   url_chain, site_for_cookies, initiator,
1686                   true /* is_main_frame_navigation */,
1687                   false /* force_ignore_site_for_cookies */),
1688               AllOf(
1689                   ContextTypeIs(
1690                       expected_context_type_for_main_frame_navigation),
1691                   CrossSiteRedirectMetadataCorrect(
1692                       HttpMethod::kUnset,
1693                       test_case
1694                           .expected_context_type_for_main_frame_navigation_without_chain,
1695                       test_case.expected_context_type_for_main_frame_navigation,
1696                       test_case.expected_redirect_type_with_chain)))
1697               << UrlChainToString(url_chain) << " "
1698               << site_for_cookies.ToDebugString() << " "
1699               << (initiator ? initiator->Serialize() : "nullopt");
1700         }
1701       }
1702     }
1703   }
1704 }
1705 
TEST_P(CookieUtilComputeSameSiteContextTest,ForSubresource)1706 TEST_P(CookieUtilComputeSameSiteContextTest, ForSubresource) {
1707   for (const GURL& url : GetSameSiteUrls()) {
1708     // Same-site site-for-cookies.
1709     // (Cross-site cases covered above in UrlAndSiteForCookiesCrossSite test.)
1710     for (const SiteForCookies& site_for_cookies :
1711          GetSameSiteSitesForCookies()) {
1712       EXPECT_THAT(
1713           cookie_util::ComputeSameSiteContextForSubresource(
1714               url, site_for_cookies, false /* force_ignore_site_for_cookies */),
1715           ContextTypeIs(ContextType::SAME_SITE_STRICT));
1716     }
1717   }
1718 }
1719 
TEST_P(CookieUtilComputeSameSiteContextTest,ForSubresource_SchemefulDowngrade)1720 TEST_P(CookieUtilComputeSameSiteContextTest,
1721        ForSubresource_SchemefulDowngrade) {
1722   // Some test cases where the context is downgraded when computed schemefully.
1723   // (Should already be covered above, but just to be explicit.)
1724   EXPECT_EQ(SameSiteCookieContext(ContextType::SAME_SITE_STRICT,
1725                                   ContextType::CROSS_SITE),
1726             cookie_util::ComputeSameSiteContextForSubresource(
1727                 kSiteUrl, kSecureSiteForCookies,
1728                 false /* force_ignore_site_for_cookies */));
1729   EXPECT_EQ(SameSiteCookieContext(ContextType::SAME_SITE_STRICT,
1730                                   ContextType::CROSS_SITE),
1731             cookie_util::ComputeSameSiteContextForSubresource(
1732                 kSecureSiteUrl, kSiteForCookies,
1733                 false /* force_ignore_site_for_cookies */));
1734 }
1735 
TEST_P(CookieUtilComputeSameSiteContextTest,ForSubresource_WebSocketSchemes)1736 TEST_P(CookieUtilComputeSameSiteContextTest, ForSubresource_WebSocketSchemes) {
1737   // wss/https and http/ws are considered the same for schemeful purposes.
1738   EXPECT_THAT(cookie_util::ComputeSameSiteContextForSubresource(
1739                   kWssUrl, kSecureSiteForCookies,
1740                   false /* force_ignore_site_for_cookies */),
1741               ContextTypeIs(ContextType::SAME_SITE_STRICT));
1742   EXPECT_THAT(
1743       cookie_util::ComputeSameSiteContextForSubresource(
1744           kWsUrl, kSiteForCookies, false /* force_ignore_site_for_cookies */),
1745       ContextTypeIs(ContextType::SAME_SITE_STRICT));
1746 }
1747 
TEST_P(CookieUtilComputeSameSiteContextTest,ForceIgnoreSiteForCookies)1748 TEST_P(CookieUtilComputeSameSiteContextTest, ForceIgnoreSiteForCookies) {
1749   // force_ignore_site_for_cookies overrides all checks and returns same-site
1750   // (STRICT for get or LAX for set).
1751   for (const GURL& url : GetAllUrls()) {
1752     for (const SiteForCookies& site_for_cookies : GetAllSitesForCookies()) {
1753       for (const std::optional<url::Origin>& initiator : GetAllInitiators()) {
1754         for (const std::string& method : {"GET", "POST", "PUT", "HEAD"}) {
1755           EXPECT_THAT(cookie_util::ComputeSameSiteContextForScriptGet(
1756                           url, site_for_cookies, initiator,
1757                           true /* force_ignore_site_for_cookies */),
1758                       ContextTypeIs(ContextType::SAME_SITE_STRICT));
1759           EXPECT_THAT(cookie_util::ComputeSameSiteContextForScriptSet(
1760                           url, site_for_cookies,
1761                           true /* force_ignore_site_for_cookies */),
1762                       ContextTypeIs(ContextType::SAME_SITE_LAX));
1763           for (bool is_main_frame_navigation :
1764                IsMainFrameNavigationPossibleValues(url, site_for_cookies)) {
1765             EXPECT_THAT(cookie_util::ComputeSameSiteContextForRequest(
1766                             method, {url}, site_for_cookies, initiator,
1767                             is_main_frame_navigation,
1768                             true /* force_ignore_site_for_cookies */),
1769                         ContextTypeIs(ContextType::SAME_SITE_STRICT));
1770             EXPECT_THAT(cookie_util::ComputeSameSiteContextForResponse(
1771                             {url}, site_for_cookies, initiator,
1772                             is_main_frame_navigation,
1773                             true /* force_ignore_site_for_cookies */),
1774                         ContextTypeIs(ContextType::SAME_SITE_LAX));
1775             EXPECT_THAT(
1776                 cookie_util::ComputeSameSiteContextForRequest(
1777                     method, {site_for_cookies.RepresentativeUrl(), url},
1778                     site_for_cookies, initiator, is_main_frame_navigation,
1779                     true /* force_ignore_site_for_cookies */),
1780                 ContextTypeIs(ContextType::SAME_SITE_STRICT));
1781             EXPECT_THAT(
1782                 cookie_util::ComputeSameSiteContextForResponse(
1783                     {site_for_cookies.RepresentativeUrl(), url},
1784                     site_for_cookies, initiator, is_main_frame_navigation,
1785                     true /* force_ignore_site_for_cookies */),
1786                 ContextTypeIs(ContextType::SAME_SITE_LAX));
1787           }
1788           EXPECT_THAT(cookie_util::ComputeSameSiteContextForSubresource(
1789                           url, site_for_cookies,
1790                           true /* force_ignore_site_for_cookies */),
1791                       ContextTypeIs(ContextType::SAME_SITE_STRICT));
1792         }
1793       }
1794     }
1795   }
1796 }
1797 
1798 INSTANTIATE_TEST_SUITE_P(/* no label */,
1799                          CookieUtilComputeSameSiteContextTest,
1800                          ::testing::Combine(::testing::Bool(),
1801                                             ::testing::Bool()));
1802 
TEST(CookieUtilTest,IsCookieAccessResultInclude)1803 TEST(CookieUtilTest, IsCookieAccessResultInclude) {
1804   EXPECT_FALSE(cookie_util::IsCookieAccessResultInclude(CookieAccessResult(
1805       CookieInclusionStatus(CookieInclusionStatus::EXCLUDE_UNKNOWN_ERROR))));
1806 
1807   EXPECT_TRUE(cookie_util::IsCookieAccessResultInclude(CookieAccessResult()));
1808 }
1809 
1810 }  // namespace
1811 
1812 }  // namespace net
1813