blob: 6a3128b7be2a8a87d1b0a5a840a0671e4af725a7 [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
16TEST(OriginTest, UniqueOriginComparison) {
17 url::Origin unique_origin;
18 EXPECT_EQ("", unique_origin.scheme());
19 EXPECT_EQ("", unique_origin.host());
20 EXPECT_EQ(0, unique_origin.port());
21 EXPECT_TRUE(unique_origin.unique());
22 EXPECT_FALSE(unique_origin.IsSameOriginWith(unique_origin));
23
24 const char* const urls[] = {"data:text/html,Hello!",
25 "javascript:alert(1)",
26 "file://example.com:443/etc/passwd",
27 "yay",
28 "http::///invalid.example.com/"};
29
30 for (const auto& test_url : urls) {
31 SCOPED_TRACE(test_url);
32 GURL url(test_url);
33 url::Origin origin(url);
34 EXPECT_EQ("", origin.scheme());
35 EXPECT_EQ("", origin.host());
36 EXPECT_EQ(0, origin.port());
37 EXPECT_TRUE(origin.unique());
38 EXPECT_FALSE(origin.IsSameOriginWith(origin));
39 EXPECT_FALSE(unique_origin.IsSameOriginWith(origin));
40 EXPECT_FALSE(origin.IsSameOriginWith(unique_origin));
41 }
42}
43
44TEST(OriginTest, ConstructFromGURL) {
45 url::Origin different_origin(GURL("https://not-in-the-list.test/"));
46
47 struct TestCases {
48 const char* const url;
49 const char* const expected_scheme;
50 const char* const expected_host;
avic0c60312015-12-21 21:03:5051 const uint16_t expected_port;
mkwst9f2cc892015-07-22 06:03:2552 } cases[] = {
53 // IP Addresses
54 {"http://192.168.9.1/", "http", "192.168.9.1", 80},
55 {"http://[2001:db8::1]/", "http", "[2001:db8::1]", 80},
56
57 // Punycode
58 {"http://☃.net/", "http", "xn--n3h.net", 80},
59 {"blob:http://☃.net/", "http", "xn--n3h.net", 80},
60
61 // Generic URLs
62 {"http://example.com/", "http", "example.com", 80},
63 {"http://example.com:123/", "http", "example.com", 123},
64 {"https://example.com/", "https", "example.com", 443},
65 {"https://example.com:123/", "https", "example.com", 123},
66 {"http://user:[email protected]/", "http", "example.com", 80},
67 {"http://example.com:123/?query", "http", "example.com", 123},
68 {"https://example.com/#1234", "https", "example.com", 443},
69 {"https://u:[email protected]:123/?query#1234", "https", "example.com", 123},
70
71 // Registered URLs
72 {"ftp://example.com/", "ftp", "example.com", 21},
73 {"gopher://example.com/", "gopher", "example.com", 70},
74 {"ws://example.com/", "ws", "example.com", 80},
75 {"wss://example.com/", "wss", "example.com", 443},
76
77 // file: URLs
78 {"file:///etc/passwd", "file", "", 0},
79 {"file://example.com/etc/passwd", "file", "example.com", 0},
80
81 // Filesystem:
82 {"filesystem:http://example.com/type/", "http", "example.com", 80},
83 {"filesystem:http://example.com:123/type/", "http", "example.com", 123},
84 {"filesystem:https://example.com/type/", "https", "example.com", 443},
85 {"filesystem:https://example.com:123/type/", "https", "example.com", 123},
86
87 // Blob:
88 {"blob:http://example.com/guid-goes-here", "http", "example.com", 80},
89 {"blob:http://example.com:123/guid-goes-here", "http", "example.com", 123},
90 {"blob:https://example.com/guid-goes-here", "https", "example.com", 443},
91 {"blob:http://u:[email protected]/guid-goes-here", "http", "example.com", 80},
92 };
93
94 for (const auto& test_case : cases) {
95 SCOPED_TRACE(test_case.url);
96 GURL url(test_case.url);
97 EXPECT_TRUE(url.is_valid());
98 url::Origin origin(url);
99 EXPECT_EQ(test_case.expected_scheme, origin.scheme());
100 EXPECT_EQ(test_case.expected_host, origin.host());
101 EXPECT_EQ(test_case.expected_port, origin.port());
102 EXPECT_FALSE(origin.unique());
103 EXPECT_TRUE(origin.IsSameOriginWith(origin));
104 EXPECT_FALSE(different_origin.IsSameOriginWith(origin));
105 EXPECT_FALSE(origin.IsSameOriginWith(different_origin));
106 }
107}
108
109TEST(OriginTest, Serialization) {
110 struct TestCases {
111 const char* const url;
112 const char* const expected;
113 } cases[] = {
114 {"http://192.168.9.1/", "http://192.168.9.1"},
115 {"http://[2001:db8::1]/", "http://[2001:db8::1]"},
116 {"http://☃.net/", "http://xn--n3h.net"},
117 {"http://example.com/", "http://example.com"},
118 {"http://example.com:123/", "http://example.com:123"},
119 {"https://example.com/", "https://example.com"},
120 {"https://example.com:123/", "https://example.com:123"},
121 {"file:///etc/passwd", "file://"},
122 {"file://example.com/etc/passwd", "file://"},
123 };
124
125 for (const auto& test_case : cases) {
126 SCOPED_TRACE(test_case.url);
127 GURL url(test_case.url);
128 EXPECT_TRUE(url.is_valid());
129 url::Origin origin(url);
130 EXPECT_EQ(test_case.expected, origin.Serialize());
131
132 // The '<<' operator should produce the same serialization as Serialize().
133 std::stringstream out;
134 out << origin;
135 EXPECT_EQ(test_case.expected, out.str());
136 }
137}
138
139TEST(OriginTest, Comparison) {
140 // These URLs are arranged in increasing order:
141 const char* const urls[] = {
142 "data:uniqueness",
143 "http://a:80",
144 "http://b:80",
145 "https://a:80",
146 "https://b:80",
147 "http://a:81",
148 "http://b:81",
149 "https://a:81",
150 "https://b:81",
151 };
152
153 for (size_t i = 0; i < arraysize(urls); i++) {
154 GURL current_url(urls[i]);
155 url::Origin current(current_url);
156 for (size_t j = i; j < arraysize(urls); j++) {
157 GURL compare_url(urls[j]);
158 url::Origin to_compare(compare_url);
159 EXPECT_EQ(i < j, current < to_compare) << i << " < " << j;
160 EXPECT_EQ(j < i, to_compare < current) << j << " < " << i;
161 }
162 }
163}
164
mkwstd8335d982015-07-25 05:18:48165TEST(OriginTest, UnsafelyCreate) {
166 struct TestCase {
167 const char* scheme;
168 const char* host;
avic0c60312015-12-21 21:03:50169 uint16_t port;
mkwstd8335d982015-07-25 05:18:48170 } cases[] = {
171 {"http", "example.com", 80},
172 {"http", "example.com", 123},
173 {"https", "example.com", 443},
174 {"https", "example.com", 123},
175 {"file", "", 0},
176 {"file", "example.com", 0},
177 };
178
179 for (const auto& test : cases) {
180 SCOPED_TRACE(testing::Message() << test.scheme << "://" << test.host << ":"
181 << test.port);
182 url::Origin origin = url::Origin::UnsafelyCreateOriginWithoutNormalization(
183 test.scheme, test.host, test.port);
184 EXPECT_EQ(test.scheme, origin.scheme());
185 EXPECT_EQ(test.host, origin.host());
186 EXPECT_EQ(test.port, origin.port());
187 EXPECT_FALSE(origin.unique());
188 EXPECT_TRUE(origin.IsSameOriginWith(origin));
189 }
190}
191
192TEST(OriginTest, UnsafelyCreateUniqueOnInvalidInput) {
193 struct TestCases {
194 const char* scheme;
195 const char* host;
avic0c60312015-12-21 21:03:50196 uint16_t port;
mkwstd8335d982015-07-25 05:18:48197 } cases[] = {{"", "", 0},
198 {"data", "", 0},
199 {"blob", "", 0},
200 {"filesystem", "", 0},
201 {"data", "example.com", 80},
202 {"http", "☃.net", 80},
203 {"http\nmore", "example.com", 80},
204 {"http\rmore", "example.com", 80},
205 {"http\n", "example.com", 80},
206 {"http\r", "example.com", 80},
207 {"http", "example.com\nnot-example.com", 80},
208 {"http", "example.com\rnot-example.com", 80},
209 {"http", "example.com\n", 80},
210 {"http", "example.com\r", 80},
211 {"http", "example.com", 0},
212 {"file", "", 80}};
213
214 for (const auto& test : cases) {
215 SCOPED_TRACE(testing::Message() << test.scheme << "://" << test.host << ":"
216 << test.port);
217 url::Origin origin = url::Origin::UnsafelyCreateOriginWithoutNormalization(
218 test.scheme, test.host, test.port);
219 EXPECT_EQ("", origin.scheme());
220 EXPECT_EQ("", origin.host());
221 EXPECT_EQ(0, origin.port());
222 EXPECT_TRUE(origin.unique());
223 EXPECT_FALSE(origin.IsSameOriginWith(origin));
224 }
225}
226
227TEST(OriginTest, UnsafelyCreateUniqueViaEmbeddedNulls) {
228 struct TestCases {
229 const char* scheme;
230 size_t scheme_length;
231 const char* host;
232 size_t host_length;
avic0c60312015-12-21 21:03:50233 uint16_t port;
mkwstd8335d982015-07-25 05:18:48234 } cases[] = {{"http\0more", 9, "example.com", 11, 80},
235 {"http\0", 5, "example.com", 11, 80},
236 {"\0http", 5, "example.com", 11, 80},
237 {"http", 4, "example.com\0not-example.com", 27, 80},
238 {"http", 4, "example.com\0", 12, 80},
239 {"http", 4, "\0example.com", 12, 80}};
240
241 for (const auto& test : cases) {
242 SCOPED_TRACE(testing::Message() << test.scheme << "://" << test.host << ":"
243 << test.port);
244 url::Origin origin = url::Origin::UnsafelyCreateOriginWithoutNormalization(
245 std::string(test.scheme, test.scheme_length),
246 std::string(test.host, test.host_length), test.port);
247 EXPECT_EQ("", origin.scheme());
248 EXPECT_EQ("", origin.host());
249 EXPECT_EQ(0, origin.port());
250 EXPECT_TRUE(origin.unique());
251 EXPECT_FALSE(origin.IsSameOriginWith(origin));
252 }
253}
254
mkwst9f2cc892015-07-22 06:03:25255} // namespace url