OLD | NEW |
1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. | 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 | 2 // Use of this source code is governed by a BSD-style license that can be |
3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
4 | 4 |
5 #include "extensions/common/url_pattern.h" | 5 #include "extensions/common/url_pattern.h" |
6 | 6 |
7 #include "base/string_number_conversions.h" | 7 #include "base/string_number_conversions.h" |
8 #include "base/string_piece.h" | 8 #include "base/string_piece.h" |
9 #include "base/string_split.h" | 9 #include "base/string_split.h" |
10 #include "base/string_util.h" | 10 #include "base/string_util.h" |
(...skipping 75 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
86 url_parse::PORT_UNSPECIFIED) { | 86 url_parse::PORT_UNSPECIFIED) { |
87 return false; | 87 return false; |
88 } | 88 } |
89 | 89 |
90 int parsed_port = url_parse::PORT_UNSPECIFIED; | 90 int parsed_port = url_parse::PORT_UNSPECIFIED; |
91 if (!base::StringToInt(port, &parsed_port)) | 91 if (!base::StringToInt(port, &parsed_port)) |
92 return false; | 92 return false; |
93 return (parsed_port >= 0) && (parsed_port < 65536); | 93 return (parsed_port >= 0) && (parsed_port < 65536); |
94 } | 94 } |
95 | 95 |
| 96 // Returns |path| with the trailing wildcard stripped if one existed. |
| 97 // |
| 98 // The functions that rely on this (OverlapsWith and Contains) are only |
| 99 // called for the patterns inside URLPatternSet. In those cases, we know that |
| 100 // the path will have only a single wildcard at the end. This makes figuring |
| 101 // out overlap much easier. It seems like there is probably a computer-sciency |
| 102 // way to solve the general case, but we don't need that yet. |
| 103 std::string StripTrailingWildcard(const std::string& path) { |
| 104 size_t wildcard_index = path.find('*'); |
| 105 size_t path_last = path.size() - 1; |
| 106 DCHECK(wildcard_index == std::string::npos || wildcard_index == path_last); |
| 107 return wildcard_index == path_last ? path.substr(0, path_last) : path; |
| 108 } |
| 109 |
96 } // namespace | 110 } // namespace |
97 | 111 |
98 URLPattern::URLPattern() | 112 URLPattern::URLPattern() |
99 : valid_schemes_(SCHEME_NONE), | 113 : valid_schemes_(SCHEME_NONE), |
100 match_all_urls_(false), | 114 match_all_urls_(false), |
101 match_subdomains_(false), | 115 match_subdomains_(false), |
102 port_("*") {} | 116 port_("*") {} |
103 | 117 |
104 URLPattern::URLPattern(int valid_schemes) | 118 URLPattern::URLPattern(int valid_schemes) |
105 : valid_schemes_(valid_schemes), | 119 : valid_schemes_(valid_schemes), |
(...skipping 278 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
384 return test.host()[test.host().length() - host_.length() - 1] == '.'; | 398 return test.host()[test.host().length() - host_.length() - 1] == '.'; |
385 } | 399 } |
386 | 400 |
387 bool URLPattern::MatchesPath(const std::string& test) const { | 401 bool URLPattern::MatchesPath(const std::string& test) const { |
388 if (!MatchPattern(test, path_escaped_)) | 402 if (!MatchPattern(test, path_escaped_)) |
389 return false; | 403 return false; |
390 | 404 |
391 return true; | 405 return true; |
392 } | 406 } |
393 | 407 |
394 bool URLPattern::MatchesPort(int port) const { | |
395 if (port == url_parse::PORT_INVALID) | |
396 return false; | |
397 | |
398 return port_ == "*" || port_ == base::IntToString(port); | |
399 } | |
400 | |
401 | |
402 const std::string& URLPattern::GetAsString() const { | 408 const std::string& URLPattern::GetAsString() const { |
403 if (!spec_.empty()) | 409 if (!spec_.empty()) |
404 return spec_; | 410 return spec_; |
405 | 411 |
406 if (match_all_urls_) { | 412 if (match_all_urls_) { |
407 spec_ = kAllUrlsPattern; | 413 spec_ = kAllUrlsPattern; |
408 return spec_; | 414 return spec_; |
409 } | 415 } |
410 | 416 |
411 bool standard_scheme = IsStandardScheme(scheme_); | 417 bool standard_scheme = IsStandardScheme(scheme_); |
(...skipping 18 matching lines...) Expand all Loading... |
430 } | 436 } |
431 | 437 |
432 if (!path_.empty()) | 438 if (!path_.empty()) |
433 spec += path_; | 439 spec += path_; |
434 | 440 |
435 spec_ = spec; | 441 spec_ = spec; |
436 return spec_; | 442 return spec_; |
437 } | 443 } |
438 | 444 |
439 bool URLPattern::OverlapsWith(const URLPattern& other) const { | 445 bool URLPattern::OverlapsWith(const URLPattern& other) const { |
440 if (!MatchesAnyScheme(other.GetExplicitSchemes()) && | 446 if (match_all_urls() || other.match_all_urls()) |
441 !other.MatchesAnyScheme(GetExplicitSchemes())) { | 447 return true; |
442 return false; | 448 return (MatchesAnyScheme(other.GetExplicitSchemes()) || |
443 } | 449 other.MatchesAnyScheme(GetExplicitSchemes())) |
| 450 && (MatchesHost(other.host()) || other.MatchesHost(host())) |
| 451 && (MatchesPortPattern(other.port()) || other.MatchesPortPattern(port())) |
| 452 && (MatchesPath(StripTrailingWildcard(other.path())) || |
| 453 other.MatchesPath(StripTrailingWildcard(path()))); |
| 454 } |
444 | 455 |
445 if (!MatchesHost(other.host()) && !other.MatchesHost(host_)) | 456 bool URLPattern::Contains(const URLPattern& other) const { |
446 return false; | 457 if (match_all_urls()) |
447 | 458 return true; |
448 if (port_ != "*" && other.port() != "*" && port_ != other.port()) | 459 return MatchesAllSchemes(other.GetExplicitSchemes()) |
449 return false; | 460 && MatchesHost(other.host()) |
450 | 461 && MatchesPortPattern(other.port()) |
451 // We currently only use OverlapsWith() for the patterns inside | 462 && MatchesPath(StripTrailingWildcard(other.path())); |
452 // URLPatternSet. In those cases, we know that the path will have only a | |
453 // single wildcard at the end. This makes figuring out overlap much easier. It | |
454 // seems like there is probably a computer-sciency way to solve the general | |
455 // case, but we don't need that yet. | |
456 DCHECK(path_.find('*') == path_.size() - 1); | |
457 DCHECK(other.path().find('*') == other.path().size() - 1); | |
458 | |
459 if (!MatchesPath(other.path().substr(0, other.path().size() - 1)) && | |
460 !other.MatchesPath(path_.substr(0, path_.size() - 1))) | |
461 return false; | |
462 | |
463 return true; | |
464 } | 463 } |
465 | 464 |
466 bool URLPattern::MatchesAnyScheme( | 465 bool URLPattern::MatchesAnyScheme( |
467 const std::vector<std::string>& schemes) const { | 466 const std::vector<std::string>& schemes) const { |
468 for (std::vector<std::string>::const_iterator i = schemes.begin(); | 467 for (std::vector<std::string>::const_iterator i = schemes.begin(); |
469 i != schemes.end(); ++i) { | 468 i != schemes.end(); ++i) { |
470 if (MatchesScheme(*i)) | 469 if (MatchesScheme(*i)) |
471 return true; | 470 return true; |
472 } | 471 } |
473 | 472 |
474 return false; | 473 return false; |
475 } | 474 } |
476 | 475 |
| 476 bool URLPattern::MatchesAllSchemes( |
| 477 const std::vector<std::string>& schemes) const { |
| 478 for (std::vector<std::string>::const_iterator i = schemes.begin(); |
| 479 i != schemes.end(); ++i) { |
| 480 if (!MatchesScheme(*i)) |
| 481 return false; |
| 482 } |
| 483 |
| 484 return true; |
| 485 } |
| 486 |
477 bool URLPattern::MatchesSecurityOriginHelper(const GURL& test) const { | 487 bool URLPattern::MatchesSecurityOriginHelper(const GURL& test) const { |
478 // Ignore hostname if scheme is file://. | 488 // Ignore hostname if scheme is file://. |
479 if (scheme_ != chrome::kFileScheme && !MatchesHost(test)) | 489 if (scheme_ != chrome::kFileScheme && !MatchesHost(test)) |
480 return false; | 490 return false; |
481 | 491 |
482 if (!MatchesPort(test.EffectiveIntPort())) | 492 if (!MatchesPortPattern(base::IntToString(test.EffectiveIntPort()))) |
483 return false; | 493 return false; |
484 | 494 |
485 return true; | 495 return true; |
486 } | 496 } |
487 | 497 |
| 498 bool URLPattern::MatchesPortPattern(const std::string& port) const { |
| 499 return port_ == "*" || port_ == port; |
| 500 } |
| 501 |
488 std::vector<std::string> URLPattern::GetExplicitSchemes() const { | 502 std::vector<std::string> URLPattern::GetExplicitSchemes() const { |
489 std::vector<std::string> result; | 503 std::vector<std::string> result; |
490 | 504 |
491 if (scheme_ != "*" && !match_all_urls_ && IsValidScheme(scheme_)) { | 505 if (scheme_ != "*" && !match_all_urls_ && IsValidScheme(scheme_)) { |
492 result.push_back(scheme_); | 506 result.push_back(scheme_); |
493 return result; | 507 return result; |
494 } | 508 } |
495 | 509 |
496 for (size_t i = 0; i < arraysize(kValidSchemes); ++i) { | 510 for (size_t i = 0; i < arraysize(kValidSchemes); ++i) { |
497 if (MatchesScheme(kValidSchemes[i])) { | 511 if (MatchesScheme(kValidSchemes[i])) { |
(...skipping 17 matching lines...) Expand all Loading... |
515 } | 529 } |
516 | 530 |
517 return result; | 531 return result; |
518 } | 532 } |
519 | 533 |
520 // static | 534 // static |
521 const char* URLPattern::GetParseResultString( | 535 const char* URLPattern::GetParseResultString( |
522 URLPattern::ParseResult parse_result) { | 536 URLPattern::ParseResult parse_result) { |
523 return kParseResultMessages[parse_result]; | 537 return kParseResultMessages[parse_result]; |
524 } | 538 } |
OLD | NEW |