summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authormarkusheintz@chromium.org <markusheintz@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2011-05-19 14:38:28 +0000
committermarkusheintz@chromium.org <markusheintz@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2011-05-19 14:38:28 +0000
commite8491289e4313d396ea9e1522209c1305d60a227 (patch)
tree4ca2b7eeb5e19ed0097a16bb4f3d1492c25ab4e5
parent65cc854b7dd673ba413da7364d5b0b3eb25da405 (diff)
downloadchromium_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
-rw-r--r--chrome/browser/automation/testing_automation_provider.cc2
-rw-r--r--chrome/browser/content_settings/content_settings_base_provider.cc10
-rw-r--r--chrome/browser/content_settings/content_settings_details.h4
-rw-r--r--chrome/browser/content_settings/content_settings_notification_provider.cc24
-rw-r--r--chrome/browser/content_settings/content_settings_pattern.cc457
-rw-r--r--chrome/browser/content_settings/content_settings_pattern.h215
-rw-r--r--chrome/browser/content_settings/content_settings_pattern_parser.cc226
-rw-r--r--chrome/browser/content_settings/content_settings_pattern_parser.h41
-rw-r--r--chrome/browser/content_settings/content_settings_pattern_parser_unittest.cc157
-rw-r--r--chrome/browser/content_settings/content_settings_pattern_unittest.cc531
-rw-r--r--chrome/browser/content_settings/content_settings_policy_provider.cc5
-rw-r--r--chrome/browser/content_settings/content_settings_policy_provider_unittest.cc5
-rw-r--r--chrome/browser/content_settings/content_settings_pref_provider.cc20
-rw-r--r--chrome/browser/content_settings/content_settings_pref_provider_unittest.cc18
-rw-r--r--chrome/browser/content_settings/content_settings_provider_unittest.cc5
-rw-r--r--chrome/browser/content_settings/host_content_settings_map_unittest.cc51
-rw-r--r--chrome/browser/cookies_tree_model_unittest.cc3
-rw-r--r--chrome/browser/notifications/desktop_notification_service.cc2
-rw-r--r--chrome/browser/plugin_exceptions_table_model.cc2
-rw-r--r--chrome/browser/plugin_exceptions_table_model_unittest.cc8
-rw-r--r--chrome/browser/ui/cocoa/table_model_array_controller_unittest.mm11
-rw-r--r--chrome/browser/ui/webui/options/content_settings_handler.cc12
-rw-r--r--chrome/chrome_browser.gypi2
-rw-r--r--chrome/chrome_tests.gypi1
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',