blob: ba97a6a54922711b4cd50e827445933f25312781 [file] [log] [blame]
mkwst28c7c112015-07-14 22:41:061// 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
8#include "base/macros.h"
mkwst28c7c112015-07-14 22:41:069#include "testing/gtest/include/gtest/gtest.h"
10#include "url/gurl.h"
11#include "url/scheme_host_port.h"
12
13namespace {
14
csharrison6fbc9fa2016-10-08 03:31:5015void ExpectParsedUrlsEqual(const GURL& a, const GURL& b) {
16 EXPECT_EQ(a, b);
17 const url::Parsed& a_parsed = a.parsed_for_possibly_invalid_spec();
18 const url::Parsed& b_parsed = b.parsed_for_possibly_invalid_spec();
19 EXPECT_EQ(a_parsed.scheme.begin, b_parsed.scheme.begin);
20 EXPECT_EQ(a_parsed.scheme.len, b_parsed.scheme.len);
21 EXPECT_EQ(a_parsed.username.begin, b_parsed.username.begin);
22 EXPECT_EQ(a_parsed.username.len, b_parsed.username.len);
23 EXPECT_EQ(a_parsed.password.begin, b_parsed.password.begin);
24 EXPECT_EQ(a_parsed.password.len, b_parsed.password.len);
25 EXPECT_EQ(a_parsed.host.begin, b_parsed.host.begin);
26 EXPECT_EQ(a_parsed.host.len, b_parsed.host.len);
27 EXPECT_EQ(a_parsed.port.begin, b_parsed.port.begin);
28 EXPECT_EQ(a_parsed.port.len, b_parsed.port.len);
29 EXPECT_EQ(a_parsed.path.begin, b_parsed.path.begin);
30 EXPECT_EQ(a_parsed.path.len, b_parsed.path.len);
31 EXPECT_EQ(a_parsed.query.begin, b_parsed.query.begin);
32 EXPECT_EQ(a_parsed.query.len, b_parsed.query.len);
33 EXPECT_EQ(a_parsed.ref.begin, b_parsed.ref.begin);
34 EXPECT_EQ(a_parsed.ref.len, b_parsed.ref.len);
35}
36
mkwst28c7c112015-07-14 22:41:0637TEST(SchemeHostPortTest, Invalid) {
38 url::SchemeHostPort invalid;
39 EXPECT_EQ("", invalid.scheme());
40 EXPECT_EQ("", invalid.host());
41 EXPECT_EQ(0, invalid.port());
42 EXPECT_TRUE(invalid.IsInvalid());
43 EXPECT_TRUE(invalid.Equals(invalid));
44
csharrison39a260f92017-01-09 22:24:1445 const char* urls[] = {
46 "data:text/html,Hello!", "javascript:alert(1)",
47 "file://example.com:443/etc/passwd",
48
49 // These schemes do not follow the generic URL syntax, so make sure we
50 // treat them as invalid (scheme, host, port) tuples (even though such
51 // URLs' _Origin_ might have a (scheme, host, port) tuple, they themselves
52 // do not). This is only *implicitly* checked in the code, by means of
53 // blob schemes not being standard, and filesystem schemes having type
54 // SCHEME_WITHOUT_AUTHORITY. If conditions change such that the implicit
55 // checks no longer hold, this policy should be made explicit.
56 "blob:https://example.com/uuid-goes-here",
57 "filesystem:https://example.com/temporary/yay.png"};
mkwst28c7c112015-07-14 22:41:0658
vmpstr981aa5a2016-07-14 01:05:0859 for (auto* test : urls) {
mkwst28c7c112015-07-14 22:41:0660 SCOPED_TRACE(test);
61 GURL url(test);
62 url::SchemeHostPort tuple(url);
63 EXPECT_EQ("", tuple.scheme());
64 EXPECT_EQ("", tuple.host());
65 EXPECT_EQ(0, tuple.port());
66 EXPECT_TRUE(tuple.IsInvalid());
67 EXPECT_TRUE(tuple.Equals(tuple));
68 EXPECT_TRUE(tuple.Equals(invalid));
69 EXPECT_TRUE(invalid.Equals(tuple));
csharrison6fbc9fa2016-10-08 03:31:5070 ExpectParsedUrlsEqual(GURL(tuple.Serialize()), tuple.GetURL());
mkwst28c7c112015-07-14 22:41:0671 }
72}
73
74TEST(SchemeHostPortTest, ExplicitConstruction) {
75 struct TestCases {
76 const char* scheme;
77 const char* host;
avic0c60312015-12-21 21:03:5078 uint16_t port;
mkwst28c7c112015-07-14 22:41:0679 } cases[] = {
80 {"http", "example.com", 80},
81 {"http", "example.com", 123},
82 {"https", "example.com", 443},
83 {"https", "example.com", 123},
84 {"file", "", 0},
85 {"file", "example.com", 0},
86 };
87
88 for (const auto& test : cases) {
89 SCOPED_TRACE(testing::Message() << test.scheme << "://" << test.host << ":"
90 << test.port);
91 url::SchemeHostPort tuple(test.scheme, test.host, test.port);
92 EXPECT_EQ(test.scheme, tuple.scheme());
93 EXPECT_EQ(test.host, tuple.host());
94 EXPECT_EQ(test.port, tuple.port());
95 EXPECT_FALSE(tuple.IsInvalid());
96 EXPECT_TRUE(tuple.Equals(tuple));
csharrison6fbc9fa2016-10-08 03:31:5097 ExpectParsedUrlsEqual(GURL(tuple.Serialize()), tuple.GetURL());
mkwst28c7c112015-07-14 22:41:0698 }
99}
100
mkwstd8335d982015-07-25 05:18:48101TEST(SchemeHostPortTest, InvalidConstruction) {
102 struct TestCases {
103 const char* scheme;
104 const char* host;
avic0c60312015-12-21 21:03:50105 uint16_t port;
mkwstd8335d982015-07-25 05:18:48106 } cases[] = {{"", "", 0},
107 {"data", "", 0},
108 {"blob", "", 0},
109 {"filesystem", "", 0},
110 {"http", "", 80},
111 {"data", "example.com", 80},
112 {"http", "☃.net", 80},
113 {"http\nmore", "example.com", 80},
114 {"http\rmore", "example.com", 80},
115 {"http\n", "example.com", 80},
116 {"http\r", "example.com", 80},
117 {"http", "example.com\nnot-example.com", 80},
118 {"http", "example.com\rnot-example.com", 80},
119 {"http", "example.com\n", 80},
120 {"http", "example.com\r", 80},
121 {"http", "example.com", 0},
122 {"file", "", 80}};
123
124 for (const auto& test : cases) {
125 SCOPED_TRACE(testing::Message() << test.scheme << "://" << test.host << ":"
126 << test.port);
127 url::SchemeHostPort tuple(test.scheme, test.host, test.port);
128 EXPECT_EQ("", tuple.scheme());
129 EXPECT_EQ("", tuple.host());
130 EXPECT_EQ(0, tuple.port());
131 EXPECT_TRUE(tuple.IsInvalid());
132 EXPECT_TRUE(tuple.Equals(tuple));
csharrison6fbc9fa2016-10-08 03:31:50133 ExpectParsedUrlsEqual(GURL(tuple.Serialize()), tuple.GetURL());
mkwstd8335d982015-07-25 05:18:48134 }
135}
136
137TEST(SchemeHostPortTest, InvalidConstructionWithEmbeddedNulls) {
138 struct TestCases {
139 const char* scheme;
140 size_t scheme_length;
141 const char* host;
142 size_t host_length;
avic0c60312015-12-21 21:03:50143 uint16_t port;
mkwstd8335d982015-07-25 05:18:48144 } cases[] = {{"http\0more", 9, "example.com", 11, 80},
145 {"http\0", 5, "example.com", 11, 80},
146 {"\0http", 5, "example.com", 11, 80},
147 {"http", 4, "example.com\0not-example.com", 27, 80},
148 {"http", 4, "example.com\0", 12, 80},
149 {"http", 4, "\0example.com", 12, 80}};
150
151 for (const auto& test : cases) {
152 SCOPED_TRACE(testing::Message() << test.scheme << "://" << test.host << ":"
153 << test.port);
154 url::SchemeHostPort tuple(std::string(test.scheme, test.scheme_length),
155 std::string(test.host, test.host_length),
156 test.port);
157 EXPECT_EQ("", tuple.scheme());
158 EXPECT_EQ("", tuple.host());
159 EXPECT_EQ(0, tuple.port());
160 EXPECT_TRUE(tuple.IsInvalid());
csharrison6fbc9fa2016-10-08 03:31:50161 ExpectParsedUrlsEqual(GURL(tuple.Serialize()), tuple.GetURL());
mkwstd8335d982015-07-25 05:18:48162 }
163}
164
mkwst28c7c112015-07-14 22:41:06165TEST(SchemeHostPortTest, GURLConstruction) {
166 struct TestCases {
167 const char* url;
168 const char* scheme;
169 const char* host;
avic0c60312015-12-21 21:03:50170 uint16_t port;
mkwst28c7c112015-07-14 22:41:06171 } cases[] = {
172 {"http://192.168.9.1/", "http", "192.168.9.1", 80},
173 {"http://[2001:db8::1]/", "http", "[2001:db8::1]", 80},
174 {"http://☃.net/", "http", "xn--n3h.net", 80},
175 {"http://example.com/", "http", "example.com", 80},
176 {"http://example.com:123/", "http", "example.com", 123},
177 {"https://example.com/", "https", "example.com", 443},
178 {"https://example.com:123/", "https", "example.com", 123},
179 {"file:///etc/passwd", "file", "", 0},
180 {"file://example.com/etc/passwd", "file", "example.com", 0},
181 {"http://u:[email protected]/", "http", "example.com", 80},
182 {"http://u:[email protected]/path", "http", "example.com", 80},
183 {"http://u:[email protected]/path?123", "http", "example.com", 80},
184 {"http://u:[email protected]/path?123#hash", "http", "example.com", 80},
185 };
186
187 for (const auto& test : cases) {
188 SCOPED_TRACE(test.url);
189 GURL url(test.url);
190 EXPECT_TRUE(url.is_valid());
191 url::SchemeHostPort tuple(url);
192 EXPECT_EQ(test.scheme, tuple.scheme());
193 EXPECT_EQ(test.host, tuple.host());
194 EXPECT_EQ(test.port, tuple.port());
195 EXPECT_FALSE(tuple.IsInvalid());
196 EXPECT_TRUE(tuple.Equals(tuple));
csharrison6fbc9fa2016-10-08 03:31:50197 ExpectParsedUrlsEqual(GURL(tuple.Serialize()), tuple.GetURL());
mkwst28c7c112015-07-14 22:41:06198 }
199}
200
201TEST(SchemeHostPortTest, Serialization) {
202 struct TestCases {
203 const char* url;
204 const char* expected;
205 } cases[] = {
206 {"http://192.168.9.1/", "http://192.168.9.1"},
207 {"http://[2001:db8::1]/", "http://[2001:db8::1]"},
208 {"http://☃.net/", "http://xn--n3h.net"},
209 {"http://example.com/", "http://example.com"},
210 {"http://example.com:123/", "http://example.com:123"},
211 {"https://example.com/", "https://example.com"},
212 {"https://example.com:123/", "https://example.com:123"},
213 {"file:///etc/passwd", "file://"},
214 {"file://example.com/etc/passwd", "file://example.com"},
215 };
216
217 for (const auto& test : cases) {
218 SCOPED_TRACE(test.url);
219 GURL url(test.url);
220 url::SchemeHostPort tuple(url);
221 EXPECT_EQ(test.expected, tuple.Serialize());
csharrison6fbc9fa2016-10-08 03:31:50222 ExpectParsedUrlsEqual(GURL(tuple.Serialize()), tuple.GetURL());
mkwst28c7c112015-07-14 22:41:06223 }
224}
225
226TEST(SchemeHostPortTest, Comparison) {
227 // These tuples are arranged in increasing order:
228 struct SchemeHostPorts {
229 const char* scheme;
230 const char* host;
avic0c60312015-12-21 21:03:50231 uint16_t port;
mkwst28c7c112015-07-14 22:41:06232 } tuples[] = {
233 {"http", "a", 80},
234 {"http", "b", 80},
235 {"https", "a", 80},
236 {"https", "b", 80},
237 {"http", "a", 81},
238 {"http", "b", 81},
239 {"https", "a", 81},
240 {"https", "b", 81},
241 };
242
243 for (size_t i = 0; i < arraysize(tuples); i++) {
244 url::SchemeHostPort current(tuples[i].scheme, tuples[i].host,
245 tuples[i].port);
246 for (size_t j = i; j < arraysize(tuples); j++) {
247 url::SchemeHostPort to_compare(tuples[j].scheme, tuples[j].host,
248 tuples[j].port);
249 EXPECT_EQ(i < j, current < to_compare) << i << " < " << j;
250 EXPECT_EQ(j < i, to_compare < current) << j << " < " << i;
251 }
252 }
253}
254
255} // namespace url