blob: c692e6b4d6e40424c1b3296b43f9ac6a488be742 [file] [log] [blame]
mkwst9f2cc892015-07-22 06:03:251// Copyright 2015 The Chromium Authors. All rights reserved.
2// Use of this source code is governed by a BSD-style license that can be
3// found in the LICENSE file.
4
avic0c60312015-12-21 21:03:505#include <stddef.h>
6#include <stdint.h>
7
mkwstd8335d982015-07-25 05:18:488#include "base/logging.h"
avic0c60312015-12-21 21:03:509#include "base/macros.h"
mkwst9f2cc892015-07-22 06:03:2510#include "testing/gtest/include/gtest/gtest.h"
11#include "url/gurl.h"
avic0c60312015-12-21 21:03:5012#include "url/origin.h"
mkwst9f2cc892015-07-22 06:03:2513
14namespace {
15
csharrison048bee12016-10-04 00:08:2116void ExpectParsedUrlsEqual(const GURL& a, const GURL& b) {
17 EXPECT_EQ(a, b);
18 const url::Parsed& a_parsed = a.parsed_for_possibly_invalid_spec();
19 const url::Parsed& b_parsed = b.parsed_for_possibly_invalid_spec();
csharrison6fbc9fa2016-10-08 03:31:5020 EXPECT_EQ(a_parsed.scheme.begin, b_parsed.scheme.begin);
21 EXPECT_EQ(a_parsed.scheme.len, b_parsed.scheme.len);
22 EXPECT_EQ(a_parsed.username.begin, b_parsed.username.begin);
23 EXPECT_EQ(a_parsed.username.len, b_parsed.username.len);
24 EXPECT_EQ(a_parsed.password.begin, b_parsed.password.begin);
25 EXPECT_EQ(a_parsed.password.len, b_parsed.password.len);
26 EXPECT_EQ(a_parsed.host.begin, b_parsed.host.begin);
27 EXPECT_EQ(a_parsed.host.len, b_parsed.host.len);
28 EXPECT_EQ(a_parsed.port.begin, b_parsed.port.begin);
29 EXPECT_EQ(a_parsed.port.len, b_parsed.port.len);
30 EXPECT_EQ(a_parsed.path.begin, b_parsed.path.begin);
31 EXPECT_EQ(a_parsed.path.len, b_parsed.path.len);
32 EXPECT_EQ(a_parsed.query.begin, b_parsed.query.begin);
33 EXPECT_EQ(a_parsed.query.len, b_parsed.query.len);
34 EXPECT_EQ(a_parsed.ref.begin, b_parsed.ref.begin);
35 EXPECT_EQ(a_parsed.ref.len, b_parsed.ref.len);
csharrison048bee12016-10-04 00:08:2136}
37
mkwst9f2cc892015-07-22 06:03:2538TEST(OriginTest, UniqueOriginComparison) {
39 url::Origin unique_origin;
40 EXPECT_EQ("", unique_origin.scheme());
41 EXPECT_EQ("", unique_origin.host());
42 EXPECT_EQ(0, unique_origin.port());
43 EXPECT_TRUE(unique_origin.unique());
44 EXPECT_FALSE(unique_origin.IsSameOriginWith(unique_origin));
45
46 const char* const urls[] = {"data:text/html,Hello!",
47 "javascript:alert(1)",
48 "file://example.com:443/etc/passwd",
49 "yay",
50 "http::///invalid.example.com/"};
51
vmpstr981aa5a2016-07-14 01:05:0852 for (auto* test_url : urls) {
mkwst9f2cc892015-07-22 06:03:2553 SCOPED_TRACE(test_url);
54 GURL url(test_url);
55 url::Origin origin(url);
56 EXPECT_EQ("", origin.scheme());
57 EXPECT_EQ("", origin.host());
58 EXPECT_EQ(0, origin.port());
59 EXPECT_TRUE(origin.unique());
60 EXPECT_FALSE(origin.IsSameOriginWith(origin));
61 EXPECT_FALSE(unique_origin.IsSameOriginWith(origin));
62 EXPECT_FALSE(origin.IsSameOriginWith(unique_origin));
csharrison048bee12016-10-04 00:08:2163
64 ExpectParsedUrlsEqual(GURL(origin.Serialize()), origin.GetURL());
mkwst9f2cc892015-07-22 06:03:2565 }
66}
67
68TEST(OriginTest, ConstructFromGURL) {
69 url::Origin different_origin(GURL("https://not-in-the-list.test/"));
70
71 struct TestCases {
72 const char* const url;
73 const char* const expected_scheme;
74 const char* const expected_host;
avic0c60312015-12-21 21:03:5075 const uint16_t expected_port;
mkwst9f2cc892015-07-22 06:03:2576 } cases[] = {
77 // IP Addresses
78 {"http://192.168.9.1/", "http", "192.168.9.1", 80},
79 {"http://[2001:db8::1]/", "http", "[2001:db8::1]", 80},
80
81 // Punycode
82 {"http://☃.net/", "http", "xn--n3h.net", 80},
83 {"blob:http://☃.net/", "http", "xn--n3h.net", 80},
84
85 // Generic URLs
86 {"http://example.com/", "http", "example.com", 80},
87 {"http://example.com:123/", "http", "example.com", 123},
88 {"https://example.com/", "https", "example.com", 443},
89 {"https://example.com:123/", "https", "example.com", 123},
90 {"http://user:[email protected]/", "http", "example.com", 80},
91 {"http://example.com:123/?query", "http", "example.com", 123},
92 {"https://example.com/#1234", "https", "example.com", 443},
93 {"https://u:[email protected]:123/?query#1234", "https", "example.com", 123},
94
95 // Registered URLs
96 {"ftp://example.com/", "ftp", "example.com", 21},
97 {"gopher://example.com/", "gopher", "example.com", 70},
98 {"ws://example.com/", "ws", "example.com", 80},
99 {"wss://example.com/", "wss", "example.com", 443},
100
101 // file: URLs
102 {"file:///etc/passwd", "file", "", 0},
103 {"file://example.com/etc/passwd", "file", "example.com", 0},
104
105 // Filesystem:
106 {"filesystem:http://example.com/type/", "http", "example.com", 80},
107 {"filesystem:http://example.com:123/type/", "http", "example.com", 123},
108 {"filesystem:https://example.com/type/", "https", "example.com", 443},
109 {"filesystem:https://example.com:123/type/", "https", "example.com", 123},
110
111 // Blob:
112 {"blob:http://example.com/guid-goes-here", "http", "example.com", 80},
113 {"blob:http://example.com:123/guid-goes-here", "http", "example.com", 123},
114 {"blob:https://example.com/guid-goes-here", "https", "example.com", 443},
115 {"blob:http://u:[email protected]/guid-goes-here", "http", "example.com", 80},
116 };
117
118 for (const auto& test_case : cases) {
119 SCOPED_TRACE(test_case.url);
120 GURL url(test_case.url);
121 EXPECT_TRUE(url.is_valid());
122 url::Origin origin(url);
123 EXPECT_EQ(test_case.expected_scheme, origin.scheme());
124 EXPECT_EQ(test_case.expected_host, origin.host());
125 EXPECT_EQ(test_case.expected_port, origin.port());
126 EXPECT_FALSE(origin.unique());
127 EXPECT_TRUE(origin.IsSameOriginWith(origin));
128 EXPECT_FALSE(different_origin.IsSameOriginWith(origin));
129 EXPECT_FALSE(origin.IsSameOriginWith(different_origin));
csharrison048bee12016-10-04 00:08:21130
131 ExpectParsedUrlsEqual(GURL(origin.Serialize()), origin.GetURL());
mkwst9f2cc892015-07-22 06:03:25132 }
133}
134
135TEST(OriginTest, Serialization) {
136 struct TestCases {
137 const char* const url;
138 const char* const expected;
139 } cases[] = {
140 {"http://192.168.9.1/", "http://192.168.9.1"},
141 {"http://[2001:db8::1]/", "http://[2001:db8::1]"},
142 {"http://☃.net/", "http://xn--n3h.net"},
143 {"http://example.com/", "http://example.com"},
144 {"http://example.com:123/", "http://example.com:123"},
145 {"https://example.com/", "https://example.com"},
146 {"https://example.com:123/", "https://example.com:123"},
147 {"file:///etc/passwd", "file://"},
148 {"file://example.com/etc/passwd", "file://"},
149 };
150
151 for (const auto& test_case : cases) {
152 SCOPED_TRACE(test_case.url);
153 GURL url(test_case.url);
154 EXPECT_TRUE(url.is_valid());
155 url::Origin origin(url);
csharrison048bee12016-10-04 00:08:21156 std::string serialized = origin.Serialize();
157 ExpectParsedUrlsEqual(GURL(serialized), origin.GetURL());
158
159 EXPECT_EQ(test_case.expected, serialized);
mkwst9f2cc892015-07-22 06:03:25160
161 // The '<<' operator should produce the same serialization as Serialize().
162 std::stringstream out;
163 out << origin;
164 EXPECT_EQ(test_case.expected, out.str());
165 }
166}
167
168TEST(OriginTest, Comparison) {
169 // These URLs are arranged in increasing order:
170 const char* const urls[] = {
171 "data:uniqueness",
172 "http://a:80",
173 "http://b:80",
174 "https://a:80",
175 "https://b:80",
176 "http://a:81",
177 "http://b:81",
178 "https://a:81",
179 "https://b:81",
180 };
181
182 for (size_t i = 0; i < arraysize(urls); i++) {
183 GURL current_url(urls[i]);
184 url::Origin current(current_url);
185 for (size_t j = i; j < arraysize(urls); j++) {
186 GURL compare_url(urls[j]);
187 url::Origin to_compare(compare_url);
188 EXPECT_EQ(i < j, current < to_compare) << i << " < " << j;
189 EXPECT_EQ(j < i, to_compare < current) << j << " < " << i;
190 }
191 }
192}
193
mkwstd8335d982015-07-25 05:18:48194TEST(OriginTest, UnsafelyCreate) {
195 struct TestCase {
196 const char* scheme;
197 const char* host;
avic0c60312015-12-21 21:03:50198 uint16_t port;
mkwstd8335d982015-07-25 05:18:48199 } cases[] = {
200 {"http", "example.com", 80},
201 {"http", "example.com", 123},
202 {"https", "example.com", 443},
203 {"https", "example.com", 123},
204 {"file", "", 0},
205 {"file", "example.com", 0},
206 };
207
208 for (const auto& test : cases) {
209 SCOPED_TRACE(testing::Message() << test.scheme << "://" << test.host << ":"
210 << test.port);
211 url::Origin origin = url::Origin::UnsafelyCreateOriginWithoutNormalization(
212 test.scheme, test.host, test.port);
213 EXPECT_EQ(test.scheme, origin.scheme());
214 EXPECT_EQ(test.host, origin.host());
215 EXPECT_EQ(test.port, origin.port());
216 EXPECT_FALSE(origin.unique());
217 EXPECT_TRUE(origin.IsSameOriginWith(origin));
csharrison048bee12016-10-04 00:08:21218
219 ExpectParsedUrlsEqual(GURL(origin.Serialize()), origin.GetURL());
mkwstd8335d982015-07-25 05:18:48220 }
221}
222
223TEST(OriginTest, UnsafelyCreateUniqueOnInvalidInput) {
224 struct TestCases {
225 const char* scheme;
226 const char* host;
avic0c60312015-12-21 21:03:50227 uint16_t port;
mkwstd8335d982015-07-25 05:18:48228 } cases[] = {{"", "", 0},
229 {"data", "", 0},
230 {"blob", "", 0},
231 {"filesystem", "", 0},
232 {"data", "example.com", 80},
233 {"http", "☃.net", 80},
234 {"http\nmore", "example.com", 80},
235 {"http\rmore", "example.com", 80},
236 {"http\n", "example.com", 80},
237 {"http\r", "example.com", 80},
238 {"http", "example.com\nnot-example.com", 80},
239 {"http", "example.com\rnot-example.com", 80},
240 {"http", "example.com\n", 80},
241 {"http", "example.com\r", 80},
242 {"http", "example.com", 0},
243 {"file", "", 80}};
244
245 for (const auto& test : cases) {
246 SCOPED_TRACE(testing::Message() << test.scheme << "://" << test.host << ":"
247 << test.port);
248 url::Origin origin = url::Origin::UnsafelyCreateOriginWithoutNormalization(
249 test.scheme, test.host, test.port);
250 EXPECT_EQ("", origin.scheme());
251 EXPECT_EQ("", origin.host());
252 EXPECT_EQ(0, origin.port());
253 EXPECT_TRUE(origin.unique());
254 EXPECT_FALSE(origin.IsSameOriginWith(origin));
csharrison048bee12016-10-04 00:08:21255
256 ExpectParsedUrlsEqual(GURL(origin.Serialize()), origin.GetURL());
mkwstd8335d982015-07-25 05:18:48257 }
258}
259
260TEST(OriginTest, UnsafelyCreateUniqueViaEmbeddedNulls) {
261 struct TestCases {
262 const char* scheme;
263 size_t scheme_length;
264 const char* host;
265 size_t host_length;
avic0c60312015-12-21 21:03:50266 uint16_t port;
mkwstd8335d982015-07-25 05:18:48267 } cases[] = {{"http\0more", 9, "example.com", 11, 80},
268 {"http\0", 5, "example.com", 11, 80},
269 {"\0http", 5, "example.com", 11, 80},
270 {"http", 4, "example.com\0not-example.com", 27, 80},
271 {"http", 4, "example.com\0", 12, 80},
272 {"http", 4, "\0example.com", 12, 80}};
273
274 for (const auto& test : cases) {
275 SCOPED_TRACE(testing::Message() << test.scheme << "://" << test.host << ":"
276 << test.port);
277 url::Origin origin = url::Origin::UnsafelyCreateOriginWithoutNormalization(
278 std::string(test.scheme, test.scheme_length),
279 std::string(test.host, test.host_length), test.port);
280 EXPECT_EQ("", origin.scheme());
281 EXPECT_EQ("", origin.host());
282 EXPECT_EQ(0, origin.port());
283 EXPECT_TRUE(origin.unique());
284 EXPECT_FALSE(origin.IsSameOriginWith(origin));
csharrison048bee12016-10-04 00:08:21285
286 ExpectParsedUrlsEqual(GURL(origin.Serialize()), origin.GetURL());
mkwstd8335d982015-07-25 05:18:48287 }
288}
289
pkalinnikov054f4032016-08-31 10:54:17290TEST(OriginTest, DomainIs) {
291 const struct {
292 const char* url;
293 const char* lower_ascii_domain;
294 bool expected_domain_is;
295 } kTestCases[] = {
296 {"http://google.com/foo", "google.com", true},
297 {"http://www.google.com:99/foo", "google.com", true},
298 {"http://www.google.com.cn/foo", "google.com", false},
299 {"http://www.google.comm", "google.com", false},
300 {"http://www.iamnotgoogle.com/foo", "google.com", false},
301 {"http://www.google.com/foo", "Google.com", false},
302
303 // If the host ends with a dot, it matches domains with or without a dot.
304 {"http://www.google.com./foo", "google.com", true},
305 {"http://www.google.com./foo", "google.com.", true},
306 {"http://www.google.com./foo", ".com", true},
307 {"http://www.google.com./foo", ".com.", true},
308
309 // But, if the host doesn't end with a dot and the input domain does, then
310 // it's considered to not match.
311 {"http://google.com/foo", "google.com.", false},
312
313 // If the host ends with two dots, it doesn't match.
314 {"http://www.google.com../foo", "google.com", false},
315
316 // Filesystem scheme.
317 {"filesystem:http://www.google.com:99/foo/", "google.com", true},
318 {"filesystem:http://www.iamnotgoogle.com/foo/", "google.com", false},
319
320 // File scheme.
321 {"file:///home/user/text.txt", "", false},
322 {"file:///home/user/text.txt", "txt", false},
323 };
324
325 for (const auto& test_case : kTestCases) {
326 SCOPED_TRACE(testing::Message() << "(url, domain): (" << test_case.url
327 << ", " << test_case.lower_ascii_domain
328 << ")");
329 GURL url(test_case.url);
330 ASSERT_TRUE(url.is_valid());
331 url::Origin origin(url);
332
333 EXPECT_EQ(test_case.expected_domain_is,
334 origin.DomainIs(test_case.lower_ascii_domain));
335 }
336
337 // If the URL is invalid, DomainIs returns false.
338 GURL invalid_url("google.com");
339 ASSERT_FALSE(invalid_url.is_valid());
340 EXPECT_FALSE(url::Origin(invalid_url).DomainIs("google.com"));
341
342 // Unique origins.
343 EXPECT_FALSE(url::Origin().DomainIs(""));
344 EXPECT_FALSE(url::Origin().DomainIs("com"));
345}
346
mkwst9f2cc892015-07-22 06:03:25347} // namespace url