xref: /aosp_15_r20/external/cronet/url/origin_unittest.cc (revision 6777b5387eb2ff775bb5750e3f5d96f37fb7352b)
1*6777b538SAndroid Build Coastguard Worker // Copyright 2015 The Chromium Authors
2*6777b538SAndroid Build Coastguard Worker // Use of this source code is governed by a BSD-style license that can be
3*6777b538SAndroid Build Coastguard Worker // found in the LICENSE file.
4*6777b538SAndroid Build Coastguard Worker 
5*6777b538SAndroid Build Coastguard Worker #include <stddef.h>
6*6777b538SAndroid Build Coastguard Worker #include <stdint.h>
7*6777b538SAndroid Build Coastguard Worker 
8*6777b538SAndroid Build Coastguard Worker #include "base/memory/raw_ptr.h"
9*6777b538SAndroid Build Coastguard Worker #include "base/test/scoped_feature_list.h"
10*6777b538SAndroid Build Coastguard Worker #include "testing/gmock/include/gmock/gmock.h"
11*6777b538SAndroid Build Coastguard Worker #include "testing/gtest/include/gtest/gtest.h"
12*6777b538SAndroid Build Coastguard Worker #include "url/gurl.h"
13*6777b538SAndroid Build Coastguard Worker #include "url/origin.h"
14*6777b538SAndroid Build Coastguard Worker #include "url/origin_abstract_tests.h"
15*6777b538SAndroid Build Coastguard Worker #include "url/url_features.h"
16*6777b538SAndroid Build Coastguard Worker #include "url/url_util.h"
17*6777b538SAndroid Build Coastguard Worker 
18*6777b538SAndroid Build Coastguard Worker namespace url {
19*6777b538SAndroid Build Coastguard Worker 
20*6777b538SAndroid Build Coastguard Worker class OriginTest : public ::testing::TestWithParam<bool> {
21*6777b538SAndroid Build Coastguard Worker  public:
OriginTest()22*6777b538SAndroid Build Coastguard Worker   OriginTest()
23*6777b538SAndroid Build Coastguard Worker       : use_standard_compliant_non_special_scheme_url_parsing_(GetParam()) {
24*6777b538SAndroid Build Coastguard Worker     if (use_standard_compliant_non_special_scheme_url_parsing_) {
25*6777b538SAndroid Build Coastguard Worker       scoped_feature_list_.InitAndEnableFeature(
26*6777b538SAndroid Build Coastguard Worker           kStandardCompliantNonSpecialSchemeURLParsing);
27*6777b538SAndroid Build Coastguard Worker     } else {
28*6777b538SAndroid Build Coastguard Worker       scoped_feature_list_.InitAndDisableFeature(
29*6777b538SAndroid Build Coastguard Worker           kStandardCompliantNonSpecialSchemeURLParsing);
30*6777b538SAndroid Build Coastguard Worker     }
31*6777b538SAndroid Build Coastguard Worker   }
32*6777b538SAndroid Build Coastguard Worker 
SetUp()33*6777b538SAndroid Build Coastguard Worker   void SetUp() override {
34*6777b538SAndroid Build Coastguard Worker     // Add two schemes which are local but nonstandard.
35*6777b538SAndroid Build Coastguard Worker     AddLocalScheme("local-but-nonstandard");
36*6777b538SAndroid Build Coastguard Worker     AddLocalScheme("also-local-but-nonstandard");
37*6777b538SAndroid Build Coastguard Worker 
38*6777b538SAndroid Build Coastguard Worker     // Add a scheme that's both local and standard.
39*6777b538SAndroid Build Coastguard Worker     AddStandardScheme("local-and-standard", SchemeType::SCHEME_WITH_HOST);
40*6777b538SAndroid Build Coastguard Worker     AddLocalScheme("local-and-standard");
41*6777b538SAndroid Build Coastguard Worker 
42*6777b538SAndroid Build Coastguard Worker     // Add a scheme that's standard but no-access. We still want these to
43*6777b538SAndroid Build Coastguard Worker     // form valid SchemeHostPorts, even though they always commit as opaque
44*6777b538SAndroid Build Coastguard Worker     // origins, so that they can represent the source of the resource even if
45*6777b538SAndroid Build Coastguard Worker     // it's not committable as a non-opaque origin.
46*6777b538SAndroid Build Coastguard Worker     AddStandardScheme("standard-but-noaccess", SchemeType::SCHEME_WITH_HOST);
47*6777b538SAndroid Build Coastguard Worker     AddNoAccessScheme("standard-but-noaccess");
48*6777b538SAndroid Build Coastguard Worker   }
49*6777b538SAndroid Build Coastguard Worker 
DoEqualityComparisons(const url::Origin & a,const url::Origin & b,bool should_compare_equal)50*6777b538SAndroid Build Coastguard Worker   ::testing::AssertionResult DoEqualityComparisons(const url::Origin& a,
51*6777b538SAndroid Build Coastguard Worker                                                    const url::Origin& b,
52*6777b538SAndroid Build Coastguard Worker                                                    bool should_compare_equal) {
53*6777b538SAndroid Build Coastguard Worker     ::testing::AssertionResult failure = ::testing::AssertionFailure();
54*6777b538SAndroid Build Coastguard Worker     failure << "DoEqualityComparisons failure. Expecting "
55*6777b538SAndroid Build Coastguard Worker             << (should_compare_equal ? "equality" : "inequality")
56*6777b538SAndroid Build Coastguard Worker             << " between:\n  a\n    Which is: " << a
57*6777b538SAndroid Build Coastguard Worker             << "\n  b\n    Which is: " << b << "\nThe following check failed: ";
58*6777b538SAndroid Build Coastguard Worker     if (a.IsSameOriginWith(b) != should_compare_equal)
59*6777b538SAndroid Build Coastguard Worker       return failure << "a.IsSameOriginWith(b)";
60*6777b538SAndroid Build Coastguard Worker     if (b.IsSameOriginWith(a) != should_compare_equal)
61*6777b538SAndroid Build Coastguard Worker       return failure << "b.IsSameOriginWith(a)";
62*6777b538SAndroid Build Coastguard Worker     if ((a == b) != should_compare_equal)
63*6777b538SAndroid Build Coastguard Worker       return failure << "(a == b)";
64*6777b538SAndroid Build Coastguard Worker     if ((b == a) != should_compare_equal)
65*6777b538SAndroid Build Coastguard Worker       return failure << "(b == a)";
66*6777b538SAndroid Build Coastguard Worker     if ((b != a) != !should_compare_equal)
67*6777b538SAndroid Build Coastguard Worker       return failure << "(b != a)";
68*6777b538SAndroid Build Coastguard Worker     if ((a != b) != !should_compare_equal)
69*6777b538SAndroid Build Coastguard Worker       return failure << "(a != b)";
70*6777b538SAndroid Build Coastguard Worker     return ::testing::AssertionSuccess();
71*6777b538SAndroid Build Coastguard Worker   }
72*6777b538SAndroid Build Coastguard Worker 
HasNonceTokenBeenInitialized(const url::Origin & origin)73*6777b538SAndroid Build Coastguard Worker   bool HasNonceTokenBeenInitialized(const url::Origin& origin) {
74*6777b538SAndroid Build Coastguard Worker     EXPECT_TRUE(origin.opaque());
75*6777b538SAndroid Build Coastguard Worker     // Avoid calling nonce_.token() here, to not trigger lazy initialization.
76*6777b538SAndroid Build Coastguard Worker     return !origin.nonce_->token_.is_empty();
77*6777b538SAndroid Build Coastguard Worker   }
78*6777b538SAndroid Build Coastguard Worker 
CreateNonce()79*6777b538SAndroid Build Coastguard Worker   Origin::Nonce CreateNonce() { return Origin::Nonce(); }
80*6777b538SAndroid Build Coastguard Worker 
CreateNonce(base::UnguessableToken nonce)81*6777b538SAndroid Build Coastguard Worker   Origin::Nonce CreateNonce(base::UnguessableToken nonce) {
82*6777b538SAndroid Build Coastguard Worker     return Origin::Nonce(nonce);
83*6777b538SAndroid Build Coastguard Worker   }
84*6777b538SAndroid Build Coastguard Worker 
GetNonce(const Origin & origin)85*6777b538SAndroid Build Coastguard Worker   const base::UnguessableToken* GetNonce(const Origin& origin) {
86*6777b538SAndroid Build Coastguard Worker     return origin.GetNonceForSerialization();
87*6777b538SAndroid Build Coastguard Worker   }
88*6777b538SAndroid Build Coastguard Worker 
89*6777b538SAndroid Build Coastguard Worker   // Wrappers around url::Origin methods to expose it to tests.
90*6777b538SAndroid Build Coastguard Worker 
UnsafelyCreateOpaqueOriginWithoutNormalization(std::string_view precursor_scheme,std::string_view precursor_host,uint16_t precursor_port,const Origin::Nonce & nonce)91*6777b538SAndroid Build Coastguard Worker   std::optional<Origin> UnsafelyCreateOpaqueOriginWithoutNormalization(
92*6777b538SAndroid Build Coastguard Worker       std::string_view precursor_scheme,
93*6777b538SAndroid Build Coastguard Worker       std::string_view precursor_host,
94*6777b538SAndroid Build Coastguard Worker       uint16_t precursor_port,
95*6777b538SAndroid Build Coastguard Worker       const Origin::Nonce& nonce) {
96*6777b538SAndroid Build Coastguard Worker     return Origin::UnsafelyCreateOpaqueOriginWithoutNormalization(
97*6777b538SAndroid Build Coastguard Worker         precursor_scheme, precursor_host, precursor_port, nonce);
98*6777b538SAndroid Build Coastguard Worker   }
99*6777b538SAndroid Build Coastguard Worker 
SerializeWithNonce(const Origin & origin)100*6777b538SAndroid Build Coastguard Worker   std::optional<std::string> SerializeWithNonce(const Origin& origin) {
101*6777b538SAndroid Build Coastguard Worker     return origin.SerializeWithNonce();
102*6777b538SAndroid Build Coastguard Worker   }
103*6777b538SAndroid Build Coastguard Worker 
SerializeWithNonceAndInitIfNeeded(Origin & origin)104*6777b538SAndroid Build Coastguard Worker   std::optional<std::string> SerializeWithNonceAndInitIfNeeded(Origin& origin) {
105*6777b538SAndroid Build Coastguard Worker     return origin.SerializeWithNonceAndInitIfNeeded();
106*6777b538SAndroid Build Coastguard Worker   }
107*6777b538SAndroid Build Coastguard Worker 
Deserialize(const std::string & value)108*6777b538SAndroid Build Coastguard Worker   std::optional<Origin> Deserialize(const std::string& value) {
109*6777b538SAndroid Build Coastguard Worker     return Origin::Deserialize(value);
110*6777b538SAndroid Build Coastguard Worker   }
111*6777b538SAndroid Build Coastguard Worker 
112*6777b538SAndroid Build Coastguard Worker  protected:
113*6777b538SAndroid Build Coastguard Worker   struct SerializationTestCase {
114*6777b538SAndroid Build Coastguard Worker     std::string_view url;
115*6777b538SAndroid Build Coastguard Worker     std::string_view expected;
116*6777b538SAndroid Build Coastguard Worker     std::optional<std::string_view> expected_log;
117*6777b538SAndroid Build Coastguard Worker   };
118*6777b538SAndroid Build Coastguard Worker 
TestSerialization(const SerializationTestCase & test_case) const119*6777b538SAndroid Build Coastguard Worker   void TestSerialization(const SerializationTestCase& test_case) const {
120*6777b538SAndroid Build Coastguard Worker     SCOPED_TRACE(test_case.url);
121*6777b538SAndroid Build Coastguard Worker     GURL url(test_case.url);
122*6777b538SAndroid Build Coastguard Worker     EXPECT_TRUE(url.is_valid());
123*6777b538SAndroid Build Coastguard Worker     Origin origin = Origin::Create(url);
124*6777b538SAndroid Build Coastguard Worker     std::string serialized = origin.Serialize();
125*6777b538SAndroid Build Coastguard Worker 
126*6777b538SAndroid Build Coastguard Worker     ExpectParsedUrlsEqual(GURL(serialized), origin.GetURL());
127*6777b538SAndroid Build Coastguard Worker 
128*6777b538SAndroid Build Coastguard Worker     EXPECT_EQ(test_case.expected, serialized);
129*6777b538SAndroid Build Coastguard Worker 
130*6777b538SAndroid Build Coastguard Worker     // The '<<' operator sometimes produces additional information.
131*6777b538SAndroid Build Coastguard Worker     std::stringstream out;
132*6777b538SAndroid Build Coastguard Worker     out << origin;
133*6777b538SAndroid Build Coastguard Worker     if (test_case.expected_log) {
134*6777b538SAndroid Build Coastguard Worker       EXPECT_EQ(test_case.expected_log, out.str());
135*6777b538SAndroid Build Coastguard Worker     } else {
136*6777b538SAndroid Build Coastguard Worker       EXPECT_EQ(test_case.expected, out.str());
137*6777b538SAndroid Build Coastguard Worker     }
138*6777b538SAndroid Build Coastguard Worker   }
139*6777b538SAndroid Build Coastguard Worker 
140*6777b538SAndroid Build Coastguard Worker   bool use_standard_compliant_non_special_scheme_url_parsing_;
141*6777b538SAndroid Build Coastguard Worker 
142*6777b538SAndroid Build Coastguard Worker  private:
143*6777b538SAndroid Build Coastguard Worker   base::test::ScopedFeatureList scoped_feature_list_;
144*6777b538SAndroid Build Coastguard Worker   ScopedSchemeRegistryForTests scoped_registry_;
145*6777b538SAndroid Build Coastguard Worker };
146*6777b538SAndroid Build Coastguard Worker 
147*6777b538SAndroid Build Coastguard Worker INSTANTIATE_TEST_SUITE_P(All, OriginTest, ::testing::Bool());
148*6777b538SAndroid Build Coastguard Worker 
TEST_P(OriginTest,OpaqueOriginComparison)149*6777b538SAndroid Build Coastguard Worker TEST_P(OriginTest, OpaqueOriginComparison) {
150*6777b538SAndroid Build Coastguard Worker   // A default-constructed Origin should should be cross origin to everything
151*6777b538SAndroid Build Coastguard Worker   // but itself.
152*6777b538SAndroid Build Coastguard Worker   url::Origin opaque_a, opaque_b;
153*6777b538SAndroid Build Coastguard Worker   EXPECT_TRUE(opaque_a.opaque());
154*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ("", opaque_a.scheme());
155*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ("", opaque_a.host());
156*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(0, opaque_a.port());
157*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(SchemeHostPort(), opaque_a.GetTupleOrPrecursorTupleIfOpaque());
158*6777b538SAndroid Build Coastguard Worker   EXPECT_FALSE(opaque_a.GetTupleOrPrecursorTupleIfOpaque().IsValid());
159*6777b538SAndroid Build Coastguard Worker 
160*6777b538SAndroid Build Coastguard Worker   EXPECT_TRUE(opaque_b.opaque());
161*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ("", opaque_b.scheme());
162*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ("", opaque_b.host());
163*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(0, opaque_b.port());
164*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(SchemeHostPort(), opaque_b.GetTupleOrPrecursorTupleIfOpaque());
165*6777b538SAndroid Build Coastguard Worker   EXPECT_FALSE(opaque_b.GetTupleOrPrecursorTupleIfOpaque().IsValid());
166*6777b538SAndroid Build Coastguard Worker 
167*6777b538SAndroid Build Coastguard Worker   // Two default-constructed Origins should always be cross origin to each
168*6777b538SAndroid Build Coastguard Worker   // other.
169*6777b538SAndroid Build Coastguard Worker   EXPECT_TRUE(DoEqualityComparisons(opaque_a, opaque_b, false));
170*6777b538SAndroid Build Coastguard Worker   EXPECT_TRUE(DoEqualityComparisons(opaque_b, opaque_b, true));
171*6777b538SAndroid Build Coastguard Worker   EXPECT_TRUE(DoEqualityComparisons(opaque_a, opaque_a, true));
172*6777b538SAndroid Build Coastguard Worker 
173*6777b538SAndroid Build Coastguard Worker   // The streaming operator should not trigger lazy initialization to the token.
174*6777b538SAndroid Build Coastguard Worker   std::ostringstream stream;
175*6777b538SAndroid Build Coastguard Worker   stream << opaque_a;
176*6777b538SAndroid Build Coastguard Worker   EXPECT_STREQ("null [internally: (nonce TBD) anonymous]",
177*6777b538SAndroid Build Coastguard Worker                stream.str().c_str());
178*6777b538SAndroid Build Coastguard Worker   EXPECT_FALSE(HasNonceTokenBeenInitialized(opaque_a));
179*6777b538SAndroid Build Coastguard Worker 
180*6777b538SAndroid Build Coastguard Worker   // None of the operations thus far should have triggered lazy-generation of
181*6777b538SAndroid Build Coastguard Worker   // the UnguessableToken. Copying an origin, however, should trigger this.
182*6777b538SAndroid Build Coastguard Worker   EXPECT_FALSE(HasNonceTokenBeenInitialized(opaque_a));
183*6777b538SAndroid Build Coastguard Worker   EXPECT_FALSE(HasNonceTokenBeenInitialized(opaque_b));
184*6777b538SAndroid Build Coastguard Worker   opaque_b = opaque_a;
185*6777b538SAndroid Build Coastguard Worker 
186*6777b538SAndroid Build Coastguard Worker   EXPECT_TRUE(HasNonceTokenBeenInitialized(opaque_a));
187*6777b538SAndroid Build Coastguard Worker   EXPECT_TRUE(HasNonceTokenBeenInitialized(opaque_b));
188*6777b538SAndroid Build Coastguard Worker   EXPECT_TRUE(DoEqualityComparisons(opaque_a, opaque_b, true));
189*6777b538SAndroid Build Coastguard Worker   EXPECT_TRUE(DoEqualityComparisons(opaque_b, opaque_b, true));
190*6777b538SAndroid Build Coastguard Worker   EXPECT_TRUE(DoEqualityComparisons(opaque_a, opaque_a, true));
191*6777b538SAndroid Build Coastguard Worker 
192*6777b538SAndroid Build Coastguard Worker   // Move-initializing to a fresh Origin should restore the lazy initialization.
193*6777b538SAndroid Build Coastguard Worker   opaque_a = url::Origin();
194*6777b538SAndroid Build Coastguard Worker   EXPECT_FALSE(HasNonceTokenBeenInitialized(opaque_a));
195*6777b538SAndroid Build Coastguard Worker   EXPECT_TRUE(HasNonceTokenBeenInitialized(opaque_b));
196*6777b538SAndroid Build Coastguard Worker   EXPECT_TRUE(DoEqualityComparisons(opaque_a, opaque_b, false));
197*6777b538SAndroid Build Coastguard Worker   EXPECT_TRUE(DoEqualityComparisons(opaque_b, opaque_b, true));
198*6777b538SAndroid Build Coastguard Worker   EXPECT_TRUE(DoEqualityComparisons(opaque_a, opaque_a, true));
199*6777b538SAndroid Build Coastguard Worker 
200*6777b538SAndroid Build Coastguard Worker   // Comparing two opaque Origins with matching SchemeHostPorts should trigger
201*6777b538SAndroid Build Coastguard Worker   // lazy initialization.
202*6777b538SAndroid Build Coastguard Worker   EXPECT_FALSE(HasNonceTokenBeenInitialized(opaque_a));
203*6777b538SAndroid Build Coastguard Worker   EXPECT_TRUE(HasNonceTokenBeenInitialized(opaque_b));
204*6777b538SAndroid Build Coastguard Worker   bool should_swap = opaque_b < opaque_a;
205*6777b538SAndroid Build Coastguard Worker   EXPECT_TRUE(HasNonceTokenBeenInitialized(opaque_a));
206*6777b538SAndroid Build Coastguard Worker   EXPECT_TRUE(HasNonceTokenBeenInitialized(opaque_b));
207*6777b538SAndroid Build Coastguard Worker 
208*6777b538SAndroid Build Coastguard Worker   if (should_swap)
209*6777b538SAndroid Build Coastguard Worker     std::swap(opaque_a, opaque_b);
210*6777b538SAndroid Build Coastguard Worker   EXPECT_LT(opaque_a, opaque_b);
211*6777b538SAndroid Build Coastguard Worker   EXPECT_FALSE(opaque_b < opaque_a);
212*6777b538SAndroid Build Coastguard Worker 
213*6777b538SAndroid Build Coastguard Worker   EXPECT_TRUE(DoEqualityComparisons(opaque_a, opaque_b, false));
214*6777b538SAndroid Build Coastguard Worker   EXPECT_TRUE(DoEqualityComparisons(opaque_b, opaque_b, true));
215*6777b538SAndroid Build Coastguard Worker   EXPECT_TRUE(DoEqualityComparisons(opaque_a, opaque_a, true));
216*6777b538SAndroid Build Coastguard Worker 
217*6777b538SAndroid Build Coastguard Worker   EXPECT_LT(opaque_a, url::Origin::Create(GURL("http://www.google.com")));
218*6777b538SAndroid Build Coastguard Worker   EXPECT_LT(opaque_b, url::Origin::Create(GURL("http://www.google.com")));
219*6777b538SAndroid Build Coastguard Worker 
220*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(opaque_b, url::Origin::Resolve(GURL(), opaque_b));
221*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(opaque_b, url::Origin::Resolve(GURL("about:blank"), opaque_b));
222*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(opaque_b, url::Origin::Resolve(GURL("about:srcdoc"), opaque_b));
223*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(opaque_b,
224*6777b538SAndroid Build Coastguard Worker             url::Origin::Resolve(GURL("about:blank?hello#whee"), opaque_b));
225*6777b538SAndroid Build Coastguard Worker }
226*6777b538SAndroid Build Coastguard Worker 
TEST_P(OriginTest,ConstructFromTuple)227*6777b538SAndroid Build Coastguard Worker TEST_P(OriginTest, ConstructFromTuple) {
228*6777b538SAndroid Build Coastguard Worker   struct TestCases {
229*6777b538SAndroid Build Coastguard Worker     const char* const scheme;
230*6777b538SAndroid Build Coastguard Worker     const char* const host;
231*6777b538SAndroid Build Coastguard Worker     const uint16_t port;
232*6777b538SAndroid Build Coastguard Worker   } cases[] = {
233*6777b538SAndroid Build Coastguard Worker       {"http", "example.com", 80},
234*6777b538SAndroid Build Coastguard Worker       {"http", "example.com", 123},
235*6777b538SAndroid Build Coastguard Worker       {"https", "example.com", 443},
236*6777b538SAndroid Build Coastguard Worker   };
237*6777b538SAndroid Build Coastguard Worker 
238*6777b538SAndroid Build Coastguard Worker   for (const auto& test_case : cases) {
239*6777b538SAndroid Build Coastguard Worker     testing::Message scope_message;
240*6777b538SAndroid Build Coastguard Worker     scope_message << test_case.scheme << "://" << test_case.host << ":"
241*6777b538SAndroid Build Coastguard Worker                   << test_case.port;
242*6777b538SAndroid Build Coastguard Worker     SCOPED_TRACE(scope_message);
243*6777b538SAndroid Build Coastguard Worker     Origin origin = Origin::CreateFromNormalizedTuple(
244*6777b538SAndroid Build Coastguard Worker         test_case.scheme, test_case.host, test_case.port);
245*6777b538SAndroid Build Coastguard Worker 
246*6777b538SAndroid Build Coastguard Worker     EXPECT_EQ(test_case.scheme, origin.scheme());
247*6777b538SAndroid Build Coastguard Worker     EXPECT_EQ(test_case.host, origin.host());
248*6777b538SAndroid Build Coastguard Worker     EXPECT_EQ(test_case.port, origin.port());
249*6777b538SAndroid Build Coastguard Worker   }
250*6777b538SAndroid Build Coastguard Worker }
251*6777b538SAndroid Build Coastguard Worker 
TEST_P(OriginTest,Serialization)252*6777b538SAndroid Build Coastguard Worker TEST_P(OriginTest, Serialization) {
253*6777b538SAndroid Build Coastguard Worker   // Common test cases
254*6777b538SAndroid Build Coastguard Worker   SerializationTestCase common_cases[] = {
255*6777b538SAndroid Build Coastguard Worker       {"http://192.168.9.1/", "http://192.168.9.1"},
256*6777b538SAndroid Build Coastguard Worker       {"http://[2001:db8::1]/", "http://[2001:db8::1]"},
257*6777b538SAndroid Build Coastguard Worker       {"http://☃.net/", "http://xn--n3h.net"},
258*6777b538SAndroid Build Coastguard Worker       {"http://example.com/", "http://example.com"},
259*6777b538SAndroid Build Coastguard Worker       {"http://example.com:123/", "http://example.com:123"},
260*6777b538SAndroid Build Coastguard Worker       {"https://example.com/", "https://example.com"},
261*6777b538SAndroid Build Coastguard Worker       {"https://example.com:123/", "https://example.com:123"},
262*6777b538SAndroid Build Coastguard Worker       {"file:///etc/passwd", "file://", "file:// [internally: file://]"},
263*6777b538SAndroid Build Coastguard Worker       {"file://example.com/etc/passwd", "file://",
264*6777b538SAndroid Build Coastguard Worker        "file:// [internally: file://example.com]"},
265*6777b538SAndroid Build Coastguard Worker       {"data:,", "null", "null [internally: (nonce TBD) anonymous]"},
266*6777b538SAndroid Build Coastguard Worker       {"git:", "null", "null [internally: (nonce TBD) anonymous]"},
267*6777b538SAndroid Build Coastguard Worker       {"git:/", "null", "null [internally: (nonce TBD) anonymous]"},
268*6777b538SAndroid Build Coastguard Worker       {"git://host/path", "null", "null [internally: (nonce TBD) anonymous]"},
269*6777b538SAndroid Build Coastguard Worker       {"local-and-standard://host/path", "local-and-standard://host"},
270*6777b538SAndroid Build Coastguard Worker       // A port is omitted if the scheme doesn't have the default port.
271*6777b538SAndroid Build Coastguard Worker       // See SchemeHostPort::SerializeInternal for details.
272*6777b538SAndroid Build Coastguard Worker       {"local-and-standard://host:123/path", "local-and-standard://host"},
273*6777b538SAndroid Build Coastguard Worker       {"standard-but-noaccess://host/path", "null",
274*6777b538SAndroid Build Coastguard Worker        "null [internally: (nonce TBD) anonymous]"},
275*6777b538SAndroid Build Coastguard Worker   };
276*6777b538SAndroid Build Coastguard Worker   for (const auto& test_case : common_cases) {
277*6777b538SAndroid Build Coastguard Worker     TestSerialization(test_case);
278*6777b538SAndroid Build Coastguard Worker   }
279*6777b538SAndroid Build Coastguard Worker 
280*6777b538SAndroid Build Coastguard Worker   // Flag-dependent test cases
281*6777b538SAndroid Build Coastguard Worker   if (use_standard_compliant_non_special_scheme_url_parsing_) {
282*6777b538SAndroid Build Coastguard Worker     SerializationTestCase cases[] = {
283*6777b538SAndroid Build Coastguard Worker         {"local-but-nonstandard://host/path", "local-but-nonstandard://host"},
284*6777b538SAndroid Build Coastguard Worker         {"local-but-nonstandard://host:123/path",
285*6777b538SAndroid Build Coastguard Worker          "local-but-nonstandard://host"},
286*6777b538SAndroid Build Coastguard Worker     };
287*6777b538SAndroid Build Coastguard Worker     for (const auto& test_case : cases) {
288*6777b538SAndroid Build Coastguard Worker       TestSerialization(test_case);
289*6777b538SAndroid Build Coastguard Worker     }
290*6777b538SAndroid Build Coastguard Worker   } else {
291*6777b538SAndroid Build Coastguard Worker     SerializationTestCase cases[] = {
292*6777b538SAndroid Build Coastguard Worker         {"local-but-nonstandard://host/path", "local-but-nonstandard://"},
293*6777b538SAndroid Build Coastguard Worker         {"local-but-nonstandard://host:123/path", "local-but-nonstandard://"},
294*6777b538SAndroid Build Coastguard Worker     };
295*6777b538SAndroid Build Coastguard Worker     for (const auto& test_case : cases) {
296*6777b538SAndroid Build Coastguard Worker       TestSerialization(test_case);
297*6777b538SAndroid Build Coastguard Worker     }
298*6777b538SAndroid Build Coastguard Worker   }
299*6777b538SAndroid Build Coastguard Worker }
300*6777b538SAndroid Build Coastguard Worker 
TEST_P(OriginTest,SerializationWithAndroidWebViewHackEnabled)301*6777b538SAndroid Build Coastguard Worker TEST_P(OriginTest, SerializationWithAndroidWebViewHackEnabled) {
302*6777b538SAndroid Build Coastguard Worker   EnableNonStandardSchemesForAndroidWebView();
303*6777b538SAndroid Build Coastguard Worker 
304*6777b538SAndroid Build Coastguard Worker   if (use_standard_compliant_non_special_scheme_url_parsing_) {
305*6777b538SAndroid Build Coastguard Worker     SerializationTestCase cases[] = {
306*6777b538SAndroid Build Coastguard Worker         {"nonstandard://host/path", "nonstandard://"},
307*6777b538SAndroid Build Coastguard Worker         {"nonstandard://host:123/path", "nonstandard://"},
308*6777b538SAndroid Build Coastguard Worker     };
309*6777b538SAndroid Build Coastguard Worker     for (const auto& test_case : cases) {
310*6777b538SAndroid Build Coastguard Worker       TestSerialization(test_case);
311*6777b538SAndroid Build Coastguard Worker     }
312*6777b538SAndroid Build Coastguard Worker   } else {
313*6777b538SAndroid Build Coastguard Worker   }
314*6777b538SAndroid Build Coastguard Worker }
315*6777b538SAndroid Build Coastguard Worker 
TEST_P(OriginTest,Comparison)316*6777b538SAndroid Build Coastguard Worker TEST_P(OriginTest, Comparison) {
317*6777b538SAndroid Build Coastguard Worker   // These URLs are arranged in increasing order:
318*6777b538SAndroid Build Coastguard Worker   const char* const urls[] = {
319*6777b538SAndroid Build Coastguard Worker       "data:uniqueness", "http://a:80",  "http://b:80",
320*6777b538SAndroid Build Coastguard Worker       "https://a:80",    "https://b:80", "http://a:81",
321*6777b538SAndroid Build Coastguard Worker       "http://b:81",     "https://a:81", "https://b:81",
322*6777b538SAndroid Build Coastguard Worker   };
323*6777b538SAndroid Build Coastguard Worker   // Validate the comparison logic still works when creating a canonical origin,
324*6777b538SAndroid Build Coastguard Worker   // when any created opaque origins contain a nonce.
325*6777b538SAndroid Build Coastguard Worker   {
326*6777b538SAndroid Build Coastguard Worker     // Pre-create the origins, as the internal nonce for unique origins changes
327*6777b538SAndroid Build Coastguard Worker     // with each freshly-constructed Origin (that's not copied).
328*6777b538SAndroid Build Coastguard Worker     std::vector<Origin> origins;
329*6777b538SAndroid Build Coastguard Worker     for (const auto* test_url : urls)
330*6777b538SAndroid Build Coastguard Worker       origins.push_back(Origin::Create(GURL(test_url)));
331*6777b538SAndroid Build Coastguard Worker     for (size_t i = 0; i < origins.size(); i++) {
332*6777b538SAndroid Build Coastguard Worker       const Origin& current = origins[i];
333*6777b538SAndroid Build Coastguard Worker       for (size_t j = i; j < origins.size(); j++) {
334*6777b538SAndroid Build Coastguard Worker         const Origin& to_compare = origins[j];
335*6777b538SAndroid Build Coastguard Worker         EXPECT_EQ(i < j, current < to_compare) << i << " < " << j;
336*6777b538SAndroid Build Coastguard Worker         EXPECT_EQ(j < i, to_compare < current) << j << " < " << i;
337*6777b538SAndroid Build Coastguard Worker       }
338*6777b538SAndroid Build Coastguard Worker     }
339*6777b538SAndroid Build Coastguard Worker   }
340*6777b538SAndroid Build Coastguard Worker }
341*6777b538SAndroid Build Coastguard Worker 
TEST_P(OriginTest,UnsafelyCreate)342*6777b538SAndroid Build Coastguard Worker TEST_P(OriginTest, UnsafelyCreate) {
343*6777b538SAndroid Build Coastguard Worker   struct TestCase {
344*6777b538SAndroid Build Coastguard Worker     const char* scheme;
345*6777b538SAndroid Build Coastguard Worker     const char* host;
346*6777b538SAndroid Build Coastguard Worker     uint16_t port;
347*6777b538SAndroid Build Coastguard Worker   } cases[] = {
348*6777b538SAndroid Build Coastguard Worker       {"http", "example.com", 80},
349*6777b538SAndroid Build Coastguard Worker       {"http", "example.com", 123},
350*6777b538SAndroid Build Coastguard Worker       {"https", "example.com", 443},
351*6777b538SAndroid Build Coastguard Worker       {"https", "example.com", 123},
352*6777b538SAndroid Build Coastguard Worker       {"http", "example.com", 0},  // 0 is a valid port for http.
353*6777b538SAndroid Build Coastguard Worker       {"file", "", 0},             // 0 indicates "no port" for file: scheme.
354*6777b538SAndroid Build Coastguard Worker       {"file", "example.com", 0},
355*6777b538SAndroid Build Coastguard Worker   };
356*6777b538SAndroid Build Coastguard Worker 
357*6777b538SAndroid Build Coastguard Worker   for (const auto& test : cases) {
358*6777b538SAndroid Build Coastguard Worker     SCOPED_TRACE(testing::Message()
359*6777b538SAndroid Build Coastguard Worker                  << test.scheme << "://" << test.host << ":" << test.port);
360*6777b538SAndroid Build Coastguard Worker     std::optional<url::Origin> origin =
361*6777b538SAndroid Build Coastguard Worker         url::Origin::UnsafelyCreateTupleOriginWithoutNormalization(
362*6777b538SAndroid Build Coastguard Worker             test.scheme, test.host, test.port);
363*6777b538SAndroid Build Coastguard Worker     ASSERT_TRUE(origin);
364*6777b538SAndroid Build Coastguard Worker     EXPECT_EQ(test.scheme, origin->scheme());
365*6777b538SAndroid Build Coastguard Worker     EXPECT_EQ(test.host, origin->host());
366*6777b538SAndroid Build Coastguard Worker     EXPECT_EQ(test.port, origin->port());
367*6777b538SAndroid Build Coastguard Worker     EXPECT_FALSE(origin->opaque());
368*6777b538SAndroid Build Coastguard Worker     EXPECT_TRUE(origin->IsSameOriginWith(*origin));
369*6777b538SAndroid Build Coastguard Worker 
370*6777b538SAndroid Build Coastguard Worker     ExpectParsedUrlsEqual(GURL(origin->Serialize()), origin->GetURL());
371*6777b538SAndroid Build Coastguard Worker 
372*6777b538SAndroid Build Coastguard Worker     base::UnguessableToken nonce = base::UnguessableToken::Create();
373*6777b538SAndroid Build Coastguard Worker     std::optional<url::Origin> opaque_origin =
374*6777b538SAndroid Build Coastguard Worker         UnsafelyCreateOpaqueOriginWithoutNormalization(
375*6777b538SAndroid Build Coastguard Worker             test.scheme, test.host, test.port, CreateNonce(nonce));
376*6777b538SAndroid Build Coastguard Worker     ASSERT_TRUE(opaque_origin);
377*6777b538SAndroid Build Coastguard Worker     EXPECT_TRUE(opaque_origin->opaque());
378*6777b538SAndroid Build Coastguard Worker     EXPECT_FALSE(*opaque_origin == origin);
379*6777b538SAndroid Build Coastguard Worker     EXPECT_EQ(opaque_origin->GetTupleOrPrecursorTupleIfOpaque(),
380*6777b538SAndroid Build Coastguard Worker               origin->GetTupleOrPrecursorTupleIfOpaque());
381*6777b538SAndroid Build Coastguard Worker     EXPECT_EQ(opaque_origin,
382*6777b538SAndroid Build Coastguard Worker               UnsafelyCreateOpaqueOriginWithoutNormalization(
383*6777b538SAndroid Build Coastguard Worker                   test.scheme, test.host, test.port, CreateNonce(nonce)));
384*6777b538SAndroid Build Coastguard Worker     EXPECT_FALSE(*opaque_origin == origin->DeriveNewOpaqueOrigin());
385*6777b538SAndroid Build Coastguard Worker   }
386*6777b538SAndroid Build Coastguard Worker }
387*6777b538SAndroid Build Coastguard Worker 
TEST_P(OriginTest,UnsafelyCreateUniqueOnInvalidInput)388*6777b538SAndroid Build Coastguard Worker TEST_P(OriginTest, UnsafelyCreateUniqueOnInvalidInput) {
389*6777b538SAndroid Build Coastguard Worker   url::AddStandardScheme("host-only", url::SCHEME_WITH_HOST);
390*6777b538SAndroid Build Coastguard Worker   url::AddStandardScheme("host-port-only", url::SCHEME_WITH_HOST_AND_PORT);
391*6777b538SAndroid Build Coastguard Worker   struct TestCases {
392*6777b538SAndroid Build Coastguard Worker     const char* scheme;
393*6777b538SAndroid Build Coastguard Worker     const char* host;
394*6777b538SAndroid Build Coastguard Worker     uint16_t port = 80;
395*6777b538SAndroid Build Coastguard Worker   } cases[] = {{"", "", 33},
396*6777b538SAndroid Build Coastguard Worker                {"data", "", 0},
397*6777b538SAndroid Build Coastguard Worker                {"blob", "", 0},
398*6777b538SAndroid Build Coastguard Worker                {"filesystem", "", 0},
399*6777b538SAndroid Build Coastguard Worker                {"data", "example.com"},
400*6777b538SAndroid Build Coastguard Worker                {"http", "☃.net"},
401*6777b538SAndroid Build Coastguard Worker                {"http\nmore", "example.com"},
402*6777b538SAndroid Build Coastguard Worker                {"http\rmore", "example.com"},
403*6777b538SAndroid Build Coastguard Worker                {"http\n", "example.com"},
404*6777b538SAndroid Build Coastguard Worker                {"http\r", "example.com"},
405*6777b538SAndroid Build Coastguard Worker                {"http", "example.com\nnot-example.com"},
406*6777b538SAndroid Build Coastguard Worker                {"http", "example.com\rnot-example.com"},
407*6777b538SAndroid Build Coastguard Worker                {"http", "example.com\n"},
408*6777b538SAndroid Build Coastguard Worker                {"http", "example.com\r"},
409*6777b538SAndroid Build Coastguard Worker                {"unknown-scheme", "example.com"},
410*6777b538SAndroid Build Coastguard Worker                {"host-only", "\r", 0},
411*6777b538SAndroid Build Coastguard Worker                {"host-only", "example.com", 22},
412*6777b538SAndroid Build Coastguard Worker                {"file", "", 123}};  // file: shouldn't have a port.
413*6777b538SAndroid Build Coastguard Worker 
414*6777b538SAndroid Build Coastguard Worker   for (const auto& test : cases) {
415*6777b538SAndroid Build Coastguard Worker     SCOPED_TRACE(testing::Message()
416*6777b538SAndroid Build Coastguard Worker                  << test.scheme << "://" << test.host << ":" << test.port);
417*6777b538SAndroid Build Coastguard Worker     EXPECT_FALSE(UnsafelyCreateOpaqueOriginWithoutNormalization(
418*6777b538SAndroid Build Coastguard Worker         test.scheme, test.host, test.port, CreateNonce()));
419*6777b538SAndroid Build Coastguard Worker     EXPECT_FALSE(url::Origin::UnsafelyCreateTupleOriginWithoutNormalization(
420*6777b538SAndroid Build Coastguard Worker         test.scheme, test.host, test.port));
421*6777b538SAndroid Build Coastguard Worker   }
422*6777b538SAndroid Build Coastguard Worker 
423*6777b538SAndroid Build Coastguard Worker   // An empty scheme/host/port tuple is not a valid tuple origin.
424*6777b538SAndroid Build Coastguard Worker   EXPECT_FALSE(
425*6777b538SAndroid Build Coastguard Worker       url::Origin::UnsafelyCreateTupleOriginWithoutNormalization("", "", 0));
426*6777b538SAndroid Build Coastguard Worker 
427*6777b538SAndroid Build Coastguard Worker   // Opaque origins with unknown precursors are allowed.
428*6777b538SAndroid Build Coastguard Worker   base::UnguessableToken token = base::UnguessableToken::Create();
429*6777b538SAndroid Build Coastguard Worker   std::optional<url::Origin> anonymous_opaque =
430*6777b538SAndroid Build Coastguard Worker       UnsafelyCreateOpaqueOriginWithoutNormalization("", "", 0,
431*6777b538SAndroid Build Coastguard Worker                                                      CreateNonce(token));
432*6777b538SAndroid Build Coastguard Worker   ASSERT_TRUE(anonymous_opaque)
433*6777b538SAndroid Build Coastguard Worker       << "An invalid tuple is a valid input to "
434*6777b538SAndroid Build Coastguard Worker       << "UnsafelyCreateOpaqueOriginWithoutNormalization, so long as it is "
435*6777b538SAndroid Build Coastguard Worker       << "the canonical form of the invalid tuple.";
436*6777b538SAndroid Build Coastguard Worker   EXPECT_TRUE(anonymous_opaque->opaque());
437*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(*GetNonce(anonymous_opaque.value()), token);
438*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(anonymous_opaque->GetTupleOrPrecursorTupleIfOpaque(),
439*6777b538SAndroid Build Coastguard Worker             url::SchemeHostPort());
440*6777b538SAndroid Build Coastguard Worker }
441*6777b538SAndroid Build Coastguard Worker 
TEST_P(OriginTest,UnsafelyCreateUniqueViaEmbeddedNulls)442*6777b538SAndroid Build Coastguard Worker TEST_P(OriginTest, UnsafelyCreateUniqueViaEmbeddedNulls) {
443*6777b538SAndroid Build Coastguard Worker   struct TestCases {
444*6777b538SAndroid Build Coastguard Worker     std::string_view scheme;
445*6777b538SAndroid Build Coastguard Worker     std::string_view host;
446*6777b538SAndroid Build Coastguard Worker     uint16_t port = 80;
447*6777b538SAndroid Build Coastguard Worker   } cases[] = {{{"http\0more", 9}, {"example.com", 11}},
448*6777b538SAndroid Build Coastguard Worker                {{"http\0", 5}, {"example.com", 11}},
449*6777b538SAndroid Build Coastguard Worker                {{"\0http", 5}, {"example.com", 11}},
450*6777b538SAndroid Build Coastguard Worker                {{"http"}, {"example.com\0not-example.com", 27}},
451*6777b538SAndroid Build Coastguard Worker                {{"http"}, {"example.com\0", 12}},
452*6777b538SAndroid Build Coastguard Worker                {{"http"}, {"\0example.com", 12}},
453*6777b538SAndroid Build Coastguard Worker                {{""}, {"\0", 1}, 0},
454*6777b538SAndroid Build Coastguard Worker                {{"\0", 1}, {""}, 0}};
455*6777b538SAndroid Build Coastguard Worker 
456*6777b538SAndroid Build Coastguard Worker   for (const auto& test : cases) {
457*6777b538SAndroid Build Coastguard Worker     SCOPED_TRACE(testing::Message()
458*6777b538SAndroid Build Coastguard Worker                  << test.scheme << "://" << test.host << ":" << test.port);
459*6777b538SAndroid Build Coastguard Worker     EXPECT_FALSE(url::Origin::UnsafelyCreateTupleOriginWithoutNormalization(
460*6777b538SAndroid Build Coastguard Worker         test.scheme, test.host, test.port));
461*6777b538SAndroid Build Coastguard Worker     EXPECT_FALSE(UnsafelyCreateOpaqueOriginWithoutNormalization(
462*6777b538SAndroid Build Coastguard Worker         test.scheme, test.host, test.port, CreateNonce()));
463*6777b538SAndroid Build Coastguard Worker   }
464*6777b538SAndroid Build Coastguard Worker }
465*6777b538SAndroid Build Coastguard Worker 
TEST_P(OriginTest,DomainIs)466*6777b538SAndroid Build Coastguard Worker TEST_P(OriginTest, DomainIs) {
467*6777b538SAndroid Build Coastguard Worker   const struct {
468*6777b538SAndroid Build Coastguard Worker     const char* url;
469*6777b538SAndroid Build Coastguard Worker     const char* lower_ascii_domain;
470*6777b538SAndroid Build Coastguard Worker     bool expected_domain_is;
471*6777b538SAndroid Build Coastguard Worker   } kTestCases[] = {
472*6777b538SAndroid Build Coastguard Worker       {"http://google.com/foo", "google.com", true},
473*6777b538SAndroid Build Coastguard Worker       {"http://www.google.com:99/foo", "google.com", true},
474*6777b538SAndroid Build Coastguard Worker       {"http://www.google.com.cn/foo", "google.com", false},
475*6777b538SAndroid Build Coastguard Worker       {"http://www.google.comm", "google.com", false},
476*6777b538SAndroid Build Coastguard Worker       {"http://www.iamnotgoogle.com/foo", "google.com", false},
477*6777b538SAndroid Build Coastguard Worker       {"http://www.google.com/foo", "Google.com", false},
478*6777b538SAndroid Build Coastguard Worker 
479*6777b538SAndroid Build Coastguard Worker       // If the host ends with a dot, it matches domains with or without a dot.
480*6777b538SAndroid Build Coastguard Worker       {"http://www.google.com./foo", "google.com", true},
481*6777b538SAndroid Build Coastguard Worker       {"http://www.google.com./foo", "google.com.", true},
482*6777b538SAndroid Build Coastguard Worker       {"http://www.google.com./foo", ".com", true},
483*6777b538SAndroid Build Coastguard Worker       {"http://www.google.com./foo", ".com.", true},
484*6777b538SAndroid Build Coastguard Worker 
485*6777b538SAndroid Build Coastguard Worker       // But, if the host doesn't end with a dot and the input domain does, then
486*6777b538SAndroid Build Coastguard Worker       // it's considered to not match.
487*6777b538SAndroid Build Coastguard Worker       {"http://google.com/foo", "google.com.", false},
488*6777b538SAndroid Build Coastguard Worker 
489*6777b538SAndroid Build Coastguard Worker       // If the host ends with two dots, it doesn't match.
490*6777b538SAndroid Build Coastguard Worker       {"http://www.google.com../foo", "google.com", false},
491*6777b538SAndroid Build Coastguard Worker 
492*6777b538SAndroid Build Coastguard Worker       // Filesystem scheme.
493*6777b538SAndroid Build Coastguard Worker       {"filesystem:http://www.google.com:99/foo/", "google.com", true},
494*6777b538SAndroid Build Coastguard Worker       {"filesystem:http://www.iamnotgoogle.com/foo/", "google.com", false},
495*6777b538SAndroid Build Coastguard Worker 
496*6777b538SAndroid Build Coastguard Worker       // File scheme.
497*6777b538SAndroid Build Coastguard Worker       {"file:///home/user/text.txt", "", false},
498*6777b538SAndroid Build Coastguard Worker       {"file:///home/user/text.txt", "txt", false},
499*6777b538SAndroid Build Coastguard Worker   };
500*6777b538SAndroid Build Coastguard Worker 
501*6777b538SAndroid Build Coastguard Worker   for (const auto& test_case : kTestCases) {
502*6777b538SAndroid Build Coastguard Worker     SCOPED_TRACE(testing::Message()
503*6777b538SAndroid Build Coastguard Worker                  << "(url, domain): (" << test_case.url << ", "
504*6777b538SAndroid Build Coastguard Worker                  << test_case.lower_ascii_domain << ")");
505*6777b538SAndroid Build Coastguard Worker     GURL url(test_case.url);
506*6777b538SAndroid Build Coastguard Worker     ASSERT_TRUE(url.is_valid());
507*6777b538SAndroid Build Coastguard Worker     Origin origin = Origin::Create(url);
508*6777b538SAndroid Build Coastguard Worker 
509*6777b538SAndroid Build Coastguard Worker     EXPECT_EQ(test_case.expected_domain_is,
510*6777b538SAndroid Build Coastguard Worker               origin.DomainIs(test_case.lower_ascii_domain));
511*6777b538SAndroid Build Coastguard Worker     EXPECT_FALSE(
512*6777b538SAndroid Build Coastguard Worker         origin.DeriveNewOpaqueOrigin().DomainIs(test_case.lower_ascii_domain));
513*6777b538SAndroid Build Coastguard Worker   }
514*6777b538SAndroid Build Coastguard Worker 
515*6777b538SAndroid Build Coastguard Worker   // If the URL is invalid, DomainIs returns false.
516*6777b538SAndroid Build Coastguard Worker   GURL invalid_url("google.com");
517*6777b538SAndroid Build Coastguard Worker   ASSERT_FALSE(invalid_url.is_valid());
518*6777b538SAndroid Build Coastguard Worker   EXPECT_FALSE(Origin::Create(invalid_url).DomainIs("google.com"));
519*6777b538SAndroid Build Coastguard Worker 
520*6777b538SAndroid Build Coastguard Worker   // Unique origins.
521*6777b538SAndroid Build Coastguard Worker   EXPECT_FALSE(Origin().DomainIs(""));
522*6777b538SAndroid Build Coastguard Worker   EXPECT_FALSE(Origin().DomainIs("com"));
523*6777b538SAndroid Build Coastguard Worker }
524*6777b538SAndroid Build Coastguard Worker 
TEST_P(OriginTest,DebugAlias)525*6777b538SAndroid Build Coastguard Worker TEST_P(OriginTest, DebugAlias) {
526*6777b538SAndroid Build Coastguard Worker   Origin origin1 = Origin::Create(GURL("https://foo.com/bar"));
527*6777b538SAndroid Build Coastguard Worker   DEBUG_ALIAS_FOR_ORIGIN(origin1_debug_alias, origin1);
528*6777b538SAndroid Build Coastguard Worker   EXPECT_STREQ("https://foo.com", origin1_debug_alias);
529*6777b538SAndroid Build Coastguard Worker }
530*6777b538SAndroid Build Coastguard Worker 
TEST_P(OriginTest,CanBeDerivedFrom)531*6777b538SAndroid Build Coastguard Worker TEST_P(OriginTest, CanBeDerivedFrom) {
532*6777b538SAndroid Build Coastguard Worker   AddStandardScheme("new-standard", SchemeType::SCHEME_WITH_HOST);
533*6777b538SAndroid Build Coastguard Worker   Origin opaque_unique_origin = Origin();
534*6777b538SAndroid Build Coastguard Worker 
535*6777b538SAndroid Build Coastguard Worker   Origin regular_origin = Origin::Create(GURL("https://a.com/"));
536*6777b538SAndroid Build Coastguard Worker   Origin opaque_precursor_origin = regular_origin.DeriveNewOpaqueOrigin();
537*6777b538SAndroid Build Coastguard Worker 
538*6777b538SAndroid Build Coastguard Worker   Origin file_origin = Origin::Create(GURL("file:///foo/bar"));
539*6777b538SAndroid Build Coastguard Worker   Origin file_opaque_precursor_origin = file_origin.DeriveNewOpaqueOrigin();
540*6777b538SAndroid Build Coastguard Worker   Origin file_host_origin = Origin::Create(GURL("file://a.com/foo/bar"));
541*6777b538SAndroid Build Coastguard Worker   Origin file_host_opaque_precursor_origin =
542*6777b538SAndroid Build Coastguard Worker       file_host_origin.DeriveNewOpaqueOrigin();
543*6777b538SAndroid Build Coastguard Worker 
544*6777b538SAndroid Build Coastguard Worker   Origin non_standard_scheme_origin =
545*6777b538SAndroid Build Coastguard Worker       Origin::Create(GURL("non-standard-scheme:foo"));
546*6777b538SAndroid Build Coastguard Worker   Origin non_standard_opaque_precursor_origin =
547*6777b538SAndroid Build Coastguard Worker       non_standard_scheme_origin.DeriveNewOpaqueOrigin();
548*6777b538SAndroid Build Coastguard Worker 
549*6777b538SAndroid Build Coastguard Worker   // Also, add new standard scheme that is local to the test.
550*6777b538SAndroid Build Coastguard Worker   Origin new_standard_origin = Origin::Create(GURL("new-standard://host/"));
551*6777b538SAndroid Build Coastguard Worker   Origin new_standard_opaque_precursor_origin =
552*6777b538SAndroid Build Coastguard Worker       new_standard_origin.DeriveNewOpaqueOrigin();
553*6777b538SAndroid Build Coastguard Worker 
554*6777b538SAndroid Build Coastguard Worker   // No access schemes always get unique opaque origins.
555*6777b538SAndroid Build Coastguard Worker   Origin no_access_origin =
556*6777b538SAndroid Build Coastguard Worker       Origin::Create(GURL("standard-but-noaccess://b.com"));
557*6777b538SAndroid Build Coastguard Worker   Origin no_access_opaque_precursor_origin =
558*6777b538SAndroid Build Coastguard Worker       no_access_origin.DeriveNewOpaqueOrigin();
559*6777b538SAndroid Build Coastguard Worker 
560*6777b538SAndroid Build Coastguard Worker   Origin local_non_standard_origin =
561*6777b538SAndroid Build Coastguard Worker       Origin::Create(GURL("local-but-nonstandard://a.com"));
562*6777b538SAndroid Build Coastguard Worker   Origin local_non_standard_opaque_precursor_origin =
563*6777b538SAndroid Build Coastguard Worker       local_non_standard_origin.DeriveNewOpaqueOrigin();
564*6777b538SAndroid Build Coastguard Worker 
565*6777b538SAndroid Build Coastguard Worker   // Call origin.CanBeDerivedFrom(url) for each of the following test cases
566*6777b538SAndroid Build Coastguard Worker   // and ensure that it returns |expected_value|
567*6777b538SAndroid Build Coastguard Worker   struct TestCase {
568*6777b538SAndroid Build Coastguard Worker     const char* url;
569*6777b538SAndroid Build Coastguard Worker     raw_ptr<Origin> origin;
570*6777b538SAndroid Build Coastguard Worker     bool expected_value;
571*6777b538SAndroid Build Coastguard Worker   };
572*6777b538SAndroid Build Coastguard Worker 
573*6777b538SAndroid Build Coastguard Worker   const TestCase common_test_cases[] = {
574*6777b538SAndroid Build Coastguard Worker       {"https://a.com", &regular_origin, true},
575*6777b538SAndroid Build Coastguard Worker       // Web URL can commit in an opaque origin with precursor information.
576*6777b538SAndroid Build Coastguard Worker       // Example: iframe sandbox navigated to a.com.
577*6777b538SAndroid Build Coastguard Worker       {"https://a.com", &opaque_precursor_origin, true},
578*6777b538SAndroid Build Coastguard Worker       // URL that comes from the web can never commit in an opaque unique
579*6777b538SAndroid Build Coastguard Worker       // origin. It must have precursor information.
580*6777b538SAndroid Build Coastguard Worker       {"https://a.com", &opaque_unique_origin, false},
581*6777b538SAndroid Build Coastguard Worker 
582*6777b538SAndroid Build Coastguard Worker       // Cross-origin URLs should never work.
583*6777b538SAndroid Build Coastguard Worker       {"https://b.com", &regular_origin, false},
584*6777b538SAndroid Build Coastguard Worker       {"https://b.com", &opaque_precursor_origin, false},
585*6777b538SAndroid Build Coastguard Worker 
586*6777b538SAndroid Build Coastguard Worker       // data: URL can never commit in a regular, non-opaque origin.
587*6777b538SAndroid Build Coastguard Worker       {"data:text/html,foo", &regular_origin, false},
588*6777b538SAndroid Build Coastguard Worker       // This is the default case: data: URLs commit in opaque origin carrying
589*6777b538SAndroid Build Coastguard Worker       // precursor information for the origin that created them.
590*6777b538SAndroid Build Coastguard Worker       {"data:text/html,foo", &opaque_precursor_origin, true},
591*6777b538SAndroid Build Coastguard Worker       // Browser-initiated navigations can result in data: URL committing in
592*6777b538SAndroid Build Coastguard Worker       // opaque unique origin.
593*6777b538SAndroid Build Coastguard Worker       {"data:text/html,foo", &opaque_unique_origin, true},
594*6777b538SAndroid Build Coastguard Worker 
595*6777b538SAndroid Build Coastguard Worker       // about:blank can commit in regular origin (default case for iframes).
596*6777b538SAndroid Build Coastguard Worker       {"about:blank", &regular_origin, true},
597*6777b538SAndroid Build Coastguard Worker       // This can happen if data: URL that originated at a.com creates an
598*6777b538SAndroid Build Coastguard Worker       // about:blank iframe.
599*6777b538SAndroid Build Coastguard Worker       {"about:blank", &opaque_precursor_origin, true},
600*6777b538SAndroid Build Coastguard Worker       // Browser-initiated navigations can result in about:blank URL committing
601*6777b538SAndroid Build Coastguard Worker       // in opaque unique origin.
602*6777b538SAndroid Build Coastguard Worker       {"about:blank", &opaque_unique_origin, true},
603*6777b538SAndroid Build Coastguard Worker 
604*6777b538SAndroid Build Coastguard Worker       // Default behavior of srcdoc is to inherit the origin of the parent
605*6777b538SAndroid Build Coastguard Worker       // document.
606*6777b538SAndroid Build Coastguard Worker       {"about:srcdoc", &regular_origin, true},
607*6777b538SAndroid Build Coastguard Worker       // This happens for sandboxed srcdoc iframe.
608*6777b538SAndroid Build Coastguard Worker       {"about:srcdoc", &opaque_precursor_origin, true},
609*6777b538SAndroid Build Coastguard Worker       // This can happen with browser-initiated navigation to about:blank or
610*6777b538SAndroid Build Coastguard Worker       // data: URL, which in turn add srcdoc iframe.
611*6777b538SAndroid Build Coastguard Worker       {"about:srcdoc", &opaque_unique_origin, true},
612*6777b538SAndroid Build Coastguard Worker 
613*6777b538SAndroid Build Coastguard Worker       // Just like srcdoc, blob: URLs can be created in all the cases.
614*6777b538SAndroid Build Coastguard Worker       {"blob:https://a.com/foo", &regular_origin, true},
615*6777b538SAndroid Build Coastguard Worker       {"blob:https://a.com/foo", &opaque_precursor_origin, true},
616*6777b538SAndroid Build Coastguard Worker       {"blob:https://a.com/foo", &opaque_unique_origin, true},
617*6777b538SAndroid Build Coastguard Worker 
618*6777b538SAndroid Build Coastguard Worker       {"filesystem:https://a.com/foo", &regular_origin, true},
619*6777b538SAndroid Build Coastguard Worker       {"filesystem:https://a.com/foo", &opaque_precursor_origin, true},
620*6777b538SAndroid Build Coastguard Worker       // Unlike blob: URLs, filesystem: ones cannot be created in an unique
621*6777b538SAndroid Build Coastguard Worker       // opaque origin.
622*6777b538SAndroid Build Coastguard Worker       {"filesystem:https://a.com/foo", &opaque_unique_origin, false},
623*6777b538SAndroid Build Coastguard Worker 
624*6777b538SAndroid Build Coastguard Worker       // file: URLs cannot result in regular web origins, regardless of
625*6777b538SAndroid Build Coastguard Worker       // opaqueness.
626*6777b538SAndroid Build Coastguard Worker       {"file:///etc/passwd", &regular_origin, false},
627*6777b538SAndroid Build Coastguard Worker       {"file:///etc/passwd", &opaque_precursor_origin, false},
628*6777b538SAndroid Build Coastguard Worker       // However, they can result in regular file: origin and an opaque one
629*6777b538SAndroid Build Coastguard Worker       // containing another file: origin as precursor.
630*6777b538SAndroid Build Coastguard Worker       {"file:///etc/passwd", &file_origin, true},
631*6777b538SAndroid Build Coastguard Worker       {"file:///etc/passwd", &file_opaque_precursor_origin, true},
632*6777b538SAndroid Build Coastguard Worker       // It should not be possible to get an opaque unique origin for file:
633*6777b538SAndroid Build Coastguard Worker       // as it is a standard scheme and will always result in a tuple origin
634*6777b538SAndroid Build Coastguard Worker       // or will always be derived by other origin.
635*6777b538SAndroid Build Coastguard Worker       // Note: file:// URLs should become unique opaque origins at some point.
636*6777b538SAndroid Build Coastguard Worker       {"file:///etc/passwd", &opaque_unique_origin, false},
637*6777b538SAndroid Build Coastguard Worker 
638*6777b538SAndroid Build Coastguard Worker       // The same set as above, but including a host.
639*6777b538SAndroid Build Coastguard Worker       {"file://a.com/etc/passwd", &regular_origin, false},
640*6777b538SAndroid Build Coastguard Worker       {"file://a.com/etc/passwd", &opaque_precursor_origin, false},
641*6777b538SAndroid Build Coastguard Worker       {"file://a.com/etc/passwd", &file_host_origin, true},
642*6777b538SAndroid Build Coastguard Worker       {"file://a.com/etc/passwd", &file_host_opaque_precursor_origin, true},
643*6777b538SAndroid Build Coastguard Worker       {"file://a.com/etc/passwd", &opaque_unique_origin, false},
644*6777b538SAndroid Build Coastguard Worker 
645*6777b538SAndroid Build Coastguard Worker       // Locally registered standard scheme should behave the same way
646*6777b538SAndroid Build Coastguard Worker       // as built-in standard schemes.
647*6777b538SAndroid Build Coastguard Worker       {"new-standard://host/foo", &new_standard_origin, true},
648*6777b538SAndroid Build Coastguard Worker       {"new-standard://host/foo", &new_standard_opaque_precursor_origin, true},
649*6777b538SAndroid Build Coastguard Worker       {"new-standard://host/foo", &opaque_unique_origin, false},
650*6777b538SAndroid Build Coastguard Worker       {"new-standard://host2/foo", &new_standard_origin, false},
651*6777b538SAndroid Build Coastguard Worker       {"new-standard://host2/foo", &new_standard_opaque_precursor_origin,
652*6777b538SAndroid Build Coastguard Worker        false},
653*6777b538SAndroid Build Coastguard Worker 
654*6777b538SAndroid Build Coastguard Worker       // A non-standard scheme should never commit in an standard origin or
655*6777b538SAndroid Build Coastguard Worker       // opaque origin with standard precursor information.
656*6777b538SAndroid Build Coastguard Worker       {"non-standard-scheme://a.com/foo", &regular_origin, false},
657*6777b538SAndroid Build Coastguard Worker       {"non-standard-scheme://a.com/foo", &opaque_precursor_origin, false},
658*6777b538SAndroid Build Coastguard Worker       // However, it should be fine to commit in unique opaque origins or in its
659*6777b538SAndroid Build Coastguard Worker       // own origin.
660*6777b538SAndroid Build Coastguard Worker       // Note: since non-standard scheme URLs don't parse out anything
661*6777b538SAndroid Build Coastguard Worker       // but the scheme, using a random different hostname here would work.
662*6777b538SAndroid Build Coastguard Worker       {"non-standard-scheme://b.com/foo2", &opaque_unique_origin, true},
663*6777b538SAndroid Build Coastguard Worker       {"non-standard-scheme://b.com/foo3", &non_standard_scheme_origin, true},
664*6777b538SAndroid Build Coastguard Worker       {"non-standard-scheme://b.com/foo4",
665*6777b538SAndroid Build Coastguard Worker        &non_standard_opaque_precursor_origin, true},
666*6777b538SAndroid Build Coastguard Worker 
667*6777b538SAndroid Build Coastguard Worker       // No access scheme can only commit in opaque origin.
668*6777b538SAndroid Build Coastguard Worker       {"standard-but-noaccess://a.com/foo", &regular_origin, false},
669*6777b538SAndroid Build Coastguard Worker       {"standard-but-noaccess://a.com/foo", &opaque_precursor_origin, false},
670*6777b538SAndroid Build Coastguard Worker       {"standard-but-noaccess://a.com/foo", &opaque_unique_origin, true},
671*6777b538SAndroid Build Coastguard Worker       {"standard-but-noaccess://a.com/foo", &no_access_origin, true},
672*6777b538SAndroid Build Coastguard Worker       {"standard-but-noaccess://a.com/foo", &no_access_opaque_precursor_origin,
673*6777b538SAndroid Build Coastguard Worker        true},
674*6777b538SAndroid Build Coastguard Worker       {"standard-but-noaccess://b.com/foo", &no_access_origin, true},
675*6777b538SAndroid Build Coastguard Worker       {"standard-but-noaccess://b.com/foo", &no_access_opaque_precursor_origin,
676*6777b538SAndroid Build Coastguard Worker        true},
677*6777b538SAndroid Build Coastguard Worker 
678*6777b538SAndroid Build Coastguard Worker       // Local schemes can be non-standard, verify they also work as expected.
679*6777b538SAndroid Build Coastguard Worker       {"local-but-nonstandard://a.com", &regular_origin, false},
680*6777b538SAndroid Build Coastguard Worker       {"local-but-nonstandard://a.com", &opaque_precursor_origin, false},
681*6777b538SAndroid Build Coastguard Worker       {"local-but-nonstandard://a.com", &opaque_unique_origin, true},
682*6777b538SAndroid Build Coastguard Worker       {"local-but-nonstandard://a.com", &local_non_standard_origin, true},
683*6777b538SAndroid Build Coastguard Worker       {"local-but-nonstandard://a.com",
684*6777b538SAndroid Build Coastguard Worker        &local_non_standard_opaque_precursor_origin, true},
685*6777b538SAndroid Build Coastguard Worker   };
686*6777b538SAndroid Build Coastguard Worker 
687*6777b538SAndroid Build Coastguard Worker   for (const auto& test_case : common_test_cases) {
688*6777b538SAndroid Build Coastguard Worker     SCOPED_TRACE(testing::Message() << "(origin, url): (" << *test_case.origin
689*6777b538SAndroid Build Coastguard Worker                                     << ", " << test_case.url << ")");
690*6777b538SAndroid Build Coastguard Worker     EXPECT_EQ(test_case.expected_value,
691*6777b538SAndroid Build Coastguard Worker               test_case.origin->CanBeDerivedFrom(GURL(test_case.url)));
692*6777b538SAndroid Build Coastguard Worker   }
693*6777b538SAndroid Build Coastguard Worker 
694*6777b538SAndroid Build Coastguard Worker   // Flag-dependent tests
695*6777b538SAndroid Build Coastguard Worker   const TestCase flag_dependent_test_cases[] = {
696*6777b538SAndroid Build Coastguard Worker       {"local-but-nonstandard://b.com", &local_non_standard_origin,
697*6777b538SAndroid Build Coastguard Worker        !use_standard_compliant_non_special_scheme_url_parsing_},
698*6777b538SAndroid Build Coastguard Worker       {"local-but-nonstandard://b.com",
699*6777b538SAndroid Build Coastguard Worker        &local_non_standard_opaque_precursor_origin,
700*6777b538SAndroid Build Coastguard Worker        !use_standard_compliant_non_special_scheme_url_parsing_},
701*6777b538SAndroid Build Coastguard Worker   };
702*6777b538SAndroid Build Coastguard Worker   for (const auto& test_case : flag_dependent_test_cases) {
703*6777b538SAndroid Build Coastguard Worker     SCOPED_TRACE(testing::Message() << "(origin, url): (" << *test_case.origin
704*6777b538SAndroid Build Coastguard Worker                                     << ", " << test_case.url << ")");
705*6777b538SAndroid Build Coastguard Worker     EXPECT_EQ(test_case.expected_value,
706*6777b538SAndroid Build Coastguard Worker               test_case.origin->CanBeDerivedFrom(GURL(test_case.url)));
707*6777b538SAndroid Build Coastguard Worker   }
708*6777b538SAndroid Build Coastguard Worker }
709*6777b538SAndroid Build Coastguard Worker 
TEST_P(OriginTest,GetDebugString)710*6777b538SAndroid Build Coastguard Worker TEST_P(OriginTest, GetDebugString) {
711*6777b538SAndroid Build Coastguard Worker   Origin http_origin = Origin::Create(GURL("http://192.168.9.1"));
712*6777b538SAndroid Build Coastguard Worker   EXPECT_STREQ(http_origin.GetDebugString().c_str(), "http://192.168.9.1");
713*6777b538SAndroid Build Coastguard Worker 
714*6777b538SAndroid Build Coastguard Worker   Origin http_opaque_origin = http_origin.DeriveNewOpaqueOrigin();
715*6777b538SAndroid Build Coastguard Worker   EXPECT_THAT(
716*6777b538SAndroid Build Coastguard Worker       http_opaque_origin.GetDebugString().c_str(),
717*6777b538SAndroid Build Coastguard Worker       ::testing::MatchesRegex(
718*6777b538SAndroid Build Coastguard Worker           "null \\[internally: \\(\\w*\\) derived from http://192.168.9.1\\]"));
719*6777b538SAndroid Build Coastguard Worker   EXPECT_THAT(
720*6777b538SAndroid Build Coastguard Worker       http_opaque_origin.GetDebugString(false /* include_nonce */).c_str(),
721*6777b538SAndroid Build Coastguard Worker       ::testing::MatchesRegex(
722*6777b538SAndroid Build Coastguard Worker           "null \\[internally: derived from http://192.168.9.1\\]"));
723*6777b538SAndroid Build Coastguard Worker 
724*6777b538SAndroid Build Coastguard Worker   Origin data_origin = Origin::Create(GURL("data:"));
725*6777b538SAndroid Build Coastguard Worker   EXPECT_STREQ(data_origin.GetDebugString().c_str(),
726*6777b538SAndroid Build Coastguard Worker                "null [internally: (nonce TBD) anonymous]");
727*6777b538SAndroid Build Coastguard Worker 
728*6777b538SAndroid Build Coastguard Worker   // The nonce of the origin will be initialized if a new opaque origin is
729*6777b538SAndroid Build Coastguard Worker   // derived.
730*6777b538SAndroid Build Coastguard Worker   Origin data_derived_origin = data_origin.DeriveNewOpaqueOrigin();
731*6777b538SAndroid Build Coastguard Worker   EXPECT_THAT(
732*6777b538SAndroid Build Coastguard Worker       data_derived_origin.GetDebugString().c_str(),
733*6777b538SAndroid Build Coastguard Worker       ::testing::MatchesRegex("null \\[internally: \\(\\w*\\) anonymous\\]"));
734*6777b538SAndroid Build Coastguard Worker   EXPECT_THAT(
735*6777b538SAndroid Build Coastguard Worker       data_derived_origin.GetDebugString(false /* include_nonce */).c_str(),
736*6777b538SAndroid Build Coastguard Worker       ::testing::MatchesRegex("null \\[internally: anonymous\\]"));
737*6777b538SAndroid Build Coastguard Worker 
738*6777b538SAndroid Build Coastguard Worker   Origin file_origin = Origin::Create(GURL("file:///etc/passwd"));
739*6777b538SAndroid Build Coastguard Worker   EXPECT_STREQ(file_origin.GetDebugString().c_str(),
740*6777b538SAndroid Build Coastguard Worker                "file:// [internally: file://]");
741*6777b538SAndroid Build Coastguard Worker 
742*6777b538SAndroid Build Coastguard Worker   Origin file_server_origin =
743*6777b538SAndroid Build Coastguard Worker       Origin::Create(GURL("file://example.com/etc/passwd"));
744*6777b538SAndroid Build Coastguard Worker   EXPECT_STREQ(file_server_origin.GetDebugString().c_str(),
745*6777b538SAndroid Build Coastguard Worker                "file:// [internally: file://example.com]");
746*6777b538SAndroid Build Coastguard Worker }
747*6777b538SAndroid Build Coastguard Worker 
TEST_P(OriginTest,Deserialize)748*6777b538SAndroid Build Coastguard Worker TEST_P(OriginTest, Deserialize) {
749*6777b538SAndroid Build Coastguard Worker   std::vector<GURL> valid_urls = {
750*6777b538SAndroid Build Coastguard Worker       GURL("https://a.com"),         GURL("http://a"),
751*6777b538SAndroid Build Coastguard Worker       GURL("http://a:80"),           GURL("file://a.com/etc/passwd"),
752*6777b538SAndroid Build Coastguard Worker       GURL("file:///etc/passwd"),    GURL("http://192.168.1.1"),
753*6777b538SAndroid Build Coastguard Worker       GURL("http://[2001:db8::1]/"),
754*6777b538SAndroid Build Coastguard Worker   };
755*6777b538SAndroid Build Coastguard Worker   for (const GURL& url : valid_urls) {
756*6777b538SAndroid Build Coastguard Worker     SCOPED_TRACE(url.spec());
757*6777b538SAndroid Build Coastguard Worker     Origin origin = Origin::Create(url);
758*6777b538SAndroid Build Coastguard Worker     std::optional<std::string> serialized = SerializeWithNonce(origin);
759*6777b538SAndroid Build Coastguard Worker     ASSERT_TRUE(serialized);
760*6777b538SAndroid Build Coastguard Worker 
761*6777b538SAndroid Build Coastguard Worker     std::optional<Origin> deserialized = Deserialize(std::move(*serialized));
762*6777b538SAndroid Build Coastguard Worker     ASSERT_TRUE(deserialized.has_value());
763*6777b538SAndroid Build Coastguard Worker 
764*6777b538SAndroid Build Coastguard Worker     EXPECT_TRUE(DoEqualityComparisons(origin, deserialized.value(), true));
765*6777b538SAndroid Build Coastguard Worker     EXPECT_EQ(origin.GetDebugString(), deserialized.value().GetDebugString());
766*6777b538SAndroid Build Coastguard Worker   }
767*6777b538SAndroid Build Coastguard Worker }
768*6777b538SAndroid Build Coastguard Worker 
TEST_P(OriginTest,DeserializeInvalid)769*6777b538SAndroid Build Coastguard Worker TEST_P(OriginTest, DeserializeInvalid) {
770*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(std::nullopt, Deserialize(std::string()));
771*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(std::nullopt, Deserialize("deadbeef"));
772*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(std::nullopt, Deserialize("0123456789"));
773*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(std::nullopt, Deserialize("https://a.com"));
774*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(std::nullopt, Deserialize("https://192.168.1.1"));
775*6777b538SAndroid Build Coastguard Worker }
776*6777b538SAndroid Build Coastguard Worker 
TEST_P(OriginTest,SerializeTBDNonce)777*6777b538SAndroid Build Coastguard Worker TEST_P(OriginTest, SerializeTBDNonce) {
778*6777b538SAndroid Build Coastguard Worker   std::vector<GURL> invalid_urls = {
779*6777b538SAndroid Build Coastguard Worker       GURL("data:uniqueness"),       GURL("data:,"),
780*6777b538SAndroid Build Coastguard Worker       GURL("data:text/html,Hello!"), GURL("javascript:alert(1)"),
781*6777b538SAndroid Build Coastguard Worker       GURL("about:blank"),           GURL("google.com"),
782*6777b538SAndroid Build Coastguard Worker   };
783*6777b538SAndroid Build Coastguard Worker   for (const GURL& url : invalid_urls) {
784*6777b538SAndroid Build Coastguard Worker     SCOPED_TRACE(url.spec());
785*6777b538SAndroid Build Coastguard Worker     Origin origin = Origin::Create(url);
786*6777b538SAndroid Build Coastguard Worker     std::optional<std::string> serialized = SerializeWithNonce(origin);
787*6777b538SAndroid Build Coastguard Worker     std::optional<Origin> deserialized = Deserialize(std::move(*serialized));
788*6777b538SAndroid Build Coastguard Worker     ASSERT_TRUE(deserialized.has_value());
789*6777b538SAndroid Build Coastguard Worker 
790*6777b538SAndroid Build Coastguard Worker     // Can't use DoEqualityComparisons here since empty nonces are never ==
791*6777b538SAndroid Build Coastguard Worker     // unless they are the same object.
792*6777b538SAndroid Build Coastguard Worker     EXPECT_EQ(origin.GetDebugString(), deserialized.value().GetDebugString());
793*6777b538SAndroid Build Coastguard Worker   }
794*6777b538SAndroid Build Coastguard Worker 
795*6777b538SAndroid Build Coastguard Worker   {
796*6777b538SAndroid Build Coastguard Worker     // Same basic test as above, but without a GURL to create tuple_.
797*6777b538SAndroid Build Coastguard Worker     Origin opaque;
798*6777b538SAndroid Build Coastguard Worker     std::optional<std::string> serialized = SerializeWithNonce(opaque);
799*6777b538SAndroid Build Coastguard Worker     ASSERT_TRUE(serialized);
800*6777b538SAndroid Build Coastguard Worker 
801*6777b538SAndroid Build Coastguard Worker     std::optional<Origin> deserialized = Deserialize(std::move(*serialized));
802*6777b538SAndroid Build Coastguard Worker     ASSERT_TRUE(deserialized.has_value());
803*6777b538SAndroid Build Coastguard Worker 
804*6777b538SAndroid Build Coastguard Worker     // Can't use DoEqualityComparisons here since empty nonces are never ==
805*6777b538SAndroid Build Coastguard Worker     // unless they are the same object.
806*6777b538SAndroid Build Coastguard Worker     EXPECT_EQ(opaque.GetDebugString(), deserialized.value().GetDebugString());
807*6777b538SAndroid Build Coastguard Worker   }
808*6777b538SAndroid Build Coastguard Worker 
809*6777b538SAndroid Build Coastguard Worker   // Now force initialization of the nonce prior to serialization.
810*6777b538SAndroid Build Coastguard Worker   for (const GURL& url : invalid_urls) {
811*6777b538SAndroid Build Coastguard Worker     SCOPED_TRACE(url.spec());
812*6777b538SAndroid Build Coastguard Worker     Origin origin = Origin::Create(url);
813*6777b538SAndroid Build Coastguard Worker     std::optional<std::string> serialized =
814*6777b538SAndroid Build Coastguard Worker         SerializeWithNonceAndInitIfNeeded(origin);
815*6777b538SAndroid Build Coastguard Worker     std::optional<Origin> deserialized = Deserialize(std::move(*serialized));
816*6777b538SAndroid Build Coastguard Worker     ASSERT_TRUE(deserialized.has_value());
817*6777b538SAndroid Build Coastguard Worker 
818*6777b538SAndroid Build Coastguard Worker     // The nonce should have been initialized prior to Serialization().
819*6777b538SAndroid Build Coastguard Worker     EXPECT_EQ(origin, deserialized.value());
820*6777b538SAndroid Build Coastguard Worker   }
821*6777b538SAndroid Build Coastguard Worker }
822*6777b538SAndroid Build Coastguard Worker 
TEST_P(OriginTest,DeserializeValidNonce)823*6777b538SAndroid Build Coastguard Worker TEST_P(OriginTest, DeserializeValidNonce) {
824*6777b538SAndroid Build Coastguard Worker   Origin opaque;
825*6777b538SAndroid Build Coastguard Worker   GetNonce(opaque);
826*6777b538SAndroid Build Coastguard Worker 
827*6777b538SAndroid Build Coastguard Worker   std::optional<std::string> serialized = SerializeWithNonce(opaque);
828*6777b538SAndroid Build Coastguard Worker   ASSERT_TRUE(serialized);
829*6777b538SAndroid Build Coastguard Worker 
830*6777b538SAndroid Build Coastguard Worker   std::optional<Origin> deserialized = Deserialize(std::move(*serialized));
831*6777b538SAndroid Build Coastguard Worker   ASSERT_TRUE(deserialized.has_value());
832*6777b538SAndroid Build Coastguard Worker 
833*6777b538SAndroid Build Coastguard Worker   EXPECT_TRUE(DoEqualityComparisons(opaque, deserialized.value(), true));
834*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(opaque.GetDebugString(), deserialized.value().GetDebugString());
835*6777b538SAndroid Build Coastguard Worker }
836*6777b538SAndroid Build Coastguard Worker 
TEST_P(OriginTest,IsSameOriginWith)837*6777b538SAndroid Build Coastguard Worker TEST_P(OriginTest, IsSameOriginWith) {
838*6777b538SAndroid Build Coastguard Worker   url::Origin opaque_origin;
839*6777b538SAndroid Build Coastguard Worker   GURL foo_url = GURL("https://foo.com/path");
840*6777b538SAndroid Build Coastguard Worker   url::Origin foo_origin = url::Origin::Create(foo_url);
841*6777b538SAndroid Build Coastguard Worker   GURL bar_url = GURL("https://bar.com/path");
842*6777b538SAndroid Build Coastguard Worker   url::Origin bar_origin = url::Origin::Create(bar_url);
843*6777b538SAndroid Build Coastguard Worker 
844*6777b538SAndroid Build Coastguard Worker   EXPECT_FALSE(opaque_origin.IsSameOriginWith(foo_origin));
845*6777b538SAndroid Build Coastguard Worker   EXPECT_FALSE(opaque_origin.IsSameOriginWith(foo_url));
846*6777b538SAndroid Build Coastguard Worker 
847*6777b538SAndroid Build Coastguard Worker   EXPECT_TRUE(foo_origin.IsSameOriginWith(foo_origin));
848*6777b538SAndroid Build Coastguard Worker   EXPECT_TRUE(foo_origin.IsSameOriginWith(foo_url));
849*6777b538SAndroid Build Coastguard Worker 
850*6777b538SAndroid Build Coastguard Worker   EXPECT_FALSE(foo_origin.IsSameOriginWith(bar_origin));
851*6777b538SAndroid Build Coastguard Worker   EXPECT_FALSE(foo_origin.IsSameOriginWith(bar_url));
852*6777b538SAndroid Build Coastguard Worker 
853*6777b538SAndroid Build Coastguard Worker   // Documenting legacy behavior.  This doesn't necessarily mean that the legacy
854*6777b538SAndroid Build Coastguard Worker   // behavior is correct (or desirable in the long-term).
855*6777b538SAndroid Build Coastguard Worker   EXPECT_FALSE(foo_origin.IsSameOriginWith(GURL("about:blank")));
856*6777b538SAndroid Build Coastguard Worker   EXPECT_FALSE(foo_origin.IsSameOriginWith(GURL()));  // Invalid GURL.
857*6777b538SAndroid Build Coastguard Worker   EXPECT_TRUE(foo_origin.IsSameOriginWith(GURL("blob:https://foo.com/guid")));
858*6777b538SAndroid Build Coastguard Worker }
859*6777b538SAndroid Build Coastguard Worker 
TEST_P(OriginTest,IsSameOriginLocalNonStandardScheme)860*6777b538SAndroid Build Coastguard Worker TEST_P(OriginTest, IsSameOriginLocalNonStandardScheme) {
861*6777b538SAndroid Build Coastguard Worker   GURL a_url = GURL("local-but-nonstandard://a.com/");
862*6777b538SAndroid Build Coastguard Worker   GURL b_url = GURL("local-but-nonstandard://b.com/");
863*6777b538SAndroid Build Coastguard Worker   url::Origin a_origin = url::Origin::Create(a_url);
864*6777b538SAndroid Build Coastguard Worker   url::Origin b_origin = url::Origin::Create(b_url);
865*6777b538SAndroid Build Coastguard Worker 
866*6777b538SAndroid Build Coastguard Worker   EXPECT_TRUE(a_origin.IsSameOriginWith(a_origin));
867*6777b538SAndroid Build Coastguard Worker   EXPECT_TRUE(a_origin.IsSameOriginWith(a_url));
868*6777b538SAndroid Build Coastguard Worker 
869*6777b538SAndroid Build Coastguard Worker   if (use_standard_compliant_non_special_scheme_url_parsing_) {
870*6777b538SAndroid Build Coastguard Worker     // If the flag is enabled, host and port are also checked.
871*6777b538SAndroid Build Coastguard Worker     EXPECT_FALSE(a_origin.IsSameOriginWith(b_origin));
872*6777b538SAndroid Build Coastguard Worker     EXPECT_FALSE(a_origin.IsSameOriginWith(b_url));
873*6777b538SAndroid Build Coastguard Worker   } else {
874*6777b538SAndroid Build Coastguard Worker     EXPECT_TRUE(a_origin.IsSameOriginWith(b_origin));
875*6777b538SAndroid Build Coastguard Worker     EXPECT_TRUE(a_origin.IsSameOriginWith(b_url));
876*6777b538SAndroid Build Coastguard Worker   }
877*6777b538SAndroid Build Coastguard Worker }
878*6777b538SAndroid Build Coastguard Worker 
TEST_P(OriginTest,OriginWithAndroidWebViewHackEnabled)879*6777b538SAndroid Build Coastguard Worker TEST_P(OriginTest, OriginWithAndroidWebViewHackEnabled) {
880*6777b538SAndroid Build Coastguard Worker   EnableNonStandardSchemesForAndroidWebView();
881*6777b538SAndroid Build Coastguard Worker 
882*6777b538SAndroid Build Coastguard Worker   GURL a_url = GURL("nonstandard://a.com/");
883*6777b538SAndroid Build Coastguard Worker   GURL b_url = GURL("nonstandard://b.com/");
884*6777b538SAndroid Build Coastguard Worker   url::Origin a_origin = url::Origin::Create(a_url);
885*6777b538SAndroid Build Coastguard Worker   url::Origin b_origin = url::Origin::Create(b_url);
886*6777b538SAndroid Build Coastguard Worker 
887*6777b538SAndroid Build Coastguard Worker   EXPECT_TRUE(a_origin.IsSameOriginWith(a_origin));
888*6777b538SAndroid Build Coastguard Worker   EXPECT_TRUE(a_origin.IsSameOriginWith(a_url));
889*6777b538SAndroid Build Coastguard Worker 
890*6777b538SAndroid Build Coastguard Worker   // When AndroidWebViewHack is enabled, only a scheme part is checked. Thus,
891*6777b538SAndroid Build Coastguard Worker   // "nonstandard://a.com/" and "nonstandard://b.com/" are considered as the
892*6777b538SAndroid Build Coastguard Worker   // same origin. This is not ideal, given that a host and a port are available
893*6777b538SAndroid Build Coastguard Worker   // when kStandardCompliantNonSpecialSchemeURLParsing flag is enabled, but we
894*6777b538SAndroid Build Coastguard Worker   // can't check a host nor a port to avoid breaking existing WebView code.
895*6777b538SAndroid Build Coastguard Worker   // See https://crbug.com/40063064 for details.
896*6777b538SAndroid Build Coastguard Worker   EXPECT_TRUE(a_origin.IsSameOriginWith(b_origin));
897*6777b538SAndroid Build Coastguard Worker   EXPECT_TRUE(a_origin.IsSameOriginWith(b_url));
898*6777b538SAndroid Build Coastguard Worker   EXPECT_TRUE(a_origin.CanBeDerivedFrom(b_url));
899*6777b538SAndroid Build Coastguard Worker 
900*6777b538SAndroid Build Coastguard Worker   GURL another_scheme_url = GURL("another-nonstandard://a.com/");
901*6777b538SAndroid Build Coastguard Worker   url::Origin another_scheme_origin = url::Origin::Create(another_scheme_url);
902*6777b538SAndroid Build Coastguard Worker   EXPECT_FALSE(a_origin.IsSameOriginWith(another_scheme_origin));
903*6777b538SAndroid Build Coastguard Worker   EXPECT_FALSE(a_origin.IsSameOriginWith(another_scheme_url));
904*6777b538SAndroid Build Coastguard Worker   EXPECT_FALSE(a_origin.CanBeDerivedFrom(another_scheme_url));
905*6777b538SAndroid Build Coastguard Worker }
906*6777b538SAndroid Build Coastguard Worker 
907*6777b538SAndroid Build Coastguard Worker INSTANTIATE_TYPED_TEST_SUITE_P(UrlOrigin,
908*6777b538SAndroid Build Coastguard Worker                                AbstractOriginTest,
909*6777b538SAndroid Build Coastguard Worker                                UrlOriginTestTraits);
910*6777b538SAndroid Build Coastguard Worker 
911*6777b538SAndroid Build Coastguard Worker }  // namespace url
912