diff options
author | markusheintz@chromium.org <markusheintz@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2011-05-19 14:38:28 +0000 |
---|---|---|
committer | markusheintz@chromium.org <markusheintz@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2011-05-19 14:38:28 +0000 |
commit | e8491289e4313d396ea9e1522209c1305d60a227 (patch) | |
tree | 4ca2b7eeb5e19ed0097a16bb4f3d1492c25ab4e5 | |
parent | 65cc854b7dd673ba413da7364d5b0b3eb25da405 (diff) | |
download | chromium_src-e8491289e4313d396ea9e1522209c1305d60a227.zip chromium_src-e8491289e4313d396ea9e1522209c1305d60a227.tar.gz chromium_src-e8491289e4313d396ea9e1522209c1305d60a227.tar.bz2 |
Enable ContentSettingsPattern to match origins.
BUG=83200
TEST=content_settings_pattern_unittests.cc, content_settings_pattern_parser_unittests.cc
Review URL: http://codereview.chromium.org/6820039
git-svn-id: svn://svn.chromium.org/chrome/trunk/src@85909 0039d316-1c4b-4281-b951-d872f2087c98
24 files changed, 1599 insertions, 213 deletions
diff --git a/chrome/browser/automation/testing_automation_provider.cc b/chrome/browser/automation/testing_automation_provider.cc index 11b9063..574b54b 100644 --- a/chrome/browser/automation/testing_automation_provider.cc +++ b/chrome/browser/automation/testing_automation_provider.cc @@ -5825,7 +5825,7 @@ void TestingAutomationProvider::SetContentSetting( if (host.empty()) { map->SetDefaultContentSetting(content_type, setting); } else { - map->SetContentSetting(ContentSettingsPattern(host), + map->SetContentSetting(ContentSettingsPattern::FromString(host), content_type, "", setting); } *success = true; diff --git a/chrome/browser/content_settings/content_settings_base_provider.cc b/chrome/browser/content_settings/content_settings_base_provider.cc index a956035..d76cc7b 100644 --- a/chrome/browser/content_settings/content_settings_base_provider.cc +++ b/chrome/browser/content_settings/content_settings_base_provider.cc @@ -168,9 +168,10 @@ void BaseProvider::GetAllContentSettingsRules( if (setting != CONTENT_SETTING_DEFAULT) { // Use of push_back() relies on the map iterator traversing in order of // ascending keys. - content_setting_rules->push_back(Rule(ContentSettingsPattern(i->first), - ContentSettingsPattern(i->first), - setting)); + content_setting_rules->push_back( + Rule(ContentSettingsPattern::FromString(i->first), + ContentSettingsPattern::FromString(i->first), + setting)); } } } @@ -233,10 +234,9 @@ void BaseProvider::UpdateContentSettingsMap( ContentSettingsType content_type, const ResourceIdentifier& resource_identifier, ContentSetting content_setting) { - std::string pattern_str(requesting_pattern.CanonicalizePattern()); HostContentSettings* content_settings_map = host_content_settings(); ExtendedContentSettings& extended_settings = - (*content_settings_map)[pattern_str]; + (*content_settings_map)[requesting_pattern.ToString()]; extended_settings.content_settings.settings[content_type] = content_setting; } diff --git a/chrome/browser/content_settings/content_settings_details.h b/chrome/browser/content_settings/content_settings_details.h index 51c54314c..857a82a 100644 --- a/chrome/browser/content_settings/content_settings_details.h +++ b/chrome/browser/content_settings/content_settings_details.h @@ -1,4 +1,4 @@ -// Copyright (c) 2010 The Chromium Authors. All rights reserved. +// Copyright (c) 2011 The Chromium Authors. All rights reserved. // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. @@ -31,7 +31,7 @@ class ContentSettingsDetails { const ContentSettingsPattern& pattern() const { return pattern_; } // True if all settings should be updated for the given type. - bool update_all() const { return pattern_.AsString().empty(); } + bool update_all() const { return pattern_.ToString().empty(); } // The type of the pattern whose settings have changed. ContentSettingsType type() const { return type_; } diff --git a/chrome/browser/content_settings/content_settings_notification_provider.cc b/chrome/browser/content_settings/content_settings_notification_provider.cc index 7d7a0e3..dcedd99 100644 --- a/chrome/browser/content_settings/content_settings_notification_provider.cc +++ b/chrome/browser/content_settings/content_settings_notification_provider.cc @@ -52,32 +52,20 @@ ContentSettingsPattern NotificationProvider::ToContentSettingsPattern( if (origin.spec().empty()) { std::string pattern_spec(chrome::kFileScheme); pattern_spec += chrome::kStandardSchemeSeparator; - return ContentSettingsPattern(pattern_spec); + return ContentSettingsPattern::FromString(pattern_spec); } return ContentSettingsPattern::FromURLNoWildcard(origin); } // static GURL NotificationProvider::ToGURL(const ContentSettingsPattern& pattern) { - std::string pattern_spec(pattern.AsString()); - - if (pattern_spec.empty() || - StartsWithASCII(pattern_spec, - std::string(ContentSettingsPattern::kDomainWildcard), - true)) { + std::string pattern_spec(pattern.ToString()); + if (!pattern.IsValid() || + (pattern_spec.find(std::string( + ContentSettingsPattern::kDomainWildcard)) != std::string::npos)) { NOTREACHED(); } - - std::string url_spec(""); - if (StartsWithASCII(pattern_spec, std::string(chrome::kFileScheme), false)) { - url_spec += pattern_spec; - } else if (!pattern.scheme().empty()) { - url_spec += pattern.scheme(); - url_spec += chrome::kStandardSchemeSeparator; - url_spec += pattern_spec; - } - - return GURL(url_spec); + return GURL(pattern_spec); } NotificationProvider::NotificationProvider( diff --git a/chrome/browser/content_settings/content_settings_pattern.cc b/chrome/browser/content_settings/content_settings_pattern.cc index 8a52a1d..d47eb5f 100644 --- a/chrome/browser/content_settings/content_settings_pattern.cc +++ b/chrome/browser/content_settings/content_settings_pattern.cc @@ -5,6 +5,8 @@ #include "chrome/browser/content_settings/content_settings_pattern.h" #include "base/string_util.h" +#include "base/scoped_ptr.h" +#include "chrome/browser/content_settings/content_settings_pattern_parser.h" #include "chrome/common/url_constants.h" #include "net/base/net_util.h" #include "googleurl/src/gurl.h" @@ -12,15 +14,138 @@ namespace { -bool IsValidHostlessPattern(const std::string& pattern) { - std::string file_scheme_plus_separator(chrome::kFileScheme); - file_scheme_plus_separator += chrome::kStandardSchemeSeparator; +std::string GetDefaultPort(const std::string& scheme) { + if (scheme == chrome::kHttpScheme) + return "80"; + if (scheme == chrome::kHttpsScheme) + return "443"; + return ""; +} - return StartsWithASCII(pattern, file_scheme_plus_separator, false); +// Returns true if |sub_domain| is a sub domain or equls |domain|. E.g. +// "mail.google.com" is a sub domain of "google.com" but "evilhost.com" is not a +// subdomain of "host.com". +bool IsSubDomainOrEqual(const std::string sub_domain, + const std::string domain) { + // The empty string serves as wildcard. Each domain is a subdomain of the + // wildcard. + if (domain.empty()) + return true; + const size_t match = sub_domain.rfind(domain); + if (match == std::string::npos || + (match > 0 && sub_domain[match - 1] != '.') || + (match + domain.length() != sub_domain.length())) { + return false; + } + return true; } +typedef ContentSettingsPattern::BuilderInterface BuilderInterface; + } // namespace +// //////////////////////////////////////////////////////////////////////////// +// ContentSettingsPattern::Builder +// + +ContentSettingsPattern::Builder::Builder() : invalid_(false) {} + +ContentSettingsPattern::Builder::~Builder() {} + +BuilderInterface* ContentSettingsPattern::Builder::WithPort( + const std::string& port) { + parts_.port = port; + parts_.is_port_wildcard = false; + return this; +} + +BuilderInterface* ContentSettingsPattern::Builder::WithPortWildcard() { + parts_.port = ""; + parts_.is_port_wildcard = true; + return this; +} + +BuilderInterface* ContentSettingsPattern::Builder::WithHost( + const std::string& host) { + parts_.host = host; + return this; +} + +BuilderInterface* ContentSettingsPattern::Builder::WithDomainWildcard() { + parts_.has_domain_wildcard = true; + return this; +} + +BuilderInterface* ContentSettingsPattern::Builder::WithScheme( + const std::string& scheme) { + parts_.scheme = scheme; + parts_.is_scheme_wildcard = false; + return this; +} + +BuilderInterface* ContentSettingsPattern::Builder::WithSchemeWildcard() { + parts_.scheme = ""; + parts_.is_scheme_wildcard = true; + return this; +} + +BuilderInterface* ContentSettingsPattern::Builder::WithPath( + const std::string& path) { + parts_.path = path; + return this; +} + +BuilderInterface* ContentSettingsPattern::Builder::Invalid() { + invalid_ = true; + return this; +} + +ContentSettingsPattern ContentSettingsPattern::Builder::Build() { + if (invalid_) + return ContentSettingsPattern(); + Canonicalize(&parts_); + return ContentSettingsPattern(parts_); +} + +// static +void ContentSettingsPattern::Builder::Canonicalize(PatternParts* parts) { + // Canonicalize the scheme part. + const std::string scheme(StringToLowerASCII(parts->scheme)); + parts->scheme = scheme; + + if (parts->scheme == std::string(chrome::kFileScheme)) { + GURL url(std::string(chrome::kFileScheme) + + std::string(chrome::kStandardSchemeSeparator) + parts->path); + parts->path = url.path(); + } + + // Canonicalize the host part. + const std::string host(parts->host); + url_canon::CanonHostInfo host_info; + const std::string canonicalized_host(net::CanonicalizeHost(host, &host_info)); + + parts->host = ""; + if ((host.find('*') == std::string::npos) && + !canonicalized_host.empty()) { + // Valid host. + parts->host += canonicalized_host; + } +} + +// //////////////////////////////////////////////////////////////////////////// +// ContentSettingsPattern::PatternParts +// +ContentSettingsPattern::PatternParts::PatternParts() + : is_scheme_wildcard(false), + has_domain_wildcard(false), + is_port_wildcard(false) {} + +ContentSettingsPattern::PatternParts::~PatternParts() {} + +// //////////////////////////////////////////////////////////////////////////// +// ContentSettingsPattern +// + // The version of the pattern format implemented. Version 1 includes the // following patterns: // - [*.]domain.tld (matches domain.tld and all sub-domains) @@ -31,75 +156,319 @@ bool IsValidHostlessPattern(const std::string& pattern) { // Version 2 adds a resource identifier for plugins. // TODO(jochen): update once this feature is no longer behind a flag. const int ContentSettingsPattern::kContentSettingsPatternVersion = 1; + +// TODO(markusheintz): These two constants were moved to the Pattern Parser. +// Remove once the dependency of the ContentSettingsBaseProvider is removed. const char* ContentSettingsPattern::kDomainWildcard = "[*.]"; const size_t ContentSettingsPattern::kDomainWildcardLength = 4; // static +BuilderInterface* ContentSettingsPattern::CreateBuilder() { + return new Builder(); +} + +// static ContentSettingsPattern ContentSettingsPattern::FromURL( const GURL& url) { - // TODO(markusheintz): Add scheme wildcard; - return ContentSettingsPattern(!url.has_host() || url.HostIsIPAddress() ? - net::GetHostOrSpecFromURL(url) : - std::string(kDomainWildcard) + url.host()); + scoped_ptr<ContentSettingsPattern::BuilderInterface> builder( + ContentSettingsPattern::CreateBuilder()); + + if (url.SchemeIsFile()) { + builder->WithScheme(url.scheme())->WithPath(url.path()); + } else { + // Please keep the order of the ifs below as URLs with an IP as host can + // also have a "http" scheme. + if (url.HostIsIPAddress()) { + builder->WithScheme(url.scheme())->WithHost(url.host()); + } else if (url.SchemeIs(chrome::kHttpScheme)) { + builder->WithSchemeWildcard()->WithDomainWildcard()->WithHost(url.host()); + } else if (url.SchemeIs(chrome::kHttpsScheme)) { + builder->WithScheme(url.scheme())->WithDomainWildcard()->WithHost( + url.host()); + } else { + // Unsupported scheme + } + if (url.port().empty()) { + builder->WithPortWildcard(); + } else { + builder->WithPort(url.port()); + } + } + return builder->Build(); } // static ContentSettingsPattern ContentSettingsPattern::FromURLNoWildcard( const GURL& url) { - return ContentSettingsPattern(net::GetHostOrSpecFromURL(url), url.scheme()); + scoped_ptr<ContentSettingsPattern::BuilderInterface> builder( + ContentSettingsPattern::CreateBuilder()); + + if (url.SchemeIsFile()) { + builder->WithScheme(url.scheme())->WithPath(url.path()); + } else { + builder->WithScheme(url.scheme())->WithHost(url.host()); + if (url.port().empty()) { + builder->WithPort(GetDefaultPort(url.scheme())); + } else { + builder->WithPort(url.port()); + } + } + return builder->Build(); } -bool ContentSettingsPattern::IsValid() const { - if (pattern_.empty()) - return false; +// static +ContentSettingsPattern ContentSettingsPattern::FromString( + const std::string& pattern_spec) { + scoped_ptr<ContentSettingsPattern::BuilderInterface> builder( + ContentSettingsPattern::CreateBuilder()); + content_settings::PatternParser::Parse(pattern_spec, builder.get()); + return builder->Build(); +} - if (IsValidHostlessPattern(pattern_)) +// static +ContentSettingsPattern ContentSettingsPattern::Wildcard() { + scoped_ptr<ContentSettingsPattern::BuilderInterface> builder( + ContentSettingsPattern::CreateBuilder()); + builder->WithSchemeWildcard()->WithDomainWildcard()->WithPortWildcard(); + return builder->Build(); +} + +// static +bool ContentSettingsPattern::Validate(const PatternParts& parts) { + // If the pattern is for a "file-pattern" test if it is valid. + if (parts.scheme == std::string(chrome::kFileScheme) && + !parts.is_scheme_wildcard && + parts.host.empty() && + parts.port.empty()) return true; - const std::string host(pattern_.length() > kDomainWildcardLength && - StartsWithASCII(pattern_, kDomainWildcard, false) ? - pattern_.substr(kDomainWildcardLength) : - pattern_); - url_canon::CanonHostInfo host_info; - return host.find('*') == std::string::npos && - !net::CanonicalizeHost(host, &host_info).empty(); + // If the pattern is for an extension URL test if it is valid. + if (parts.scheme == std::string(chrome::kExtensionScheme) && + !parts.is_scheme_wildcard && + !parts.host.empty() && + !parts.has_domain_wildcard && + parts.port.empty() && + !parts.is_port_wildcard) + return true; + + // Non-file patterns are invalid if either the scheme, host or port part is + // empty. + if ((parts.scheme.empty() && !parts.is_scheme_wildcard) || + (parts.host.empty() && !parts.has_domain_wildcard) || + (parts.port.empty() && !parts.is_port_wildcard)) + return false; + + // Test if the scheme is supported or a wildcard. + if (!parts.is_scheme_wildcard && + parts.scheme != std::string(chrome::kHttpScheme) && + parts.scheme != std::string(chrome::kHttpsScheme)) { + return false; + } + return true; +} + +ContentSettingsPattern::ContentSettingsPattern() + : is_valid_(false) { +} + +ContentSettingsPattern::ContentSettingsPattern(const PatternParts& parts) + : parts_(parts) { + is_valid_ = Validate(parts); } -bool ContentSettingsPattern::Matches(const GURL& url) const { - if (!IsValid()) +bool ContentSettingsPattern::Matches( + const GURL& url) const { + // An invalid pattern matches nothing. + if (!is_valid_) return false; - const std::string host(net::GetHostOrSpecFromURL(url)); - if (pattern_.length() < kDomainWildcardLength || - !StartsWithASCII(pattern_, kDomainWildcard, false)) - return pattern_ == host; + // Match the scheme part. + const std::string scheme(url.scheme()); + if (!parts_.is_scheme_wildcard && + parts_.scheme != scheme) { + return false; + } + + // File URLs have no host. For file URLs check if the url path matches the + // path in the pattern. + // TODO(markusheintz): This should change in the future. There should be only + // one setting for all file URLs. So the path should be ignored. + if (!parts_.is_scheme_wildcard && + scheme == std::string(chrome::kFileScheme)) { + if (parts_.path == std::string(url.path())) + return true; + return false; + } + + // Match the host part. + const std::string host(url.host()); + if (!parts_.has_domain_wildcard) { + if (parts_.host != host) + return false; + } else { + if (!IsSubDomainOrEqual(host, parts_.host)) + return false; + } + + // For chrome extensions URLs ignore the port. + if (parts_.scheme == std::string(chrome::kExtensionScheme)) + return true; + + // Match the port part. + std::string port(url.port()); - const size_t match = - host.rfind(pattern_.substr(kDomainWildcardLength)); + // Use the default port if the port string is empty. GURL returns an empty + // string if no port at all was specified or if the default port was + // specified. + if (port.empty()) { + port = GetDefaultPort(scheme); + } - return (match != std::string::npos) && - (match == 0 || host[match - 1] == '.') && - (match + pattern_.length() - kDomainWildcardLength == host.length()); + if (!parts_.is_port_wildcard && + parts_.port != port ) { + return false; + } + + return true; } -std::string ContentSettingsPattern::CanonicalizePattern() const { - if (!IsValid()) +const std::string ContentSettingsPattern::ToString() const { + if (IsValid()) + return content_settings::PatternParser::ToString(parts_); + else return ""; +} - if (IsValidHostlessPattern(pattern_)) - return GURL(pattern_).spec(); +ContentSettingsPattern::Relation ContentSettingsPattern::Compare( + const ContentSettingsPattern& other) const { + if (this == &other) + return IDENTITY; - bool starts_with_wildcard = pattern_.length() > kDomainWildcardLength && - StartsWithASCII(pattern_, kDomainWildcard, false); + if (!is_valid_ || !other.is_valid_) { + NOTREACHED(); + return DISJOINT; + } - const std::string host(starts_with_wildcard ? - pattern_.substr(kDomainWildcardLength) : pattern_); + // If either host, port or scheme are disjoint return immediately. + Relation host_relation = CompareHost(parts_, other.parts_); + if (host_relation == DISJOINT) + return DISJOINT; + Relation port_relation = ComparePort(parts_, other.parts_); + if (port_relation == DISJOINT) + return DISJOINT; + Relation scheme_relation = CompareScheme(parts_, other.parts_); + if (scheme_relation == DISJOINT) + return DISJOINT; - std::string canonicalized_pattern = - starts_with_wildcard ? kDomainWildcard : ""; + if (host_relation != IDENTITY) + return host_relation; + if (port_relation != IDENTITY) + return port_relation; + return scheme_relation; +} - url_canon::CanonHostInfo host_info; - canonicalized_pattern += net::CanonicalizeHost(host, &host_info); +// static +ContentSettingsPattern::Relation ContentSettingsPattern::CompareHost( + const ContentSettingsPattern::PatternParts& parts, + const ContentSettingsPattern::PatternParts& other_parts) { + if (!parts.has_domain_wildcard && !other_parts.has_domain_wildcard) { + // Case 1: No host starts with a wild card + if (parts.host == other_parts.host) { + return ContentSettingsPattern::IDENTITY; + } else { + return ContentSettingsPattern::DISJOINT; + } + } else if (parts.has_domain_wildcard && !other_parts.has_domain_wildcard) { + // Case 2: |host| starts with a domain wildcard and |other_host| does not + // start with a domain wildcard. + // Examples: + // "this" host: [*.]google.com + // "other" host: google.com + // + // [*.]google.com + // mail.google.com + // + // [*.]mail.google.com + // google.com + // + // [*.]youtube.com + // google.de + // + // [*.]youtube.com + // mail.google.com + // + // * + // google.de + if (IsSubDomainOrEqual(other_parts.host, parts.host)) { + return ContentSettingsPattern::SUCCESSOR; + } else { + return ContentSettingsPattern::DISJOINT; + } + } else if (!parts.has_domain_wildcard && other_parts.has_domain_wildcard) { + // Case 3: |host| starts NOT with a domain wildcard and |other_host| starts + // with a domain wildcard. + if (IsSubDomainOrEqual(parts.host, other_parts.host)) { + return ContentSettingsPattern::PREDECESSOR; + } else { + return ContentSettingsPattern::DISJOINT; + } + } else if (parts.has_domain_wildcard && other_parts.has_domain_wildcard) { + // Case 4: |host| and |other_host| both start with a domain wildcard. + // Examples: + // [*.]google.com + // [*.]google.com + // + // [*.]google.com + // [*.]mail.google.com + // + // [*.]youtube.com + // [*.]google.de + // + // [*.]youtube.com + // [*.]mail.google.com + // + // [*.]youtube.com + // * + // + // * + // [*.]youtube.com + if (parts.host == other_parts.host) { + return ContentSettingsPattern::IDENTITY; + } else if (IsSubDomainOrEqual(other_parts.host, parts.host)) { + return ContentSettingsPattern::SUCCESSOR; + } else if (IsSubDomainOrEqual(parts.host, other_parts.host)) { + return ContentSettingsPattern::PREDECESSOR; + } else { + return ContentSettingsPattern::DISJOINT; + } + } + + NOTREACHED(); + return ContentSettingsPattern::IDENTITY; +} - return canonicalized_pattern; +// static +ContentSettingsPattern::Relation ContentSettingsPattern::CompareScheme( + const ContentSettingsPattern::PatternParts& parts, + const ContentSettingsPattern::PatternParts& other_parts) { + if (parts.is_scheme_wildcard && !other_parts.is_scheme_wildcard) + return ContentSettingsPattern::SUCCESSOR; + if (!parts.is_scheme_wildcard && other_parts.is_scheme_wildcard) + return ContentSettingsPattern::PREDECESSOR; + if (parts.scheme != other_parts.scheme) + return ContentSettingsPattern::DISJOINT; + return ContentSettingsPattern::IDENTITY; +} + +// static +ContentSettingsPattern::Relation ContentSettingsPattern::ComparePort( + const ContentSettingsPattern::PatternParts& parts, + const ContentSettingsPattern::PatternParts& other_parts) { + if (parts.is_port_wildcard && !other_parts.is_port_wildcard) + return ContentSettingsPattern::SUCCESSOR; + if (!parts.is_port_wildcard && other_parts.is_port_wildcard) + return ContentSettingsPattern::PREDECESSOR; + if (parts.port != other_parts.port) + return ContentSettingsPattern::DISJOINT; + return ContentSettingsPattern::IDENTITY; } diff --git a/chrome/browser/content_settings/content_settings_pattern.h b/chrome/browser/content_settings/content_settings_pattern.h index a9440c5..4b55683 100644 --- a/chrome/browser/content_settings/content_settings_pattern.h +++ b/chrome/browser/content_settings/content_settings_pattern.h @@ -11,80 +11,217 @@ #include <ostream> #include <string> +#include "base/basictypes.h" + class GURL; +namespace content_settings { +class PatternParser; +} + // A pattern used in content setting rules. See |IsValid| for a description of // possible patterns. class ContentSettingsPattern { public: - // Returns a pattern that matches the host of this URL and all subdomains. + // Each content settings pattern describes a set of origins. Patterns, and the + // sets they describe, have specific relations. |Relation| describes the + // relation of two patterns A and B. When pattern A is compared with pattern B + // (A compare B) interessting relations are: + // - IDENTITY : Pattern A and B are identical. The patterns are equal. + // - DISJOINT : Pattern A and B have no intersection. A and B never match + // a the origin of a URL at the same time. + // - SUCCESSOR : Pattern A and B have an intersection. But pattern B has a + // higher precedence than pattern A for URLs that are matched + // by both pattern. + // - PREDECESSOR : Pattern A and B have an intersection. But pattern A has a + // higher precedence than pattern B for URLs that are matched + // by both pattern. + enum Relation { + DISJOINT = -2, + SUCCESSOR = -1, + IDENTITY = 0, + PREDECESSOR = 1, + }; + + class BuilderInterface { + public: + virtual ~BuilderInterface() {} + + virtual BuilderInterface* WithPort(const std::string& port) = 0; + + virtual BuilderInterface* WithPortWildcard() = 0; + + virtual BuilderInterface* WithHost(const std::string& host) = 0; + + virtual BuilderInterface* WithDomainWildcard() = 0; + + virtual BuilderInterface* WithScheme(const std::string& scheme) = 0; + + virtual BuilderInterface* WithSchemeWildcard() = 0; + + virtual BuilderInterface* WithPath(const std::string& path) = 0; + + virtual BuilderInterface* Invalid() = 0; + + // Returns a content settings pattern according to the current configuration + // of the builder. + virtual ContentSettingsPattern Build() = 0; + }; + + static BuilderInterface* CreateBuilder(); + + // The version of the pattern format implemented. + static const int kContentSettingsPatternVersion; + + // The format of a domain wildcard. + static const char* kDomainWildcard; + + // The length of kDomainWildcard (without the trailing '\0'). + static const size_t kDomainWildcardLength; + + // Returns a wildcard content settings pattern that matches all possible valid + // origins. + static ContentSettingsPattern Wildcard(); + + // Returns a pattern that matches the scheme and host of this URL, as well as + // all subdomains and ports. static ContentSettingsPattern FromURL(const GURL& url); // Returns a pattern that matches exactly this URL. static ContentSettingsPattern FromURLNoWildcard(const GURL& url); - ContentSettingsPattern() {} - - explicit ContentSettingsPattern(const std::string& pattern) - : pattern_(pattern), - scheme_("") {} - - // True if this is a valid pattern. Valid patterns are + // Returns a pattern that matches the given pattern specification. + // Valid patterns specifications are: // - [*.]domain.tld (matches domain.tld and all sub-domains) // - host (matches an exact hostname) + // - scheme://host:port (supported schemes: http,https) + // - scheme://[*.]domain.tld:port (supported schemes: http,https) + // - file://path (The path has to be an absolute path and start with a '/') // - a.b.c.d (matches an exact IPv4 ip) // - [a:b:c:d:e:f:g:h] (matches an exact IPv6 ip) - // TODO(jochen): should also return true for a complete URL without a host. - bool IsValid() const; + static ContentSettingsPattern FromString(const std::string& pattern_spec); + + // Constructs an empty pattern. Empty patterns are invalid patterns. Invalid + // patterns match nothing. + ContentSettingsPattern(); + + // True if this is a valid pattern. + bool IsValid() const { return is_valid_; } // True if |url| matches this pattern. bool Matches(const GURL& url) const; // Returns a std::string representation of this pattern. - const std::string& AsString() const { return pattern_; } + const std::string ToString() const; + + // Compares the pattern with a given |other| pattern and returns the + // |Relation| of the two patterns. + Relation Compare(const ContentSettingsPattern& other) const; bool operator==(const ContentSettingsPattern& other) const { - return pattern_ == other.pattern_; + return Compare(other) == IDENTITY; } - // Canonicalizes the pattern so that it's ASCII only, either - // in original (if it was already ASCII) or punycode form. - std::string CanonicalizePattern() const; + private: + friend class content_settings::PatternParser; + friend class ContentSettingsPatternParserTest_SerializePatterns_Test; + friend class Builder; + + struct PatternParts { + PatternParts(); + ~PatternParts(); - std::string scheme() const { - return scheme_; - } + // Lowercase string of the URL scheme to match. This string is empty if the + // |is_scheme_wildcard| flag is set. + std::string scheme; - // The version of the pattern format implemented. - static const int kContentSettingsPatternVersion; + // True if the scheme wildcard is set. + bool is_scheme_wildcard; - // The format of a domain wildcard. - static const char* kDomainWildcard; + // Normalized string that is either of the following: + // - IPv4 or IPv6 + // - hostname + // - domain + // - empty string if the |is_host_wildcard flag is set. + std::string host; - // The length of kDomainWildcard (without the trailing '\0'). - static const size_t kDomainWildcardLength; + // True if the domain wildcard is set. + bool has_domain_wildcard; - private: - // TODO(markusheintz): This constructor is only here to fix bug 76693. Further - // refactoring pending to fully integrate scheme support in content settings - // patterns. - ContentSettingsPattern(const std::string& host, const std::string& scheme) - : pattern_(host), - scheme_(scheme) {} - - std::string pattern_; - - // TODO(markusheintz): This is only here to fix bug 76693. There is more work - // to do to add scheme support to content-settings patterns. - // TODO(markusheintz): canonicalize to lowercase; - std::string scheme_; + // String with the port to match. This string is empty if the + // |is_port_wildcard| flag is set. + std::string port; + + // True if the port wildcard is set. + bool is_port_wildcard; + + // TODO(markusheintz): Needed for legacy reasons. Remove. Path + // specification. Only used for content settings pattern with a "file" + // scheme part. + std::string path; + }; + + class Builder : public BuilderInterface { + public: + Builder(); + virtual ~Builder(); + + // Overrides BuilderInterface + virtual BuilderInterface* WithPort(const std::string& port); + + virtual BuilderInterface* WithPortWildcard(); + + virtual BuilderInterface* WithHost(const std::string& host); + + virtual BuilderInterface* WithDomainWildcard(); + + virtual BuilderInterface* WithScheme(const std::string& scheme); + + virtual BuilderInterface* WithSchemeWildcard(); + + virtual BuilderInterface* WithPath(const std::string& path); + + virtual BuilderInterface* Invalid(); + + virtual ContentSettingsPattern Build(); + private: + // Canonicalizes the pattern parts so that they are ASCII only, either + // in original (if it was already ASCII) or punycode form. + static void Canonicalize(PatternParts* parts); + + bool invalid_; + + PatternParts parts_; + + DISALLOW_COPY_AND_ASSIGN(Builder); + }; + + static Relation CompareScheme( + const ContentSettingsPattern::PatternParts& parts, + const ContentSettingsPattern::PatternParts& other_parts); + + static Relation CompareHost( + const ContentSettingsPattern::PatternParts& parts, + const ContentSettingsPattern::PatternParts& other_parts); + + static Relation ComparePort( + const ContentSettingsPattern::PatternParts& parts, + const ContentSettingsPattern::PatternParts& other_parts); + + static bool Validate(const PatternParts& parts); + + explicit ContentSettingsPattern(const PatternParts& parts); + + PatternParts parts_; + + bool is_valid_; }; // Stream operator so ContentSettingsPattern can be used in assertion // statements. inline std::ostream& operator<<( std::ostream& out, const ContentSettingsPattern& pattern) { - return out << pattern.AsString(); + return out << pattern.ToString(); } #endif // CHROME_BROWSER_CONTENT_SETTINGS_CONTENT_SETTINGS_PATTERN_H_ diff --git a/chrome/browser/content_settings/content_settings_pattern_parser.cc b/chrome/browser/content_settings/content_settings_pattern_parser.cc new file mode 100644 index 0000000..39e3091 --- /dev/null +++ b/chrome/browser/content_settings/content_settings_pattern_parser.cc @@ -0,0 +1,226 @@ +// Copyright (c) 2011 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#include "chrome/browser/content_settings/content_settings_pattern_parser.h" + +#include "base/string_util.h" +#include "chrome/common/url_constants.h" +#include "net/base/net_util.h" +#include "googleurl/src/gurl.h" +#include "googleurl/src/url_canon.h" + +namespace { + +const char* kUrlPathSeparator = "/"; +const char* kUrlPortSeparator = ":"; + +class Component { + public: + Component() : start(0), len(0) {} + Component(size_t s, size_t l) : start(s), len(l) {} + + bool IsNonEmpty() { + return len > 0; + } + + size_t start; + size_t len; +}; + +} // namespace + +namespace content_settings { + +const char* PatternParser::kDomainWildcard = "[*.]"; + +const size_t PatternParser::kDomainWildcardLength = 4; + +const char* PatternParser::kSchemeWildcard = "*"; + +const char* PatternParser::kHostWildcard = "*"; + +const char* PatternParser::kPortWildcard = "*"; + +// static +void PatternParser::Parse(const std::string& pattern_spec, + ContentSettingsPattern::BuilderInterface* builder) { + if (pattern_spec == "*") { + builder->WithSchemeWildcard(); + builder->WithDomainWildcard(); + builder->WithPortWildcard(); + return; + } + + // Initialize components for the individual patterns parts to empty + // sub-strings. + Component scheme_component; + Component host_component; + Component port_component; + Component path_component; + + size_t start = 0; + size_t current_pos = 0; + + if (pattern_spec.empty()) + return; + + // Test if a scheme pattern is in the spec. + current_pos = pattern_spec.find( + std::string(chrome::kStandardSchemeSeparator), start); + if (current_pos != std::string::npos) { + scheme_component = Component(start, current_pos); + start = current_pos + strlen(chrome::kStandardSchemeSeparator); + current_pos = start; + } else { + current_pos = start; + } + + if (start >= pattern_spec.size()) + return; // Bad pattern spec. + + // Jump to the end of domain wildcards or an IPv6 addresses. IPv6 addresses + // contain ':'. So first move to the end of an IPv6 address befor searching + // for the ':' that separates the port form the host. + if (pattern_spec[current_pos] == '[') + current_pos = pattern_spec.find("]", start); + + if (current_pos == std::string::npos) + return; // Bad pattern spec. + + current_pos = pattern_spec.find(std::string(kUrlPortSeparator), current_pos); + if (current_pos == std::string::npos) { + // No port spec found + current_pos = pattern_spec.find(std::string(kUrlPathSeparator), start); + if (current_pos == std::string::npos) { + current_pos = pattern_spec.size(); + host_component = Component(start, current_pos - start); + } else { + // Pattern has a path spec. + host_component = Component(start, current_pos - start); + } + start = current_pos; + } else { + // Port spec found. + host_component = Component(start, current_pos - start); + start = current_pos + 1; + if (start < pattern_spec.size()) { + current_pos = pattern_spec.find(std::string(kUrlPathSeparator), start); + if (current_pos == std::string::npos) { + current_pos = pattern_spec.size(); + } + port_component = Component(start, current_pos - start); + start = current_pos; + } + } + + current_pos = pattern_spec.size(); + if (start < current_pos) { + // Pattern has a path spec. + path_component = Component(start, current_pos - start); + } + + // Set pattern parts. + std::string scheme; + if (scheme_component.IsNonEmpty()) { + scheme = pattern_spec.substr(scheme_component.start, scheme_component.len); + if (scheme == kSchemeWildcard) { + builder->WithSchemeWildcard(); + } else { + builder->WithScheme(scheme); + } + } else { + builder->WithSchemeWildcard(); + } + + if (host_component.IsNonEmpty()) { + std::string host = pattern_spec.substr(host_component.start, + host_component.len); + if (host == kHostWildcard) { + builder->WithDomainWildcard(); + } else if (StartsWithASCII(host, kDomainWildcard, true)) { + host = host.substr(kDomainWildcardLength); + // If the host still contains a wildcard symbol then it is invalid. + if (host.find(kHostWildcard) != std::string::npos) { + builder->Invalid(); + return; + } else { + builder->WithDomainWildcard(); + builder->WithHost(host); + } + } else { + // If the host contains a wildcard symbol then it is invalid. + if (host.find(kHostWildcard) != std::string::npos) { + builder->Invalid(); + return; + } + builder->WithHost(host); + } + } + + if (port_component.IsNonEmpty()) { + const std::string port = pattern_spec.substr(port_component.start, + port_component.len); + if (port == kPortWildcard) { + builder->WithPortWildcard(); + } else { + // Check if the port string represents a valid port. + for (size_t i = 0; i < port.size(); ++i) { + if (!IsAsciiDigit(port[i])) { + builder->Invalid(); + return; + } + } + // TODO(markusheintz): Check port range. + builder->WithPort(port); + } + } else { + if (scheme != std::string(chrome::kExtensionScheme)) + builder->WithPortWildcard(); + } + + if (path_component.IsNonEmpty()) { + builder->WithPath(pattern_spec.substr(path_component.start, + path_component.len)); + } +} + +// static +std::string PatternParser::ToString( + const ContentSettingsPattern::PatternParts& parts) { + // Return the most compact form to support legacy code and legacy pattern + // strings. + if (parts.is_scheme_wildcard && + parts.has_domain_wildcard && + parts.host.empty() && + parts.is_port_wildcard) + return "*"; + + std::string str = ""; + if (!parts.is_scheme_wildcard) + str += parts.scheme + chrome::kStandardSchemeSeparator; + + if (parts.scheme == std::string(chrome::kFileScheme)) + return str + parts.path; + + if (parts.has_domain_wildcard) { + if (parts.host.empty()) + str += kHostWildcard; + else + str += kDomainWildcard; + } + str += parts.host; + + if (parts.scheme == std::string(chrome::kExtensionScheme)) { + str += parts.path.empty() ? std::string(kUrlPathSeparator) : parts.path; + return str; + } + + if (!parts.is_port_wildcard) { + str += std::string(kUrlPortSeparator) + parts.port; + } + + return str; +} + +} // namespace content_settings diff --git a/chrome/browser/content_settings/content_settings_pattern_parser.h b/chrome/browser/content_settings/content_settings_pattern_parser.h new file mode 100644 index 0000000..eca4568 --- /dev/null +++ b/chrome/browser/content_settings/content_settings_pattern_parser.h @@ -0,0 +1,41 @@ +// Copyright (c) 2011 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#ifndef CHROME_BROWSER_CONTENT_SETTINGS_CONTENT_SETTINGS_PATTERN_PARSER_H_ +#define CHROME_BROWSER_CONTENT_SETTINGS_CONTENT_SETTINGS_PATTERN_PARSER_H_ + +#include <string> + +#include "base/basictypes.h" +#include "chrome/browser/content_settings/content_settings_pattern.h" + +namespace content_settings { + +struct PatternParts; + +class PatternParser { + public: + static void Parse(const std::string& pattern_spec, + ContentSettingsPattern::BuilderInterface* builder); + + static std::string ToString( + const ContentSettingsPattern::PatternParts& parts); + + private: + static const char* kDomainWildcard; + + static const size_t kDomainWildcardLength; + + static const char* kSchemeWildcard; + + static const char* kHostWildcard; + + static const char* kPortWildcard; + + DISALLOW_COPY_AND_ASSIGN(PatternParser); +}; + +} // namespace content_settings + +#endif // CHROME_BROWSER_CONTENT_SETTINGS_CONTENT_SETTINGS_PATTERN_PARSER_H_ diff --git a/chrome/browser/content_settings/content_settings_pattern_parser_unittest.cc b/chrome/browser/content_settings/content_settings_pattern_parser_unittest.cc new file mode 100644 index 0000000..8a8aeca --- /dev/null +++ b/chrome/browser/content_settings/content_settings_pattern_parser_unittest.cc @@ -0,0 +1,157 @@ +// Copyright (c) 2011 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#include "chrome/browser/content_settings/content_settings_pattern.h" +#include "chrome/browser/content_settings/content_settings_pattern_parser.h" + +#include "testing/gmock/include/gmock/gmock.h" +#include "testing/gtest/include/gtest/gtest.h" + +namespace { +typedef ContentSettingsPattern::BuilderInterface BuilderInterface; +} // namespace + +class MockBuilder : public ContentSettingsPattern::BuilderInterface { + public: + MOCK_METHOD0(WithSchemeWildcard, BuilderInterface*()); + MOCK_METHOD0(WithDomainWildcard, BuilderInterface*()); + MOCK_METHOD0(WithPortWildcard, BuilderInterface*()); + MOCK_METHOD1(WithScheme, BuilderInterface*(const std::string& scheme)); + MOCK_METHOD1(WithHost, BuilderInterface*(const std::string& host)); + MOCK_METHOD1(WithPort, BuilderInterface*(const std::string& port)); + MOCK_METHOD1(WithPath, BuilderInterface*(const std::string& path)); + MOCK_METHOD0(Invalid, BuilderInterface*()); + MOCK_METHOD0(Build, ContentSettingsPattern()); +}; + +TEST(ContentSettingsPatternParserTest, ParsePatterns) { + // Test valid patterns + MockBuilder builder; + + EXPECT_CALL(builder, WithScheme("http")).Times(1).WillOnce( + ::testing::Return(&builder)); + EXPECT_CALL(builder, WithHost("www.youtube.com")).Times(1).WillOnce( + ::testing::Return(&builder)); + EXPECT_CALL(builder, WithPort("8080")).Times(1).WillOnce( + ::testing::Return(&builder)); + content_settings::PatternParser::Parse( + "http://www.youtube.com:8080", &builder); + ::testing::Mock::VerifyAndClear(&builder); + + EXPECT_CALL(builder, WithSchemeWildcard()).Times(1).WillOnce( + ::testing::Return(&builder)); + EXPECT_CALL(builder, WithHost("www.gmail.com")).Times(1).WillOnce( + ::testing::Return(&builder)); + EXPECT_CALL(builder, WithPort("80")).Times(1).WillOnce( + ::testing::Return(&builder)); + content_settings::PatternParser::Parse("*://www.gmail.com:80", &builder); + ::testing::Mock::VerifyAndClear(&builder); + + EXPECT_CALL(builder, WithScheme("http")).Times(1).WillOnce( + ::testing::Return(&builder)); + EXPECT_CALL(builder, WithHost("www.gmail.com")).Times(1).WillOnce( + ::testing::Return(&builder)); + EXPECT_CALL(builder, WithPortWildcard()).Times(1).WillOnce( + ::testing::Return(&builder)); + content_settings::PatternParser::Parse("http://www.gmail.com:*", &builder); + ::testing::Mock::VerifyAndClear(&builder); + + EXPECT_CALL(builder, WithScheme("http")).Times(1).WillOnce( + ::testing::Return(&builder)); + EXPECT_CALL(builder, WithDomainWildcard()).WillOnce( + ::testing::Return(&builder)); + EXPECT_CALL(builder, WithHost("google.com")).Times(1).WillOnce( + ::testing::Return(&builder)); + EXPECT_CALL(builder, WithPort("80")).Times(1).WillOnce( + ::testing::Return(&builder)); + content_settings::PatternParser::Parse("http://[*.]google.com:80", &builder); + ::testing::Mock::VerifyAndClear(&builder); + + EXPECT_CALL(builder, WithScheme("https")).Times(1).WillOnce( + ::testing::Return(&builder)); + EXPECT_CALL(builder, WithHost("[::1]")).Times(1).WillOnce( + ::testing::Return(&builder)); + EXPECT_CALL(builder, WithPort("8080")).Times(1).WillOnce( + ::testing::Return(&builder)); + content_settings::PatternParser::Parse("https://[::1]:8080", &builder); + ::testing::Mock::VerifyAndClear(&builder); + + EXPECT_CALL(builder, WithScheme("http")).Times(1).WillOnce( + ::testing::Return(&builder)); + EXPECT_CALL(builder, WithHost("127.0.0.1")).Times(1).WillOnce( + ::testing::Return(&builder)); + EXPECT_CALL(builder, WithPort("8080")).Times(1).WillOnce( + ::testing::Return(&builder)); + content_settings::PatternParser::Parse("http://127.0.0.1:8080", &builder); + ::testing::Mock::VerifyAndClear(&builder); + + EXPECT_CALL(builder, WithScheme("file")).Times(1).WillOnce( + ::testing::Return(&builder)); + EXPECT_CALL(builder, WithPath("/foo/bar/test.html")).Times(1).WillOnce( + ::testing::Return(&builder)); + content_settings::PatternParser::Parse( + "file:///foo/bar/test.html", &builder); + ::testing::Mock::VerifyAndClear(&builder); + + // Test valid pattern short forms + EXPECT_CALL(builder, WithSchemeWildcard()).Times(1).WillOnce( + ::testing::Return(&builder)); + EXPECT_CALL(builder, WithHost("www.youtube.com")).Times(1).WillOnce( + ::testing::Return(&builder)); + EXPECT_CALL(builder, WithPort("8080")).Times(1).WillOnce( + ::testing::Return(&builder)); + content_settings::PatternParser::Parse("www.youtube.com:8080", &builder); + ::testing::Mock::VerifyAndClear(&builder); + + EXPECT_CALL(builder, WithSchemeWildcard()).Times(1).WillOnce( + ::testing::Return(&builder)); + EXPECT_CALL(builder, WithHost("www.youtube.com")).Times(1).WillOnce( + ::testing::Return(&builder)); + EXPECT_CALL(builder, WithPortWildcard()).Times(1).WillOnce( + ::testing::Return(&builder)); + content_settings::PatternParser::Parse("www.youtube.com", &builder); + ::testing::Mock::VerifyAndClear(&builder); + + EXPECT_CALL(builder, WithSchemeWildcard()).Times(1).WillOnce( + ::testing::Return(&builder)); + EXPECT_CALL(builder, WithDomainWildcard()).Times(1).WillOnce( + ::testing::Return(&builder)); + EXPECT_CALL(builder, WithHost("youtube.com")).Times(1).WillOnce( + ::testing::Return(&builder)); + EXPECT_CALL(builder, WithPortWildcard()).Times(1).WillOnce( + ::testing::Return(&builder)); + content_settings::PatternParser::Parse("[*.]youtube.com", &builder); + ::testing::Mock::VerifyAndClear(&builder); + + // Test invalid patterns + EXPECT_CALL(builder, Invalid()).Times(1).WillOnce( + ::testing::Return(&builder)); + content_settings::PatternParser::Parse("*youtube.com", &builder); + ::testing::Mock::VerifyAndClear(&builder); + + EXPECT_CALL(builder, Invalid()).Times(1).WillOnce( + ::testing::Return(&builder)); + content_settings::PatternParser::Parse("*.youtube.com", &builder); + ::testing::Mock::VerifyAndClear(&builder); + + EXPECT_CALL(builder, Invalid()).Times(1).WillOnce( + ::testing::Return(&builder)); + content_settings::PatternParser::Parse("www.youtube.com*", &builder); + ::testing::Mock::VerifyAndClear(&builder); +} + +TEST(ContentSettingsPatternParserTest, SerializePatterns) { + ContentSettingsPattern::PatternParts parts; + parts.scheme = "http"; + parts.host = "www.youtube.com"; + parts.port = "8080"; + EXPECT_STREQ("http://www.youtube.com:8080", + content_settings::PatternParser::ToString(parts).c_str()); + + parts = ContentSettingsPattern::PatternParts(); + parts.scheme = "file"; + parts.path = "/foo/bar/test.html"; + EXPECT_STREQ("file:///foo/bar/test.html", + content_settings::PatternParser::ToString(parts).c_str()); +} diff --git a/chrome/browser/content_settings/content_settings_pattern_unittest.cc b/chrome/browser/content_settings/content_settings_pattern_unittest.cc index 4882e34..57078d2 100644 --- a/chrome/browser/content_settings/content_settings_pattern_unittest.cc +++ b/chrome/browser/content_settings/content_settings_pattern_unittest.cc @@ -1,4 +1,4 @@ -// Copyright (c) 2010 The Chromium Authors. All rights reserved. +// Copyright (c) 2011 The Chromium Authors. All rights reserved. // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. @@ -9,70 +9,503 @@ namespace { -TEST(ContentSettingsPatternTest, PatternSupport) { - EXPECT_TRUE(ContentSettingsPattern("[*.]example.com").IsValid()); - EXPECT_TRUE(ContentSettingsPattern("example.com").IsValid()); - EXPECT_TRUE(ContentSettingsPattern("192.168.0.1").IsValid()); - EXPECT_TRUE(ContentSettingsPattern("[::1]").IsValid()); - EXPECT_TRUE(ContentSettingsPattern("file:///tmp/test.html").IsValid()); - EXPECT_FALSE(ContentSettingsPattern("*example.com").IsValid()); - EXPECT_FALSE(ContentSettingsPattern("example.*").IsValid()); - EXPECT_FALSE(ContentSettingsPattern("http://example.com").IsValid()); - - EXPECT_TRUE(ContentSettingsPattern("[*.]example.com").Matches( +ContentSettingsPattern Pattern(const std::string& str) { + return ContentSettingsPattern::FromString(str); +} + +} // namespace + +TEST(ContentSettingsPatternTest, RealWorldPatterns) { + // This is the place for real world patterns that unveiled bugs. + EXPECT_STREQ("[*.]ikea.com", + Pattern("[*.]ikea.com").ToString().c_str()); +} + +TEST(ContentSettingsPatternTest, GURL) { + // Document and verify GURL behavior. + GURL url("http://mail.google.com:80"); + EXPECT_EQ(-1, url.IntPort()); + EXPECT_EQ("", url.port()); + + url = GURL("http://mail.google.com"); + EXPECT_EQ(-1, url.IntPort()); + EXPECT_EQ("", url.port()); + + url = GURL("https://mail.google.com:443"); + EXPECT_EQ(-1, url.IntPort()); + EXPECT_EQ("", url.port()); + + url = GURL("https://mail.google.com"); + EXPECT_EQ(-1, url.IntPort()); + EXPECT_EQ("", url.port()); + + url = GURL("http://mail.google.com"); + EXPECT_EQ(-1, url.IntPort()); + EXPECT_EQ("", url.port()); +} + +TEST(ContentSettingsPatternTest, FromURL) { + // NOTICE: When content settings pattern are created from a GURL the following + // happens: + // - If the GURL scheme is "http" the scheme wildcard is used. Otherwise the + // GURL scheme is used. + // - A domain wildcard is added to the GURL host. + // - A port wildcard is used instead of the schemes default port. + // In case of non-default ports the specific GURL port is used. + ContentSettingsPattern pattern = ContentSettingsPattern::FromURL( + GURL("http://www.youtube.com")); + EXPECT_TRUE(pattern.IsValid()); + EXPECT_STREQ("[*.]www.youtube.com", pattern.ToString().c_str()); + + // Patterns created from a URL. + pattern = ContentSettingsPattern::FromURL(GURL("http://www.google.com")); + EXPECT_TRUE(pattern.Matches(GURL("http://www.google.com"))); + EXPECT_TRUE(pattern.Matches(GURL("http://foo.www.google.com"))); + EXPECT_TRUE(pattern.Matches(GURL("http://www.google.com:80"))); + EXPECT_TRUE(pattern.Matches(GURL("http://www.google.com:81"))); + EXPECT_FALSE(pattern.Matches(GURL("https://mail.google.com"))); + EXPECT_TRUE(pattern.Matches(GURL("https://www.google.com"))); + + pattern = ContentSettingsPattern::FromURL(GURL("http://www.google.com:80")); + EXPECT_TRUE(pattern.Matches(GURL("http://www.google.com"))); + EXPECT_TRUE(pattern.Matches(GURL("http://www.google.com:80"))); + EXPECT_TRUE(pattern.Matches(GURL("http://www.google.com:81"))); + + pattern = ContentSettingsPattern::FromURL(GURL("https://www.google.com:443")); + EXPECT_TRUE(pattern.Matches(GURL("https://www.google.com"))); + EXPECT_TRUE(pattern.Matches(GURL("https://www.google.com:443"))); + EXPECT_TRUE(pattern.Matches(GURL("https://www.google.com:444"))); + EXPECT_FALSE(pattern.Matches(GURL("http://www.google.com:443"))); + + pattern = ContentSettingsPattern::FromURL(GURL("https://127.0.0.1")); + EXPECT_TRUE(pattern.IsValid()); + EXPECT_STREQ("https://127.0.0.1", pattern.ToString().c_str()); + + pattern = ContentSettingsPattern::FromURL(GURL("http://[::1]")); + EXPECT_TRUE(pattern.IsValid()); + + pattern = ContentSettingsPattern::FromURL(GURL("file:///foo/bar.html")); + EXPECT_TRUE(pattern.IsValid()); + EXPECT_STREQ("file:///foo/bar.html", pattern.ToString().c_str()); +} + +TEST(ContentSettingsPatternTest, FromURLNoWildcard) { + // If no port is specifed GURLs always use the default port for the schemes + // HTTP and HTTPS. Hence a GURL always carries a port specification either + // explicitly or implicitly. Therefore if a content settings pattern is + // created from a GURL with no wildcard, specific values are used for the + // scheme, host and port part of the pattern. + // Creating content settings patterns from strings behaves different. Pattern + // parts that are omitted in pattern specifications (strings), are completed + // with a wildcard. + ContentSettingsPattern pattern = ContentSettingsPattern::FromURLNoWildcard( + GURL("http://www.example.com")); + EXPECT_TRUE(pattern.IsValid()); + EXPECT_STREQ("http://www.example.com:80", pattern.ToString().c_str()); + EXPECT_TRUE(pattern.Matches(GURL("http://www.example.com"))); + EXPECT_FALSE(pattern.Matches(GURL("https://www.example.com"))); + EXPECT_FALSE(pattern.Matches(GURL("http://foo.www.example.com"))); + + pattern = ContentSettingsPattern::FromURLNoWildcard( + GURL("https://www.example.com")); + EXPECT_TRUE(pattern.IsValid()); + EXPECT_STREQ("https://www.example.com:443", pattern.ToString().c_str()); + EXPECT_FALSE(pattern.Matches(GURL("http://www.example.com"))); + EXPECT_TRUE(pattern.Matches(GURL("https://www.example.com"))); + EXPECT_FALSE(pattern.Matches(GURL("http://foo.www.example.com"))); + + pattern = ContentSettingsPattern::FromURLNoWildcard( + GURL("https://www.example.com")); +} + +TEST(ContentSettingsPatternTest, Wildcard) { + EXPECT_TRUE(ContentSettingsPattern::Wildcard().IsValid()); + + EXPECT_TRUE(ContentSettingsPattern::Wildcard().Matches( + GURL("http://www.google.com"))); + EXPECT_TRUE(ContentSettingsPattern::Wildcard().Matches( + GURL("https://www.google.com"))); + EXPECT_TRUE(ContentSettingsPattern::Wildcard().Matches( + GURL("https://myhost:8080"))); + EXPECT_TRUE(ContentSettingsPattern::Wildcard().Matches( + GURL("file:///foo/bar.txt"))); + + EXPECT_STREQ("*", ContentSettingsPattern::Wildcard().ToString().c_str()); + + EXPECT_EQ(ContentSettingsPattern::IDENTITY, + ContentSettingsPattern::Wildcard().Compare( + ContentSettingsPattern::Wildcard())); +} + +TEST(ContentSettingsPatternTest, FromString_WithNoWildcards) { + // HTTP patterns with default port. + EXPECT_TRUE(Pattern("http://www.example.com:80").IsValid()); + EXPECT_STREQ("http://www.example.com:80", + Pattern("http://www.example.com:80").ToString().c_str()); + // HTTP patterns with none default port. + EXPECT_TRUE(Pattern("http://www.example.com:81").IsValid()); + EXPECT_STREQ("http://www.example.com:81", + Pattern("http://www.example.com:81").ToString().c_str()); + + // HTTPS patterns with default port. + EXPECT_TRUE(Pattern("https://www.example.com:443").IsValid()); + EXPECT_STREQ("https://www.example.com:443", + Pattern("https://www.example.com:443").ToString().c_str()); + // HTTPS patterns with none default port. + EXPECT_TRUE(Pattern("https://www.example.com:8080").IsValid()); + EXPECT_STREQ("https://www.example.com:8080", + Pattern("https://www.example.com:8080").ToString().c_str()); +} + +TEST(ContentSettingsPatternTest, FromString_FilePatterns) { + EXPECT_TRUE(Pattern("file:///").IsValid()); + EXPECT_STREQ("file:///", + Pattern("file:///").ToString().c_str()); + EXPECT_TRUE(Pattern("file:///").Matches( + GURL("file:///"))); + EXPECT_FALSE(Pattern("file:///").Matches( + GURL("file:///tmp/test.html"))); + + EXPECT_TRUE(Pattern("file:///tmp/test.html").IsValid()); + EXPECT_STREQ("file:///tmp/file.html", + Pattern("file:///tmp/file.html").ToString().c_str()); + EXPECT_TRUE(Pattern("file:///tmp/test.html").Matches( + GURL("file:///tmp/test.html"))); + EXPECT_FALSE(Pattern("file:///tmp/test.html").Matches( + GURL("file:///tmp/other.html"))); + EXPECT_FALSE(Pattern("file:///tmp/test.html").Matches( + GURL("http://example.org/"))); +} + +TEST(ContentSettingsPatternTest, FromString_ExtensionPatterns) { + EXPECT_TRUE(Pattern("chrome-extension://peoadpeiejnhkmpaakpnompolbglelel/") + .IsValid()); + EXPECT_STREQ("chrome-extension://peoadpeiejnhkmpaakpnompolbglelel/", + Pattern("chrome-extension://peoadpeiejnhkmpaakpnompolbglelel/") + .ToString().c_str()); + EXPECT_TRUE(Pattern("chrome-extension://peoadpeiejnhkmpaakpnompolbglelel/") + .Matches(GURL("chrome-extension://peoadpeiejnhkmpaakpnompolbglelel/"))); +} + +TEST(ContentSettingsPatternTest, FromString_WithIPAdresses) { + // IPv4 + EXPECT_TRUE(Pattern("192.168.0.1").IsValid()); + EXPECT_STREQ("192.168.1.1", Pattern("192.168.1.1").ToString().c_str()); + EXPECT_TRUE(Pattern("https://192.168.0.1:8080").IsValid()); + EXPECT_STREQ("https://192.168.0.1:8080", + Pattern("https://192.168.0.1:8080").ToString().c_str()); + // IPv6 + EXPECT_TRUE(Pattern("[::1]").IsValid()); + EXPECT_STREQ("[::1]", Pattern("[::1]").ToString().c_str()); + EXPECT_TRUE(Pattern("https://[::1]:8080").IsValid()); + EXPECT_STREQ("https://[::1]:8080", + Pattern("https://[::1]:8080").ToString().c_str()); +} + +TEST(ContentSettingsPatternTest, FromString_WithWildcards) { + // Creating content settings patterns from strings completes pattern parts + // that are omitted in pattern specifications (strings) with a wildcard. + + // The wildcard pattern. + EXPECT_TRUE(Pattern("*").IsValid()); + EXPECT_STREQ("*", Pattern("*").ToString().c_str()); + EXPECT_EQ(ContentSettingsPattern::IDENTITY, + Pattern("*").Compare(ContentSettingsPattern::Wildcard())); + + // Patterns with port wildcard. + EXPECT_TRUE(Pattern("http://example.com:*").IsValid()); + EXPECT_STREQ("http://example.com", + Pattern("http://example.com:*").ToString().c_str()); + + EXPECT_TRUE(Pattern("https://example.com").IsValid()); + EXPECT_STREQ("https://example.com", + Pattern("https://example.com").ToString().c_str()); + + EXPECT_TRUE(Pattern("*://www.google.com.com:8080").IsValid()); + EXPECT_STREQ("www.google.com:8080", + Pattern("*://www.google.com:8080").ToString().c_str()); + EXPECT_TRUE(Pattern("*://www.google.com:8080").Matches( + GURL("http://www.google.com:8080"))); + EXPECT_TRUE(Pattern("*://www.google.com:8080").Matches( + GURL("https://www.google.com:8080"))); + EXPECT_FALSE( + Pattern("*://www.google.com").Matches(GURL("file:///foo/bar.html"))); + + EXPECT_TRUE(Pattern("www.example.com:8080").IsValid()); + + // Patterns with port and scheme wildcard. + EXPECT_TRUE(Pattern("*://www.example.com:*").IsValid()); + EXPECT_STREQ("www.example.com", + Pattern("*://www.example.com:*").ToString().c_str()); + + EXPECT_TRUE(Pattern("*://www.example.com").IsValid()); + EXPECT_STREQ("www.example.com", + Pattern("*://www.example.com").ToString().c_str()); + + EXPECT_TRUE(Pattern("www.example.com:*").IsValid()); + EXPECT_STREQ("www.example.com", + Pattern("www.example.com:*").ToString().c_str()); + + EXPECT_TRUE(Pattern("www.example.com").IsValid()); + EXPECT_STREQ("www.example.com", + Pattern("www.example.com").ToString().c_str()); + EXPECT_TRUE(Pattern("www.example.com").Matches( + GURL("http://www.example.com/"))); + EXPECT_FALSE(Pattern("example.com").Matches( + GURL("http://example.org/"))); + + // Patterns with domain wildcard. + EXPECT_TRUE(Pattern("[*.]example.com").IsValid()); + EXPECT_STREQ("[*.]example.com", + Pattern("[*.]example.com").ToString().c_str()); + EXPECT_TRUE(Pattern("[*.]example.com").Matches( + GURL("http://example.com/"))); + EXPECT_TRUE(Pattern("[*.]example.com").Matches( + GURL("http://foo.example.com/"))); + EXPECT_FALSE(Pattern("[*.]example.com").Matches( + GURL("http://example.org/"))); + + EXPECT_TRUE(Pattern("[*.]google.com:80").Matches( + GURL("http://mail.google.com:80"))); + EXPECT_FALSE(Pattern("[*.]google.com:80").Matches( + GURL("http://mail.google.com:81"))); + EXPECT_TRUE(Pattern("[*.]google.com:80").Matches( + GURL("http://www.google.com"))); + + EXPECT_TRUE(Pattern("[*.]google.com:8080").Matches( + GURL("http://mail.google.com:8080"))); + + EXPECT_TRUE(Pattern("[*.]google.com:443").Matches( + GURL("https://mail.google.com:443"))); + EXPECT_TRUE(Pattern("[*.]google.com:443").Matches( + GURL("https://www.google.com"))); + + EXPECT_TRUE(Pattern("[*.]google.com:4321").Matches( + GURL("https://mail.google.com:4321"))); + EXPECT_TRUE(Pattern("[*.]example.com").Matches( + GURL("http://example.com/"))); + EXPECT_TRUE(Pattern("[*.]example.com").Matches( + GURL("http://www.example.com/"))); + + // Patterns with host wildcard + // TODO(markusheintz): Should these patterns be allowed? + // EXPECT_TRUE(Pattern("http://*").IsValid()); + // EXPECT_TRUE(Pattern("http://*:8080").IsValid()); + EXPECT_TRUE(Pattern("*://*").IsValid()); + EXPECT_STREQ("*", Pattern("*://*").ToString().c_str()); +} + +TEST(ContentSettingsPatternTest, FromString_Canonicalized) { + // UTF-8 patterns. + EXPECT_TRUE(Pattern("[*.]\xC4\x87ira.com").IsValid()); + EXPECT_STREQ("[*.]xn--ira-ppa.com", + Pattern("[*.]\xC4\x87ira.com").ToString().c_str()); + EXPECT_TRUE(Pattern("\xC4\x87ira.com").IsValid()); + EXPECT_STREQ("xn--ira-ppa.com", + Pattern("\xC4\x87ira.com").ToString().c_str()); + EXPECT_TRUE(Pattern("file:///\xC4\x87ira.html").IsValid()); + EXPECT_STREQ("file:///%C4%87ira.html", + Pattern("file:///\xC4\x87ira.html").ToString().c_str()); + + // File path normalization. + EXPECT_TRUE(Pattern("file:///tmp/bar/../test.html").IsValid()); + EXPECT_STREQ("file:///tmp/test.html", + Pattern("file:///tmp/bar/../test.html").ToString().c_str()); +} + +TEST(ContentSettingsPatternTest, InvalidPatterns) { + // StubObserver expects an empty pattern top be returned as empty string. + EXPECT_FALSE(ContentSettingsPattern().IsValid()); + EXPECT_STREQ("", ContentSettingsPattern().ToString().c_str()); + + // Empty pattern string + EXPECT_FALSE(Pattern("").IsValid()); + EXPECT_STREQ("", Pattern("").ToString().c_str()); + + // Pattern strings with invalid scheme part. + EXPECT_FALSE(Pattern("ftp://myhost.org").IsValid()); + EXPECT_STREQ("", Pattern("ftp://myhost.org").ToString().c_str()); + + // Pattern strings with invalid host part. + EXPECT_FALSE(Pattern("*example.com").IsValid()); + EXPECT_STREQ("", Pattern("*example.com").ToString().c_str()); + EXPECT_FALSE(Pattern("example.*").IsValid()); + EXPECT_STREQ("", Pattern("example.*").ToString().c_str()); + EXPECT_FALSE(Pattern("*\xC4\x87ira.com").IsValid()); + EXPECT_STREQ("", Pattern("*\xC4\x87ira.com").ToString().c_str()); + EXPECT_FALSE(Pattern("\xC4\x87ira.*").IsValid()); + EXPECT_STREQ("", Pattern("\xC4\x87ira.*").ToString().c_str()); + + // Pattern strings with invalid port parts. + EXPECT_FALSE(Pattern("example.com:abc").IsValid()); + EXPECT_STREQ("", Pattern("example.com:abc").ToString().c_str()); + + // Invalid file pattern strings. + EXPECT_FALSE(Pattern("file://").IsValid()); + EXPECT_STREQ("", Pattern("file://").ToString().c_str()); + EXPECT_FALSE(Pattern("file:///foo/bar.html:8080").IsValid()); + EXPECT_STREQ("", Pattern("file:///foo/bar.html:8080").ToString().c_str()); +} + +TEST(ContentSettingsPatternTest, Compare) { + // Test identical patterns patterns. + ContentSettingsPattern pattern1 = + Pattern("http://www.google.com"); + EXPECT_EQ(ContentSettingsPattern::IDENTITY, pattern1.Compare(pattern1)); + EXPECT_EQ(ContentSettingsPattern::IDENTITY, + Pattern("http://www.google.com:80").Compare( + Pattern("http://www.google.com:80"))); + EXPECT_EQ(ContentSettingsPattern::IDENTITY, + Pattern("*://[*.]google.com:*").Compare( + Pattern("*://[*.]google.com:*"))); + + // Test disjoint patterns. + EXPECT_EQ(ContentSettingsPattern::DISJOINT, + Pattern("http://www.google.com").Compare( + Pattern("http://www.youtube.com"))); + EXPECT_EQ(ContentSettingsPattern::DISJOINT, + Pattern("http://[*.]google.com").Compare( + Pattern("http://[*.]youtube.com"))); + EXPECT_EQ(ContentSettingsPattern::DISJOINT, + Pattern("http://[*.]host.com").Compare( + Pattern("http://[*.]evilhost.com"))); + EXPECT_EQ(ContentSettingsPattern::DISJOINT, + Pattern("*://www.google.com:80").Compare( + Pattern("*://www.google.com:8080"))); + EXPECT_EQ(ContentSettingsPattern::DISJOINT, + Pattern("https://www.google.com:80").Compare( + Pattern("http://www.google.com:80"))); + + EXPECT_EQ(ContentSettingsPattern::DISJOINT, + Pattern("http://[*.]google.com:90").Compare( + Pattern("http://mail.google.com:80"))); + EXPECT_EQ(ContentSettingsPattern::DISJOINT, + Pattern("https://[*.]google.com:80").Compare( + Pattern("http://mail.google.com:80"))); + EXPECT_EQ(ContentSettingsPattern::DISJOINT, + Pattern("https://mail.google.com:*").Compare( + Pattern("http://mail.google.com:80"))); + + // Test patterns with different precedences. + EXPECT_EQ(ContentSettingsPattern::PREDECESSOR, + Pattern("mail.google.com").Compare( + Pattern("[*.]google.com"))); + EXPECT_EQ(ContentSettingsPattern::SUCCESSOR, + Pattern("[*.]google.com").Compare( + Pattern("mail.google.com"))); + + EXPECT_EQ(ContentSettingsPattern::PREDECESSOR, + Pattern("[*.]mail.google.com").Compare( + Pattern("[*.]google.com"))); + EXPECT_EQ(ContentSettingsPattern::SUCCESSOR, + Pattern("[*.]google.com").Compare( + Pattern("[*.]mail.google.com"))); + + EXPECT_EQ(ContentSettingsPattern::PREDECESSOR, + Pattern("mail.google.com:80").Compare( + Pattern("mail.google.com:*"))); + EXPECT_EQ(ContentSettingsPattern::SUCCESSOR, + Pattern("mail.google.com:*").Compare( + Pattern("mail.google.com:80"))); + + EXPECT_EQ(ContentSettingsPattern::PREDECESSOR, + Pattern("https://mail.google.com:*").Compare( + Pattern("*://mail.google.com:*"))); + EXPECT_EQ(ContentSettingsPattern::SUCCESSOR, + Pattern("*://mail.google.com:*").Compare( + Pattern("https://mail.google.com:*"))); + + EXPECT_EQ(ContentSettingsPattern::PREDECESSOR, + Pattern("*://mail.google.com:80").Compare( + Pattern("https://mail.google.com:*"))); + EXPECT_EQ(ContentSettingsPattern::SUCCESSOR, + Pattern("https://mail.google.com:*").Compare( + Pattern("*://mail.google.com:80"))); + + // Test the wildcard pattern. + EXPECT_EQ(ContentSettingsPattern::IDENTITY, + ContentSettingsPattern::Wildcard().Compare( + ContentSettingsPattern::Wildcard())); + + EXPECT_EQ(ContentSettingsPattern::PREDECESSOR, + Pattern("[*.]google.com").Compare( + ContentSettingsPattern::Wildcard())); + EXPECT_EQ(ContentSettingsPattern::SUCCESSOR, + ContentSettingsPattern::Wildcard().Compare( + Pattern("[*.]google.com"))); + + EXPECT_EQ(ContentSettingsPattern::PREDECESSOR, + Pattern("mail.google.com").Compare( + ContentSettingsPattern::Wildcard())); + EXPECT_EQ(ContentSettingsPattern::SUCCESSOR, + ContentSettingsPattern::Wildcard().Compare( + Pattern("mail.google.com"))); +} + +// Legacy tests to ensure backwards compatibility. + +TEST(ContentSettingsPatternTest, PatternSupport_Legacy) { + EXPECT_TRUE(Pattern("[*.]example.com").IsValid()); + EXPECT_TRUE(Pattern("example.com").IsValid()); + EXPECT_TRUE(Pattern("192.168.0.1").IsValid()); + EXPECT_TRUE(Pattern("[::1]").IsValid()); + EXPECT_TRUE( + Pattern("file:///tmp/test.html").IsValid()); + EXPECT_FALSE(Pattern("*example.com").IsValid()); + EXPECT_FALSE(Pattern("example.*").IsValid()); + + EXPECT_TRUE( + Pattern("http://example.com").IsValid()); + EXPECT_TRUE( + Pattern("https://example.com").IsValid()); + + EXPECT_TRUE(Pattern("[*.]example.com").Matches( GURL("http://example.com/"))); - EXPECT_TRUE(ContentSettingsPattern("[*.]example.com").Matches( + EXPECT_TRUE(Pattern("[*.]example.com").Matches( GURL("http://www.example.com/"))); - EXPECT_TRUE(ContentSettingsPattern("www.example.com").Matches( + EXPECT_TRUE(Pattern("www.example.com").Matches( GURL("http://www.example.com/"))); - EXPECT_TRUE(ContentSettingsPattern("file:///tmp/test.html").Matches( + EXPECT_TRUE( + Pattern("file:///tmp/test.html").Matches( GURL("file:///tmp/test.html"))); - EXPECT_FALSE(ContentSettingsPattern("").Matches( + EXPECT_FALSE(Pattern("").Matches( GURL("http://www.example.com/"))); - EXPECT_FALSE(ContentSettingsPattern("[*.]example.com").Matches( + EXPECT_FALSE(Pattern("[*.]example.com").Matches( GURL("http://example.org/"))); - EXPECT_FALSE(ContentSettingsPattern("example.com").Matches( + EXPECT_FALSE(Pattern("example.com").Matches( GURL("http://example.org/"))); - EXPECT_FALSE(ContentSettingsPattern("file:///tmp/test.html").Matches( + EXPECT_FALSE( + Pattern("file:///tmp/test.html").Matches( GURL("file:///tmp/other.html"))); - EXPECT_FALSE(ContentSettingsPattern("file:///tmp/test.html").Matches( + EXPECT_FALSE( + Pattern("file:///tmp/test.html").Matches( GURL("http://example.org/"))); } -TEST(ContentSettingsPatternTest, CanonicalizePattern) { +TEST(ContentSettingsPatternTest, CanonicalizePattern_Legacy) { // Basic patterns. - EXPECT_STREQ("[*.]ikea.com", ContentSettingsPattern("[*.]ikea.com") - .CanonicalizePattern().c_str()); - EXPECT_STREQ("example.com", ContentSettingsPattern("example.com") - .CanonicalizePattern().c_str()); - EXPECT_STREQ("192.168.1.1", ContentSettingsPattern("192.168.1.1") - .CanonicalizePattern().c_str()); - EXPECT_STREQ("[::1]", ContentSettingsPattern("[::1]") - .CanonicalizePattern().c_str()); - EXPECT_STREQ("file:///tmp/file.html", ContentSettingsPattern( - "file:///tmp/file.html").CanonicalizePattern().c_str()); + EXPECT_STREQ("[*.]ikea.com", Pattern("[*.]ikea.com").ToString().c_str()); + EXPECT_STREQ("example.com", Pattern("example.com").ToString().c_str()); + EXPECT_STREQ("192.168.1.1", Pattern("192.168.1.1").ToString().c_str()); + EXPECT_STREQ("[::1]", Pattern("[::1]").ToString().c_str()); + EXPECT_STREQ("file:///tmp/file.html", + Pattern("file:///tmp/file.html").ToString().c_str()); // UTF-8 patterns. - EXPECT_STREQ("[*.]xn--ira-ppa.com", ContentSettingsPattern( - "[*.]\xC4\x87ira.com").CanonicalizePattern().c_str()); - EXPECT_STREQ("xn--ira-ppa.com", ContentSettingsPattern( - "\xC4\x87ira.com").CanonicalizePattern().c_str()); - EXPECT_STREQ("file:///%C4%87ira.html", ContentSettingsPattern( - "file:///\xC4\x87ira.html").CanonicalizePattern().c_str()); + EXPECT_STREQ("[*.]xn--ira-ppa.com", + Pattern("[*.]\xC4\x87ira.com").ToString().c_str()); + EXPECT_STREQ("xn--ira-ppa.com", + Pattern("\xC4\x87ira.com").ToString().c_str()); + EXPECT_STREQ("file:///%C4%87ira.html", + Pattern("file:///\xC4\x87ira.html").ToString().c_str()); // file:/// normalization. - EXPECT_STREQ("file:///tmp/test.html", ContentSettingsPattern( - "file:///tmp/bar/../test.html").CanonicalizePattern().c_str()); + EXPECT_STREQ("file:///tmp/test.html", + Pattern("file:///tmp/bar/../test.html").ToString().c_str()); // Invalid patterns. - EXPECT_STREQ("", ContentSettingsPattern( - "*example.com").CanonicalizePattern().c_str()); - EXPECT_STREQ("", ContentSettingsPattern( - "example.*").CanonicalizePattern().c_str()); - EXPECT_STREQ("", ContentSettingsPattern( - "*\xC4\x87ira.com").CanonicalizePattern().c_str()); - EXPECT_STREQ("", ContentSettingsPattern( - "\xC4\x87ira.*").CanonicalizePattern().c_str()); + EXPECT_STREQ("", Pattern("*example.com").ToString().c_str()); + EXPECT_STREQ("", Pattern("example.*").ToString().c_str()); + EXPECT_STREQ("", Pattern("*\xC4\x87ira.com").ToString().c_str()); + EXPECT_STREQ("", Pattern("\xC4\x87ira.*").ToString().c_str()); } - -} // namespace diff --git a/chrome/browser/content_settings/content_settings_policy_provider.cc b/chrome/browser/content_settings/content_settings_policy_provider.cc index 1b16947..dcd595a 100644 --- a/chrome/browser/content_settings/content_settings_policy_provider.cc +++ b/chrome/browser/content_settings/content_settings_policy_provider.cc @@ -340,11 +340,12 @@ void PolicyProvider::GetContentSettingsFromPreferences( for (size_t j = 0; j < pattern_str_list->GetSize(); ++j) { std::string original_pattern_str; pattern_str_list->GetString(j, &original_pattern_str); - ContentSettingsPattern pattern(original_pattern_str); + ContentSettingsPattern pattern = ContentSettingsPattern::FromString( + original_pattern_str); // Ignore invalid patterns. if (!pattern.IsValid()) { VLOG(1) << "Ignoring invalid content settings pattern: " << - pattern.AsString(); + pattern.ToString(); continue; } rules->push_back(MakeTuple( diff --git a/chrome/browser/content_settings/content_settings_policy_provider_unittest.cc b/chrome/browser/content_settings/content_settings_policy_provider_unittest.cc index d18d7a2..ec29eb1 100644 --- a/chrome/browser/content_settings/content_settings_policy_provider_unittest.cc +++ b/chrome/browser/content_settings/content_settings_policy_provider_unittest.cc @@ -68,7 +68,6 @@ TEST_F(PolicyDefaultProviderTest, ObserveManagedSettingsChange) { prefs->SetManagedPref(prefs::kManagedDefaultImagesSetting, Value::CreateIntegerValue(CONTENT_SETTING_BLOCK)); EXPECT_EQ(profile.GetHostContentSettingsMap(), observer.last_notifier); - EXPECT_EQ(ContentSettingsPattern(), observer.last_pattern); EXPECT_EQ(CONTENT_SETTINGS_TYPE_DEFAULT, observer.last_type); EXPECT_TRUE(observer.last_update_all); EXPECT_TRUE(observer.last_update_all_types); @@ -78,7 +77,6 @@ TEST_F(PolicyDefaultProviderTest, ObserveManagedSettingsChange) { prefs->RemoveManagedPref(prefs::kManagedDefaultImagesSetting); EXPECT_EQ(profile.GetHostContentSettingsMap(), observer.last_notifier); EXPECT_EQ(CONTENT_SETTINGS_TYPE_DEFAULT, observer.last_type); - EXPECT_EQ(ContentSettingsPattern(), observer.last_pattern); EXPECT_TRUE(observer.last_update_all); EXPECT_TRUE(observer.last_update_all_types); EXPECT_EQ(2, observer.counter); @@ -110,7 +108,8 @@ TEST_F(PolicyProviderTest, Default) { PolicyProvider provider(&profile, NULL); - ContentSettingsPattern yt_url_pattern("www.youtube.com"); + ContentSettingsPattern yt_url_pattern = + ContentSettingsPattern::FromString("www.youtube.com"); GURL youtube_url("http://www.youtube.com"); GURL google_url("http://mail.google.com"); diff --git a/chrome/browser/content_settings/content_settings_pref_provider.cc b/chrome/browser/content_settings/content_settings_pref_provider.cc index a9ae7c3..0d26a26 100644 --- a/chrome/browser/content_settings/content_settings_pref_provider.cc +++ b/chrome/browser/content_settings/content_settings_pref_provider.cc @@ -398,15 +398,13 @@ void PrefProvider::SetContentSetting( CommandLine::ForCurrentProcess()->HasSwitch( switches::kEnableClickToPlay)); - const ContentSettingsPattern pattern( - requesting_pattern.CanonicalizePattern()); - bool early_exit = false; - std::string pattern_str(pattern.AsString()); + std::string pattern_str(requesting_pattern.ToString()); DictionaryValue* all_settings_dictionary = NULL; updating_preferences_ = true; - { // Begin scope of update. + { + // Begin scope of update. // profile_ may be NULL in unit tests. DictionaryPrefUpdate update(profile_ ? profile_->GetPrefs() : NULL, prefs::kContentSettingsPatterns); @@ -493,7 +491,7 @@ void PrefProvider::SetContentSetting( } // End scope of update. updating_preferences_ = false; - NotifyObservers(ContentSettingsDetails(pattern, content_type, "")); + NotifyObservers(ContentSettingsDetails(requesting_pattern, content_type, "")); } void PrefProvider::ResetToDefaults() { @@ -639,7 +637,7 @@ void PrefProvider::ReadExceptions(bool overwrite) { for (DictionaryValue::key_iterator i(mutable_settings->begin_keys()); i != mutable_settings->end_keys(); ++i) { const std::string& pattern(*i); - if (!ContentSettingsPattern(pattern).IsValid()) + if (!ContentSettingsPattern::FromString(pattern).IsValid()) LOG(WARNING) << "Invalid pattern stored in content settings"; DictionaryValue* pattern_settings_dictionary = NULL; bool found = mutable_settings->GetDictionaryWithoutPathExpansion( @@ -669,7 +667,7 @@ void PrefProvider::CanonicalizeContentSettingsExceptions( i != all_settings_dictionary->end_keys(); ++i) { const std::string& pattern(*i); const std::string canonicalized_pattern = - ContentSettingsPattern(pattern).CanonicalizePattern(); + ContentSettingsPattern::FromString(pattern).ToString(); if (canonicalized_pattern.empty() || canonicalized_pattern == pattern) continue; @@ -793,7 +791,7 @@ void PrefProvider::MigrateObsoletePerhostPref(PrefService* prefs) { i(all_settings_dictionary->begin_keys()); i != all_settings_dictionary->end_keys(); ++i) { const std::string& host(*i); - ContentSettingsPattern pattern( + ContentSettingsPattern pattern = ContentSettingsPattern::FromString( std::string(ContentSettingsPattern::kDomainWildcard) + host); DictionaryValue* host_settings_dictionary = NULL; bool found = all_settings_dictionary->GetDictionaryWithoutPathExpansion( @@ -825,8 +823,8 @@ void PrefProvider::MigrateObsoletePopupsPref(PrefService* prefs) { i != whitelist_pref->end(); ++i) { std::string host; (*i)->GetAsString(&host); - SetContentSetting(ContentSettingsPattern(host), - ContentSettingsPattern(host), + SetContentSetting(ContentSettingsPattern::FromString(host), + ContentSettingsPattern::FromString(host), CONTENT_SETTINGS_TYPE_POPUPS, "", CONTENT_SETTING_ALLOW); diff --git a/chrome/browser/content_settings/content_settings_pref_provider_unittest.cc b/chrome/browser/content_settings/content_settings_pref_provider_unittest.cc index c6f7f2d..c3a92be 100644 --- a/chrome/browser/content_settings/content_settings_pref_provider_unittest.cc +++ b/chrome/browser/content_settings/content_settings_pref_provider_unittest.cc @@ -177,7 +177,8 @@ TEST_F(PrefProviderTest, Observer) { Profile* p = &profile; PrefProvider pref_content_settings_provider(p); StubSettingsObserver observer; - ContentSettingsPattern pattern("[*.]example.com"); + ContentSettingsPattern pattern = + ContentSettingsPattern::FromString("[*.]example.com"); pref_content_settings_provider.SetContentSetting( pattern, @@ -234,7 +235,8 @@ TEST_F(PrefProviderTest, Incognito) { PrefProvider pref_content_settings_provider(&profile); PrefProvider pref_content_settings_provider_incognito(otr_profile); - ContentSettingsPattern pattern("[*.]example.com"); + ContentSettingsPattern pattern = + ContentSettingsPattern::FromString("[*.]example.com"); pref_content_settings_provider.SetContentSetting( pattern, pattern, @@ -265,9 +267,12 @@ TEST_F(PrefProviderTest, Patterns) { GURL host2("http://www.example.com/"); GURL host3("http://example.org/"); GURL host4("file:///tmp/test.html"); - ContentSettingsPattern pattern1("[*.]example.com"); - ContentSettingsPattern pattern2("example.org"); - ContentSettingsPattern pattern3("file:///tmp/test.html"); + ContentSettingsPattern pattern1 = + ContentSettingsPattern::FromString("[*.]example.com"); + ContentSettingsPattern pattern2 = + ContentSettingsPattern::FromString("example.org"); + ContentSettingsPattern pattern3 = + ContentSettingsPattern::FromString("file:///tmp/test.html"); EXPECT_EQ(CONTENT_SETTING_DEFAULT, pref_content_settings_provider.GetContentSetting( @@ -324,7 +329,8 @@ TEST_F(PrefProviderTest, ResourceIdentifier) { testing_profile.GetOriginalProfile()); GURL host("http://example.com/"); - ContentSettingsPattern pattern("[*.]example.com"); + ContentSettingsPattern pattern = + ContentSettingsPattern::FromString("[*.]example.com"); std::string resource1("someplugin"); std::string resource2("otherplugin"); diff --git a/chrome/browser/content_settings/content_settings_provider_unittest.cc b/chrome/browser/content_settings/content_settings_provider_unittest.cc index 11c0284..0b41475 100644 --- a/chrome/browser/content_settings/content_settings_provider_unittest.cc +++ b/chrome/browser/content_settings/content_settings_provider_unittest.cc @@ -1,4 +1,4 @@ -// Copyright (c) 2010 The Chromium Authors. All rights reserved. +// Copyright (c) 2011 The Chromium Authors. All rights reserved. // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. @@ -25,7 +25,8 @@ TEST(ContentSettingsProviderTest, Mock) { EXPECT_EQ(CONTENT_SETTING_BLOCK, provider.ProvideDefaultSetting(CONTENT_SETTINGS_TYPE_COOKIES)); - ContentSettingsPattern pattern("[*.]youtube.com"); + ContentSettingsPattern pattern = + ContentSettingsPattern::FromString("[*.]youtube.com"); GURL url("http://www.youtube.com"); MockProvider mock_provider( diff --git a/chrome/browser/content_settings/host_content_settings_map_unittest.cc b/chrome/browser/content_settings/host_content_settings_map_unittest.cc index 47b6702..71a5c08 100644 --- a/chrome/browser/content_settings/host_content_settings_map_unittest.cc +++ b/chrome/browser/content_settings/host_content_settings_map_unittest.cc @@ -83,7 +83,8 @@ TEST_F(HostContentSettingsMapTest, DefaultValues) { // Check returning individual settings. GURL host("http://example.com/"); - ContentSettingsPattern pattern("[*.]example.com"); + ContentSettingsPattern pattern = + ContentSettingsPattern::FromString("[*.]example.com"); EXPECT_EQ(CONTENT_SETTING_ALLOW, host_content_settings_map->GetContentSetting( host, CONTENT_SETTINGS_TYPE_IMAGES, "")); @@ -130,7 +131,8 @@ TEST_F(HostContentSettingsMapTest, DefaultValues) { EXPECT_TRUE(SettingsEqual(desired_settings, settings)); // Check returning all hosts for a setting. - ContentSettingsPattern pattern2("[*.]example.org"); + ContentSettingsPattern pattern2 = + ContentSettingsPattern::FromString("[*.]example.org"); host_content_settings_map->SetContentSetting(pattern2, CONTENT_SETTINGS_TYPE_IMAGES, "", CONTENT_SETTING_BLOCK); host_content_settings_map->SetContentSetting(pattern2, @@ -153,7 +155,8 @@ TEST_F(HostContentSettingsMapTest, DefaultValues) { EXPECT_EQ(0U, host_settings.size()); // Check clearing one type. - ContentSettingsPattern pattern3("[*.]example.net"); + ContentSettingsPattern pattern3 = + ContentSettingsPattern::FromString("[*.]example.net"); host_content_settings_map->SetContentSetting(pattern, CONTENT_SETTINGS_TYPE_IMAGES, "", CONTENT_SETTING_BLOCK); host_content_settings_map->SetContentSetting(pattern2, @@ -181,8 +184,10 @@ TEST_F(HostContentSettingsMapTest, Patterns) { GURL host1("http://example.com/"); GURL host2("http://www.example.com/"); GURL host3("http://example.org/"); - ContentSettingsPattern pattern1("[*.]example.com"); - ContentSettingsPattern pattern2("example.org"); + ContentSettingsPattern pattern1 = + ContentSettingsPattern::FromString("[*.]example.com"); + ContentSettingsPattern pattern2 = + ContentSettingsPattern::FromString("example.org"); EXPECT_EQ(CONTENT_SETTING_ALLOW, host_content_settings_map->GetContentSetting( host1, CONTENT_SETTINGS_TYPE_IMAGES, "")); @@ -210,7 +215,8 @@ TEST_F(HostContentSettingsMapTest, Observer) { profile.GetHostContentSettingsMap(); StubSettingsObserver observer; - ContentSettingsPattern pattern("[*.]example.com"); + ContentSettingsPattern pattern = + ContentSettingsPattern::FromString("[*.]example.com"); host_content_settings_map->SetContentSetting(pattern, CONTENT_SETTINGS_TYPE_IMAGES, "", CONTENT_SETTING_ALLOW); EXPECT_EQ(host_content_settings_map, observer.last_notifier); @@ -287,7 +293,8 @@ TEST_F(HostContentSettingsMapTest, ObserveExceptionPref) { scoped_ptr<Value> default_value(prefs->FindPreference( prefs::kContentSettingsPatterns)->GetValue()->DeepCopy()); - ContentSettingsPattern pattern("[*.]example.com"); + ContentSettingsPattern pattern = + ContentSettingsPattern::FromString("[*.]example.com"); GURL host("http://example.com"); host_content_settings_map->SetContentSetting(pattern, @@ -318,7 +325,8 @@ TEST_F(HostContentSettingsMapTest, HostTrimEndingDotCheck) { HostContentSettingsMap* host_content_settings_map = profile.GetHostContentSettingsMap(); - ContentSettingsPattern pattern("[*.]example.com"); + ContentSettingsPattern pattern = + ContentSettingsPattern::FromString("[*.]example.com"); GURL host_ending_with_dot("http://example.com./"); EXPECT_EQ(CONTENT_SETTING_ALLOW, @@ -398,9 +406,12 @@ TEST_F(HostContentSettingsMapTest, NestedSettings) { profile.GetHostContentSettingsMap(); GURL host("http://a.b.example.com/"); - ContentSettingsPattern pattern1("[*.]example.com"); - ContentSettingsPattern pattern2("[*.]b.example.com"); - ContentSettingsPattern pattern3("a.b.example.com"); + ContentSettingsPattern pattern1 = + ContentSettingsPattern::FromString("[*.]example.com"); + ContentSettingsPattern pattern2 = + ContentSettingsPattern::FromString("[*.]b.example.com"); + ContentSettingsPattern pattern3 = + ContentSettingsPattern::FromString("a.b.example.com"); host_content_settings_map->SetContentSetting(pattern1, CONTENT_SETTINGS_TYPE_IMAGES, "", CONTENT_SETTING_BLOCK); @@ -455,7 +466,8 @@ TEST_F(HostContentSettingsMapTest, OffTheRecord) { profile.set_incognito(false); GURL host("http://example.com/"); - ContentSettingsPattern pattern("[*.]example.com"); + ContentSettingsPattern pattern = + ContentSettingsPattern::FromString("[*.]example.com"); EXPECT_EQ(CONTENT_SETTING_ALLOW, host_content_settings_map->GetContentSetting( @@ -605,7 +617,8 @@ TEST_F(HostContentSettingsMapTest, NonDefaultSettings) { profile.GetHostContentSettingsMap(); GURL host("http://example.com/"); - ContentSettingsPattern pattern("[*.]example.com"); + ContentSettingsPattern pattern = + ContentSettingsPattern::FromString("[*.]example.com"); ContentSettings desired_settings(CONTENT_SETTING_DEFAULT); ContentSettings settings = @@ -632,7 +645,8 @@ TEST_F(HostContentSettingsMapTest, ResourceIdentifier) { profile.GetHostContentSettingsMap(); GURL host("http://example.com/"); - ContentSettingsPattern pattern("[*.]example.com"); + ContentSettingsPattern pattern = + ContentSettingsPattern::FromString("[*.]example.com"); std::string resource1("someplugin"); std::string resource2("otherplugin"); @@ -671,7 +685,8 @@ TEST_F(HostContentSettingsMapTest, ResourceIdentifierPrefs) { profile.GetHostContentSettingsMap(); GURL host("http://example.com/"); - ContentSettingsPattern pattern("[*.]example.com"); + ContentSettingsPattern pattern = + ContentSettingsPattern::FromString("[*.]example.com"); std::string resource1("someplugin"); std::string resource2("otherplugin"); @@ -745,7 +760,8 @@ TEST_F(HostContentSettingsMapTest, TestingPrefService* prefs = profile.GetTestingPrefService(); // Set pattern for JavaScript setting. - ContentSettingsPattern pattern("[*.]example.com"); + ContentSettingsPattern pattern = + ContentSettingsPattern::FromString("[*.]example.com"); host_content_settings_map->SetContentSetting(pattern, CONTENT_SETTINGS_TYPE_JAVASCRIPT, "", CONTENT_SETTING_BLOCK); @@ -780,7 +796,8 @@ TEST_F(HostContentSettingsMapTest, CONTENT_SETTINGS_TYPE_JAVASCRIPT, CONTENT_SETTING_BLOCK); // Set an exception to allow "[*.]example.com" - ContentSettingsPattern pattern("[*.]example.com"); + ContentSettingsPattern pattern = + ContentSettingsPattern::FromString("[*.]example.com"); host_content_settings_map->SetContentSetting(pattern, CONTENT_SETTINGS_TYPE_JAVASCRIPT, "", CONTENT_SETTING_ALLOW); diff --git a/chrome/browser/cookies_tree_model_unittest.cc b/chrome/browser/cookies_tree_model_unittest.cc index d30c136..94051ac 100644 --- a/chrome/browser/cookies_tree_model_unittest.cc +++ b/chrome/browser/cookies_tree_model_unittest.cc @@ -651,7 +651,8 @@ TEST_F(CookiesTreeModelTest, OriginOrdering) { TEST_F(CookiesTreeModelTest, ContentSettings) { GURL host("http://example.com/"); - ContentSettingsPattern pattern("[*.]example.com"); + ContentSettingsPattern pattern = + ContentSettingsPattern::FromString("[*.]example.com"); net::CookieMonster* monster = profile_->GetCookieMonster(); monster->SetCookie(host, "A=1"); diff --git a/chrome/browser/notifications/desktop_notification_service.cc b/chrome/browser/notifications/desktop_notification_service.cc index 6241808..205afb6 100644 --- a/chrome/browser/notifications/desktop_notification_service.cc +++ b/chrome/browser/notifications/desktop_notification_service.cc @@ -60,7 +60,7 @@ void GetOriginsWithSettingFromContentSettingsRules( rule != content_setting_rules.end(); ++rule) { if (setting == rule->content_setting) { - std::string url_str = rule->requesting_url_pattern.AsString(); + std::string url_str = rule->requesting_url_pattern.ToString(); if (!rule->requesting_url_pattern.IsValid()) { // TODO(markusheintz): This will be removed in one of the next // refactoring steps as this entire function will disapear. diff --git a/chrome/browser/plugin_exceptions_table_model.cc b/chrome/browser/plugin_exceptions_table_model.cc index 81200fe..c6b310b 100644 --- a/chrome/browser/plugin_exceptions_table_model.cc +++ b/chrome/browser/plugin_exceptions_table_model.cc @@ -84,7 +84,7 @@ string16 PluginExceptionsTableModel::GetText(int row, int column_id) { SettingsEntry& entry = settings_[row]; if (column_id == IDS_EXCEPTIONS_PATTERN_HEADER || column_id == IDS_EXCEPTIONS_HOSTNAME_HEADER) { - return UTF8ToUTF16(entry.pattern.AsString()); + return UTF8ToUTF16(entry.pattern.ToString()); } else if (column_id == IDS_EXCEPTIONS_ACTION_HEADER) { switch (entry.setting) { case CONTENT_SETTING_ALLOW: diff --git a/chrome/browser/plugin_exceptions_table_model_unittest.cc b/chrome/browser/plugin_exceptions_table_model_unittest.cc index 95342b1..80b3526 100644 --- a/chrome/browser/plugin_exceptions_table_model_unittest.cc +++ b/chrome/browser/plugin_exceptions_table_model_unittest.cc @@ -67,8 +67,10 @@ class PluginExceptionsTableModelTest : public testing::Test { HostContentSettingsMap* map = profile_->GetHostContentSettingsMap(); - ContentSettingsPattern example_com("[*.]example.com"); - ContentSettingsPattern moose_org("[*.]moose.org"); + ContentSettingsPattern example_com = + ContentSettingsPattern::FromString("[*.]example.com"); + ContentSettingsPattern moose_org = + ContentSettingsPattern::FromString("[*.]moose.org"); map->SetContentSetting(example_com, CONTENT_SETTINGS_TYPE_PLUGINS, "a-foo", @@ -185,7 +187,7 @@ TEST_F(PluginExceptionsTableModelTest, RemoveLastRowInGroup) { HostContentSettingsMap* map = profile_->GetHostContentSettingsMap(); EXPECT_CALL(observer, OnModelChanged()); - map->SetContentSetting(ContentSettingsPattern("[*.]blurp.net"), + map->SetContentSetting(ContentSettingsPattern::FromString("[*.]blurp.net"), CONTENT_SETTINGS_TYPE_PLUGINS, "b-bar", CONTENT_SETTING_BLOCK); diff --git a/chrome/browser/ui/cocoa/table_model_array_controller_unittest.mm b/chrome/browser/ui/cocoa/table_model_array_controller_unittest.mm index 65a14910..f7ce628 100644 --- a/chrome/browser/ui/cocoa/table_model_array_controller_unittest.mm +++ b/chrome/browser/ui/cocoa/table_model_array_controller_unittest.mm @@ -1,4 +1,4 @@ -// Copyright (c) 2010 The Chromium Authors. All rights reserved. +// Copyright (c) 2011 The Chromium Authors. All rights reserved. // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. @@ -33,8 +33,10 @@ class TableModelArrayControllerTest : public CocoaTest { TestingProfile* profile = browser_helper_.profile(); HostContentSettingsMap* map = profile->GetHostContentSettingsMap(); - ContentSettingsPattern example_com("[*.]example.com"); - ContentSettingsPattern moose_org("[*.]moose.org"); + ContentSettingsPattern example_com = + ContentSettingsPattern::FromString("[*.]example.com"); + ContentSettingsPattern moose_org = + ContentSettingsPattern::FromString("[*.]moose.org"); map->SetContentSetting(example_com, CONTENT_SETTINGS_TYPE_PLUGINS, "a-foo", @@ -142,7 +144,8 @@ TEST_F(TableModelArrayControllerTest, RemoveAll) { TEST_F(TableModelArrayControllerTest, AddException) { TestingProfile* profile = browser_helper_.profile(); HostContentSettingsMap* map = profile->GetHostContentSettingsMap(); - ContentSettingsPattern example_com("[*.]example.com"); + ContentSettingsPattern example_com = + ContentSettingsPattern::FromString("[*.]example.com"); map->SetContentSetting(example_com, CONTENT_SETTINGS_TYPE_PLUGINS, "c-blurp", diff --git a/chrome/browser/ui/webui/options/content_settings_handler.cc b/chrome/browser/ui/webui/options/content_settings_handler.cc index 7f76ed8..25263bb 100644 --- a/chrome/browser/ui/webui/options/content_settings_handler.cc +++ b/chrome/browser/ui/webui/options/content_settings_handler.cc @@ -4,6 +4,9 @@ #include "chrome/browser/ui/webui/options/content_settings_handler.h" +#include <string> +#include <vector> + #include "base/callback.h" #include "base/command_line.h" #include "base/utf_string_conversions.h" @@ -126,7 +129,7 @@ DictionaryValue* GetExceptionForPage( DictionaryValue* exception = new DictionaryValue(); exception->Set( kDisplayPattern, - new StringValue(pattern.AsString())); + new StringValue(pattern.ToString())); exception->Set( kSetting, new StringValue(ContentSettingToString(setting))); @@ -641,7 +644,7 @@ void ContentSettingsHandler::RemoveException(const ListValue* args) { // got destroyed before we received this message. if (settings_map) { settings_map->SetContentSetting( - ContentSettingsPattern(pattern), + ContentSettingsPattern::FromString(pattern), ContentSettingsTypeFromGroupName(type_string), "", CONTENT_SETTING_DEFAULT); @@ -676,7 +679,7 @@ void ContentSettingsHandler::SetException(const ListValue* args) { if (!settings_map) return; - settings_map->SetContentSetting(ContentSettingsPattern(pattern), + settings_map->SetContentSetting(ContentSettingsPattern::FromString(pattern), type, "", ContentSettingFromString(setting)); @@ -692,7 +695,8 @@ void ContentSettingsHandler::CheckExceptionPatternValidity( std::string pattern_string; CHECK(args->GetString(arg_i++, &pattern_string)); - ContentSettingsPattern pattern(pattern_string); + ContentSettingsPattern pattern = ContentSettingsPattern::FromString( + pattern_string); scoped_ptr<Value> mode_value(Value::CreateStringValue(mode_string)); scoped_ptr<Value> pattern_value(Value::CreateStringValue(pattern_string)); diff --git a/chrome/chrome_browser.gypi b/chrome/chrome_browser.gypi index b71828f..0ce0575 100644 --- a/chrome/chrome_browser.gypi +++ b/chrome/chrome_browser.gypi @@ -738,6 +738,8 @@ 'browser/content_settings/content_settings_details.h', 'browser/content_settings/content_settings_pattern.cc', 'browser/content_settings/content_settings_pattern.h', + 'browser/content_settings/content_settings_pattern_parser.cc', + 'browser/content_settings/content_settings_pattern_parser.h', 'browser/content_settings/content_settings_provider.h', 'browser/content_settings/host_content_settings_map.cc', 'browser/content_settings/host_content_settings_map.h', diff --git a/chrome/chrome_tests.gypi b/chrome/chrome_tests.gypi index abcc095..b5f6e64 100644 --- a/chrome/chrome_tests.gypi +++ b/chrome/chrome_tests.gypi @@ -1323,6 +1323,7 @@ 'browser/content_settings/content_settings_mock_provider.cc', 'browser/content_settings/content_settings_mock_provider.h', 'browser/content_settings/content_settings_pattern_unittest.cc', + 'browser/content_settings/content_settings_pattern_parser_unittest.cc', 'browser/content_settings/content_settings_policy_provider_unittest.cc', 'browser/content_settings/content_settings_pref_provider_unittest.cc', 'browser/content_settings/content_settings_provider_unittest.cc', |