xref: /aosp_15_r20/external/cronet/net/cookies/site_for_cookies_unittest.cc (revision 6777b5387eb2ff775bb5750e3f5d96f37fb7352b)
1 // Copyright 2019 The Chromium Authors
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
4 
5 #include "net/cookies/site_for_cookies.h"
6 
7 #include <string>
8 #include <vector>
9 
10 #include "base/strings/strcat.h"
11 #include "base/test/scoped_feature_list.h"
12 #include "net/base/features.h"
13 #include "net/base/url_util.h"
14 #include "testing/gtest/include/gtest/gtest.h"
15 #include "url/gurl.h"
16 #include "url/origin.h"
17 #include "url/url_util.h"
18 
19 namespace net {
20 namespace {
21 
22 class SchemelessSiteForCookiesTest : public ::testing::Test {
23  public:
SchemelessSiteForCookiesTest()24   SchemelessSiteForCookiesTest() {
25     scope_feature_list_.InitAndDisableFeature(features::kSchemefulSameSite);
26   }
27 
28  protected:
29   base::test::ScopedFeatureList scope_feature_list_;
30 };
31 
NormalizedScheme(const GURL & url)32 std::string NormalizedScheme(const GURL& url) {
33   return url.SchemeIsWSOrWSS() ? ChangeWebSocketSchemeToHttpScheme(url).scheme()
34                                : url.scheme();
35 }
36 
37 // Tests that all URLs from |equivalent| produce SiteForCookies that match
38 // URLs in the set and are equivalent to each other, and are distinct and
39 // don't match |distinct|.
TestEquivalentAndDistinct(const std::vector<GURL> & equivalent,const std::vector<GURL> & distinct,const std::string & expect_host)40 void TestEquivalentAndDistinct(const std::vector<GURL>& equivalent,
41                                const std::vector<GURL>& distinct,
42                                const std::string& expect_host) {
43   for (const GURL& equiv_url_a : equivalent) {
44     SiteForCookies equiv_a = SiteForCookies::FromUrl(equiv_url_a);
45     EXPECT_EQ(NormalizedScheme(equiv_url_a), equiv_a.scheme());
46 
47     EXPECT_EQ(equiv_a.RepresentativeUrl().spec(),
48               base::StrCat({equiv_a.scheme(), "://", expect_host, "/"}));
49 
50     for (const GURL& equiv_url_b : equivalent) {
51       SiteForCookies equiv_b = SiteForCookies::FromUrl(equiv_url_a);
52 
53       EXPECT_TRUE(equiv_a.IsEquivalent(equiv_b));
54       EXPECT_TRUE(equiv_b.IsEquivalent(equiv_a));
55       EXPECT_TRUE(equiv_a.IsFirstParty(equiv_url_a));
56       EXPECT_TRUE(equiv_a.IsFirstParty(equiv_url_b));
57       EXPECT_TRUE(equiv_b.IsFirstParty(equiv_url_a));
58       EXPECT_TRUE(equiv_b.IsFirstParty(equiv_url_b));
59     }
60 
61     for (const GURL& other_url : distinct) {
62       SiteForCookies other = SiteForCookies::FromUrl(other_url);
63       EXPECT_EQ(NormalizedScheme(other_url), other.scheme());
64       EXPECT_EQ(other.RepresentativeUrl().spec(),
65                 base::StrCat({other.scheme(), "://", other_url.host(), "/"}));
66 
67       EXPECT_FALSE(equiv_a.IsEquivalent(other));
68       EXPECT_FALSE(other.IsEquivalent(equiv_a));
69       EXPECT_FALSE(equiv_a.IsFirstParty(other_url))
70           << equiv_a.ToDebugString() << " " << other_url.spec();
71       EXPECT_FALSE(other.IsFirstParty(equiv_url_a));
72 
73       EXPECT_TRUE(other.IsFirstParty(other_url));
74     }
75   }
76 }
77 
TEST(SiteForCookiesTest,Default)78 TEST(SiteForCookiesTest, Default) {
79   SiteForCookies should_match_none;
80   EXPECT_FALSE(should_match_none.IsFirstParty(GURL("http://example.com")));
81   EXPECT_FALSE(should_match_none.IsFirstParty(GURL("file:///home/me/.bashrc")));
82   EXPECT_FALSE(should_match_none.IsFirstParty(GURL()));
83 
84   // Before SiteForCookies existed, empty URL would represent match-none
85   EXPECT_TRUE(should_match_none.IsEquivalent(SiteForCookies::FromUrl(GURL())));
86   EXPECT_TRUE(should_match_none.RepresentativeUrl().is_empty());
87   EXPECT_TRUE(should_match_none.IsEquivalent(
88       SiteForCookies::FromOrigin(url::Origin())));
89 
90   EXPECT_TRUE(should_match_none.site().opaque());
91   EXPECT_EQ("", should_match_none.scheme());
92   EXPECT_EQ("SiteForCookies: {site=null; schemefully_same=false}",
93             should_match_none.ToDebugString());
94 }
95 
TEST_F(SchemelessSiteForCookiesTest,Basic)96 TEST_F(SchemelessSiteForCookiesTest, Basic) {
97   std::vector<GURL> equivalent = {
98       GURL("https://example.com"),
99       GURL("http://sub1.example.com:42/something"),
100       GURL("ws://sub2.example.com/something"),
101       // This one is disputable.
102       GURL("file://example.com/helo"),
103   };
104 
105   std::vector<GURL> distinct = {GURL("https://example.org"),
106                                 GURL("http://com/i_am_a_tld")};
107 
108   TestEquivalentAndDistinct(equivalent, distinct, "example.com");
109 }
110 
111 // Similar to SchemelessSiteForCookiesTest_Basic with a focus on testing secure
112 // SFCs.
TEST(SiteForCookiesTest,BasicSecure)113 TEST(SiteForCookiesTest, BasicSecure) {
114   std::vector<GURL> equivalent = {GURL("https://example.com"),
115                                   GURL("wss://example.com"),
116                                   GURL("https://sub1.example.com:42/something"),
117                                   GURL("wss://sub2.example.com/something")};
118 
119   std::vector<GURL> distinct = {
120       GURL("http://example.com"),      GURL("https://example.org"),
121       GURL("ws://example.com"),        GURL("https://com/i_am_a_tld"),
122       GURL("file://example.com/helo"),
123   };
124 
125   TestEquivalentAndDistinct(equivalent, distinct, "example.com");
126 }
127 
128 // Similar to SchemelessSiteForCookiesTest_Basic with a focus on testing
129 // insecure SFCs.
TEST(SiteForCookiesTest,BasicInsecure)130 TEST(SiteForCookiesTest, BasicInsecure) {
131   std::vector<GURL> equivalent = {GURL("http://example.com"),
132                                   GURL("ws://example.com"),
133                                   GURL("http://sub1.example.com:42/something"),
134                                   GURL("ws://sub2.example.com/something")};
135 
136   std::vector<GURL> distinct = {
137       GURL("https://example.com"),     GURL("http://example.org"),
138       GURL("wss://example.com"),       GURL("http://com/i_am_a_tld"),
139       GURL("file://example.com/helo"),
140   };
141 
142   TestEquivalentAndDistinct(equivalent, distinct, "example.com");
143 }
144 
TEST(SiteForCookiesTest,File)145 TEST(SiteForCookiesTest, File) {
146   std::vector<GURL> equivalent = {GURL("file:///a/b/c"),
147                                   GURL("file:///etc/shaaadow")};
148 
149   std::vector<GURL> distinct = {GURL("file://nonlocal/file.txt")};
150 
151   TestEquivalentAndDistinct(equivalent, distinct, "");
152 }
153 
TEST_F(SchemelessSiteForCookiesTest,Extension)154 TEST_F(SchemelessSiteForCookiesTest, Extension) {
155   url::ScopedSchemeRegistryForTests scoped_registry;
156   url::AddStandardScheme("chrome-extension", url::SCHEME_WITH_HOST);
157   std::vector<GURL> equivalent = {GURL("chrome-extension://abc/"),
158                                   GURL("chrome-extension://abc/foo.txt"),
159                                   GURL("https://abc"), GURL("http://abc"),
160                                   // This one is disputable.
161                                   GURL("file://abc/bar.txt")};
162 
163   std::vector<GURL> distinct = {GURL("chrome-extension://def")};
164 
165   TestEquivalentAndDistinct(equivalent, distinct, "abc");
166 }
167 
168 // Similar to SchemelessSiteForCookiesTest_Extension with a focus on ensuring
169 // that http(s) schemes are distinct.
TEST(SiteForCookiesTest,Extension)170 TEST(SiteForCookiesTest, Extension) {
171   url::ScopedSchemeRegistryForTests scoped_registry;
172   url::AddStandardScheme("chrome-extension", url::SCHEME_WITH_HOST);
173   std::vector<GURL> equivalent = {
174       GURL("chrome-extension://abc/"),
175       GURL("chrome-extension://abc/foo.txt"),
176   };
177 
178   std::vector<GURL> distinct = {GURL("chrome-extension://def"),
179                                 GURL("https://abc"), GURL("http://abc"),
180                                 GURL("file://abc/bar.txt")};
181 
182   TestEquivalentAndDistinct(equivalent, distinct, "abc");
183 }
184 
TEST(SiteForCookiesTest,NonStandard)185 TEST(SiteForCookiesTest, NonStandard) {
186   // If we don't register the scheme, nothing matches, even identical ones
187   std::vector<GURL> equivalent;
188   std::vector<GURL> distinct = {GURL("non-standard://abc"),
189                                 GURL("non-standard://abc"),
190                                 GURL("non-standard://def")};
191 
192   // Last parameter is "" since GURL doesn't put the hostname in if
193   // the URL is non-standard.
194   TestEquivalentAndDistinct(equivalent, distinct, "");
195 }
196 
TEST_F(SchemelessSiteForCookiesTest,Blob)197 TEST_F(SchemelessSiteForCookiesTest, Blob) {
198   // This case isn't really well-specified and is inconsistent between
199   // different user agents; the behavior chosen here was to be more
200   // consistent between url and origin handling.
201   //
202   // Thanks file API spec for the sample blob URL.
203   SiteForCookies from_blob = SiteForCookies::FromUrl(
204       GURL("blob:https://example.org/9115d58c-bcda-ff47-86e5-083e9a2153041"));
205 
206   EXPECT_TRUE(from_blob.IsFirstParty(GURL("http://sub.example.org/resource")));
207   EXPECT_EQ("https", from_blob.scheme());
208   EXPECT_EQ("SiteForCookies: {site=https://example.org; schemefully_same=true}",
209             from_blob.ToDebugString());
210   EXPECT_EQ("https://example.org/", from_blob.RepresentativeUrl().spec());
211   EXPECT_TRUE(from_blob.IsEquivalent(
212       SiteForCookies::FromUrl(GURL("http://www.example.org:631"))));
213 }
214 
215 // Similar to SchemelessSiteForCookiesTest_Blob with a focus on a secure blob.
TEST(SiteForCookiesTest,SecureBlob)216 TEST(SiteForCookiesTest, SecureBlob) {
217   SiteForCookies from_blob = SiteForCookies::FromUrl(
218       GURL("blob:https://example.org/9115d58c-bcda-ff47-86e5-083e9a2153041"));
219 
220   EXPECT_TRUE(from_blob.IsFirstParty(GURL("https://sub.example.org/resource")));
221   EXPECT_FALSE(from_blob.IsFirstParty(GURL("http://sub.example.org/resource")));
222   EXPECT_EQ("https", from_blob.scheme());
223   EXPECT_EQ("SiteForCookies: {site=https://example.org; schemefully_same=true}",
224             from_blob.ToDebugString());
225   EXPECT_EQ("https://example.org/", from_blob.RepresentativeUrl().spec());
226   EXPECT_TRUE(from_blob.IsEquivalent(
227       SiteForCookies::FromUrl(GURL("https://www.example.org:631"))));
228   EXPECT_FALSE(from_blob.IsEquivalent(
229       SiteForCookies::FromUrl(GURL("http://www.example.org:631"))));
230 }
231 
232 // Similar to SchemelessSiteForCookiesTest_Blob with a focus on an insecure
233 // blob.
TEST(SiteForCookiesTest,InsecureBlob)234 TEST(SiteForCookiesTest, InsecureBlob) {
235   SiteForCookies from_blob = SiteForCookies::FromUrl(
236       GURL("blob:http://example.org/9115d58c-bcda-ff47-86e5-083e9a2153041"));
237 
238   EXPECT_TRUE(from_blob.IsFirstParty(GURL("http://sub.example.org/resource")));
239   EXPECT_FALSE(
240       from_blob.IsFirstParty(GURL("https://sub.example.org/resource")));
241   EXPECT_EQ("http", from_blob.scheme());
242   EXPECT_EQ("SiteForCookies: {site=http://example.org; schemefully_same=true}",
243             from_blob.ToDebugString());
244   EXPECT_EQ("http://example.org/", from_blob.RepresentativeUrl().spec());
245   EXPECT_TRUE(from_blob.IsEquivalent(
246       SiteForCookies::FromUrl(GURL("http://www.example.org:631"))));
247   EXPECT_FALSE(from_blob.IsEquivalent(
248       SiteForCookies::FromUrl(GURL("https://www.example.org:631"))));
249 }
250 
TEST_F(SchemelessSiteForCookiesTest,Wire)251 TEST_F(SchemelessSiteForCookiesTest, Wire) {
252   SiteForCookies out;
253 
254   // Empty one.
255   EXPECT_TRUE(SiteForCookies::FromWire(SchemefulSite(), false, &out));
256   EXPECT_TRUE(out.IsNull());
257 
258   EXPECT_TRUE(SiteForCookies::FromWire(SchemefulSite(), true, &out));
259   EXPECT_TRUE(out.IsNull());
260 
261   // Not a valid site. (Scheme should have been converted to https.)
262   EXPECT_FALSE(SiteForCookies::FromWire(
263       SchemefulSite(GURL("wss://host.example.test")), false, &out));
264   EXPECT_TRUE(out.IsNull());
265 
266   // Not a valid scheme. (Same result as opaque SchemefulSite.)
267   EXPECT_TRUE(SiteForCookies::FromWire(SchemefulSite(GURL("aH://example.test")),
268                                        false, &out));
269   EXPECT_TRUE(out.IsNull());
270 
271   // Not a eTLD + 1 (or something hosty), but this is fine. (Is converted to a
272   // registrable domain by SchemefulSite constructor.)
273   EXPECT_TRUE(SiteForCookies::FromWire(
274       SchemefulSite(GURL("http://sub.example.test")), false, &out));
275   EXPECT_FALSE(out.IsNull());
276   EXPECT_EQ(
277       "SiteForCookies: {site=http://example.test; schemefully_same=false}",
278       out.ToDebugString());
279 
280   // IP address is fine.
281   EXPECT_TRUE(SiteForCookies::FromWire(SchemefulSite(GURL("https://127.0.0.1")),
282                                        true, &out));
283   EXPECT_FALSE(out.IsNull());
284   EXPECT_EQ("SiteForCookies: {site=https://127.0.0.1; schemefully_same=true}",
285             out.ToDebugString());
286 
287   EXPECT_TRUE(SiteForCookies::FromWire(SchemefulSite(GURL("https://127.0.0.1")),
288                                        false, &out));
289   EXPECT_FALSE(out.IsNull());
290   EXPECT_EQ("SiteForCookies: {site=https://127.0.0.1; schemefully_same=false}",
291             out.ToDebugString());
292 
293   // An actual eTLD+1 is fine.
294   EXPECT_TRUE(SiteForCookies::FromWire(
295       SchemefulSite(GURL("http://example.test")), true, &out));
296   EXPECT_FALSE(out.IsNull());
297   EXPECT_EQ("SiteForCookies: {site=http://example.test; schemefully_same=true}",
298             out.ToDebugString());
299 }
300 
301 // Similar to SchemelessSiteForCookiesTest_Wire except that schemefully_same has
302 // an effect (makes IsNull() return true if schemefully_same is false).
TEST(SiteForCookiesTest,Wire)303 TEST(SiteForCookiesTest, Wire) {
304   SiteForCookies out;
305 
306   // Empty one.
307   EXPECT_TRUE(SiteForCookies::FromWire(SchemefulSite(), false, &out));
308   EXPECT_TRUE(out.IsNull());
309 
310   EXPECT_TRUE(SiteForCookies::FromWire(SchemefulSite(), true, &out));
311   EXPECT_TRUE(out.IsNull());
312 
313   // Not a valid site. (Scheme should have been converted to https.)
314   EXPECT_FALSE(SiteForCookies::FromWire(
315       SchemefulSite(GURL("wss://host.example.test")), false, &out));
316   EXPECT_TRUE(out.IsNull());
317 
318   // Not a valid scheme. (Same result as opaque SchemefulSite.)
319   EXPECT_TRUE(SiteForCookies::FromWire(SchemefulSite(GURL("aH://example.test")),
320                                        false, &out));
321   EXPECT_TRUE(out.IsNull());
322 
323   // Not a eTLD + 1 (or something hosty), but this is fine. (Is converted to a
324   // registrable domain by SchemefulSite constructor.)
325   EXPECT_TRUE(SiteForCookies::FromWire(
326       SchemefulSite(GURL("http://sub.example.test")), false, &out));
327   EXPECT_TRUE(out.IsNull());
328   EXPECT_EQ(
329       "SiteForCookies: {site=http://example.test; schemefully_same=false}",
330       out.ToDebugString());
331 
332   // IP address is fine.
333   EXPECT_TRUE(SiteForCookies::FromWire(SchemefulSite(GURL("https://127.0.0.1")),
334                                        true, &out));
335   EXPECT_FALSE(out.IsNull());
336   EXPECT_EQ("SiteForCookies: {site=https://127.0.0.1; schemefully_same=true}",
337             out.ToDebugString());
338 
339   // This one's schemefully_same is false
340   EXPECT_TRUE(SiteForCookies::FromWire(SchemefulSite(GURL("https://127.0.0.1")),
341                                        false, &out));
342   EXPECT_TRUE(out.IsNull());
343   EXPECT_EQ("SiteForCookies: {site=https://127.0.0.1; schemefully_same=false}",
344             out.ToDebugString());
345 
346   // An actual eTLD+1 is fine.
347   EXPECT_TRUE(SiteForCookies::FromWire(
348       SchemefulSite(GURL("http://example.test")), true, &out));
349   EXPECT_FALSE(out.IsNull());
350   EXPECT_EQ("SiteForCookies: {site=http://example.test; schemefully_same=true}",
351             out.ToDebugString());
352 
353   // This one's schemefully_same is false.
354   EXPECT_TRUE(SiteForCookies::FromWire(
355       SchemefulSite(GURL("http://example.test")), false, &out));
356   EXPECT_TRUE(out.IsNull());
357   EXPECT_EQ(
358       "SiteForCookies: {site=http://example.test; schemefully_same=false}",
359       out.ToDebugString());
360 }
361 
TEST(SiteForCookiesTest,SchemefulSite)362 TEST(SiteForCookiesTest, SchemefulSite) {
363   const char* kTestCases[] = {"opaque.com",
364                               "http://a.com",
365                               "https://sub1.example.com:42/something",
366                               "https://a.com",
367                               "ws://a.com",
368                               "wss://a.com",
369                               "file://a.com",
370                               "file://folder1/folder2/file.txt",
371                               "file:///file.txt"};
372 
373   for (std::string url : kTestCases) {
374     url::Origin origin = url::Origin::Create(GURL(url));
375     SiteForCookies from_origin = SiteForCookies::FromOrigin(origin);
376     SchemefulSite schemeful_site = SchemefulSite(origin);
377     SiteForCookies from_schemeful_site = SiteForCookies(schemeful_site);
378 
379     EXPECT_TRUE(from_origin.IsEquivalent(from_schemeful_site));
380     EXPECT_TRUE(from_schemeful_site.IsEquivalent(from_origin));
381   }
382 }
383 
TEST(SiteForCookiesTest,CompareWithFrameTreeSiteAndRevise)384 TEST(SiteForCookiesTest, CompareWithFrameTreeSiteAndRevise) {
385   SchemefulSite secure_example = SchemefulSite(GURL("https://example.com"));
386   SchemefulSite insecure_example = SchemefulSite(GURL("http://example.com"));
387   SchemefulSite secure_other = SchemefulSite(GURL("https://other.com"));
388   SchemefulSite insecure_other = SchemefulSite(GURL("http://other.com"));
389 
390   // Other scheme tests.
391   url::ScopedSchemeRegistryForTests scoped_registry;
392   AddStandardScheme("other", url::SCHEME_WITH_HOST);
393   SchemefulSite file_scheme =
394       SchemefulSite(GURL("file:///C:/Users/Default/Pictures/photo.png"));
395   SchemefulSite file_scheme2 = SchemefulSite(GURL("file:///C:/file.txt"));
396   SchemefulSite other_scheme = SchemefulSite(GURL("other://"));
397 
398   // This function should work the same regardless the state of Schemeful
399   // Same-Site.
400   for (const bool toggle : {false, true}) {
401     base::test::ScopedFeatureList scope_feature_list;
402     scope_feature_list.InitWithFeatureState(features::kSchemefulSameSite,
403                                             toggle);
404 
405     SiteForCookies candidate1 = SiteForCookies(secure_example);
406     EXPECT_TRUE(candidate1.CompareWithFrameTreeSiteAndRevise(secure_example));
407     EXPECT_FALSE(candidate1.site().opaque());
408     EXPECT_TRUE(candidate1.schemefully_same());
409 
410     SiteForCookies candidate2 = SiteForCookies(secure_example);
411     EXPECT_TRUE(candidate2.CompareWithFrameTreeSiteAndRevise(insecure_example));
412     EXPECT_FALSE(candidate2.site().opaque());
413     EXPECT_FALSE(candidate2.schemefully_same());
414 
415     SiteForCookies candidate3 = SiteForCookies(secure_example);
416     EXPECT_FALSE(candidate3.CompareWithFrameTreeSiteAndRevise(secure_other));
417     EXPECT_TRUE(candidate3.site().opaque());
418     // schemefully_same is N/A if the site() is opaque.
419 
420     SiteForCookies candidate4 = SiteForCookies(secure_example);
421     EXPECT_FALSE(candidate4.CompareWithFrameTreeSiteAndRevise(insecure_other));
422     EXPECT_TRUE(candidate4.site().opaque());
423     // schemefully_same is N/A if the site() is opaque.
424 
425     // This function's check is bi-directional, so try reversed pairs just in
426     // case.
427     SiteForCookies candidate2_reversed = SiteForCookies(insecure_example);
428     EXPECT_TRUE(
429         candidate2_reversed.CompareWithFrameTreeSiteAndRevise(secure_example));
430     EXPECT_FALSE(candidate2_reversed.site().opaque());
431     EXPECT_FALSE(candidate2_reversed.schemefully_same());
432 
433     SiteForCookies candidate3_reversed = SiteForCookies(secure_other);
434     EXPECT_FALSE(
435         candidate3_reversed.CompareWithFrameTreeSiteAndRevise(secure_example));
436     EXPECT_TRUE(candidate3_reversed.site().opaque());
437     // schemefully_same is N/A if the site() is opaque.
438 
439     SiteForCookies candidate4_reversed = SiteForCookies(insecure_other);
440     EXPECT_FALSE(
441         candidate4_reversed.CompareWithFrameTreeSiteAndRevise(secure_example));
442     EXPECT_TRUE(candidate4_reversed.site().opaque());
443     // schemefully_same is N/A if the site() is opaque.
444 
445     // Now try some different schemes.
446     SiteForCookies candidate5 = SiteForCookies(file_scheme);
447     EXPECT_TRUE(candidate5.CompareWithFrameTreeSiteAndRevise(file_scheme2));
448     EXPECT_FALSE(candidate5.site().opaque());
449     EXPECT_TRUE(candidate5.schemefully_same());
450 
451     SiteForCookies candidate6 = SiteForCookies(file_scheme);
452     EXPECT_FALSE(candidate6.CompareWithFrameTreeSiteAndRevise(other_scheme));
453     EXPECT_TRUE(candidate6.site().opaque());
454     // schemefully_same is N/A if the site() is opaque.
455 
456     SiteForCookies candidate5_reversed = SiteForCookies(file_scheme2);
457     EXPECT_TRUE(
458         candidate5_reversed.CompareWithFrameTreeSiteAndRevise(file_scheme));
459     EXPECT_FALSE(candidate5_reversed.site().opaque());
460     EXPECT_TRUE(candidate5_reversed.schemefully_same());
461 
462     SiteForCookies candidate6_reversed = SiteForCookies(other_scheme);
463     EXPECT_FALSE(
464         candidate6_reversed.CompareWithFrameTreeSiteAndRevise(file_scheme));
465     EXPECT_TRUE(candidate6_reversed.site().opaque());
466     // schemefully_same is N/A if the site() is opaque.
467   }
468 }
469 
TEST(SiteForCookiesTest,CompareWithFrameTreeSiteAndReviseOpaque)470 TEST(SiteForCookiesTest, CompareWithFrameTreeSiteAndReviseOpaque) {
471   url::Origin opaque1 = url::Origin();
472   url::Origin opaque2 = url::Origin();
473 
474   SchemefulSite opaque_site1 = SchemefulSite(opaque1);
475   SchemefulSite opaque_site2 = SchemefulSite(opaque2);
476   SchemefulSite example = SchemefulSite(GURL("https://example.com"));
477 
478   // Opaque origins are able to match on the frame comparison.
479   SiteForCookies candidate1 = SiteForCookies(opaque_site1);
480   EXPECT_TRUE(candidate1.CompareWithFrameTreeSiteAndRevise(opaque_site1));
481   EXPECT_TRUE(candidate1.site().opaque());
482   // schemefully_same is N/A if the site() is opaque.
483   EXPECT_EQ(candidate1.site(), opaque_site1);
484 
485   SiteForCookies candidate2 = SiteForCookies(opaque_site1);
486   EXPECT_TRUE(candidate2.CompareWithFrameTreeSiteAndRevise(opaque_site2));
487   EXPECT_TRUE(candidate2.site().opaque());
488   // schemefully_same is N/A if the site() is opaque.
489   EXPECT_EQ(candidate2.site(), opaque_site1);
490 
491   // But if only one is opaque they won't match.
492   SiteForCookies candidate3 = SiteForCookies(example);
493   EXPECT_FALSE(candidate3.CompareWithFrameTreeSiteAndRevise(opaque_site1));
494   EXPECT_TRUE(candidate3.site().opaque());
495   // schemefully_same is N/A if the site() is opaque.
496   EXPECT_NE(candidate3.site(), opaque_site1);
497 
498   SiteForCookies candidate4 = SiteForCookies(opaque_site1);
499   EXPECT_FALSE(candidate4.CompareWithFrameTreeSiteAndRevise(example));
500   EXPECT_TRUE(candidate4.site().opaque());
501   // schemefully_same is N/A if the site() is opaque.
502   EXPECT_EQ(candidate4.site(), opaque_site1);
503 }
504 
TEST(SiteForCookiesTest,NotSchemefullySameEquivalent)505 TEST(SiteForCookiesTest, NotSchemefullySameEquivalent) {
506   SiteForCookies first =
507       SiteForCookies::FromUrl(GURL("https://www.example.com"));
508   SiteForCookies second =
509       SiteForCookies::FromUrl(GURL("https://www.example.com"));
510   // Smoke check that two SFCs should match when they're the same.
511   EXPECT_TRUE(first.IsEquivalent(second));
512   EXPECT_TRUE(second.IsEquivalent(first));
513 
514   // Two SFC should not be equivalent to each other when one of their
515   // schemefully_same_ flags is false, even if they're otherwise the same, when
516   // Schemeful Same-Site is enabled.
517   second.SetSchemefullySameForTesting(false);
518   EXPECT_FALSE(first.IsEquivalent(second));
519   EXPECT_FALSE(second.IsEquivalent(first));
520 
521   // However, they should match if both their schemefully_same_ flags are false.
522   // Because they're both considered null at that point.
523   first.SetSchemefullySameForTesting(false);
524   EXPECT_TRUE(first.IsEquivalent(second));
525   EXPECT_TRUE(second.IsEquivalent(first));
526 }
527 
528 }  // namespace
529 
TEST(SiteForCookiesTest,SameScheme)530 TEST(SiteForCookiesTest, SameScheme) {
531   struct TestCase {
532     const char* first;
533     const char* second;
534     bool expected_value;
535   };
536 
537   const TestCase kTestCases[] = {
538       {"http://a.com", "http://a.com", true},
539       {"https://a.com", "https://a.com", true},
540       {"ws://a.com", "ws://a.com", true},
541       {"wss://a.com", "wss://a.com", true},
542       {"https://a.com", "wss://a.com", true},
543       {"wss://a.com", "https://a.com", true},
544       {"http://a.com", "ws://a.com", true},
545       {"ws://a.com", "http://a.com", true},
546       {"file://a.com", "file://a.com", true},
547       {"file://folder1/folder2/file.txt", "file://folder1/folder2/file.txt",
548        true},
549       {"ftp://a.com", "ftp://a.com", true},
550       {"http://a.com", "file://a.com", false},
551       {"ws://a.com", "wss://a.com", false},
552       {"wss://a.com", "ws://a.com", false},
553       {"https://a.com", "http://a.com", false},
554       {"file://a.com", "https://a.com", false},
555       {"https://a.com", "file://a.com", false},
556       {"file://a.com", "ftp://a.com", false},
557       {"ftp://a.com", "file://a.com", false},
558   };
559 
560   for (const TestCase& t : kTestCases) {
561     SiteForCookies first = SiteForCookies::FromUrl(GURL(t.first));
562     SchemefulSite second(GURL(t.second));
563     EXPECT_FALSE(first.IsNull());
564     first.MarkIfCrossScheme(second);
565     EXPECT_EQ(first.schemefully_same(), t.expected_value);
566   }
567 }
568 
TEST(SiteForCookiesTest,SameSchemeOpaque)569 TEST(SiteForCookiesTest, SameSchemeOpaque) {
570   url::Origin not_opaque_secure =
571       url::Origin::Create(GURL("https://site.example"));
572   url::Origin not_opaque_nonsecure =
573       url::Origin::Create(GURL("http://site.example"));
574   // Check an opaque origin made from a triple origin and one from the default
575   // constructor.
576   const url::Origin kOpaqueOrigins[] = {
577       not_opaque_secure.DeriveNewOpaqueOrigin(),
578       not_opaque_nonsecure.DeriveNewOpaqueOrigin(), url::Origin()};
579 
580   for (const url::Origin& origin : kOpaqueOrigins) {
581     SiteForCookies secure_sfc = SiteForCookies::FromOrigin(not_opaque_secure);
582     EXPECT_FALSE(secure_sfc.IsNull());
583     SiteForCookies nonsecure_sfc =
584         SiteForCookies::FromOrigin(not_opaque_nonsecure);
585     EXPECT_FALSE(nonsecure_sfc.IsNull());
586 
587     SchemefulSite site(origin);
588 
589     EXPECT_TRUE(secure_sfc.schemefully_same());
590     secure_sfc.MarkIfCrossScheme(site);
591     EXPECT_FALSE(secure_sfc.schemefully_same());
592 
593     EXPECT_TRUE(nonsecure_sfc.schemefully_same());
594     nonsecure_sfc.MarkIfCrossScheme(site);
595     EXPECT_FALSE(nonsecure_sfc.schemefully_same());
596 
597     SiteForCookies opaque_sfc = SiteForCookies(site);
598     EXPECT_TRUE(opaque_sfc.IsNull());
599     // Slightly implementation detail specific as the value isn't relevant for
600     // null SFCs.
601     EXPECT_FALSE(nonsecure_sfc.schemefully_same());
602   }
603 }
604 
605 // Quick correctness check that the less-than operator works as expected.
TEST(SiteForCookiesTest,LessThan)606 TEST(SiteForCookiesTest, LessThan) {
607   SiteForCookies first = SiteForCookies::FromUrl(GURL("https://example.com"));
608   SiteForCookies second =
609       SiteForCookies::FromUrl(GURL("https://examplelonger.com"));
610   SiteForCookies third =
611       SiteForCookies::FromUrl(GURL("https://examplelongerstill.com"));
612 
613   SiteForCookies null1 = SiteForCookies();
614   SiteForCookies null2 =
615       SiteForCookies::FromUrl(GURL("https://examplelongerstillstill.com"));
616   null2.SetSchemefullySameForTesting(false);
617 
618   EXPECT_LT(first, second);
619   EXPECT_LT(second, third);
620   EXPECT_LT(first, third);
621   EXPECT_LT(null1, first);
622   EXPECT_LT(null2, first);
623 
624   EXPECT_FALSE(second < first);
625   EXPECT_FALSE(first < null1);
626   EXPECT_FALSE(first < null2);
627   EXPECT_FALSE(null1 < null2);
628   EXPECT_FALSE(null2 < null1);
629 }
630 
631 }  // namespace net
632