Index: extensions/common/url_pattern.cc |
diff --git a/extensions/common/url_pattern.cc b/extensions/common/url_pattern.cc |
index 5677fbc8367682015aea8baff570c266e0815fc9..dba84a529cae21c7b2dd9d0303fd45ad458498ce 100644 |
--- a/extensions/common/url_pattern.cc |
+++ b/extensions/common/url_pattern.cc |
@@ -141,12 +141,14 @@ URLPattern::URLPattern() |
: valid_schemes_(SCHEME_NONE), |
match_all_urls_(false), |
match_subdomains_(false), |
+ match_effective_tld_(true), |
port_("*") {} |
URLPattern::URLPattern(int valid_schemes) |
: valid_schemes_(valid_schemes), |
match_all_urls_(false), |
match_subdomains_(false), |
+ match_effective_tld_(true), |
port_("*") {} |
URLPattern::URLPattern(int valid_schemes, base::StringPiece pattern) |
@@ -155,6 +157,7 @@ URLPattern::URLPattern(int valid_schemes, base::StringPiece pattern) |
: valid_schemes_(valid_schemes), |
match_all_urls_(false), |
match_subdomains_(false), |
+ match_effective_tld_(true), |
port_("*") { |
ParseResult result = Parse(pattern); |
if (PARSE_SUCCESS != result) |
@@ -183,9 +186,15 @@ std::ostream& operator<<(std::ostream& out, const URLPattern& url_pattern) { |
} |
URLPattern::ParseResult URLPattern::Parse(base::StringPiece pattern) { |
+ return Parse(pattern, DENY_WILDCARD_FOR_EFFECTIVE_TLD); |
+} |
+ |
+URLPattern::ParseResult URLPattern::Parse(base::StringPiece pattern, |
+ ParseOptions parse_options) { |
spec_.clear(); |
SetMatchAllURLs(false); |
SetMatchSubdomains(false); |
+ SetMatchEffectiveTld(true); |
SetPort("*"); |
// Special case pattern to match every valid URL. |
@@ -267,6 +276,14 @@ URLPattern::ParseResult URLPattern::Parse(base::StringPiece pattern) { |
host_components.erase(host_components.begin(), |
host_components.begin() + 1); |
} |
+ |
+ // If explicitly allowed, the last component can optionally be '*' to |
+ // match all effective TLDs. |
+ if (parse_options == ALLOW_WILDCARD_FOR_EFFECTIVE_TLD && |
+ host_components.size() > 1 && host_components.back() == "*") { |
+ match_effective_tld_ = false; |
+ host_components.pop_back(); |
+ } |
host_ = base::JoinString(host_components, "."); |
path_start_pos = host_end_pos; |
@@ -321,6 +338,11 @@ void URLPattern::SetMatchSubdomains(bool val) { |
match_subdomains_ = val; |
} |
+void URLPattern::SetMatchEffectiveTld(bool val) { |
+ spec_.clear(); |
+ match_effective_tld_ = val; |
+} |
+ |
bool URLPattern::SetScheme(base::StringPiece scheme) { |
spec_.clear(); |
scheme.CopyToString(&scheme_); |
@@ -421,10 +443,19 @@ bool URLPattern::MatchesHost(base::StringPiece host) const { |
} |
bool URLPattern::MatchesHost(const GURL& test) const { |
- const base::StringPiece test_host( |
- CanonicalizeHostForMatching(test.host_piece())); |
+ base::StringPiece test_host(CanonicalizeHostForMatching(test.host_piece())); |
const base::StringPiece pattern_host(CanonicalizeHostForMatching(host_)); |
+ // If we don't care about matching the effective TLD, remove it. |
+ if (!match_effective_tld_) { |
+ int reg_length = net::registry_controlled_domains::GetRegistryLength( |
+ test, net::registry_controlled_domains::EXCLUDE_UNKNOWN_REGISTRIES, |
+ net::registry_controlled_domains::EXCLUDE_PRIVATE_REGISTRIES); |
+ if (reg_length > 0) { |
+ test_host = test_host.substr(0, test_host.size() - reg_length - 1); |
+ } |
+ } |
+ |
// If the hosts are exactly equal, we have a match. |
if (test_host == pattern_host) |
return true; |
@@ -529,6 +560,12 @@ const std::string& URLPattern::GetAsString() const { |
if (!host_.empty()) |
spec += host_; |
+ if (!match_effective_tld_) { |
+ if (!host_.empty()) |
+ spec += "."; |
+ spec += "*"; |
+ } |
+ |
if (port_ != "*") { |
spec += ":"; |
spec += port_; |