Upload upstream chromium 67.0.3396
[platform/framework/web/chromium-efl.git] / url / scheme_host_port_unittest.cc
1 // 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
5 #include <stddef.h>
6 #include <stdint.h>
7
8 #include "base/macros.h"
9 #include "testing/gtest/include/gtest/gtest.h"
10 #include "url/gurl.h"
11 #include "url/scheme_host_port.h"
12 #include "url/url_util.h"
13
14 namespace {
15
16 class SchemeHostPortTest : public testing::Test {
17  public:
18   SchemeHostPortTest() = default;
19   ~SchemeHostPortTest() override {
20     // Reset any added schemes.
21     url::Shutdown();
22   }
23
24  private:
25   DISALLOW_COPY_AND_ASSIGN(SchemeHostPortTest);
26 };
27
28 void ExpectParsedUrlsEqual(const GURL& a, const GURL& b) {
29   EXPECT_EQ(a, b);
30   const url::Parsed& a_parsed = a.parsed_for_possibly_invalid_spec();
31   const url::Parsed& b_parsed = b.parsed_for_possibly_invalid_spec();
32   EXPECT_EQ(a_parsed.scheme.begin, b_parsed.scheme.begin);
33   EXPECT_EQ(a_parsed.scheme.len, b_parsed.scheme.len);
34   EXPECT_EQ(a_parsed.username.begin, b_parsed.username.begin);
35   EXPECT_EQ(a_parsed.username.len, b_parsed.username.len);
36   EXPECT_EQ(a_parsed.password.begin, b_parsed.password.begin);
37   EXPECT_EQ(a_parsed.password.len, b_parsed.password.len);
38   EXPECT_EQ(a_parsed.host.begin, b_parsed.host.begin);
39   EXPECT_EQ(a_parsed.host.len, b_parsed.host.len);
40   EXPECT_EQ(a_parsed.port.begin, b_parsed.port.begin);
41   EXPECT_EQ(a_parsed.port.len, b_parsed.port.len);
42   EXPECT_EQ(a_parsed.path.begin, b_parsed.path.begin);
43   EXPECT_EQ(a_parsed.path.len, b_parsed.path.len);
44   EXPECT_EQ(a_parsed.query.begin, b_parsed.query.begin);
45   EXPECT_EQ(a_parsed.query.len, b_parsed.query.len);
46   EXPECT_EQ(a_parsed.ref.begin, b_parsed.ref.begin);
47   EXPECT_EQ(a_parsed.ref.len, b_parsed.ref.len);
48 }
49
50 TEST_F(SchemeHostPortTest, Invalid) {
51   url::SchemeHostPort invalid;
52   EXPECT_EQ("", invalid.scheme());
53   EXPECT_EQ("", invalid.host());
54   EXPECT_EQ(0, invalid.port());
55   EXPECT_TRUE(invalid.IsInvalid());
56   EXPECT_TRUE(invalid.Equals(invalid));
57
58   const char* urls[] = {
59       "data:text/html,Hello!", "javascript:alert(1)",
60       "file://example.com:443/etc/passwd",
61
62       // These schemes do not follow the generic URL syntax, so make sure we
63       // treat them as invalid (scheme, host, port) tuples (even though such
64       // URLs' _Origin_ might have a (scheme, host, port) tuple, they themselves
65       // do not). This is only *implicitly* checked in the code, by means of
66       // blob schemes not being standard, and filesystem schemes having type
67       // SCHEME_WITHOUT_AUTHORITY. If conditions change such that the implicit
68       // checks no longer hold, this policy should be made explicit.
69       "blob:https://example.com/uuid-goes-here",
70       "filesystem:https://example.com/temporary/yay.png"};
71
72   for (auto* test : urls) {
73     SCOPED_TRACE(test);
74     GURL url(test);
75     url::SchemeHostPort tuple(url);
76     EXPECT_EQ("", tuple.scheme());
77     EXPECT_EQ("", tuple.host());
78     EXPECT_EQ(0, tuple.port());
79     EXPECT_TRUE(tuple.IsInvalid());
80     EXPECT_TRUE(tuple.Equals(tuple));
81     EXPECT_TRUE(tuple.Equals(invalid));
82     EXPECT_TRUE(invalid.Equals(tuple));
83     ExpectParsedUrlsEqual(GURL(tuple.Serialize()), tuple.GetURL());
84   }
85 }
86
87 TEST_F(SchemeHostPortTest, ExplicitConstruction) {
88   struct TestCases {
89     const char* scheme;
90     const char* host;
91     uint16_t port;
92   } cases[] = {
93       {"http", "example.com", 80},
94       {"http", "example.com", 123},
95       {"https", "example.com", 443},
96       {"https", "example.com", 123},
97       {"file", "", 0},
98       {"file", "example.com", 0},
99   };
100
101   for (const auto& test : cases) {
102     SCOPED_TRACE(testing::Message() << test.scheme << "://" << test.host << ":"
103                                     << test.port);
104     url::SchemeHostPort tuple(test.scheme, test.host, test.port);
105     EXPECT_EQ(test.scheme, tuple.scheme());
106     EXPECT_EQ(test.host, tuple.host());
107     EXPECT_EQ(test.port, tuple.port());
108     EXPECT_FALSE(tuple.IsInvalid());
109     EXPECT_TRUE(tuple.Equals(tuple));
110     ExpectParsedUrlsEqual(GURL(tuple.Serialize()), tuple.GetURL());
111   }
112 }
113
114 TEST_F(SchemeHostPortTest, InvalidConstruction) {
115   struct TestCases {
116     const char* scheme;
117     const char* host;
118     uint16_t port;
119   } cases[] = {{"", "", 0},
120                {"data", "", 0},
121                {"blob", "", 0},
122                {"filesystem", "", 0},
123                {"http", "", 80},
124                {"data", "example.com", 80},
125                {"http", "☃.net", 80},
126                {"http\nmore", "example.com", 80},
127                {"http\rmore", "example.com", 80},
128                {"http\n", "example.com", 80},
129                {"http\r", "example.com", 80},
130                {"http", "example.com\nnot-example.com", 80},
131                {"http", "example.com\rnot-example.com", 80},
132                {"http", "example.com\n", 80},
133                {"http", "example.com\r", 80},
134                {"http", "example.com", 0},
135                {"file", "", 80}};
136
137   for (const auto& test : cases) {
138     SCOPED_TRACE(testing::Message() << test.scheme << "://" << test.host << ":"
139                                     << test.port);
140     url::SchemeHostPort tuple(test.scheme, test.host, test.port);
141     EXPECT_EQ("", tuple.scheme());
142     EXPECT_EQ("", tuple.host());
143     EXPECT_EQ(0, tuple.port());
144     EXPECT_TRUE(tuple.IsInvalid());
145     EXPECT_TRUE(tuple.Equals(tuple));
146     ExpectParsedUrlsEqual(GURL(tuple.Serialize()), tuple.GetURL());
147   }
148 }
149
150 TEST_F(SchemeHostPortTest, InvalidConstructionWithEmbeddedNulls) {
151   struct TestCases {
152     const char* scheme;
153     size_t scheme_length;
154     const char* host;
155     size_t host_length;
156     uint16_t port;
157   } cases[] = {{"http\0more", 9, "example.com", 11, 80},
158                {"http\0", 5, "example.com", 11, 80},
159                {"\0http", 5, "example.com", 11, 80},
160                {"http", 4, "example.com\0not-example.com", 27, 80},
161                {"http", 4, "example.com\0", 12, 80},
162                {"http", 4, "\0example.com", 12, 80}};
163
164   for (const auto& test : cases) {
165     SCOPED_TRACE(testing::Message() << test.scheme << "://" << test.host << ":"
166                                     << test.port);
167     url::SchemeHostPort tuple(std::string(test.scheme, test.scheme_length),
168                               std::string(test.host, test.host_length),
169                               test.port);
170     EXPECT_EQ("", tuple.scheme());
171     EXPECT_EQ("", tuple.host());
172     EXPECT_EQ(0, tuple.port());
173     EXPECT_TRUE(tuple.IsInvalid());
174     ExpectParsedUrlsEqual(GURL(tuple.Serialize()), tuple.GetURL());
175   }
176 }
177
178 TEST_F(SchemeHostPortTest, GURLConstruction) {
179   struct TestCases {
180     const char* url;
181     const char* scheme;
182     const char* host;
183     uint16_t port;
184   } cases[] = {
185       {"http://192.168.9.1/", "http", "192.168.9.1", 80},
186       {"http://[2001:db8::1]/", "http", "[2001:db8::1]", 80},
187       {"http://☃.net/", "http", "xn--n3h.net", 80},
188       {"http://example.com/", "http", "example.com", 80},
189       {"http://example.com:123/", "http", "example.com", 123},
190       {"https://example.com/", "https", "example.com", 443},
191       {"https://example.com:123/", "https", "example.com", 123},
192       {"file:///etc/passwd", "file", "", 0},
193       {"file://example.com/etc/passwd", "file", "example.com", 0},
194       {"http://u:p@example.com/", "http", "example.com", 80},
195       {"http://u:p@example.com/path", "http", "example.com", 80},
196       {"http://u:p@example.com/path?123", "http", "example.com", 80},
197       {"http://u:p@example.com/path?123#hash", "http", "example.com", 80},
198   };
199
200   for (const auto& test : cases) {
201     SCOPED_TRACE(test.url);
202     GURL url(test.url);
203     EXPECT_TRUE(url.is_valid());
204     url::SchemeHostPort tuple(url);
205     EXPECT_EQ(test.scheme, tuple.scheme());
206     EXPECT_EQ(test.host, tuple.host());
207     EXPECT_EQ(test.port, tuple.port());
208     EXPECT_FALSE(tuple.IsInvalid());
209     EXPECT_TRUE(tuple.Equals(tuple));
210     ExpectParsedUrlsEqual(GURL(tuple.Serialize()), tuple.GetURL());
211   }
212 }
213
214 TEST_F(SchemeHostPortTest, Serialization) {
215   struct TestCases {
216     const char* url;
217     const char* expected;
218   } cases[] = {
219       {"http://192.168.9.1/", "http://192.168.9.1"},
220       {"http://[2001:db8::1]/", "http://[2001:db8::1]"},
221       {"http://☃.net/", "http://xn--n3h.net"},
222       {"http://example.com/", "http://example.com"},
223       {"http://example.com:123/", "http://example.com:123"},
224       {"https://example.com/", "https://example.com"},
225       {"https://example.com:123/", "https://example.com:123"},
226       {"file:///etc/passwd", "file://"},
227       {"file://example.com/etc/passwd", "file://example.com"},
228   };
229
230   for (const auto& test : cases) {
231     SCOPED_TRACE(test.url);
232     GURL url(test.url);
233     url::SchemeHostPort tuple(url);
234     EXPECT_EQ(test.expected, tuple.Serialize());
235     ExpectParsedUrlsEqual(GURL(tuple.Serialize()), tuple.GetURL());
236   }
237 }
238
239 TEST_F(SchemeHostPortTest, Comparison) {
240   // These tuples are arranged in increasing order:
241   struct SchemeHostPorts {
242     const char* scheme;
243     const char* host;
244     uint16_t port;
245   } tuples[] = {
246       {"http", "a", 80},
247       {"http", "b", 80},
248       {"https", "a", 80},
249       {"https", "b", 80},
250       {"http", "a", 81},
251       {"http", "b", 81},
252       {"https", "a", 81},
253       {"https", "b", 81},
254   };
255
256   for (size_t i = 0; i < arraysize(tuples); i++) {
257     url::SchemeHostPort current(tuples[i].scheme, tuples[i].host,
258                                 tuples[i].port);
259     for (size_t j = i; j < arraysize(tuples); j++) {
260       url::SchemeHostPort to_compare(tuples[j].scheme, tuples[j].host,
261                                      tuples[j].port);
262       EXPECT_EQ(i < j, current < to_compare) << i << " < " << j;
263       EXPECT_EQ(j < i, to_compare < current) << j << " < " << i;
264     }
265   }
266 }
267
268 // Some schemes have optional authority. Make sure that GURL conversion from
269 // SchemeHostPort is not opinionated in that regard. For more info, See
270 // crbug.com/820194, where we considered all SchemeHostPorts with
271 // SCHEME_WITH_HOST (i.e., without ports) as valid with empty hosts, even though
272 // most are not (e.g. chrome URLs).
273 TEST_F(SchemeHostPortTest, EmptyHostGurlConversion) {
274   url::AddStandardScheme("chrome", url::SCHEME_WITH_HOST);
275
276   GURL chrome_url("chrome:");
277   EXPECT_FALSE(chrome_url.is_valid());
278
279   url::SchemeHostPort chrome_tuple("chrome", "", 0);
280   EXPECT_FALSE(chrome_tuple.GetURL().is_valid());
281   ExpectParsedUrlsEqual(GURL(chrome_tuple.Serialize()), chrome_tuple.GetURL());
282   ExpectParsedUrlsEqual(chrome_url, chrome_tuple.GetURL());
283 }
284
285 }  // namespace url