Update To 11.40.268.0
[platform/framework/web/crosswalk.git] / src / extensions / common / url_pattern_unittest.cc
1 // Copyright (c) 2012 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 "base/memory/scoped_ptr.h"
6 #include "extensions/common/url_pattern.h"
7 #include "testing/gtest/include/gtest/gtest.h"
8 #include "url/gurl.h"
9
10 namespace {
11
12 // See url_pattern.h for examples of valid and invalid patterns.
13
14 static const int kAllSchemes =
15     URLPattern::SCHEME_HTTP |
16     URLPattern::SCHEME_HTTPS |
17     URLPattern::SCHEME_FILE |
18     URLPattern::SCHEME_FTP |
19     URLPattern::SCHEME_CHROMEUI |
20     URLPattern::SCHEME_EXTENSION |
21     URLPattern::SCHEME_FILESYSTEM;
22
23 TEST(ExtensionURLPatternTest, ParseInvalid) {
24   const struct {
25     const char* pattern;
26     URLPattern::ParseResult expected_result;
27   } kInvalidPatterns[] = {
28     { "http", URLPattern::PARSE_ERROR_MISSING_SCHEME_SEPARATOR },
29     { "http:", URLPattern::PARSE_ERROR_WRONG_SCHEME_SEPARATOR },
30     { "http:/", URLPattern::PARSE_ERROR_WRONG_SCHEME_SEPARATOR },
31     { "about://", URLPattern::PARSE_ERROR_WRONG_SCHEME_SEPARATOR },
32     { "http://", URLPattern::PARSE_ERROR_EMPTY_HOST },
33     { "http:///", URLPattern::PARSE_ERROR_EMPTY_HOST },
34     { "http:// /", URLPattern::PARSE_ERROR_EMPTY_HOST },
35     { "http://*foo/bar", URLPattern::PARSE_ERROR_INVALID_HOST_WILDCARD },
36     { "http://foo.*.bar/baz", URLPattern::PARSE_ERROR_INVALID_HOST_WILDCARD },
37     { "http://fo.*.ba:123/baz", URLPattern::PARSE_ERROR_INVALID_HOST_WILDCARD },
38     { "http:/bar", URLPattern::PARSE_ERROR_WRONG_SCHEME_SEPARATOR },
39     { "http://bar", URLPattern::PARSE_ERROR_EMPTY_PATH },
40   };
41
42   for (size_t i = 0; i < arraysize(kInvalidPatterns); ++i) {
43     URLPattern pattern(URLPattern::SCHEME_ALL);
44     EXPECT_EQ(kInvalidPatterns[i].expected_result,
45               pattern.Parse(kInvalidPatterns[i].pattern))
46         << kInvalidPatterns[i].pattern;
47   }
48
49   {
50     // Cannot use a C string, because this contains a null byte.
51     std::string null_host("http://\0www/", 12);
52     URLPattern pattern(URLPattern::SCHEME_ALL);
53     EXPECT_EQ(URLPattern::PARSE_ERROR_INVALID_HOST,
54               pattern.Parse(null_host))
55         << null_host;
56   }
57 }
58
59 TEST(ExtensionURLPatternTest, Ports) {
60   const struct {
61     const char* pattern;
62     URLPattern::ParseResult expected_result;
63     const char* expected_port;
64   } kTestPatterns[] = {
65     { "http://foo:1234/", URLPattern::PARSE_SUCCESS, "1234" },
66     { "http://foo:1234/bar", URLPattern::PARSE_SUCCESS, "1234" },
67     { "http://*.foo:1234/", URLPattern::PARSE_SUCCESS, "1234" },
68     { "http://*.foo:1234/bar", URLPattern::PARSE_SUCCESS, "1234" },
69     { "http://:1234/", URLPattern::PARSE_SUCCESS, "1234" },
70     { "http://foo:/", URLPattern::PARSE_ERROR_INVALID_PORT, "*" },
71     { "http://foo:*/", URLPattern::PARSE_SUCCESS, "*" },
72     { "http://*.foo:/", URLPattern::PARSE_ERROR_INVALID_PORT, "*" },
73     { "http://foo:com/", URLPattern::PARSE_ERROR_INVALID_PORT, "*" },
74     { "http://foo:123456/", URLPattern::PARSE_ERROR_INVALID_PORT, "*" },
75     { "http://foo:80:80/monkey", URLPattern::PARSE_ERROR_INVALID_PORT, "*" },
76     { "file://foo:1234/bar", URLPattern::PARSE_SUCCESS, "*" },
77     { "chrome://foo:1234/bar", URLPattern::PARSE_ERROR_INVALID_PORT, "*" },
78
79     // Port-like strings in the path should not trigger a warning.
80     { "http://*/:1234", URLPattern::PARSE_SUCCESS, "*" },
81     { "http://*.foo/bar:1234", URLPattern::PARSE_SUCCESS, "*" },
82     { "http://foo/bar:1234/path", URLPattern::PARSE_SUCCESS, "*" },
83   };
84
85   for (size_t i = 0; i < arraysize(kTestPatterns); ++i) {
86     URLPattern pattern(URLPattern::SCHEME_ALL);
87     EXPECT_EQ(kTestPatterns[i].expected_result,
88               pattern.Parse(kTestPatterns[i].pattern))
89         << "Got unexpected result for URL pattern: "
90         << kTestPatterns[i].pattern;
91     EXPECT_EQ(kTestPatterns[i].expected_port, pattern.port())
92         << "Got unexpected port for URL pattern: " << kTestPatterns[i].pattern;
93   }
94 }
95
96 // all pages for a given scheme
97 TEST(ExtensionURLPatternTest, Match1) {
98   URLPattern pattern(kAllSchemes);
99   EXPECT_EQ(URLPattern::PARSE_SUCCESS, pattern.Parse("http://*/*"));
100   EXPECT_EQ("http", pattern.scheme());
101   EXPECT_EQ("", pattern.host());
102   EXPECT_TRUE(pattern.match_subdomains());
103   EXPECT_FALSE(pattern.match_all_urls());
104   EXPECT_EQ("/*", pattern.path());
105   EXPECT_TRUE(pattern.MatchesURL(GURL("http://google.com")));
106   EXPECT_TRUE(pattern.MatchesURL(GURL("http://yahoo.com")));
107   EXPECT_TRUE(pattern.MatchesURL(GURL("http://google.com/foo")));
108   EXPECT_FALSE(pattern.MatchesURL(GURL("https://google.com")));
109   EXPECT_TRUE(pattern.MatchesURL(GURL("http://74.125.127.100/search")));
110 }
111
112 // all domains
113 TEST(ExtensionURLPatternTest, Match2) {
114   URLPattern pattern(kAllSchemes);
115   EXPECT_EQ(URLPattern::PARSE_SUCCESS, pattern.Parse("https://*/foo*"));
116   EXPECT_EQ("https", pattern.scheme());
117   EXPECT_EQ("", pattern.host());
118   EXPECT_TRUE(pattern.match_subdomains());
119   EXPECT_FALSE(pattern.match_all_urls());
120   EXPECT_EQ("/foo*", pattern.path());
121   EXPECT_TRUE(pattern.MatchesURL(GURL("https://www.google.com/foo")));
122   EXPECT_TRUE(pattern.MatchesURL(GURL("https://www.google.com/foobar")));
123   EXPECT_FALSE(pattern.MatchesURL(GURL("http://www.google.com/foo")));
124   EXPECT_FALSE(pattern.MatchesURL(GURL("https://www.google.com/")));
125   EXPECT_TRUE(pattern.MatchesURL(
126       GURL("filesystem:https://www.google.com/foobar/")));
127 }
128
129 // subdomains
130 TEST(URLPatternTest, Match3) {
131   URLPattern pattern(kAllSchemes);
132   EXPECT_EQ(URLPattern::PARSE_SUCCESS,
133             pattern.Parse("http://*.google.com/foo*bar"));
134   EXPECT_EQ("http", pattern.scheme());
135   EXPECT_EQ("google.com", pattern.host());
136   EXPECT_TRUE(pattern.match_subdomains());
137   EXPECT_FALSE(pattern.match_all_urls());
138   EXPECT_EQ("/foo*bar", pattern.path());
139   EXPECT_TRUE(pattern.MatchesURL(GURL("http://google.com/foobar")));
140   EXPECT_TRUE(pattern.MatchesURL(GURL("http://www.google.com/foo?bar")));
141   EXPECT_TRUE(pattern.MatchesURL(
142       GURL("http://monkey.images.google.com/foooobar")));
143   EXPECT_FALSE(pattern.MatchesURL(GURL("http://yahoo.com/foobar")));
144   EXPECT_TRUE(pattern.MatchesURL(
145       GURL("filesystem:http://google.com/foo/bar")));
146   EXPECT_FALSE(pattern.MatchesURL(
147       GURL("filesystem:http://google.com/temporary/foobar")));
148 }
149
150 // glob escaping
151 TEST(ExtensionURLPatternTest, Match5) {
152   URLPattern pattern(kAllSchemes);
153   EXPECT_EQ(URLPattern::PARSE_SUCCESS, pattern.Parse("file:///foo?bar\\*baz"));
154   EXPECT_EQ("file", pattern.scheme());
155   EXPECT_EQ("", pattern.host());
156   EXPECT_FALSE(pattern.match_subdomains());
157   EXPECT_FALSE(pattern.match_all_urls());
158   EXPECT_EQ("/foo?bar\\*baz", pattern.path());
159   EXPECT_TRUE(pattern.MatchesURL(GURL("file:///foo?bar\\hellobaz")));
160   EXPECT_FALSE(pattern.MatchesURL(GURL("file:///fooXbar\\hellobaz")));
161 }
162
163 // ip addresses
164 TEST(ExtensionURLPatternTest, Match6) {
165   URLPattern pattern(kAllSchemes);
166   EXPECT_EQ(URLPattern::PARSE_SUCCESS, pattern.Parse("http://127.0.0.1/*"));
167   EXPECT_EQ("http", pattern.scheme());
168   EXPECT_EQ("127.0.0.1", pattern.host());
169   EXPECT_FALSE(pattern.match_subdomains());
170   EXPECT_FALSE(pattern.match_all_urls());
171   EXPECT_EQ("/*", pattern.path());
172   EXPECT_TRUE(pattern.MatchesURL(GURL("http://127.0.0.1")));
173 }
174
175 // subdomain matching with ip addresses
176 TEST(ExtensionURLPatternTest, Match7) {
177   URLPattern pattern(kAllSchemes);
178   // allowed, but useless
179   EXPECT_EQ(URLPattern::PARSE_SUCCESS, pattern.Parse("http://*.0.0.1/*"));
180   EXPECT_EQ("http", pattern.scheme());
181   EXPECT_EQ("0.0.1", pattern.host());
182   EXPECT_TRUE(pattern.match_subdomains());
183   EXPECT_FALSE(pattern.match_all_urls());
184   EXPECT_EQ("/*", pattern.path());
185   // Subdomain matching is never done if the argument has an IP address host.
186   EXPECT_FALSE(pattern.MatchesURL(GURL("http://127.0.0.1")));
187 }
188
189 // unicode
190 TEST(ExtensionURLPatternTest, Match8) {
191   URLPattern pattern(kAllSchemes);
192   // The below is the ASCII encoding of the following URL:
193   // http://*.\xe1\x80\xbf/a\xc2\x81\xe1*
194   EXPECT_EQ(URLPattern::PARSE_SUCCESS,
195             pattern.Parse("http://*.xn--gkd/a%C2%81%E1*"));
196   EXPECT_EQ("http", pattern.scheme());
197   EXPECT_EQ("xn--gkd", pattern.host());
198   EXPECT_TRUE(pattern.match_subdomains());
199   EXPECT_FALSE(pattern.match_all_urls());
200   EXPECT_EQ("/a%C2%81%E1*", pattern.path());
201   EXPECT_TRUE(pattern.MatchesURL(
202       GURL("http://abc.\xe1\x80\xbf/a\xc2\x81\xe1xyz")));
203   EXPECT_TRUE(pattern.MatchesURL(
204       GURL("http://\xe1\x80\xbf/a\xc2\x81\xe1\xe1")));
205 }
206
207 // chrome://
208 TEST(ExtensionURLPatternTest, Match9) {
209   URLPattern pattern(kAllSchemes);
210   EXPECT_EQ(URLPattern::PARSE_SUCCESS, pattern.Parse("chrome://favicon/*"));
211   EXPECT_EQ("chrome", pattern.scheme());
212   EXPECT_EQ("favicon", pattern.host());
213   EXPECT_FALSE(pattern.match_subdomains());
214   EXPECT_FALSE(pattern.match_all_urls());
215   EXPECT_EQ("/*", pattern.path());
216   EXPECT_TRUE(pattern.MatchesURL(GURL("chrome://favicon/http://google.com")));
217   EXPECT_TRUE(pattern.MatchesURL(GURL("chrome://favicon/https://google.com")));
218   EXPECT_FALSE(pattern.MatchesURL(GURL("chrome://history")));
219 }
220
221 // *://
222 TEST(ExtensionURLPatternTest, Match10) {
223   URLPattern pattern(kAllSchemes);
224   EXPECT_EQ(URLPattern::PARSE_SUCCESS, pattern.Parse("*://*/*"));
225   EXPECT_TRUE(pattern.MatchesScheme("http"));
226   EXPECT_TRUE(pattern.MatchesScheme("https"));
227   EXPECT_FALSE(pattern.MatchesScheme("chrome"));
228   EXPECT_FALSE(pattern.MatchesScheme("file"));
229   EXPECT_FALSE(pattern.MatchesScheme("ftp"));
230   EXPECT_TRUE(pattern.match_subdomains());
231   EXPECT_FALSE(pattern.match_all_urls());
232   EXPECT_EQ("/*", pattern.path());
233   EXPECT_TRUE(pattern.MatchesURL(GURL("http://127.0.0.1")));
234   EXPECT_FALSE(pattern.MatchesURL(GURL("chrome://favicon/http://google.com")));
235   EXPECT_FALSE(pattern.MatchesURL(GURL("file:///foo/bar")));
236   EXPECT_FALSE(pattern.MatchesURL(GURL("file://localhost/foo/bar")));
237 }
238
239 // <all_urls>
240 TEST(ExtensionURLPatternTest, Match11) {
241   URLPattern pattern(kAllSchemes);
242   EXPECT_EQ(URLPattern::PARSE_SUCCESS, pattern.Parse("<all_urls>"));
243   EXPECT_TRUE(pattern.MatchesScheme("chrome"));
244   EXPECT_TRUE(pattern.MatchesScheme("http"));
245   EXPECT_TRUE(pattern.MatchesScheme("https"));
246   EXPECT_TRUE(pattern.MatchesScheme("file"));
247   EXPECT_TRUE(pattern.MatchesScheme("filesystem"));
248   EXPECT_TRUE(pattern.MatchesScheme("chrome-extension"));
249   EXPECT_TRUE(pattern.match_subdomains());
250   EXPECT_TRUE(pattern.match_all_urls());
251   EXPECT_EQ("/*", pattern.path());
252   EXPECT_TRUE(pattern.MatchesURL(GURL("chrome://favicon/http://google.com")));
253   EXPECT_TRUE(pattern.MatchesURL(GURL("http://127.0.0.1")));
254   EXPECT_TRUE(pattern.MatchesURL(GURL("file:///foo/bar")));
255   EXPECT_TRUE(pattern.MatchesURL(GURL("file://localhost/foo/bar")));
256
257   // Make sure the properties are the same when creating an <all_urls> pattern
258   // via SetMatchAllURLs and by parsing <all_urls>.
259   URLPattern pattern2(kAllSchemes);
260   pattern2.SetMatchAllURLs(true);
261
262   EXPECT_EQ(pattern.valid_schemes(), pattern2.valid_schemes());
263   EXPECT_EQ(pattern.match_subdomains(), pattern2.match_subdomains());
264   EXPECT_EQ(pattern.path(), pattern2.path());
265   EXPECT_EQ(pattern.match_all_urls(), pattern2.match_all_urls());
266   EXPECT_EQ(pattern.scheme(), pattern2.scheme());
267   EXPECT_EQ(pattern.port(), pattern2.port());
268   EXPECT_EQ(pattern.GetAsString(), pattern2.GetAsString());
269 }
270
271 // SCHEME_ALL matches all schemes.
272 TEST(ExtensionURLPatternTest, Match12) {
273   URLPattern pattern(URLPattern::SCHEME_ALL);
274   EXPECT_EQ(URLPattern::PARSE_SUCCESS, pattern.Parse("<all_urls>"));
275   EXPECT_TRUE(pattern.MatchesScheme("chrome"));
276   EXPECT_TRUE(pattern.MatchesScheme("http"));
277   EXPECT_TRUE(pattern.MatchesScheme("https"));
278   EXPECT_TRUE(pattern.MatchesScheme("file"));
279   EXPECT_TRUE(pattern.MatchesScheme("filesystem"));
280   EXPECT_TRUE(pattern.MatchesScheme("javascript"));
281   EXPECT_TRUE(pattern.MatchesScheme("data"));
282   EXPECT_TRUE(pattern.MatchesScheme("about"));
283   EXPECT_TRUE(pattern.MatchesScheme("chrome-extension"));
284   EXPECT_TRUE(pattern.match_subdomains());
285   EXPECT_TRUE(pattern.match_all_urls());
286   EXPECT_EQ("/*", pattern.path());
287   EXPECT_TRUE(pattern.MatchesURL(GURL("chrome://favicon/http://google.com")));
288   EXPECT_TRUE(pattern.MatchesURL(GURL("http://127.0.0.1")));
289   EXPECT_TRUE(pattern.MatchesURL(GURL("file:///foo/bar")));
290   EXPECT_TRUE(pattern.MatchesURL(GURL("file://localhost/foo/bar")));
291   EXPECT_TRUE(pattern.MatchesURL(GURL("chrome://newtab")));
292   EXPECT_TRUE(pattern.MatchesURL(GURL("about:blank")));
293   EXPECT_TRUE(pattern.MatchesURL(GURL("about:version")));
294   EXPECT_TRUE(pattern.MatchesURL(
295       GURL("data:text/html;charset=utf-8,<html>asdf</html>")));
296 }
297
298 static const struct MatchPatterns {
299   const char* pattern;
300   const char* matches;
301 } kMatch13UrlPatternTestCases[] = {
302   {"about:*", "about:blank"},
303   {"about:blank", "about:blank"},
304   {"about:*", "about:version"},
305   {"chrome-extension://*/*", "chrome-extension://FTW"},
306   {"data:*", "data:monkey"},
307   {"javascript:*", "javascript:atemyhomework"},
308 };
309
310 // SCHEME_ALL and specific schemes.
311 TEST(ExtensionURLPatternTest, Match13) {
312   for (size_t i = 0; i < arraysize(kMatch13UrlPatternTestCases); ++i) {
313     URLPattern pattern(URLPattern::SCHEME_ALL);
314     EXPECT_EQ(URLPattern::PARSE_SUCCESS,
315               pattern.Parse(kMatch13UrlPatternTestCases[i].pattern))
316         << " while parsing " << kMatch13UrlPatternTestCases[i].pattern;
317     EXPECT_TRUE(pattern.MatchesURL(
318         GURL(kMatch13UrlPatternTestCases[i].matches)))
319         << " while matching " << kMatch13UrlPatternTestCases[i].matches;
320   }
321
322   // Negative test.
323   URLPattern pattern(URLPattern::SCHEME_ALL);
324   EXPECT_EQ(URLPattern::PARSE_SUCCESS, pattern.Parse("data:*"));
325   EXPECT_FALSE(pattern.MatchesURL(GURL("about:blank")));
326 }
327
328 // file scheme with empty hostname
329 TEST(ExtensionURLPatternTest, Match14) {
330   URLPattern pattern(kAllSchemes);
331   EXPECT_EQ(URLPattern::PARSE_SUCCESS, pattern.Parse("file:///foo*"));
332   EXPECT_EQ("file", pattern.scheme());
333   EXPECT_EQ("", pattern.host());
334   EXPECT_FALSE(pattern.match_subdomains());
335   EXPECT_FALSE(pattern.match_all_urls());
336   EXPECT_EQ("/foo*", pattern.path());
337   EXPECT_FALSE(pattern.MatchesURL(GURL("file://foo")));
338   EXPECT_FALSE(pattern.MatchesURL(GURL("file://foobar")));
339   EXPECT_TRUE(pattern.MatchesURL(GURL("file:///foo")));
340   EXPECT_TRUE(pattern.MatchesURL(GURL("file:///foobar")));
341   EXPECT_TRUE(pattern.MatchesURL(GURL("file://localhost/foo")));
342 }
343
344 // file scheme without hostname part
345 TEST(ExtensionURLPatternTest, Match15) {
346   URLPattern pattern(kAllSchemes);
347   EXPECT_EQ(URLPattern::PARSE_SUCCESS, pattern.Parse("file://foo*"));
348   EXPECT_EQ("file", pattern.scheme());
349   EXPECT_EQ("", pattern.host());
350   EXPECT_FALSE(pattern.match_subdomains());
351   EXPECT_FALSE(pattern.match_all_urls());
352   EXPECT_EQ("/foo*", pattern.path());
353   EXPECT_FALSE(pattern.MatchesURL(GURL("file://foo")));
354   EXPECT_FALSE(pattern.MatchesURL(GURL("file://foobar")));
355   EXPECT_TRUE(pattern.MatchesURL(GURL("file:///foo")));
356   EXPECT_TRUE(pattern.MatchesURL(GURL("file:///foobar")));
357   EXPECT_TRUE(pattern.MatchesURL(GURL("file://localhost/foo")));
358 }
359
360 // file scheme with hostname
361 TEST(ExtensionURLPatternTest, Match16) {
362   URLPattern pattern(kAllSchemes);
363   EXPECT_EQ(URLPattern::PARSE_SUCCESS, pattern.Parse("file://localhost/foo*"));
364   EXPECT_EQ("file", pattern.scheme());
365   // Since hostname is ignored for file://.
366   EXPECT_EQ("", pattern.host());
367   EXPECT_FALSE(pattern.match_subdomains());
368   EXPECT_FALSE(pattern.match_all_urls());
369   EXPECT_EQ("/foo*", pattern.path());
370   EXPECT_FALSE(pattern.MatchesURL(GURL("file://foo")));
371   EXPECT_FALSE(pattern.MatchesURL(GURL("file://foobar")));
372   EXPECT_TRUE(pattern.MatchesURL(GURL("file:///foo")));
373   EXPECT_TRUE(pattern.MatchesURL(GURL("file:///foobar")));
374   EXPECT_TRUE(pattern.MatchesURL(GURL("file://localhost/foo")));
375 }
376
377 // Specific port
378 TEST(ExtensionURLPatternTest, Match17) {
379   URLPattern pattern(kAllSchemes);
380   EXPECT_EQ(URLPattern::PARSE_SUCCESS,
381             pattern.Parse("http://www.example.com:80/foo"));
382   EXPECT_EQ("http", pattern.scheme());
383   EXPECT_EQ("www.example.com", pattern.host());
384   EXPECT_FALSE(pattern.match_subdomains());
385   EXPECT_FALSE(pattern.match_all_urls());
386   EXPECT_EQ("/foo", pattern.path());
387   EXPECT_EQ("80", pattern.port());
388   EXPECT_TRUE(pattern.MatchesURL(GURL("http://www.example.com:80/foo")));
389   EXPECT_TRUE(pattern.MatchesURL(GURL("http://www.example.com/foo")));
390   EXPECT_FALSE(pattern.MatchesURL(GURL("http://www.example.com:8080/foo")));
391   EXPECT_FALSE(pattern.MatchesURL(
392       GURL("filesystem:http://www.example.com:8080/foo/")));
393   EXPECT_FALSE(pattern.MatchesURL(
394       GURL("filesystem:http://www.example.com/f/foo")));
395 }
396
397 // Explicit port wildcard
398 TEST(ExtensionURLPatternTest, Match18) {
399   URLPattern pattern(kAllSchemes);
400   EXPECT_EQ(URLPattern::PARSE_SUCCESS,
401             pattern.Parse("http://www.example.com:*/foo"));
402   EXPECT_EQ("http", pattern.scheme());
403   EXPECT_EQ("www.example.com", pattern.host());
404   EXPECT_FALSE(pattern.match_subdomains());
405   EXPECT_FALSE(pattern.match_all_urls());
406   EXPECT_EQ("/foo", pattern.path());
407   EXPECT_EQ("*", pattern.port());
408   EXPECT_TRUE(pattern.MatchesURL(GURL("http://www.example.com:80/foo")));
409   EXPECT_TRUE(pattern.MatchesURL(GURL("http://www.example.com/foo")));
410   EXPECT_TRUE(pattern.MatchesURL(GURL("http://www.example.com:8080/foo")));
411   EXPECT_FALSE(pattern.MatchesURL(
412       GURL("filesystem:http://www.example.com:8080/foo/")));
413 }
414
415 // chrome-extension://
416 TEST(ExtensionURLPatternTest, Match19) {
417   URLPattern pattern(URLPattern::SCHEME_EXTENSION);
418   EXPECT_EQ(URLPattern::PARSE_SUCCESS,
419             pattern.Parse("chrome-extension://ftw/*"));
420   EXPECT_EQ("chrome-extension", pattern.scheme());
421   EXPECT_EQ("ftw", pattern.host());
422   EXPECT_FALSE(pattern.match_subdomains());
423   EXPECT_FALSE(pattern.match_all_urls());
424   EXPECT_EQ("/*", pattern.path());
425   EXPECT_TRUE(pattern.MatchesURL(GURL("chrome-extension://ftw")));
426   EXPECT_TRUE(pattern.MatchesURL(
427       GURL("chrome-extension://ftw/http://google.com")));
428   EXPECT_TRUE(pattern.MatchesURL(
429       GURL("chrome-extension://ftw/https://google.com")));
430   EXPECT_FALSE(pattern.MatchesURL(GURL("chrome-extension://foobar")));
431   EXPECT_TRUE(pattern.MatchesURL(
432       GURL("filesystem:chrome-extension://ftw/t/file.txt")));
433 }
434
435 static const struct GetAsStringPatterns {
436   const char* pattern;
437 } kGetAsStringTestCases[] = {
438   { "http://www/" },
439   { "http://*/*" },
440   { "chrome://*/*" },
441   { "chrome://newtab/" },
442   { "about:*" },
443   { "about:blank" },
444   { "chrome-extension://*/*" },
445   { "chrome-extension://FTW/" },
446   { "data:*" },
447   { "data:monkey" },
448   { "javascript:*" },
449   { "javascript:atemyhomework" },
450   { "http://www.example.com:8080/foo" },
451 };
452
453 TEST(ExtensionURLPatternTest, GetAsString) {
454   for (size_t i = 0; i < arraysize(kGetAsStringTestCases); ++i) {
455     URLPattern pattern(URLPattern::SCHEME_ALL);
456     EXPECT_EQ(URLPattern::PARSE_SUCCESS,
457               pattern.Parse(kGetAsStringTestCases[i].pattern))
458         << "Error parsing " << kGetAsStringTestCases[i].pattern;
459     EXPECT_EQ(kGetAsStringTestCases[i].pattern,
460               pattern.GetAsString());
461   }
462 }
463
464 testing::AssertionResult Overlaps(const URLPattern& pattern1,
465                                   const URLPattern& pattern2) {
466   if (!pattern1.OverlapsWith(pattern2)) {
467     return testing::AssertionFailure()
468         << pattern1.GetAsString() << " does not overlap " <<
469                                      pattern2.GetAsString();
470   }
471   if (!pattern2.OverlapsWith(pattern1)) {
472     return testing::AssertionFailure()
473         << pattern2.GetAsString() << " does not overlap " <<
474                                      pattern1.GetAsString();
475   }
476   return testing::AssertionSuccess()
477       << pattern1.GetAsString() << " overlaps with " << pattern2.GetAsString();
478 }
479
480 TEST(ExtensionURLPatternTest, Overlaps) {
481   URLPattern pattern1(kAllSchemes, "http://www.google.com/foo/*");
482   URLPattern pattern2(kAllSchemes, "https://www.google.com/foo/*");
483   URLPattern pattern3(kAllSchemes, "http://*.google.com/foo/*");
484   URLPattern pattern4(kAllSchemes, "http://*.yahooo.com/foo/*");
485   URLPattern pattern5(kAllSchemes, "http://www.yahooo.com/bar/*");
486   URLPattern pattern6(kAllSchemes,
487                       "http://www.yahooo.com/bar/baz/*");
488   URLPattern pattern7(kAllSchemes, "file:///*");
489   URLPattern pattern8(kAllSchemes, "*://*/*");
490   URLPattern pattern9(URLPattern::SCHEME_HTTPS, "*://*/*");
491   URLPattern pattern10(kAllSchemes, "<all_urls>");
492
493   EXPECT_TRUE(Overlaps(pattern1, pattern1));
494   EXPECT_FALSE(Overlaps(pattern1, pattern2));
495   EXPECT_TRUE(Overlaps(pattern1, pattern3));
496   EXPECT_FALSE(Overlaps(pattern1, pattern4));
497   EXPECT_FALSE(Overlaps(pattern3, pattern4));
498   EXPECT_FALSE(Overlaps(pattern4, pattern5));
499   EXPECT_TRUE(Overlaps(pattern5, pattern6));
500
501   // Test that scheme restrictions work.
502   EXPECT_TRUE(Overlaps(pattern1, pattern8));
503   EXPECT_FALSE(Overlaps(pattern1, pattern9));
504   EXPECT_TRUE(Overlaps(pattern1, pattern10));
505
506   // Test that '<all_urls>' includes file URLs, while scheme '*' does not.
507   EXPECT_FALSE(Overlaps(pattern7, pattern8));
508   EXPECT_TRUE(Overlaps(pattern7, pattern10));
509
510   // Test that wildcard schemes are handled correctly, especially when compared
511   // to each-other.
512   URLPattern pattern11(kAllSchemes, "http://example.com/*");
513   URLPattern pattern12(kAllSchemes, "*://example.com/*");
514   URLPattern pattern13(kAllSchemes, "*://example.com/foo/*");
515   URLPattern pattern14(kAllSchemes, "*://google.com/*");
516   EXPECT_TRUE(Overlaps(pattern8, pattern12));
517   EXPECT_TRUE(Overlaps(pattern9, pattern12));
518   EXPECT_TRUE(Overlaps(pattern10, pattern12));
519   EXPECT_TRUE(Overlaps(pattern11, pattern12));
520   EXPECT_TRUE(Overlaps(pattern12, pattern13));
521   EXPECT_TRUE(Overlaps(pattern11, pattern13));
522   EXPECT_FALSE(Overlaps(pattern14, pattern12));
523   EXPECT_FALSE(Overlaps(pattern14, pattern13));
524 }
525
526 TEST(ExtensionURLPatternTest, ConvertToExplicitSchemes) {
527   URLPatternList all_urls(URLPattern(
528       kAllSchemes,
529       "<all_urls>").ConvertToExplicitSchemes());
530
531   URLPatternList all_schemes(URLPattern(
532       kAllSchemes,
533       "*://google.com/foo").ConvertToExplicitSchemes());
534
535   URLPatternList monkey(URLPattern(
536       URLPattern::SCHEME_HTTP | URLPattern::SCHEME_HTTPS |
537       URLPattern::SCHEME_FTP,
538       "http://google.com/monkey").ConvertToExplicitSchemes());
539
540   ASSERT_EQ(7u, all_urls.size());
541   ASSERT_EQ(2u, all_schemes.size());
542   ASSERT_EQ(1u, monkey.size());
543
544   EXPECT_EQ("http://*/*", all_urls[0].GetAsString());
545   EXPECT_EQ("https://*/*", all_urls[1].GetAsString());
546   EXPECT_EQ("file:///*", all_urls[2].GetAsString());
547   EXPECT_EQ("ftp://*/*", all_urls[3].GetAsString());
548   EXPECT_EQ("chrome://*/*", all_urls[4].GetAsString());
549
550   EXPECT_EQ("http://google.com/foo", all_schemes[0].GetAsString());
551   EXPECT_EQ("https://google.com/foo", all_schemes[1].GetAsString());
552
553   EXPECT_EQ("http://google.com/monkey", monkey[0].GetAsString());
554 }
555
556 TEST(ExtensionURLPatternTest, IgnorePorts) {
557   std::string pattern_str = "http://www.example.com:8080/foo";
558   GURL url("http://www.example.com:1234/foo");
559
560   URLPattern pattern(kAllSchemes);
561   EXPECT_EQ(URLPattern::PARSE_SUCCESS, pattern.Parse(pattern_str));
562
563   EXPECT_EQ(pattern_str, pattern.GetAsString());
564   EXPECT_FALSE(pattern.MatchesURL(url));
565 }
566
567 TEST(ExtensionURLPatternTest, IgnoreMissingBackslashes) {
568   std::string pattern_str1 = "http://www.example.com/example";
569   std::string pattern_str2 = "http://www.example.com/example/*";
570   GURL url1("http://www.example.com/example");
571   GURL url2("http://www.example.com/example/");
572
573   URLPattern pattern1(kAllSchemes);
574   EXPECT_EQ(URLPattern::PARSE_SUCCESS, pattern1.Parse(pattern_str1));
575   URLPattern pattern2(kAllSchemes);
576   EXPECT_EQ(URLPattern::PARSE_SUCCESS, pattern2.Parse(pattern_str2));
577
578   // Same patterns should match same urls.
579   EXPECT_TRUE(pattern1.MatchesURL(url1));
580   EXPECT_TRUE(pattern2.MatchesURL(url2));
581   // The not terminated path should match the terminated pattern.
582   EXPECT_TRUE(pattern2.MatchesURL(url1));
583   // The terminated path however should not match the unterminated pattern.
584   EXPECT_FALSE(pattern1.MatchesURL(url2));
585 }
586
587 TEST(ExtensionURLPatternTest, Equals) {
588   const struct {
589     const char* pattern1;
590     const char* pattern2;
591     bool expected_equal;
592   } kEqualsTestCases[] = {
593     // schemes
594     { "http://en.google.com/blah/*/foo",
595       "https://en.google.com/blah/*/foo",
596       false
597     },
598     { "https://en.google.com/blah/*/foo",
599       "https://en.google.com/blah/*/foo",
600       true
601     },
602     { "https://en.google.com/blah/*/foo",
603       "ftp://en.google.com/blah/*/foo",
604       false
605     },
606
607     // subdomains
608     { "https://en.google.com/blah/*/foo",
609       "https://fr.google.com/blah/*/foo",
610       false
611     },
612     { "https://www.google.com/blah/*/foo",
613       "https://*.google.com/blah/*/foo",
614       false
615     },
616     { "https://*.google.com/blah/*/foo",
617       "https://*.google.com/blah/*/foo",
618       true
619     },
620
621     // domains
622     { "http://en.example.com/blah/*/foo",
623       "http://en.google.com/blah/*/foo",
624       false
625     },
626
627     // ports
628     { "http://en.google.com:8000/blah/*/foo",
629       "http://en.google.com/blah/*/foo",
630       false
631     },
632     { "http://fr.google.com:8000/blah/*/foo",
633       "http://fr.google.com:8000/blah/*/foo",
634       true
635     },
636     { "http://en.google.com:8000/blah/*/foo",
637       "http://en.google.com:8080/blah/*/foo",
638       false
639     },
640
641     // paths
642     { "http://en.google.com/blah/*/foo",
643       "http://en.google.com/blah/*",
644       false
645     },
646     { "http://en.google.com/*",
647       "http://en.google.com/",
648       false
649     },
650     { "http://en.google.com/*",
651       "http://en.google.com/*",
652       true
653     },
654
655     // all_urls
656     { "<all_urls>",
657       "<all_urls>",
658       true
659     },
660     { "<all_urls>",
661       "http://*/*",
662       false
663     }
664   };
665
666   for (size_t i = 0; i < arraysize(kEqualsTestCases); ++i) {
667     std::string message = kEqualsTestCases[i].pattern1;
668     message += " ";
669     message += kEqualsTestCases[i].pattern2;
670
671     URLPattern pattern1(URLPattern::SCHEME_ALL);
672     URLPattern pattern2(URLPattern::SCHEME_ALL);
673
674     pattern1.Parse(kEqualsTestCases[i].pattern1);
675     pattern2.Parse(kEqualsTestCases[i].pattern2);
676     EXPECT_EQ(kEqualsTestCases[i].expected_equal, pattern1 == pattern2)
677         << message;
678   }
679 }
680
681 TEST(ExtensionURLPatternTest, CanReusePatternWithParse) {
682   URLPattern pattern1(URLPattern::SCHEME_ALL);
683   EXPECT_EQ(URLPattern::PARSE_SUCCESS, pattern1.Parse("http://aa.com/*"));
684   EXPECT_EQ(URLPattern::PARSE_SUCCESS, pattern1.Parse("http://bb.com/*"));
685
686   EXPECT_TRUE(pattern1.MatchesURL(GURL("http://bb.com/path")));
687   EXPECT_FALSE(pattern1.MatchesURL(GURL("http://aa.com/path")));
688
689   URLPattern pattern2(URLPattern::SCHEME_ALL, URLPattern::kAllUrlsPattern);
690   EXPECT_EQ(URLPattern::PARSE_SUCCESS, pattern2.Parse("http://aa.com/*"));
691
692   EXPECT_FALSE(pattern2.MatchesURL(GURL("http://bb.com/path")));
693   EXPECT_TRUE(pattern2.MatchesURL(GURL("http://aa.com/path")));
694   EXPECT_FALSE(pattern2.MatchesURL(GURL("http://sub.aa.com/path")));
695
696   URLPattern pattern3(URLPattern::SCHEME_ALL, "http://aa.com/*");
697   EXPECT_EQ(URLPattern::PARSE_SUCCESS, pattern3.Parse("http://aa.com:88/*"));
698   EXPECT_FALSE(pattern3.MatchesURL(GURL("http://aa.com/path")));
699   EXPECT_TRUE(pattern3.MatchesURL(GURL("http://aa.com:88/path")));
700 }
701
702 // Returns success if neither |a| nor |b| encompasses the other.
703 testing::AssertionResult NeitherContains(const URLPattern& a,
704                                          const URLPattern& b) {
705   if (a.Contains(b))
706     return testing::AssertionFailure() << a.GetAsString() << " encompasses " <<
707                                           b.GetAsString();
708   if (b.Contains(a))
709     return testing::AssertionFailure() << b.GetAsString() << " encompasses " <<
710                                           a.GetAsString();
711   return testing::AssertionSuccess() <<
712       "Neither " << a.GetAsString() << " nor " << b.GetAsString() <<
713       " encompass the other";
714 }
715
716 // Returns success if |a| encompasses |b| but not the other way around.
717 testing::AssertionResult StrictlyContains(const URLPattern& a,
718                                           const URLPattern& b) {
719   if (!a.Contains(b))
720     return testing::AssertionFailure() << a.GetAsString() <<
721                                           " does not encompass " <<
722                                           b.GetAsString();
723   if (b.Contains(a))
724     return testing::AssertionFailure() << b.GetAsString() << " encompasses " <<
725                                           a.GetAsString();
726   return testing::AssertionSuccess() << a.GetAsString() <<
727                                         " strictly encompasses " <<
728                                         b.GetAsString();
729 }
730
731 TEST(ExtensionURLPatternTest, Subset) {
732   URLPattern pattern1(kAllSchemes, "http://www.google.com/foo/*");
733   URLPattern pattern2(kAllSchemes, "https://www.google.com/foo/*");
734   URLPattern pattern3(kAllSchemes, "http://*.google.com/foo/*");
735   URLPattern pattern4(kAllSchemes, "http://*.yahooo.com/foo/*");
736   URLPattern pattern5(kAllSchemes, "http://www.yahooo.com/bar/*");
737   URLPattern pattern6(kAllSchemes, "http://www.yahooo.com/bar/baz/*");
738   URLPattern pattern7(kAllSchemes, "file:///*");
739   URLPattern pattern8(kAllSchemes, "*://*/*");
740   URLPattern pattern9(URLPattern::SCHEME_HTTPS, "*://*/*");
741   URLPattern pattern10(kAllSchemes, "<all_urls>");
742   URLPattern pattern11(kAllSchemes, "http://example.com/*");
743   URLPattern pattern12(kAllSchemes, "*://example.com/*");
744   URLPattern pattern13(kAllSchemes, "*://example.com/foo/*");
745
746   // All patterns should encompass themselves.
747   EXPECT_TRUE(pattern1.Contains(pattern1));
748   EXPECT_TRUE(pattern2.Contains(pattern2));
749   EXPECT_TRUE(pattern3.Contains(pattern3));
750   EXPECT_TRUE(pattern4.Contains(pattern4));
751   EXPECT_TRUE(pattern5.Contains(pattern5));
752   EXPECT_TRUE(pattern6.Contains(pattern6));
753   EXPECT_TRUE(pattern7.Contains(pattern7));
754   EXPECT_TRUE(pattern8.Contains(pattern8));
755   EXPECT_TRUE(pattern9.Contains(pattern9));
756   EXPECT_TRUE(pattern10.Contains(pattern10));
757   EXPECT_TRUE(pattern11.Contains(pattern11));
758   EXPECT_TRUE(pattern12.Contains(pattern12));
759   EXPECT_TRUE(pattern13.Contains(pattern13));
760
761   // pattern1's relationship to the other patterns.
762   EXPECT_TRUE(NeitherContains(pattern1, pattern2));
763   EXPECT_TRUE(StrictlyContains(pattern3, pattern1));
764   EXPECT_TRUE(NeitherContains(pattern1, pattern4));
765   EXPECT_TRUE(NeitherContains(pattern1, pattern5));
766   EXPECT_TRUE(NeitherContains(pattern1, pattern6));
767   EXPECT_TRUE(NeitherContains(pattern1, pattern7));
768   EXPECT_TRUE(StrictlyContains(pattern8, pattern1));
769   EXPECT_TRUE(NeitherContains(pattern1, pattern9));
770   EXPECT_TRUE(StrictlyContains(pattern10, pattern1));
771   EXPECT_TRUE(NeitherContains(pattern1, pattern11));
772   EXPECT_TRUE(NeitherContains(pattern1, pattern12));
773   EXPECT_TRUE(NeitherContains(pattern1, pattern13));
774
775   // pattern2's relationship to the other patterns.
776   EXPECT_TRUE(NeitherContains(pattern2, pattern3));
777   EXPECT_TRUE(NeitherContains(pattern2, pattern4));
778   EXPECT_TRUE(NeitherContains(pattern2, pattern5));
779   EXPECT_TRUE(NeitherContains(pattern2, pattern6));
780   EXPECT_TRUE(NeitherContains(pattern2, pattern7));
781   EXPECT_TRUE(StrictlyContains(pattern8, pattern2));
782   EXPECT_TRUE(StrictlyContains(pattern9, pattern2));
783   EXPECT_TRUE(StrictlyContains(pattern10, pattern2));
784   EXPECT_TRUE(NeitherContains(pattern2, pattern11));
785   EXPECT_TRUE(NeitherContains(pattern2, pattern12));
786   EXPECT_TRUE(NeitherContains(pattern2, pattern13));
787
788   // Specifically test file:// URLs.
789   EXPECT_TRUE(NeitherContains(pattern7, pattern8));
790   EXPECT_TRUE(NeitherContains(pattern7, pattern9));
791   EXPECT_TRUE(StrictlyContains(pattern10, pattern7));
792
793   // <all_urls> encompasses everything.
794   EXPECT_TRUE(StrictlyContains(pattern10, pattern1));
795   EXPECT_TRUE(StrictlyContains(pattern10, pattern2));
796   EXPECT_TRUE(StrictlyContains(pattern10, pattern3));
797   EXPECT_TRUE(StrictlyContains(pattern10, pattern4));
798   EXPECT_TRUE(StrictlyContains(pattern10, pattern5));
799   EXPECT_TRUE(StrictlyContains(pattern10, pattern6));
800   EXPECT_TRUE(StrictlyContains(pattern10, pattern7));
801   EXPECT_TRUE(StrictlyContains(pattern10, pattern8));
802   EXPECT_TRUE(StrictlyContains(pattern10, pattern9));
803   EXPECT_TRUE(StrictlyContains(pattern10, pattern11));
804   EXPECT_TRUE(StrictlyContains(pattern10, pattern12));
805   EXPECT_TRUE(StrictlyContains(pattern10, pattern13));
806
807   // More...
808   EXPECT_TRUE(StrictlyContains(pattern12, pattern11));
809   EXPECT_TRUE(NeitherContains(pattern11, pattern13));
810   EXPECT_TRUE(StrictlyContains(pattern12, pattern13));
811 }
812
813 TEST(ExtensionURLPatternTest, MatchesSingleOrigin) {
814   EXPECT_FALSE(
815       URLPattern(URLPattern::SCHEME_ALL, "http://*/").MatchesSingleOrigin());
816   EXPECT_FALSE(URLPattern(URLPattern::SCHEME_ALL, "https://*.google.com/*")
817                    .MatchesSingleOrigin());
818   EXPECT_TRUE(URLPattern(URLPattern::SCHEME_ALL, "http://google.com/")
819                   .MatchesSingleOrigin());
820   EXPECT_TRUE(URLPattern(URLPattern::SCHEME_ALL, "http://google.com/*")
821                   .MatchesSingleOrigin());
822   EXPECT_TRUE(URLPattern(URLPattern::SCHEME_ALL, "http://www.google.com/")
823                   .MatchesSingleOrigin());
824   EXPECT_FALSE(URLPattern(URLPattern::SCHEME_ALL, "*://www.google.com/")
825                    .MatchesSingleOrigin());
826   EXPECT_FALSE(URLPattern(URLPattern::SCHEME_ALL, "http://*.com/")
827                    .MatchesSingleOrigin());
828   EXPECT_FALSE(URLPattern(URLPattern::SCHEME_ALL, "http://*.google.com/foo/bar")
829                    .MatchesSingleOrigin());
830   EXPECT_TRUE(
831       URLPattern(URLPattern::SCHEME_ALL, "http://www.google.com/foo/bar")
832           .MatchesSingleOrigin());
833   EXPECT_FALSE(URLPattern(URLPattern::SCHEME_HTTPS, "*://*.google.com/foo/bar")
834                    .MatchesSingleOrigin());
835   EXPECT_TRUE(URLPattern(URLPattern::SCHEME_HTTPS, "https://www.google.com/")
836                   .MatchesSingleOrigin());
837   EXPECT_FALSE(URLPattern(URLPattern::SCHEME_HTTP,
838                           "http://*.google.com/foo/bar").MatchesSingleOrigin());
839   EXPECT_TRUE(
840       URLPattern(URLPattern::SCHEME_HTTP, "http://www.google.com/foo/bar")
841           .MatchesSingleOrigin());
842 }
843
844 }  // namespace