Move Service Worker %2f path validation logic from browser into Blink (1)
[chromium-blink-merge.git] / content / common / service_worker / service_worker_utils_unittest.cc
blobf8ab571682dc28df417d44ccb42926f24627b428
1 // Copyright 2014 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.
5 #include "content/common/service_worker/service_worker_utils.h"
6 #include "testing/gtest/include/gtest/gtest.h"
8 namespace content {
10 namespace {
12 bool IsPathRestrictionSatisfied(const GURL& scope, const GURL& script_url) {
13 std::string error_message;
14 return ServiceWorkerUtils::IsPathRestrictionSatisfied(
15 scope, script_url, nullptr, &error_message);
18 bool IsPathRestrictionSatisfiedWithServiceWorkerAllowedHeader(
19 const GURL& scope,
20 const GURL& script_url,
21 const std::string& service_worker_allowed) {
22 std::string error_message;
23 return ServiceWorkerUtils::IsPathRestrictionSatisfied(
24 scope, script_url, &service_worker_allowed, &error_message);
27 } // namespace
29 TEST(ServiceWorkerUtilsTest, ScopeMatches) {
30 ASSERT_TRUE(ServiceWorkerUtils::ScopeMatches(
31 GURL("http://www.example.com/"), GURL("http://www.example.com/")));
32 ASSERT_TRUE(ServiceWorkerUtils::ScopeMatches(
33 GURL("http://www.example.com/"),
34 GURL("http://www.example.com/page.html")));
36 ASSERT_FALSE(ServiceWorkerUtils::ScopeMatches(
37 GURL("http://www.example.com/"), GURL("https://www.example.com/")));
38 ASSERT_FALSE(ServiceWorkerUtils::ScopeMatches(
39 GURL("http://www.example.com/"),
40 GURL("https://www.example.com/page.html")));
42 ASSERT_FALSE(ServiceWorkerUtils::ScopeMatches(GURL("http://www.example.com/"),
43 GURL("http://www.foo.com/")));
44 ASSERT_FALSE(ServiceWorkerUtils::ScopeMatches(
45 GURL("http://www.example.com/"), GURL("https://www.foo.com/page.html")));
47 // '*' is not a wildcard.
48 ASSERT_FALSE(ServiceWorkerUtils::ScopeMatches(
49 GURL("http://www.example.com/*"), GURL("http://www.example.com/x")));
50 ASSERT_FALSE(ServiceWorkerUtils::ScopeMatches(
51 GURL("http://www.example.com/*"), GURL("http://www.example.com/")));
52 ASSERT_FALSE(ServiceWorkerUtils::ScopeMatches(
53 GURL("http://www.example.com/*"), GURL("http://www.example.com/xx")));
54 ASSERT_TRUE(ServiceWorkerUtils::ScopeMatches(
55 GURL("http://www.example.com/*"), GURL("http://www.example.com/*")));
57 ASSERT_TRUE(ServiceWorkerUtils::ScopeMatches(
58 GURL("http://www.example.com/*/x"), GURL("http://www.example.com/*/x")));
59 ASSERT_FALSE(ServiceWorkerUtils::ScopeMatches(
60 GURL("http://www.example.com/*/x"), GURL("http://www.example.com/a/x")));
61 ASSERT_FALSE(
62 ServiceWorkerUtils::ScopeMatches(GURL("http://www.example.com/*/x/*"),
63 GURL("http://www.example.com/a/x/b")));
64 ASSERT_FALSE(
65 ServiceWorkerUtils::ScopeMatches(GURL("http://www.example.com/*/x/*"),
66 GURL("http://www.example.com/*/x/b")));
68 // '?' is not a wildcard.
69 ASSERT_FALSE(ServiceWorkerUtils::ScopeMatches(
70 GURL("http://www.example.com/?"), GURL("http://www.example.com/x")));
71 ASSERT_FALSE(ServiceWorkerUtils::ScopeMatches(
72 GURL("http://www.example.com/?"), GURL("http://www.example.com/")));
73 ASSERT_FALSE(ServiceWorkerUtils::ScopeMatches(
74 GURL("http://www.example.com/?"), GURL("http://www.example.com/xx")));
75 ASSERT_TRUE(ServiceWorkerUtils::ScopeMatches(
76 GURL("http://www.example.com/?"), GURL("http://www.example.com/?")));
78 // Query string is part of the resource.
79 ASSERT_TRUE(
80 ServiceWorkerUtils::ScopeMatches(GURL("http://www.example.com/?a=b"),
81 GURL("http://www.example.com/?a=b")));
82 ASSERT_TRUE(ServiceWorkerUtils::ScopeMatches(
83 GURL("http://www.example.com/?a="), GURL("http://www.example.com/?a=b")));
84 ASSERT_TRUE(ServiceWorkerUtils::ScopeMatches(
85 GURL("http://www.example.com/"), GURL("http://www.example.com/?a=b")));
87 // URLs canonicalize \ to / so this is equivalent to "...//x"
88 ASSERT_TRUE(ServiceWorkerUtils::ScopeMatches(
89 GURL("http://www.example.com/\\x"), GURL("http://www.example.com//x")));
92 TEST(ServiceWorkerUtilsTest, FindLongestScopeMatch) {
93 LongestScopeMatcher matcher(GURL("http://www.example.com/xxx"));
95 // "/xx" should be matched longest.
96 ASSERT_TRUE(matcher.MatchLongest(GURL("http://www.example.com/x")));
97 ASSERT_FALSE(matcher.MatchLongest(GURL("http://www.example.com/")));
98 ASSERT_TRUE(matcher.MatchLongest(GURL("http://www.example.com/xx")));
100 // "/xxx" should be matched longer than "/xx".
101 ASSERT_TRUE(matcher.MatchLongest(GURL("http://www.example.com/xxx")));
103 // The second call with the same URL should return false.
104 ASSERT_FALSE(matcher.MatchLongest(GURL("http://www.example.com/xxx")));
106 ASSERT_FALSE(matcher.MatchLongest(GURL("http://www.example.com/xxxx")));
109 TEST(ServiceWorkerUtilsTest, PathRestriction_Basic) {
110 EXPECT_TRUE(IsPathRestrictionSatisfied(GURL("http://example.com/"),
111 GURL("http://example.com/sw.js")));
112 EXPECT_TRUE(IsPathRestrictionSatisfied(GURL("http://example.com/foo/"),
113 GURL("http://example.com/sw.js")));
114 EXPECT_TRUE(IsPathRestrictionSatisfied(GURL("http://example.com/foo/"),
115 GURL("http://example.com/foo/sw.js")));
116 EXPECT_TRUE(IsPathRestrictionSatisfied(GURL("http://example.com/foo/bar"),
117 GURL("http://example.com/foo/sw.js")));
118 EXPECT_FALSE(IsPathRestrictionSatisfied(
119 GURL("http://example.com/"), GURL("http://example.com/foo/sw.js")));
120 EXPECT_FALSE(IsPathRestrictionSatisfied(
121 GURL("http://example.com/bar/"), GURL("http://example.com/foo/sw.js")));
123 // The scope is under the script directory, but that doesn't have the trailing
124 // slash. In this case, the check should be failed.
125 EXPECT_FALSE(IsPathRestrictionSatisfied(
126 GURL("http://example.com/foo"), GURL("http://example.com/foo/sw.js")));
128 // Query parameters should not affect the path restriction.
129 EXPECT_TRUE(IsPathRestrictionSatisfied(GURL("http://example.com/?query"),
130 GURL("http://example.com/sw.js")));
131 EXPECT_TRUE(IsPathRestrictionSatisfied(GURL("http://example.com/foo/?query"),
132 GURL("http://example.com/sw.js")));
133 EXPECT_TRUE(IsPathRestrictionSatisfied(GURL("http://example.com/foo/?query"),
134 GURL("http://example.com/foo/sw.js")));
135 EXPECT_FALSE(IsPathRestrictionSatisfied(
136 GURL("http://example.com/?query"), GURL("http://example.com/foo/sw.js")));
137 EXPECT_FALSE(
138 IsPathRestrictionSatisfied(GURL("http://example.com/bar/query?"),
139 GURL("http://example.com/foo/sw.js")));
141 EXPECT_TRUE(IsPathRestrictionSatisfied(
142 GURL("http://example.com/"), GURL("http://example.com/sw.js?query")));
143 EXPECT_TRUE(IsPathRestrictionSatisfied(
144 GURL("http://example.com/foo/"), GURL("http://example.com/sw.js?query")));
145 EXPECT_TRUE(
146 IsPathRestrictionSatisfied(GURL("http://example.com/foo/"),
147 GURL("http://example.com/foo/sw.js?query")));
148 EXPECT_FALSE(IsPathRestrictionSatisfied(
149 GURL("http://example.com/"), GURL("http://example.com/foo/sw.js?query")));
150 EXPECT_FALSE(
151 IsPathRestrictionSatisfied(GURL("http://example.com/bar/"),
152 GURL("http://example.com/foo/sw.js?query")));
154 // Query parameter including a slash should not affect.
155 EXPECT_TRUE(IsPathRestrictionSatisfied(
156 GURL("http://example.com/foo/bar?key/value"),
157 GURL("http://example.com/foo/sw.js?key=value")));
158 EXPECT_TRUE(IsPathRestrictionSatisfied(
159 GURL("http://example.com/foo/bar?key=value"),
160 GURL("http://example.com/foo/sw.js?key/value")));
163 TEST(ServiceWorkerUtils, PathRestriction_SelfReference) {
164 // Self reference is canonicalized.
165 ASSERT_EQ(GURL("http://example.com/foo/bar"),
166 GURL("http://example.com/././foo/bar"));
167 EXPECT_TRUE(
168 IsPathRestrictionSatisfied(GURL("http://example.com/foo/"),
169 GURL("http://example.com/././foo/sw.js")));
170 EXPECT_TRUE(IsPathRestrictionSatisfied(GURL("http://example.com/././foo/"),
171 GURL("http://example.com/foo/sw.js")));
172 EXPECT_TRUE(
173 IsPathRestrictionSatisfied(GURL("http://example.com/foo/./"),
174 GURL("http://example.com/./foo/sw.js")));
176 // URL-encoded dot ('%2e') is also canonicalized.
177 ASSERT_EQ(GURL("http://example.com/foo/././bar"),
178 GURL("http://example.com/foo/%2e/%2e/bar"));
179 EXPECT_TRUE(
180 IsPathRestrictionSatisfied(GURL("http://example.com/foo/%2e/%2e/bar"),
181 GURL("http://example.com/foo/%2e/%2e/sw.js")));
182 EXPECT_TRUE(
183 IsPathRestrictionSatisfied(GURL("http://example.com/foo/bar"),
184 GURL("http://example.com/foo/%2e/%2e/sw.js")));
185 EXPECT_TRUE(
186 IsPathRestrictionSatisfied(GURL("http://example.com/foo/%2e/%2e/bar"),
187 GURL("http://example.com/foo/sw.js")));
188 EXPECT_TRUE(
189 IsPathRestrictionSatisfied(GURL("http://example.com/foo/%2e/bar"),
190 GURL("http://example.com/%2e/foo/sw.js")));
192 // URL-encoded dot ('%2E') is also canonicalized.
193 ASSERT_EQ(GURL("http://example.com/foo/././bar"),
194 GURL("http://example.com/foo/%2E/%2e/bar"));
197 TEST(ServiceWorkerUtilsTest, PathRestriction_ParentReference) {
198 // Parent reference is canonicalized.
199 ASSERT_EQ(GURL("http://example.com/foo/bar"),
200 GURL("http://example.com/foo/../foo/bar"));
201 EXPECT_TRUE(
202 IsPathRestrictionSatisfied(GURL("http://example.com/foo/bar"),
203 GURL("http://example.com/foo/../foo/sw.js")));
204 EXPECT_TRUE(
205 IsPathRestrictionSatisfied(GURL("http://example.com/foo/../foo/bar"),
206 GURL("http://example.com/foo/sw.js")));
207 EXPECT_TRUE(
208 IsPathRestrictionSatisfied(GURL("http://example.com/foo/bar/../bar"),
209 GURL("http://example.com/../foo/sw.js")));
210 EXPECT_TRUE(IsPathRestrictionSatisfied(
211 GURL("http://example.com/foo/../../../foo/bar"),
212 GURL("http://example.com/foo/sw.js")));
213 EXPECT_FALSE(
214 IsPathRestrictionSatisfied(GURL("http://example.com/foo/../bar"),
215 GURL("http://example.com/foo/sw.js")));
217 // URL-encoded dot ('%2e') is also canonicalized.
218 ASSERT_EQ(GURL("http://example.com/foo/../foo/bar"),
219 GURL("http://example.com/foo/%2e%2e/foo/bar"));
220 EXPECT_TRUE(IsPathRestrictionSatisfied(
221 GURL("http://example.com/foo/bar"),
222 GURL("http://example.com/foo/%2e%2e/foo/sw.js")));
223 EXPECT_TRUE(
224 IsPathRestrictionSatisfied(GURL("http://example.com/foo/%2e%2e/foo/bar"),
225 GURL("http://example.com/foo/sw.js")));
226 EXPECT_TRUE(
227 IsPathRestrictionSatisfied(GURL("http://example.com/foo/%2e%2e/foo/bar"),
228 GURL("http://example.com/%2e%2e/foo/sw.js")));
229 EXPECT_TRUE(IsPathRestrictionSatisfied(
230 GURL("http://example.com/foo/%2e%2e/%2e%2e/%2e%2e/foo/bar"),
231 GURL("http://example.com/foo/sw.js")));
232 EXPECT_FALSE(
233 IsPathRestrictionSatisfied(GURL("http://example.com/foo/%2e%2e/bar"),
234 GURL("http://example.com/foo/sw.js")));
236 // URL-encoded dot ('%2E') is also canonicalized.
237 ASSERT_EQ(GURL("http://example.com/foo/../foo/bar"),
238 GURL("http://example.com/foo/%2E%2E/foo/bar"));
241 TEST(ServiceWorkerUtilsTest, PathRestriction_ConsecutiveSlashes) {
242 // Consecutive slashes are not unified.
243 ASSERT_NE(GURL("http://example.com/foo/bar"),
244 GURL("http://example.com/foo///bar"));
245 EXPECT_FALSE(
246 IsPathRestrictionSatisfied(GURL("http://example.com/foo/bar"),
247 GURL("http://example.com/foo///sw.js")));
248 EXPECT_TRUE(IsPathRestrictionSatisfied(GURL("http://example.com/foo///bar"),
249 GURL("http://example.com/foo/sw.js")));
250 EXPECT_TRUE(
251 IsPathRestrictionSatisfied(GURL("http://example.com/foo///bar"),
252 GURL("http://example.com/foo///sw.js")));
255 TEST(ServiceWorkerUtilsTest, PathRestriction_BackSlash) {
256 // A backslash is converted to a slash.
257 ASSERT_EQ(GURL("http://example.com/foo/bar"),
258 GURL("http://example.com/foo\\bar"));
259 EXPECT_TRUE(IsPathRestrictionSatisfied(GURL("http://example.com/foo\\bar"),
260 GURL("http://example.com/foo/sw.js")));
262 // Consecutive back slashes should not unified.
263 ASSERT_NE(GURL("http://example.com/foo\\\\\\bar"),
264 GURL("http://example.com/foo\\bar"));
265 EXPECT_FALSE(
266 IsPathRestrictionSatisfied(GURL("http://example.com/foo\\bar"),
267 GURL("http://example.com/foo\\\\\\sw.js")));
268 EXPECT_TRUE(
269 IsPathRestrictionSatisfied(GURL("http://example.com/foo\\\\\\bar"),
270 GURL("http://example.com/foo\\sw.js")));
273 TEST(ServiceWorkerUtilsTest, PathRestriction_DisallowedCharacter) {
274 // URL-encoded slash ('%2f') is not canonicalized.
275 ASSERT_NE(GURL("http://example.com/foo///bar"),
276 GURL("http://example.com/foo/%2f/bar"));
277 EXPECT_FALSE(
278 IsPathRestrictionSatisfied(GURL("http://example.com/foo%2fbar/"),
279 GURL("http://example.com/foo/bar/sw.js")));
280 EXPECT_FALSE(
281 IsPathRestrictionSatisfied(GURL("http://example.com/foo/bar%2f"),
282 GURL("http://example.com/foo/bar/sw.js")));
283 EXPECT_FALSE(
284 IsPathRestrictionSatisfied(GURL("http://example.com/foo/bar/"),
285 GURL("http://example.com/foo/bar%2fsw.js")));
286 EXPECT_FALSE(
287 IsPathRestrictionSatisfied(GURL("http://example.com/foo/"),
288 GURL("http://example.com/foo/bar%2fsw.js")));
290 // URL-encoded slash ('%2F') is also not canonicalized.
291 ASSERT_NE(GURL("http://example.com/foo///bar"),
292 GURL("http://example.com/foo/%2F/bar"));
293 EXPECT_FALSE(
294 IsPathRestrictionSatisfied(GURL("http://example.com/foo%2Fbar/"),
295 GURL("http://example.com/foo/bar/sw.js")));
296 EXPECT_FALSE(
297 IsPathRestrictionSatisfied(GURL("http://example.com/foo/bar%2F"),
298 GURL("http://example.com/foo/bar/sw.js")));
299 EXPECT_FALSE(
300 IsPathRestrictionSatisfied(GURL("http://example.com/foo/bar/"),
301 GURL("http://example.com/foo/bar%2Fsw.js")));
302 EXPECT_FALSE(
303 IsPathRestrictionSatisfied(GURL("http://example.com/foo/"),
304 GURL("http://example.com/foo/bar%2Fsw.js")));
306 // URL-encoded backslash ('%5c') is not canonicalized.
307 ASSERT_NE(GURL("http://example.com/foo/\\/bar"),
308 GURL("http://example.com/foo/%5c/bar"));
309 EXPECT_FALSE(
310 IsPathRestrictionSatisfied(GURL("http://example.com/foo%5cbar/"),
311 GURL("http://example.com/foo/bar/sw.js")));
312 EXPECT_FALSE(
313 IsPathRestrictionSatisfied(GURL("http://example.com/foo/bar%5c"),
314 GURL("http://example.com/foo/bar/sw.js")));
315 EXPECT_FALSE(
316 IsPathRestrictionSatisfied(GURL("http://example.com/foo/bar/"),
317 GURL("http://example.com/foo/bar%5csw.js")));
318 EXPECT_FALSE(
319 IsPathRestrictionSatisfied(GURL("http://example.com/foo/"),
320 GURL("http://example.com/foo/bar%5csw.js")));
322 // URL-encoded backslash ('%5C') is also not canonicalized.
323 ASSERT_NE(GURL("http://example.com/foo/\\/bar"),
324 GURL("http://example.com/foo/%5C/bar"));
325 EXPECT_FALSE(
326 IsPathRestrictionSatisfied(GURL("http://example.com/foo%5Cbar/"),
327 GURL("http://example.com/foo/bar/sw.js")));
328 EXPECT_FALSE(
329 IsPathRestrictionSatisfied(GURL("http://example.com/foo/bar%5C"),
330 GURL("http://example.com/foo/bar/sw.js")));
331 EXPECT_FALSE(
332 IsPathRestrictionSatisfied(GURL("http://example.com/foo/bar/"),
333 GURL("http://example.com/foo/bar%5Csw.js")));
334 EXPECT_FALSE(
335 IsPathRestrictionSatisfied(GURL("http://example.com/foo/"),
336 GURL("http://example.com/foo/bar%5Csw.js")));
338 // Query parameter should be able to have escaped characters.
339 EXPECT_TRUE(IsPathRestrictionSatisfied(
340 GURL("http://example.com/foo/bar?key%2fvalue"),
341 GURL("http://example.com/foo/sw.js?key/value")));
342 EXPECT_TRUE(IsPathRestrictionSatisfied(
343 GURL("http://example.com/foo/bar?key/value"),
344 GURL("http://example.com/foo/sw.js?key%2fvalue")));
345 EXPECT_TRUE(IsPathRestrictionSatisfied(
346 GURL("http://example.com/foo/bar?key%5cvalue"),
347 GURL("http://example.com/foo/sw.js?key\\value")));
348 EXPECT_TRUE(IsPathRestrictionSatisfied(
349 GURL("http://example.com/foo/bar?key\\value"),
350 GURL("http://example.com/foo/sw.js?key%5cvalue")));
353 TEST(ServiceWorkerUtils, PathRestriction_ServiceWorkerAllowed) {
354 // Setting header to default max scope changes nothing.
355 EXPECT_TRUE(IsPathRestrictionSatisfiedWithServiceWorkerAllowedHeader(
356 GURL("http://example.com/"), GURL("http://example.com/sw.js"),
357 "http://example.com/"));
358 EXPECT_FALSE(IsPathRestrictionSatisfiedWithServiceWorkerAllowedHeader(
359 GURL("http://example.com/"), GURL("http://example.com/foo/sw.js"),
360 "http://example.com/foo/"));
362 // Using the header to widen allowed scope.
363 EXPECT_TRUE(IsPathRestrictionSatisfiedWithServiceWorkerAllowedHeader(
364 GURL("http://example.com/"), GURL("http://example.com/foo/sw.js"),
365 "http://example.com/"));
366 EXPECT_TRUE(IsPathRestrictionSatisfiedWithServiceWorkerAllowedHeader(
367 GURL("http://example.com/"), GURL("http://example.com/foo/sw.js"), "/"));
368 EXPECT_TRUE(IsPathRestrictionSatisfiedWithServiceWorkerAllowedHeader(
369 GURL("http://example.com/"), GURL("http://example.com/foo/sw.js"), ".."));
370 EXPECT_TRUE(IsPathRestrictionSatisfiedWithServiceWorkerAllowedHeader(
371 GURL("http://example.com/bar/"), GURL("http://example.com/foo/sw.js"),
372 "../b"));
373 EXPECT_FALSE(IsPathRestrictionSatisfiedWithServiceWorkerAllowedHeader(
374 GURL("http://example.com/bar/"), GURL("http://example.com/foo/sw.js"),
375 "../c"));
377 // Using the header to restrict allowed scope.
378 EXPECT_FALSE(IsPathRestrictionSatisfiedWithServiceWorkerAllowedHeader(
379 GURL("http://example.com/"), GURL("http://example.com/sw.js"),
380 "http://example.com/foo/"));
381 EXPECT_FALSE(IsPathRestrictionSatisfiedWithServiceWorkerAllowedHeader(
382 GURL("http://example.com/"), GURL("http://example.com/sw.js"), "foo"));
383 EXPECT_TRUE(IsPathRestrictionSatisfiedWithServiceWorkerAllowedHeader(
384 GURL("http://example.com/foo/"), GURL("http://example.com/sw.js"),
385 "foo"));
387 // Empty string resolves to max scope of "http://www.example.com/sw.js".
388 EXPECT_FALSE(IsPathRestrictionSatisfiedWithServiceWorkerAllowedHeader(
389 GURL("http://example.com/"), GURL("http://example.com/sw.js"), ""));
390 EXPECT_TRUE(IsPathRestrictionSatisfiedWithServiceWorkerAllowedHeader(
391 GURL("http://example.com/sw.js/hi"), GURL("http://example.com/sw.js"),
392 ""));
395 } // namespace content