diff options
author | jochen@chromium.org <jochen@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2010-12-02 14:47:45 +0000 |
---|---|---|
committer | jochen@chromium.org <jochen@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2010-12-02 14:47:45 +0000 |
commit | 5f24f215c60528bd329930bf98373a52dfe08555 (patch) | |
tree | f26f29fd3404cacb55f55a038c094d14e2076a73 /chrome/browser/content_settings | |
parent | c139f9bf6f6f5ce2e550c59952ff5bebb1430458 (diff) | |
download | chromium_src-5f24f215c60528bd329930bf98373a52dfe08555.zip chromium_src-5f24f215c60528bd329930bf98373a52dfe08555.tar.gz chromium_src-5f24f215c60528bd329930bf98373a52dfe08555.tar.bz2 |
Move ContentSettingsDetails and Pattern out of HostContentSettingsMap as separate classes.
BUG=64753
TEST=compiles
Review URL: http://codereview.chromium.org/5574001
git-svn-id: svn://svn.chromium.org/chrome/trunk/src@68005 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'chrome/browser/content_settings')
7 files changed, 351 insertions, 273 deletions
diff --git a/chrome/browser/content_settings/content_settings_details.h b/chrome/browser/content_settings/content_settings_details.h new file mode 100644 index 0000000..51c54314c --- /dev/null +++ b/chrome/browser/content_settings/content_settings_details.h @@ -0,0 +1,56 @@ +// Copyright (c) 2010 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. + +// The details send with notifications about content setting changes. + +#ifndef CHROME_BROWSER_CONTENT_SETTINGS_CONTENT_SETTINGS_DETAILS_H_ +#define CHROME_BROWSER_CONTENT_SETTINGS_CONTENT_SETTINGS_DETAILS_H_ +#pragma once + +#include "base/basictypes.h" +#include "chrome/browser/content_settings/content_settings_pattern.h" +#include "chrome/common/content_settings.h" + +// Details for the CONTENT_SETTINGS_CHANGED notification. This is sent when +// content settings change for at least one host. If settings change for more +// than one pattern in one user interaction, this will usually send a single +// notification with update_all() returning true instead of one notification +// for each pattern. +class ContentSettingsDetails { + public: + // Update the setting that matches this pattern/content type/resource. + ContentSettingsDetails(const ContentSettingsPattern& pattern, + ContentSettingsType type, + const std::string& resource_identifier) + : pattern_(pattern), + type_(type), + resource_identifier_(resource_identifier) {} + + // The pattern whose settings have changed. + 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(); } + + // The type of the pattern whose settings have changed. + ContentSettingsType type() const { return type_; } + + // The resource identifier for the settings type that has changed. + const std::string& resource_identifier() const { + return resource_identifier_; + } + + // True if all types should be updated. If update_all() is false, this will + // be false as well (although the reverse does not hold true). + bool update_all_types() const { + return CONTENT_SETTINGS_TYPE_DEFAULT == type_; + } + + private: + ContentSettingsPattern pattern_; + ContentSettingsType type_; + std::string resource_identifier_; +}; + +#endif // CHROME_BROWSER_CONTENT_SETTINGS_CONTENT_SETTINGS_DETAILS_H_ diff --git a/chrome/browser/content_settings/content_settings_pattern.cc b/chrome/browser/content_settings/content_settings_pattern.cc new file mode 100644 index 0000000..ba93ff4b --- /dev/null +++ b/chrome/browser/content_settings/content_settings_pattern.cc @@ -0,0 +1,87 @@ +// Copyright (c) 2010 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 "base/string_util.h" +#include "net/base/net_util.h" +#include "googleurl/src/gurl.h" +#include "googleurl/src/url_canon.h" + +// The version of the pattern format implemented. Version 1 includes the +// following patterns: +// - [*.]domain.tld (matches domain.tld and all sub-domains) +// - host (matches an exact hostname) +// - a.b.c.d (matches an exact IPv4 ip) +// - [a:b:c:d:e:f:g:h] (matches an exact IPv6 ip) +// - file:///tmp/test.html (a complete URL without a host) +// 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; +const char* ContentSettingsPattern::kDomainWildcard = "[*.]"; +const size_t ContentSettingsPattern::kDomainWildcardLength = 4; + +// static +ContentSettingsPattern ContentSettingsPattern::FromURL( + const GURL& url) { + return ContentSettingsPattern(!url.has_host() || url.HostIsIPAddress() ? + net::GetHostOrSpecFromURL(url) : + std::string(kDomainWildcard) + url.host()); +} + +// static +ContentSettingsPattern ContentSettingsPattern::FromURLNoWildcard( + const GURL& url) { + return ContentSettingsPattern(net::GetHostOrSpecFromURL(url)); +} + +bool ContentSettingsPattern::IsValid() const { + if (pattern_.empty()) + return false; + + 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(); +} + +bool ContentSettingsPattern::Matches(const GURL& url) const { + if (!IsValid()) + return false; + + const std::string host(net::GetHostOrSpecFromURL(url)); + if (pattern_.length() < kDomainWildcardLength || + !StartsWithASCII(pattern_, kDomainWildcard, false)) + return pattern_ == host; + + const size_t match = + host.rfind(pattern_.substr(kDomainWildcardLength)); + + return (match != std::string::npos) && + (match == 0 || host[match - 1] == '.') && + (match + pattern_.length() - kDomainWildcardLength == host.length()); +} + +std::string ContentSettingsPattern::CanonicalizePattern() const { + if (!IsValid()) { + return ""; + } + + bool starts_with_wildcard = pattern_.length() > kDomainWildcardLength && + StartsWithASCII(pattern_, kDomainWildcard, false); + + const std::string host(starts_with_wildcard ? + pattern_.substr(kDomainWildcardLength) : pattern_); + + std::string canonicalized_pattern = + starts_with_wildcard ? kDomainWildcard : ""; + + url_canon::CanonHostInfo host_info; + canonicalized_pattern += net::CanonicalizeHost(host, &host_info); + + return canonicalized_pattern; +} diff --git a/chrome/browser/content_settings/content_settings_pattern.h b/chrome/browser/content_settings/content_settings_pattern.h new file mode 100644 index 0000000..330042f --- /dev/null +++ b/chrome/browser/content_settings/content_settings_pattern.h @@ -0,0 +1,72 @@ +// Copyright (c) 2010 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. + +// Patterns used in content setting rules. + +#ifndef CHROME_BROWSER_CONTENT_SETTINGS_CONTENT_SETTINGS_PATTERN_H_ +#define CHROME_BROWSER_CONTENT_SETTINGS_CONTENT_SETTINGS_PATTERN_H_ +#pragma once + +#include <string> + +class GURL; + +// 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. + 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) {} + + // True if this is a valid pattern. Valid patterns are + // - [*.]domain.tld (matches domain.tld and all sub-domains) + // - host (matches an exact hostname) + // - 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; + + // 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_; } + + bool operator==(const ContentSettingsPattern& other) const { + return pattern_ == other.pattern_; + } + + // Canonicalizes the pattern so that it's ASCII only, either + // in original (if it was already ASCII) or punycode form. + std::string CanonicalizePattern() const; + + // 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; + + private: + std::string pattern_; +}; + +// Stream operator so ContentSettingsPattern can be used in assertion +// statements. +inline std::ostream& operator<<( + std::ostream& out, const ContentSettingsPattern& pattern) { + return out << pattern.AsString(); +} + +#endif // CHROME_BROWSER_CONTENT_SETTINGS_CONTENT_SETTINGS_PATTERN_H_ diff --git a/chrome/browser/content_settings/content_settings_pattern_unittest.cc b/chrome/browser/content_settings/content_settings_pattern_unittest.cc new file mode 100644 index 0000000..88b42dc --- /dev/null +++ b/chrome/browser/content_settings/content_settings_pattern_unittest.cc @@ -0,0 +1,69 @@ +// Copyright (c) 2010 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 "googleurl/src/gurl.h" +#include "testing/gtest/include/gtest/gtest.h" + +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_FALSE(ContentSettingsPattern("*example.com").IsValid()); + EXPECT_FALSE(ContentSettingsPattern("example.*").IsValid()); + EXPECT_FALSE(ContentSettingsPattern("http://example.com").IsValid()); + + EXPECT_TRUE(ContentSettingsPattern("[*.]example.com").Matches( + GURL("http://example.com/"))); + EXPECT_TRUE(ContentSettingsPattern("[*.]example.com").Matches( + GURL("http://www.example.com/"))); + EXPECT_TRUE(ContentSettingsPattern("www.example.com").Matches( + GURL("http://www.example.com/"))); + EXPECT_FALSE(ContentSettingsPattern("").Matches( + GURL("http://www.example.com/"))); + EXPECT_FALSE(ContentSettingsPattern("[*.]example.com").Matches( + GURL("http://example.org/"))); + EXPECT_FALSE(ContentSettingsPattern("example.com").Matches( + GURL("http://example.org/"))); +} + +TEST(ContentSettingsPatternTest, CanonicalizePattern) { + // 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()); + // IsValid returns false for file:/// patterns. + EXPECT_STREQ("", ContentSettingsPattern( + "file:///temp/file.html").CanonicalizePattern().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()); + // IsValid returns false for file:/// patterns. + EXPECT_STREQ("", ContentSettingsPattern( + "file:///\xC4\x87ira.html").CanonicalizePattern().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()); +} + +} // namespace diff --git a/chrome/browser/content_settings/host_content_settings_map.cc b/chrome/browser/content_settings/host_content_settings_map.cc index 5e167a7..fb2e6e9 100644 --- a/chrome/browser/content_settings/host_content_settings_map.cc +++ b/chrome/browser/content_settings/host_content_settings_map.cc @@ -8,6 +8,7 @@ #include "base/string_util.h" #include "base/utf_string_conversions.h" #include "chrome/browser/browser_thread.h" +#include "chrome/browser/content_settings/content_settings_details.h" #include "chrome/browser/metrics/user_metrics.h" #include "chrome/browser/prefs/pref_service.h" #include "chrome/browser/profile.h" @@ -26,22 +27,6 @@ #include "net/base/static_cookie_policy.h" namespace { -// The version of the pattern format implemented. Version 1 includes the -// following patterns: -// - [*.]domain.tld (matches domain.tld and all sub-domains) -// - host (matches an exact hostname) -// - a.b.c.d (matches an exact IPv4 ip) -// - [a:b:c:d:e:f:g:h] (matches an exact IPv6 ip) -// - file:///tmp/test.html (a complete URL without a host) -// Version 2 adds a resource identifier for plugins. -// TODO(jochen): update once this feature is no longer behind a flag. -const int kContentSettingsPatternVersion = 1; - -// The format of a domain wildcard. -const char kDomainWildcard[] = "[*.]"; - -// The length of kDomainWildcard (without the trailing '\0') -const size_t kDomainWildcardLength = arraysize(kDomainWildcard) - 1; // Base pref path of the prefs that contain the managed default content // settings values. @@ -138,70 +123,6 @@ struct HostContentSettingsMap::ExtendedContentSettings { ResourceContentSettings content_settings_for_resources; }; -// static -HostContentSettingsMap::Pattern HostContentSettingsMap::Pattern::FromURL( - const GURL& url) { - return Pattern(!url.has_host() || url.HostIsIPAddress() ? - net::GetHostOrSpecFromURL(url) : - std::string(kDomainWildcard) + url.host()); -} - -// static -HostContentSettingsMap::Pattern - HostContentSettingsMap::Pattern::FromURLNoWildcard(const GURL& url) { - return Pattern(net::GetHostOrSpecFromURL(url)); -} - -bool HostContentSettingsMap::Pattern::IsValid() const { - if (pattern_.empty()) - return false; - - 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(); -} - -bool HostContentSettingsMap::Pattern::Matches(const GURL& url) const { - if (!IsValid()) - return false; - - const std::string host(net::GetHostOrSpecFromURL(url)); - if (pattern_.length() < kDomainWildcardLength || - !StartsWithASCII(pattern_, kDomainWildcard, false)) - return pattern_ == host; - - const size_t match = - host.rfind(pattern_.substr(kDomainWildcardLength)); - - return (match != std::string::npos) && - (match == 0 || host[match - 1] == '.') && - (match + pattern_.length() - kDomainWildcardLength == host.length()); -} - -std::string HostContentSettingsMap::Pattern::CanonicalizePattern() const { - if (!IsValid()) { - return ""; - } - - bool starts_with_wildcard = pattern_.length() > kDomainWildcardLength && - StartsWithASCII(pattern_, kDomainWildcard, false); - - const std::string host(starts_with_wildcard ? - pattern_.substr(kDomainWildcardLength) : pattern_); - - std::string canonicalized_pattern = - starts_with_wildcard ? kDomainWildcard : ""; - - url_canon::CanonHostInfo host_info; - canonicalized_pattern += net::CanonicalizeHost(host, &host_info); - - return canonicalized_pattern; -} - HostContentSettingsMap::HostContentSettingsMap(Profile* profile) : profile_(profile), block_third_party_cookies_(false), @@ -232,10 +153,10 @@ HostContentSettingsMap::HostContentSettingsMap(Profile* profile) // Verify preferences version. if (!prefs->HasPrefPath(prefs::kContentSettingsVersion)) { prefs->SetInteger(prefs::kContentSettingsVersion, - kContentSettingsPatternVersion); + ContentSettingsPattern::kContentSettingsPatternVersion); } if (prefs->GetInteger(prefs::kContentSettingsVersion) > - kContentSettingsPatternVersion) { + ContentSettingsPattern::kContentSettingsPatternVersion) { LOG(ERROR) << "Unknown content settings version in preferences."; return; } @@ -268,7 +189,7 @@ HostContentSettingsMap::HostContentSettingsMap(Profile* profile) void HostContentSettingsMap::RegisterUserPrefs(PrefService* prefs) { prefs->RegisterDictionaryPref(prefs::kDefaultContentSettings); prefs->RegisterIntegerPref(prefs::kContentSettingsVersion, - kContentSettingsPatternVersion); + ContentSettingsPattern::kContentSettingsPatternVersion); prefs->RegisterDictionaryPref(prefs::kContentSettingsPatterns); prefs->RegisterBooleanPref(prefs::kBlockThirdPartyCookies, false); prefs->RegisterBooleanPref(prefs::kBlockNonsandboxedPlugins, false); @@ -364,7 +285,8 @@ ContentSetting HostContentSettingsMap::GetNonDefaultContentSetting( } // Match patterns starting with the most concrete pattern match. - for (std::string key = std::string(kDomainWildcard) + host; ; ) { + for (std::string key = + std::string(ContentSettingsPattern::kDomainWildcard) + host; ; ) { HostContentSettings::const_iterator i(off_the_record_settings_.find(key)); if (i != off_the_record_settings_.end() && i->second.content_settings_for_resources.find(requested_setting) != @@ -381,10 +303,12 @@ ContentSetting HostContentSettingsMap::GetNonDefaultContentSetting( requested_setting)->second; } - const size_t next_dot = key.find('.', kDomainWildcardLength); + const size_t next_dot = + key.find('.', ContentSettingsPattern::kDomainWildcardLength); if (next_dot == std::string::npos) break; - key.erase(kDomainWildcardLength, next_dot - kDomainWildcardLength + 1); + key.erase(ContentSettingsPattern::kDomainWildcardLength, + next_dot - ContentSettingsPattern::kDomainWildcardLength + 1); } return CONTENT_SETTING_DEFAULT; @@ -444,7 +368,8 @@ ContentSettings HostContentSettingsMap::GetNonDefaultContentSettings( } // Match patterns starting with the most concrete pattern match. - for (std::string key = std::string(kDomainWildcard) + host; ; ) { + for (std::string key = + std::string(ContentSettingsPattern::kDomainWildcard) + host; ; ) { HostContentSettings::const_iterator i(off_the_record_settings_.find(key)); if (i != off_the_record_settings_.end()) { for (int j = 0; j < CONTENT_SETTINGS_NUM_TYPES; ++j) { @@ -459,10 +384,12 @@ ContentSettings HostContentSettingsMap::GetNonDefaultContentSettings( output.settings[j] = i->second.content_settings.settings[j]; } } - const size_t next_dot = key.find('.', kDomainWildcardLength); + const size_t next_dot = + key.find('.', ContentSettingsPattern::kDomainWildcardLength); if (next_dot == std::string::npos) break; - key.erase(kDomainWildcardLength, next_dot - kDomainWildcardLength + 1); + key.erase(ContentSettingsPattern::kDomainWildcardLength, + next_dot - ContentSettingsPattern::kDomainWildcardLength + 1); } return output; @@ -499,7 +426,8 @@ void HostContentSettingsMap::GetSettingsForOneType( if (setting != CONTENT_SETTING_DEFAULT) { // Use of push_back() relies on the map iterator traversing in order of // ascending keys. - settings->push_back(std::make_pair(Pattern(i->first), setting)); + settings->push_back( + std::make_pair(ContentSettingsPattern(i->first), setting)); } } } @@ -543,11 +471,12 @@ void HostContentSettingsMap::SetDefaultContentSetting( } updating_preferences_ = false; - NotifyObservers(ContentSettingsDetails(Pattern(), content_type, "")); + NotifyObservers( + ContentSettingsDetails(ContentSettingsPattern(), content_type, "")); } void HostContentSettingsMap::SetContentSetting( - const Pattern& original_pattern, + const ContentSettingsPattern& original_pattern, ContentSettingsType content_type, const std::string& resource_identifier, ContentSetting setting) { @@ -560,7 +489,7 @@ void HostContentSettingsMap::SetContentSetting( CommandLine::ForCurrentProcess()->HasSwitch( switches::kEnableClickToPlay)); - const Pattern pattern(original_pattern.CanonicalizePattern()); + const ContentSettingsPattern pattern(original_pattern.CanonicalizePattern()); bool early_exit = false; std::string pattern_str(pattern.AsString()); @@ -659,11 +588,11 @@ void HostContentSettingsMap::AddExceptionForURL( ContentSetting setting) { // Make sure there is no entry that would override the pattern we are about // to insert for exactly this URL. - SetContentSetting(Pattern::FromURLNoWildcard(url), + SetContentSetting(ContentSettingsPattern::FromURLNoWildcard(url), content_type, resource_identifier, CONTENT_SETTING_DEFAULT); - SetContentSetting(Pattern::FromURL(url), + SetContentSetting(ContentSettingsPattern::FromURL(url), content_type, resource_identifier, setting); @@ -722,7 +651,8 @@ void HostContentSettingsMap::ClearSettingsForOneType( ScopedPrefUpdate update(prefs, prefs::kContentSettingsPatterns); updating_preferences_ = false; - NotifyObservers(ContentSettingsDetails(Pattern(), content_type, "")); + NotifyObservers( + ContentSettingsDetails(ContentSettingsPattern(), content_type, "")); } bool HostContentSettingsMap::RequiresResourceIdentifier( @@ -820,8 +750,9 @@ void HostContentSettingsMap::ResetToDefaults() { prefs->ClearPref(prefs::kBlockThirdPartyCookies); prefs->ClearPref(prefs::kBlockNonsandboxedPlugins); updating_preferences_ = false; - NotifyObservers( - ContentSettingsDetails(Pattern(), CONTENT_SETTINGS_TYPE_DEFAULT, "")); + NotifyObservers(ContentSettingsDetails(ContentSettingsPattern(), + CONTENT_SETTINGS_TYPE_DEFAULT, + "")); } } @@ -876,8 +807,9 @@ void HostContentSettingsMap::Observe(NotificationType type, } if (!is_off_the_record_) { - NotifyObservers( - ContentSettingsDetails(Pattern(), CONTENT_SETTINGS_TYPE_DEFAULT, "")); + NotifyObservers(ContentSettingsDetails(ContentSettingsPattern(), + CONTENT_SETTINGS_TYPE_DEFAULT, + "")); } } else if (NotificationType::PROFILE_DESTROYED == type) { UnregisterObservers(); @@ -1041,7 +973,7 @@ void HostContentSettingsMap::ReadExceptions(bool overwrite) { for (DictionaryValue::key_iterator i(all_settings_dictionary->begin_keys()); i != all_settings_dictionary->end_keys(); ++i) { const std::string& pattern(*i); - if (!Pattern(pattern).IsValid()) + if (!ContentSettingsPattern(pattern).IsValid()) LOG(WARNING) << "Invalid pattern stored in content settings"; DictionaryValue* pattern_settings_dictionary = NULL; bool found = all_settings_dictionary->GetDictionaryWithoutPathExpansion( @@ -1099,7 +1031,9 @@ void HostContentSettingsMap::MigrateObsoletePopupsPref(PrefService* prefs) { i != whitelist_pref->end(); ++i) { std::string host; (*i)->GetAsString(&host); - SetContentSetting(Pattern(host), CONTENT_SETTINGS_TYPE_POPUPS, "", + SetContentSetting(ContentSettingsPattern(host), + CONTENT_SETTINGS_TYPE_POPUPS, + "", CONTENT_SETTING_ALLOW); } prefs->ClearPref(prefs::kPopupWhitelistedHosts); @@ -1113,7 +1047,8 @@ void HostContentSettingsMap::MigrateObsoletePerhostPref(PrefService* prefs) { for (DictionaryValue::key_iterator i(all_settings_dictionary->begin_keys()); i != all_settings_dictionary->end_keys(); ++i) { const std::string& host(*i); - Pattern pattern(std::string(kDomainWildcard) + host); + ContentSettingsPattern pattern( + std::string(ContentSettingsPattern::kDomainWildcard) + host); DictionaryValue* host_settings_dictionary = NULL; bool found = all_settings_dictionary->GetDictionaryWithoutPathExpansion( host, &host_settings_dictionary); @@ -1141,7 +1076,7 @@ void HostContentSettingsMap::CanonicalizeContentSettingsExceptions( i != all_settings_dictionary->end_keys(); ++i) { const std::string& pattern(*i); const std::string canonicalized_pattern = - Pattern(pattern).CanonicalizePattern(); + ContentSettingsPattern(pattern).CanonicalizePattern(); if (canonicalized_pattern.empty() || canonicalized_pattern == pattern) continue; diff --git a/chrome/browser/content_settings/host_content_settings_map.h b/chrome/browser/content_settings/host_content_settings_map.h index 9f52582..e19c125 100644 --- a/chrome/browser/content_settings/host_content_settings_map.h +++ b/chrome/browser/content_settings/host_content_settings_map.h @@ -18,11 +18,13 @@ #include "base/lock.h" #include "base/ref_counted.h" #include "chrome/browser/browser_thread.h" +#include "chrome/browser/content_settings/content_settings_pattern.h" #include "chrome/browser/prefs/pref_change_registrar.h" #include "chrome/common/content_settings.h" #include "chrome/common/notification_observer.h" #include "chrome/common/notification_registrar.h" +class ContentSettingsDetails; class DictionaryValue; class GURL; class PrefService; @@ -33,86 +35,7 @@ class HostContentSettingsMap public base::RefCountedThreadSafe<HostContentSettingsMap, BrowserThread::DeleteOnUIThread> { public: - // A hostname pattern. See |IsValid| for a description of possible patterns. - class Pattern { - public: - // Returns a pattern that matches the host of this URL and all subdomains. - static Pattern FromURL(const GURL& url); - - // Returns a pattern that matches exactly this URL. - static Pattern FromURLNoWildcard(const GURL& url); - - Pattern() {} - - explicit Pattern(const std::string& pattern) : pattern_(pattern) {} - - // True if this is a valid pattern. Valid patterns are - // - [*.]domain.tld (matches domain.tld and all sub-domains) - // - host (matches an exact hostname) - // - a.b.c.d (matches an exact IPv4 ip) - // - [a:b:c:d:e:f:g:h] (matches an exact IPv6 ip) - bool IsValid() const; - - // 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_; } - - bool operator==(const Pattern& other) const { - return pattern_ == other.pattern_; - } - - // Canonicalizes the pattern so that it's ASCII only, either - // in original or punycode form. - std::string CanonicalizePattern() const; - - private: - std::string pattern_; - }; - - // Details for the CONTENT_SETTINGS_CHANGED notification. This is sent when - // content settings change for at least one host. If settings change for more - // than one pattern in one user interaction, this will usually send a single - // notification with update_all() returning true instead of one notification - // for each pattern. - class ContentSettingsDetails { - public: - // Update the setting that matches this pattern/content type/resource. - ContentSettingsDetails(const Pattern& pattern, - ContentSettingsType type, - const std::string& resource_identifier) - : pattern_(pattern), - type_(type), - resource_identifier_(resource_identifier) {} - - // The pattern whose settings have changed. - const Pattern& pattern() const { return pattern_; } - - // True if all settings should be updated for the given type. - bool update_all() const { return pattern_.AsString().empty(); } - - // The type of the pattern whose settings have changed. - ContentSettingsType type() const { return type_; } - - // The resource identifier for the settings type that has changed. - const std::string& resource_identifier() const { - return resource_identifier_; - } - - // True if all types should be updated. If update_all() is false, this will - // be false as well (although the reverse does not hold true). - bool update_all_types() const { - return CONTENT_SETTINGS_TYPE_DEFAULT == type_; - } - - private: - Pattern pattern_; - ContentSettingsType type_; - std::string resource_identifier_; - }; - - typedef std::pair<Pattern, ContentSetting> PatternSettingPair; + typedef std::pair<ContentSettingsPattern, ContentSetting> PatternSettingPair; typedef std::vector<PatternSettingPair> SettingsForOneType; explicit HostContentSettingsMap(Profile* profile); @@ -189,7 +112,7 @@ class HostContentSettingsMap // the |resource_identifier| must be non-empty. // // This should only be called on the UI thread. - void SetContentSetting(const Pattern& pattern, + void SetContentSetting(const ContentSettingsPattern& pattern, ContentSettingsType content_type, const std::string& resource_identifier, ContentSetting setting); @@ -344,11 +267,4 @@ class HostContentSettingsMap DISALLOW_COPY_AND_ASSIGN(HostContentSettingsMap); }; -// Stream operator so HostContentSettingsMap::Pattern can be used in -// assertion statements. -inline std::ostream& operator<<( - std::ostream& out, const HostContentSettingsMap::Pattern& pattern) { - return out << pattern.AsString(); -} - #endif // CHROME_BROWSER_CONTENT_SETTINGS_HOST_CONTENT_SETTINGS_MAP_H_ 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 5f6bf5c..280799b 100644 --- a/chrome/browser/content_settings/host_content_settings_map_unittest.cc +++ b/chrome/browser/content_settings/host_content_settings_map_unittest.cc @@ -8,6 +8,7 @@ #include "base/command_line.h" #include "base/json/json_reader.h" #include "base/json/json_writer.h" +#include "chrome/browser/content_settings/content_settings_details.h" #include "chrome/browser/prefs/pref_service.h" #include "chrome/common/chrome_switches.h" #include "chrome/common/notification_registrar.h" @@ -44,8 +45,7 @@ class StubSettingsObserver : public NotificationObserver { const NotificationDetails& details) { ++counter; Source<HostContentSettingsMap> content_settings(source); - Details<HostContentSettingsMap::ContentSettingsDetails> - settings_details(details); + Details<ContentSettingsDetails> settings_details(details); last_notifier = content_settings.ptr(); last_pattern = settings_details.ptr()->pattern(); last_update_all = settings_details.ptr()->update_all(); @@ -57,7 +57,7 @@ class StubSettingsObserver : public NotificationObserver { } HostContentSettingsMap* last_notifier; - HostContentSettingsMap::Pattern last_pattern; + ContentSettingsPattern last_pattern; bool last_update_all; bool last_update_all_types; int counter; @@ -118,7 +118,7 @@ TEST_F(HostContentSettingsMapTest, DefaultValues) { // Check returning individual settings. GURL host("http://example.com/"); - HostContentSettingsMap::Pattern pattern("[*.]example.com"); + ContentSettingsPattern pattern("[*.]example.com"); EXPECT_EQ(CONTENT_SETTING_ALLOW, host_content_settings_map->GetContentSetting( host, CONTENT_SETTINGS_TYPE_IMAGES, "")); @@ -163,7 +163,7 @@ TEST_F(HostContentSettingsMapTest, DefaultValues) { EXPECT_TRUE(SettingsEqual(desired_settings, settings)); // Check returning all hosts for a setting. - HostContentSettingsMap::Pattern pattern2("[*.]example.org"); + ContentSettingsPattern pattern2("[*.]example.org"); host_content_settings_map->SetContentSetting(pattern2, CONTENT_SETTINGS_TYPE_IMAGES, "", CONTENT_SETTING_BLOCK); host_content_settings_map->SetContentSetting(pattern2, @@ -186,7 +186,7 @@ TEST_F(HostContentSettingsMapTest, DefaultValues) { EXPECT_EQ(0U, host_settings.size()); // Check clearing one type. - HostContentSettingsMap::Pattern pattern3("[*.]example.net"); + ContentSettingsPattern pattern3("[*.]example.net"); host_content_settings_map->SetContentSetting(pattern, CONTENT_SETTINGS_TYPE_IMAGES, "", CONTENT_SETTING_BLOCK); host_content_settings_map->SetContentSetting(pattern2, @@ -214,8 +214,8 @@ TEST_F(HostContentSettingsMapTest, Patterns) { GURL host1("http://example.com/"); GURL host2("http://www.example.com/"); GURL host3("http://example.org/"); - HostContentSettingsMap::Pattern pattern1("[*.]example.com"); - HostContentSettingsMap::Pattern pattern2("example.org"); + ContentSettingsPattern pattern1("[*.]example.com"); + ContentSettingsPattern pattern2("example.org"); EXPECT_EQ(CONTENT_SETTING_ALLOW, host_content_settings_map->GetContentSetting( host1, CONTENT_SETTINGS_TYPE_IMAGES, "")); @@ -237,70 +237,13 @@ TEST_F(HostContentSettingsMapTest, Patterns) { host3, CONTENT_SETTINGS_TYPE_IMAGES, "")); } -TEST_F(HostContentSettingsMapTest, PatternSupport) { - EXPECT_TRUE(HostContentSettingsMap::Pattern("[*.]example.com").IsValid()); - EXPECT_TRUE(HostContentSettingsMap::Pattern("example.com").IsValid()); - EXPECT_TRUE(HostContentSettingsMap::Pattern("192.168.0.1").IsValid()); - EXPECT_TRUE(HostContentSettingsMap::Pattern("[::1]").IsValid()); - EXPECT_FALSE(HostContentSettingsMap::Pattern("*example.com").IsValid()); - EXPECT_FALSE(HostContentSettingsMap::Pattern("example.*").IsValid()); - EXPECT_FALSE(HostContentSettingsMap::Pattern("http://example.com").IsValid()); - - EXPECT_TRUE(HostContentSettingsMap::Pattern("[*.]example.com").Matches( - GURL("http://example.com/"))); - EXPECT_TRUE(HostContentSettingsMap::Pattern("[*.]example.com").Matches( - GURL("http://www.example.com/"))); - EXPECT_TRUE(HostContentSettingsMap::Pattern("www.example.com").Matches( - GURL("http://www.example.com/"))); - EXPECT_FALSE(HostContentSettingsMap::Pattern("").Matches( - GURL("http://www.example.com/"))); - EXPECT_FALSE(HostContentSettingsMap::Pattern("[*.]example.com").Matches( - GURL("http://example.org/"))); - EXPECT_FALSE(HostContentSettingsMap::Pattern("example.com").Matches( - GURL("http://example.org/"))); -} - -TEST_F(HostContentSettingsMapTest, CanonicalizePattern) { - // Basic patterns. - EXPECT_STREQ("[*.]ikea.com", HostContentSettingsMap::Pattern("[*.]ikea.com") - .CanonicalizePattern().c_str()); - EXPECT_STREQ("example.com", HostContentSettingsMap::Pattern("example.com") - .CanonicalizePattern().c_str()); - EXPECT_STREQ("192.168.1.1", HostContentSettingsMap::Pattern("192.168.1.1") - .CanonicalizePattern().c_str()); - EXPECT_STREQ("[::1]", HostContentSettingsMap::Pattern("[::1]") - .CanonicalizePattern().c_str()); - // IsValid returns false for file:/// patterns. - EXPECT_STREQ("", HostContentSettingsMap::Pattern( - "file:///temp/file.html").CanonicalizePattern().c_str()); - - // UTF-8 patterns. - EXPECT_STREQ("[*.]xn--ira-ppa.com", HostContentSettingsMap::Pattern( - "[*.]\xC4\x87ira.com").CanonicalizePattern().c_str()); - EXPECT_STREQ("xn--ira-ppa.com", HostContentSettingsMap::Pattern( - "\xC4\x87ira.com").CanonicalizePattern().c_str()); - // IsValid returns false for file:/// patterns. - EXPECT_STREQ("", HostContentSettingsMap::Pattern( - "file:///\xC4\x87ira.html").CanonicalizePattern().c_str()); - - // Invalid patterns. - EXPECT_STREQ("", HostContentSettingsMap::Pattern( - "*example.com").CanonicalizePattern().c_str()); - EXPECT_STREQ("", HostContentSettingsMap::Pattern( - "example.*").CanonicalizePattern().c_str()); - EXPECT_STREQ("", HostContentSettingsMap::Pattern( - "*\xC4\x87ira.com").CanonicalizePattern().c_str()); - EXPECT_STREQ("", HostContentSettingsMap::Pattern( - "\xC4\x87ira.*").CanonicalizePattern().c_str()); -} - TEST_F(HostContentSettingsMapTest, Observer) { TestingProfile profile; HostContentSettingsMap* host_content_settings_map = profile.GetHostContentSettingsMap(); StubSettingsObserver observer; - HostContentSettingsMap::Pattern pattern("[*.]example.com"); + ContentSettingsPattern pattern("[*.]example.com"); host_content_settings_map->SetContentSetting(pattern, CONTENT_SETTINGS_TYPE_IMAGES, "", CONTENT_SETTING_ALLOW); EXPECT_EQ(host_content_settings_map, observer.last_notifier); @@ -377,7 +320,7 @@ TEST_F(HostContentSettingsMapTest, ObserveExceptionPref) { scoped_ptr<Value> default_value(prefs->FindPreference( prefs::kContentSettingsPatterns)->GetValue()->DeepCopy()); - HostContentSettingsMap::Pattern pattern("[*.]example.com"); + ContentSettingsPattern pattern("[*.]example.com"); GURL host("http://example.com"); host_content_settings_map->SetContentSetting(pattern, @@ -408,7 +351,7 @@ TEST_F(HostContentSettingsMapTest, HostTrimEndingDotCheck) { HostContentSettingsMap* host_content_settings_map = profile.GetHostContentSettingsMap(); - HostContentSettingsMap::Pattern pattern("[*.]example.com"); + ContentSettingsPattern pattern("[*.]example.com"); GURL host_ending_with_dot("http://example.com./"); EXPECT_EQ(CONTENT_SETTING_ALLOW, @@ -488,9 +431,9 @@ TEST_F(HostContentSettingsMapTest, NestedSettings) { profile.GetHostContentSettingsMap(); GURL host("http://a.b.example.com/"); - HostContentSettingsMap::Pattern pattern1("[*.]example.com"); - HostContentSettingsMap::Pattern pattern2("[*.]b.example.com"); - HostContentSettingsMap::Pattern pattern3("a.b.example.com"); + ContentSettingsPattern pattern1("[*.]example.com"); + ContentSettingsPattern pattern2("[*.]b.example.com"); + ContentSettingsPattern pattern3("a.b.example.com"); host_content_settings_map->SetContentSetting(pattern1, CONTENT_SETTINGS_TYPE_IMAGES, "", CONTENT_SETTING_BLOCK); @@ -543,7 +486,7 @@ TEST_F(HostContentSettingsMapTest, OffTheRecord) { profile.set_off_the_record(false); GURL host("http://example.com/"); - HostContentSettingsMap::Pattern pattern("[*.]example.com"); + ContentSettingsPattern pattern("[*.]example.com"); EXPECT_EQ(CONTENT_SETTING_ALLOW, host_content_settings_map->GetContentSetting( @@ -666,7 +609,7 @@ TEST_F(HostContentSettingsMapTest, NonDefaultSettings) { profile.GetHostContentSettingsMap(); GURL host("http://example.com/"); - HostContentSettingsMap::Pattern pattern("[*.]example.com"); + ContentSettingsPattern pattern("[*.]example.com"); ContentSettings desired_settings(CONTENT_SETTING_DEFAULT); ContentSettings settings = @@ -693,7 +636,7 @@ TEST_F(HostContentSettingsMapTest, ResourceIdentifier) { profile.GetHostContentSettingsMap(); GURL host("http://example.com/"); - HostContentSettingsMap::Pattern pattern("[*.]example.com"); + ContentSettingsPattern pattern("[*.]example.com"); std::string resource1("someplugin"); std::string resource2("otherplugin"); @@ -724,7 +667,7 @@ TEST_F(HostContentSettingsMapTest, ResourceIdentifierPrefs) { profile.GetHostContentSettingsMap(); GURL host("http://example.com/"); - HostContentSettingsMap::Pattern pattern("[*.]example.com"); + ContentSettingsPattern pattern("[*.]example.com"); std::string resource1("someplugin"); std::string resource2("otherplugin"); @@ -798,7 +741,7 @@ TEST_F(HostContentSettingsMapTest, TestingPrefService* prefs = profile.GetTestingPrefService(); // Set pattern for JavaScript setting. - HostContentSettingsMap::Pattern pattern("[*.]example.com"); + ContentSettingsPattern pattern("[*.]example.com"); host_content_settings_map->SetContentSetting(pattern, CONTENT_SETTINGS_TYPE_JAVASCRIPT, "", CONTENT_SETTING_BLOCK); @@ -833,7 +776,7 @@ TEST_F(HostContentSettingsMapTest, CONTENT_SETTINGS_TYPE_JAVASCRIPT, CONTENT_SETTING_BLOCK); // Set an exception to allow "[*.]example.com" - HostContentSettingsMap::Pattern pattern("[*.]example.com"); + ContentSettingsPattern pattern("[*.]example.com"); host_content_settings_map->SetContentSetting(pattern, CONTENT_SETTINGS_TYPE_JAVASCRIPT, "", CONTENT_SETTING_ALLOW); @@ -905,7 +848,7 @@ TEST_F(HostContentSettingsMapTest, ObserveManagedSettingsChange) { prefs->SetManagedPref(prefs::kManagedDefaultImagesSetting, Value::CreateIntegerValue(CONTENT_SETTING_BLOCK)); EXPECT_EQ(host_content_settings_map, observer.last_notifier); - EXPECT_EQ(HostContentSettingsMap::Pattern(), observer.last_pattern); + 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); @@ -915,7 +858,7 @@ TEST_F(HostContentSettingsMapTest, ObserveManagedSettingsChange) { prefs->RemoveManagedPref(prefs::kManagedDefaultImagesSetting); EXPECT_EQ(host_content_settings_map, observer.last_notifier); EXPECT_EQ(CONTENT_SETTINGS_TYPE_DEFAULT, observer.last_type); - EXPECT_EQ(HostContentSettingsMap::Pattern(), observer.last_pattern); + EXPECT_EQ(ContentSettingsPattern(), observer.last_pattern); EXPECT_TRUE(observer.last_update_all); EXPECT_TRUE(observer.last_update_all_types); EXPECT_EQ(2, observer.counter); @@ -941,7 +884,7 @@ TEST_F(HostContentSettingsMapTest, ObserveManagedSettingsNoChange) { prefs->SetManagedPref(prefs::kManagedDefaultImagesSetting, Value::CreateIntegerValue(CONTENT_SETTING_ALLOW)); EXPECT_EQ(host_content_settings_map, observer.last_notifier); - EXPECT_EQ(HostContentSettingsMap::Pattern(), observer.last_pattern); + 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); @@ -951,7 +894,7 @@ TEST_F(HostContentSettingsMapTest, ObserveManagedSettingsNoChange) { prefs->RemoveManagedPref(prefs::kManagedDefaultImagesSetting); EXPECT_EQ(host_content_settings_map, observer.last_notifier); EXPECT_EQ(CONTENT_SETTINGS_TYPE_DEFAULT, observer.last_type); - EXPECT_EQ(HostContentSettingsMap::Pattern(), observer.last_pattern); + EXPECT_EQ(ContentSettingsPattern(), observer.last_pattern); EXPECT_TRUE(observer.last_update_all); EXPECT_TRUE(observer.last_update_all_types); EXPECT_EQ(2, observer.counter); |