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