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