diff options
12 files changed, 797 insertions, 281 deletions
diff --git a/chrome/browser/content_settings/content_settings_origin_identifier_value_map.cc b/chrome/browser/content_settings/content_settings_origin_identifier_value_map.cc new file mode 100644 index 0000000..1d30d90 --- /dev/null +++ b/chrome/browser/content_settings/content_settings_origin_identifier_value_map.cc @@ -0,0 +1,131 @@ +// 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_origin_identifier_value_map.h" + +#include "base/logging.h" +#include "base/values.h" +#include "googleurl/src/gurl.h" + +namespace content_settings { + +OriginIdentifierValueMap::OriginIdentifierValueMap() {} + +OriginIdentifierValueMap::~OriginIdentifierValueMap() { + Clear(); +} + +bool operator>(const OriginIdentifierValueMap::Entry& first, + const OriginIdentifierValueMap::Entry& second) { + // Compare item patterns. + if (first.item_pattern > second.item_pattern) + return true; + if (first.item_pattern < second.item_pattern) + return false; + + // Compare top_level_frame patterns. + if (first.top_level_frame_pattern > second.top_level_frame_pattern) + return true; + return false; +} + +Value* OriginIdentifierValueMap::GetValue( + const GURL& item_url, + const GURL& top_level_frame_url, + ContentSettingsType content_type, + const ResourceIdentifier& resource_identifier) const { + // Find best matching list entry. + OriginIdentifierValueMap::const_iterator best_match = entries_.end(); + for (OriginIdentifierValueMap::const_iterator entry = entries_.begin(); + entry != entries_.end(); + ++entry) { + if (entry->item_pattern.Matches(item_url) && + entry->top_level_frame_pattern.Matches(top_level_frame_url) && + entry->content_type == content_type && + entry->identifier == resource_identifier) { + if (best_match == entries_.end() || *entry > *best_match) { + best_match = entry; + } + } + } + if (best_match != entries_.end()) + return best_match->value.get(); + return NULL; +} + +void OriginIdentifierValueMap::SetValue( + const ContentSettingsPattern& item_pattern, + const ContentSettingsPattern& top_level_frame_pattern, + ContentSettingsType content_type, + const ResourceIdentifier& resource_identifier, + Value* value) { + OriginIdentifierValueMap::iterator list_entry = + FindEntry(item_pattern, + top_level_frame_pattern, + content_type, + resource_identifier); + if (list_entry == entries_.end()) { + // No matching list entry found. Add a new entry to the list. + entries_.insert(list_entry, Entry(item_pattern, + top_level_frame_pattern, + content_type, + resource_identifier, + value)); + } else { + // Update the list entry. + list_entry->value.reset(value); + } +} + +void OriginIdentifierValueMap::DeleteValue( + const ContentSettingsPattern& item_pattern, + const ContentSettingsPattern& top_level_frame_pattern, + ContentSettingsType content_type, + const ResourceIdentifier& resource_identifier) { + OriginIdentifierValueMap::iterator entry_to_delete = + FindEntry(item_pattern, + top_level_frame_pattern, + content_type, + resource_identifier); + if (entry_to_delete != entries_.end()) { + entries_.erase(entry_to_delete); + } +} + +void OriginIdentifierValueMap::Clear() { + // Delete all owned value objects. + /* + for (OriginIdentifierValueMap::iterator entry = entries_.begin(); + entry != entries_.end(); + ++entry) { + delete entry->value; + } + */ + entries_.clear(); +} + +OriginIdentifierValueMap::iterator OriginIdentifierValueMap::DeleteValue( + OriginIdentifierValueMap::iterator entry) { + return entries_.erase(entry); +} + +OriginIdentifierValueMap::iterator OriginIdentifierValueMap::FindEntry( + const ContentSettingsPattern& item_pattern, + const ContentSettingsPattern& top_level_frame_pattern, + ContentSettingsType content_type, + const ResourceIdentifier& resource_identifier) { + for (OriginIdentifierValueMap::iterator entry = entries_.begin(); + entry != entries_.end(); + ++entry) { + if (item_pattern == entry->item_pattern && + top_level_frame_pattern == entry->top_level_frame_pattern && + content_type == entry->content_type && + resource_identifier == entry->identifier) { + return entry; + } + } + return entries_.end(); +} + +} // namespace content_settings diff --git a/chrome/browser/content_settings/content_settings_origin_identifier_value_map.h b/chrome/browser/content_settings/content_settings_origin_identifier_value_map.h new file mode 100644 index 0000000..70c9f88 --- /dev/null +++ b/chrome/browser/content_settings/content_settings_origin_identifier_value_map.h @@ -0,0 +1,133 @@ +// 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_ORIGIN_IDENTIFIER_VALUE_MAP_H_ +#define CHROME_BROWSER_CONTENT_SETTINGS_CONTENT_SETTINGS_ORIGIN_IDENTIFIER_VALUE_MAP_H_ + +#include <list> +#include <map> +#include <string> + +#include "base/tuple.h" +#include "base/memory/linked_ptr.h" +#include "chrome/browser/content_settings/content_settings_pattern.h" +#include "chrome/common/content_settings_types.h" + +class GURL; +class Value; + +namespace content_settings { + +class OriginIdentifierValueMap { + public: + typedef std::string ResourceIdentifier; + + struct Entry { + Entry(ContentSettingsPattern item_pattern, + ContentSettingsPattern top_level_frame_pattern, + ContentSettingsType content_type, + ResourceIdentifier identifier, + Value* value) + : item_pattern(item_pattern), + top_level_frame_pattern(top_level_frame_pattern), + content_type(content_type), + identifier(identifier), + value(value) { + } + + ContentSettingsPattern item_pattern; + ContentSettingsPattern top_level_frame_pattern; + ContentSettingsType content_type; + ResourceIdentifier identifier; + linked_ptr<Value> value; + }; + + typedef std::list<Entry> EntryList; + + typedef EntryList::const_iterator const_iterator; + + typedef EntryList::iterator iterator; + + EntryList::iterator begin() { + return entries_.begin(); + } + + EntryList::iterator end() { + return entries_.end(); + } + + EntryList::const_iterator begin() const { + return entries_.begin(); + } + + EntryList::const_iterator end() const { + return entries_.end(); + } + + size_t size() const { + return entries_.size(); + } + + OriginIdentifierValueMap(); + ~OriginIdentifierValueMap(); + + // Returns a weak pointer to the value for the given |item_pattern|, + // |top_level_frame_pattern|, |content_type|, |resource_identifier| tuple. If + // no value is stored for the passed parameter |NULL| is returned. + Value* GetValue( + const GURL& item_url, + const GURL& top_level_frame_url, + ContentSettingsType content_type, + const ResourceIdentifier& resource_identifier) const; + + // Sets the |value| for the given |item_pattern|, |top_level_frame_pattern|, + // |content_type|, |resource_identifier| tuple. The method takes the ownership + // of the passed |value|. + void SetValue( + const ContentSettingsPattern& item_pattern, + const ContentSettingsPattern& top_level_frame_pattern, + ContentSettingsType content_type, + const ResourceIdentifier& resource_identifier, + Value* value); + + // Deletes the map entry for the given |item_pattern|, + // |top_level_frame_pattern|, |content_type|, |resource_identifier| tuple. + void DeleteValue( + const ContentSettingsPattern& item_pattern, + const ContentSettingsPattern& top_level_frame_pattern, + ContentSettingsType content_type, + const ResourceIdentifier& resource_identifier); + + // Deletes the map entry at the passed position. The method returns the + // position of the next entry in the map. + EntryList::iterator DeleteValue(EntryList::iterator entry); + + // Clears all map entries. + void Clear(); + + private: + // Finds the list entry for the given |item_pattern|, + // |top_level_frame_pattern|, |content_type|, |resource_identifier| tuple and + // returns the iterator of the list entry. If no entry is found for the passed + // parameters then the end of list iterator is returned. + EntryList::iterator FindEntry( + const ContentSettingsPattern& item_pattern, + const ContentSettingsPattern& top_level_frame_pattern, + ContentSettingsType content_type, + const ResourceIdentifier& resource_identifier); + + EntryList entries_; + + DISALLOW_COPY_AND_ASSIGN(OriginIdentifierValueMap); +}; + +// Compares two origin value map entries and tests if the item, top-level-frame +// pattern pair of the first entry has a higher precedences then the pattern +// pair of the second entry. +bool operator>(const OriginIdentifierValueMap::Entry& first, + const OriginIdentifierValueMap::Entry& second); + +} // namespace content_settings + +#endif // CHROME_BROWSER_CONTENT_SETTINGS_CONTENT_SETTINGS_ORIGIN_IDENTIFIER_VALUE_MAP_H_ diff --git a/chrome/browser/content_settings/content_settings_origin_identifier_value_map_unittest.cc b/chrome/browser/content_settings/content_settings_origin_identifier_value_map_unittest.cc new file mode 100644 index 0000000..f028524 --- /dev/null +++ b/chrome/browser/content_settings/content_settings_origin_identifier_value_map_unittest.cc @@ -0,0 +1,172 @@ +// 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_origin_identifier_value_map.h" + +#include "base/scoped_ptr.h" +#include "base/values.h" +#include "googleurl/src/gurl.h" +#include "testing/gtest/include/gtest/gtest.h" + +TEST(OriginIdentifierValueMapTest, SetGetValue) { + content_settings::OriginIdentifierValueMap map; + + EXPECT_EQ(NULL, map.GetValue(GURL("http://www.google.com"), + GURL("http://www.google.com"), + CONTENT_SETTINGS_TYPE_COOKIES, + "")); + map.SetValue( + ContentSettingsPattern::FromString("[*.]google.com"), + ContentSettingsPattern::FromString("[*.]google.com"), + CONTENT_SETTINGS_TYPE_COOKIES, + "", + Value::CreateIntegerValue(1)); + + scoped_ptr<Value> expected_value(Value::CreateIntegerValue(1)); + EXPECT_TRUE(expected_value->Equals( + map.GetValue(GURL("http://www.google.com"), + GURL("http://www.google.com"), + CONTENT_SETTINGS_TYPE_COOKIES, + ""))); + + EXPECT_EQ(NULL, map.GetValue(GURL("http://www.google.com"), + GURL("http://www.youtube.com"), + CONTENT_SETTINGS_TYPE_COOKIES, + "")); + + EXPECT_EQ(NULL, map.GetValue(GURL("http://www.youtube.com"), + GURL("http://www.google.com"), + CONTENT_SETTINGS_TYPE_COOKIES, + "")); + + EXPECT_EQ(NULL, map.GetValue(GURL("http://www.google.com"), + GURL("http://www.google.com"), + CONTENT_SETTINGS_TYPE_POPUPS, + "")); + + EXPECT_EQ(NULL, map.GetValue(GURL("http://www.google.com"), + GURL("http://www.google.com"), + CONTENT_SETTINGS_TYPE_COOKIES, + "resource_id")); +} + +TEST(OriginIdentifierValueMapTest, SetDeleteValue) { + content_settings::OriginIdentifierValueMap map; + + EXPECT_EQ(NULL, map.GetValue(GURL("http://www.google.com"), + GURL("http://www.google.com"), + CONTENT_SETTINGS_TYPE_PLUGINS, + "java-plugin")); + + // Set sample values. + map.SetValue( + ContentSettingsPattern::FromString("[*.]google.com"), + ContentSettingsPattern::FromString("[*.]google.com"), + CONTENT_SETTINGS_TYPE_PLUGINS, + "java-plugin", + Value::CreateIntegerValue(1)); + + int actual_value; + EXPECT_TRUE(map.GetValue(GURL("http://www.google.com"), + GURL("http://www.google.com"), + CONTENT_SETTINGS_TYPE_PLUGINS, + "java-plugin")->GetAsInteger(&actual_value)); + EXPECT_EQ(1, actual_value); + EXPECT_EQ(NULL, map.GetValue(GURL("http://www.google.com"), + GURL("http://www.google.com"), + CONTENT_SETTINGS_TYPE_PLUGINS, + "flash-plugin")); + // Delete non-existing value. + map.DeleteValue( + ContentSettingsPattern::FromString("[*.]google.com"), + ContentSettingsPattern::FromString("[*.]google.com"), + CONTENT_SETTINGS_TYPE_PLUGINS, + "flash-plugin"); + EXPECT_EQ(NULL, map.GetValue(GURL("http://www.google.com"), + GURL("http://www.google.com"), + CONTENT_SETTINGS_TYPE_PLUGINS, + "flash-plugin")); + EXPECT_TRUE(map.GetValue(GURL("http://www.google.com"), + GURL("http://www.google.com"), + CONTENT_SETTINGS_TYPE_PLUGINS, + "java-plugin")->GetAsInteger(&actual_value)); + EXPECT_EQ(1, actual_value); + + // Delete existing value. + map.DeleteValue( + ContentSettingsPattern::FromString("[*.]google.com"), + ContentSettingsPattern::FromString("[*.]google.com"), + CONTENT_SETTINGS_TYPE_PLUGINS, + "java-plugin"); + + EXPECT_EQ(NULL, map.GetValue(GURL("http://www.google.com"), + GURL("http://www.google.com"), + CONTENT_SETTINGS_TYPE_PLUGINS, + "java-plugin")); +} + +TEST(OriginIdentifierValueMapTest, Clear) { + content_settings::OriginIdentifierValueMap map; + EXPECT_EQ(map.begin(), map.end()); + + // Set two values. + map.SetValue( + ContentSettingsPattern::FromString("[*.]google.com"), + ContentSettingsPattern::FromString("[*.]google.com"), + CONTENT_SETTINGS_TYPE_PLUGINS, + "java-plugin", + Value::CreateIntegerValue(1)); + map.SetValue( + ContentSettingsPattern::FromString("[*.]google.com"), + ContentSettingsPattern::FromString("[*.]google.com"), + CONTENT_SETTINGS_TYPE_COOKIES, + "", + Value::CreateIntegerValue(1)); + EXPECT_NE(map.begin(), map.end()); + int actual_value; + EXPECT_TRUE(map.GetValue(GURL("http://www.google.com"), + GURL("http://www.google.com"), + CONTENT_SETTINGS_TYPE_PLUGINS, + "java-plugin")->GetAsInteger(&actual_value)); + EXPECT_EQ(1, actual_value); + + // Clear the map. + map.Clear(); + EXPECT_EQ(map.begin(), map.end()); + EXPECT_EQ(NULL, map.GetValue(GURL("http://www.google.com"), + GURL("http://www.google.com"), + CONTENT_SETTINGS_TYPE_PLUGINS, + "java-plugin")); +} + +TEST(OriginIdentifierValueMapTest, ListEntryPrecedences) { + content_settings::OriginIdentifierValueMap map; + + map.SetValue( + ContentSettingsPattern::FromString("[*.]google.com"), + ContentSettingsPattern::FromString("[*.]google.com"), + CONTENT_SETTINGS_TYPE_COOKIES, + "", + Value::CreateIntegerValue(1)); + + map.SetValue( + ContentSettingsPattern::FromString("www.google.com"), + ContentSettingsPattern::FromString("[*.]google.com"), + CONTENT_SETTINGS_TYPE_COOKIES, + "", + Value::CreateIntegerValue(2)); + + int actual_value; + EXPECT_TRUE(map.GetValue(GURL("http://mail.google.com"), + GURL("http://www.google.com"), + CONTENT_SETTINGS_TYPE_COOKIES, + "")->GetAsInteger(&actual_value)); + EXPECT_EQ(1, actual_value); + + EXPECT_TRUE(map.GetValue(GURL("http://www.google.com"), + GURL("http://www.google.com"), + CONTENT_SETTINGS_TYPE_COOKIES, + "")->GetAsInteger(&actual_value)); + EXPECT_EQ(2, actual_value); +} diff --git a/chrome/browser/content_settings/content_settings_pattern.cc b/chrome/browser/content_settings/content_settings_pattern.cc index 4721573..70cc42e 100644 --- a/chrome/browser/content_settings/content_settings_pattern.cc +++ b/chrome/browser/content_settings/content_settings_pattern.cc @@ -310,35 +310,6 @@ ContentSettingsPattern ContentSettingsPattern::FromURL( } // static -ContentSettingsPattern ContentSettingsPattern::LegacyFromURL( - const GURL& url) { - scoped_ptr<ContentSettingsPattern::BuilderInterface> builder( - ContentSettingsPattern::CreateBuilder(true)); - - 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. - // TODO(markusheintz): For HTTPS we will create scheme specific patterns as - // soon as the pattern matching code in the HostContentSettingsMap is - // replaced. - if (url.HostIsIPAddress()) { - builder->WithSchemeWildcard()->WithHost(url.host()); - } else if (url.SchemeIs(chrome::kHttpScheme)) { - builder->WithSchemeWildcard()->WithDomainWildcard()->WithHost(url.host()); - } else if (url.SchemeIs(chrome::kHttpsScheme)) { - builder->WithSchemeWildcard()->WithDomainWildcard()->WithHost( - url.host()); - } else { - // Unsupported scheme - } - builder->WithPortWildcard(); - } - return builder->Build(); -} - -// static ContentSettingsPattern ContentSettingsPattern::FromURLNoWildcard( const GURL& url) { scoped_ptr<ContentSettingsPattern::BuilderInterface> builder( @@ -358,21 +329,6 @@ ContentSettingsPattern ContentSettingsPattern::FromURLNoWildcard( } // static -ContentSettingsPattern ContentSettingsPattern::LegacyFromURLNoWildcard( - const GURL& url) { - scoped_ptr<ContentSettingsPattern::BuilderInterface> builder( - ContentSettingsPattern::CreateBuilder(true)); - - if (url.SchemeIsFile()) { - builder->WithScheme(url.scheme())->WithPath(url.path()); - } else { - builder->WithSchemeWildcard()->WithHost(url.host()); - } - builder->WithPortWildcard(); - return builder->Build(); -} - -// static ContentSettingsPattern ContentSettingsPattern::FromString( const std::string& pattern_spec) { scoped_ptr<ContentSettingsPattern::BuilderInterface> builder( diff --git a/chrome/browser/content_settings/content_settings_pattern.h b/chrome/browser/content_settings/content_settings_pattern.h index 7525089..7f8d7cf 100644 --- a/chrome/browser/content_settings/content_settings_pattern.h +++ b/chrome/browser/content_settings/content_settings_pattern.h @@ -99,13 +99,9 @@ class ContentSettingsPattern { // all subdomains and ports. static ContentSettingsPattern FromURL(const GURL& url); - static ContentSettingsPattern LegacyFromURL(const GURL& url); - // Returns a pattern that matches exactly this URL. static ContentSettingsPattern FromURLNoWildcard(const GURL& url); - static ContentSettingsPattern LegacyFromURLNoWildcard(const GURL& url); - // Returns a pattern that matches the given pattern specification. // Valid patterns specifications are: // - [*.]domain.tld (matches domain.tld and all sub-domains) diff --git a/chrome/browser/content_settings/content_settings_pref_provider.cc b/chrome/browser/content_settings/content_settings_pref_provider.cc index d487b73..072dbb6 100644 --- a/chrome/browser/content_settings/content_settings_pref_provider.cc +++ b/chrome/browser/content_settings/content_settings_pref_provider.cc @@ -85,6 +85,43 @@ void SetDefaultContentSettings(DictionaryValue* default_settings) { } } +std::string CreatePatternString( + const ContentSettingsPattern& requesting_pattern, + const ContentSettingsPattern& embedding_pattern) { + DCHECK(requesting_pattern == embedding_pattern); + return requesting_pattern.ToString(); +} + +ContentSetting ValueToContentSetting(Value* value) { + int int_value; + value->GetAsInteger(&int_value); + return IntToContentSetting(int_value); +} + +ContentSettingsType StringToContentSettingsType( + const std::string& content_type_str) { + for (size_t type = 0; type < arraysize(kTypeNames); ++type) { + if ((kTypeNames[type] != NULL) && (kTypeNames[type] == content_type_str)) + return ContentSettingsType(type); + } + for (size_t type = 0; type < arraysize(kResourceTypeNames); ++type) { + if ((kResourceTypeNames[type] != NULL) && + (kResourceTypeNames[type] == content_type_str)) { + return ContentSettingsType(type); + } + } + return CONTENT_SETTINGS_TYPE_DEFAULT; +} + +ContentSetting FixObsoleteCookiePromptMode(ContentSettingsType content_type, + ContentSetting setting) { + if (content_type == CONTENT_SETTINGS_TYPE_COOKIES && + setting == CONTENT_SETTING_ASK) { + return CONTENT_SETTING_BLOCK; + } + return setting; +} + } // namespace namespace content_settings { @@ -344,8 +381,8 @@ void PrefProvider::RegisterUserPrefs(PrefService* prefs) { } PrefProvider::PrefProvider(Profile* profile) - : BaseProvider(profile->IsOffTheRecord()), - profile_(profile), + : profile_(profile), + is_incognito_(profile_->IsOffTheRecord()), updating_preferences_(false) { Init(); } @@ -372,9 +409,9 @@ void PrefProvider::Init() { // Read exceptions. ReadExceptions(false); - if (!is_incognito()) { + if (!is_incognito_) { UMA_HISTOGRAM_COUNTS("ContentSettings.NumberOfExceptions", - host_content_settings()->size()); + value_map_.size()); } pref_change_registrar_.Init(prefs); @@ -385,6 +422,66 @@ void PrefProvider::Init() { initializing_ = false; } +ContentSetting PrefProvider::GetContentSetting( + const GURL& requesting_url, + const GURL& embedding_url, + ContentSettingsType content_type, + const ResourceIdentifier& resource_identifier) const { + // Support for item, top-level-frame URLs are not enabled yet. + DCHECK(requesting_url == embedding_url); + + // For a |PrefProvider| used in a |HostContentSettingsMap| of a non incognito + // profile, this will always return NULL. + // TODO(markusheintz): I don't like this. I'd like to have an + // IncognitoProviderWrapper that wrapps the pref provider for a host content + // settings map of an incognito profile. + Value* incognito_value = incognito_value_map_.GetValue( + requesting_url, + embedding_url, + content_type, + resource_identifier); + if (incognito_value) + return ValueToContentSetting(incognito_value); + + Value* value = value_map_.GetValue( + requesting_url, + embedding_url, + content_type, + resource_identifier); + if (value) + return ValueToContentSetting(value); + + return CONTENT_SETTING_DEFAULT; +} + +void PrefProvider::GetAllContentSettingsRules( + ContentSettingsType content_type, + const ResourceIdentifier& resource_identifier, + Rules* content_setting_rules) const { + DCHECK_NE(RequiresResourceIdentifier(content_type), + resource_identifier.empty()); + DCHECK(content_setting_rules); + content_setting_rules->clear(); + + const OriginIdentifierValueMap* map_to_return = + is_incognito_ ? &incognito_value_map_ : &value_map_; + + base::AutoLock auto_lock(lock_); + for (OriginIdentifierValueMap::const_iterator entry = map_to_return->begin(); + entry != map_to_return->end(); + ++entry) { + if (entry->content_type == content_type && + entry->identifier == resource_identifier) { + ContentSetting setting = ValueToContentSetting(entry->value.get()); + DCHECK(setting != CONTENT_SETTING_DEFAULT); + Rule new_rule(entry->item_pattern, + entry->top_level_frame_pattern, + setting); + content_setting_rules->push_back(new_rule); + } + } +} + void PrefProvider::SetContentSetting( const ContentSettingsPattern& requesting_pattern, const ContentSettingsPattern& embedding_pattern, @@ -403,97 +500,96 @@ void PrefProvider::SetContentSetting( CommandLine::ForCurrentProcess()->HasSwitch( switches::kEnableClickToPlay)); - bool early_exit = false; - std::string pattern_str(requesting_pattern.ToString()); - DictionaryValue* all_settings_dictionary = NULL; - updating_preferences_ = true; { - // Begin scope of update. - // profile_ may be NULL in unit tests. DictionaryPrefUpdate update(profile_ ? profile_->GetPrefs() : NULL, prefs::kContentSettingsPatterns); + DictionaryValue* all_settings_dictionary = NULL; - // Select content-settings-map to write to. - HostContentSettings* map_to_modify = incognito_settings(); - if (!is_incognito()) { + OriginIdentifierValueMap* map_to_modify = &incognito_value_map_; + if (!is_incognito_) { + map_to_modify = &value_map_; all_settings_dictionary = update.Get(); - - map_to_modify = host_content_settings(); } - // Update content-settings-map. + // Update in memory value map. { - base::AutoLock auto_lock(lock()); - if (!map_to_modify->count(pattern_str)) - (*map_to_modify)[pattern_str].content_settings = ContentSettings(); - HostContentSettings::iterator i(map_to_modify->find(pattern_str)); - ContentSettings& settings = i->second.content_settings; - if (RequiresResourceIdentifier(content_type)) { - settings.settings[content_type] = CONTENT_SETTING_DEFAULT; - if (setting != CONTENT_SETTING_DEFAULT) { - i->second.content_settings_for_resources[ - ContentSettingsTypeResourceIdentifierPair(content_type, - resource_identifier)] = setting; - } else { - i->second.content_settings_for_resources.erase( - ContentSettingsTypeResourceIdentifierPair(content_type, - resource_identifier)); - } + base::AutoLock auto_lock(lock_); + if (setting == CONTENT_SETTING_DEFAULT) { + map_to_modify->DeleteValue( + requesting_pattern, + embedding_pattern, + content_type, + resource_identifier); } else { - settings.settings[content_type] = setting; - } - if (AllDefault(i->second)) { - map_to_modify->erase(i); - if (all_settings_dictionary) - all_settings_dictionary->RemoveWithoutPathExpansion( - pattern_str, NULL); - - // We can't just return because |NotifyObservers()| needs to be called, - // without lock() being held. - early_exit = true; + map_to_modify->SetValue( + requesting_pattern, + embedding_pattern, + content_type, + resource_identifier, + Value::CreateIntegerValue(setting)); } } - // Update the content_settings preference. - if (!early_exit && all_settings_dictionary) { - DictionaryValue* host_settings_dictionary = NULL; + // Update the content settings preference. + std::string pattern_str(CreatePatternString(requesting_pattern, + embedding_pattern)); + if (all_settings_dictionary) { + // Get settings dictionary for the pattern string (key). + DictionaryValue* settings_dictionary = NULL; bool found = all_settings_dictionary->GetDictionaryWithoutPathExpansion( - pattern_str, &host_settings_dictionary); - if (!found) { - host_settings_dictionary = new DictionaryValue; + pattern_str, &settings_dictionary); + + if (!found && (setting != CONTENT_SETTING_DEFAULT)) { + settings_dictionary = new DictionaryValue; all_settings_dictionary->SetWithoutPathExpansion( - pattern_str, host_settings_dictionary); - DCHECK_NE(setting, CONTENT_SETTING_DEFAULT); + pattern_str, settings_dictionary); } - if (RequiresResourceIdentifier(content_type)) { - std::string dictionary_path(kResourceTypeNames[content_type]); - DictionaryValue* resource_dictionary = NULL; - found = host_settings_dictionary->GetDictionary( - dictionary_path, &resource_dictionary); - if (!found) { - resource_dictionary = new DictionaryValue; - host_settings_dictionary->Set(dictionary_path, resource_dictionary); - } - if (setting == CONTENT_SETTING_DEFAULT) { - resource_dictionary->RemoveWithoutPathExpansion(resource_identifier, - NULL); + + if (settings_dictionary) { + if (RequiresResourceIdentifier(content_type)) { + // Get resource dictionary. + std::string res_dictionary_path(kResourceTypeNames[content_type]); + DictionaryValue* resource_dictionary = NULL; + found = settings_dictionary->GetDictionary( + res_dictionary_path, &resource_dictionary); + if (!found) { + if (setting == CONTENT_SETTING_DEFAULT) + return; // Nothing to remove. Exit early. + resource_dictionary = new DictionaryValue; + settings_dictionary->Set(res_dictionary_path, resource_dictionary); + } + // Update resource dictionary. + if (setting == CONTENT_SETTING_DEFAULT) { + resource_dictionary->RemoveWithoutPathExpansion(resource_identifier, + NULL); + if (resource_dictionary->empty()) { + settings_dictionary->RemoveWithoutPathExpansion( + res_dictionary_path, NULL); + } + } else { + resource_dictionary->SetWithoutPathExpansion( + resource_identifier, Value::CreateIntegerValue(setting)); + } } else { - resource_dictionary->SetWithoutPathExpansion( - resource_identifier, Value::CreateIntegerValue(setting)); + // Update settings dictionary. + std::string setting_path(kTypeNames[content_type]); + if (setting == CONTENT_SETTING_DEFAULT) { + settings_dictionary->RemoveWithoutPathExpansion(setting_path, + NULL); + } else { + settings_dictionary->SetWithoutPathExpansion( + setting_path, Value::CreateIntegerValue(setting)); + } } - } else { - std::string dictionary_path(kTypeNames[content_type]); - if (setting == CONTENT_SETTING_DEFAULT) { - host_settings_dictionary->RemoveWithoutPathExpansion(dictionary_path, - NULL); - } else { - host_settings_dictionary->SetWithoutPathExpansion( - dictionary_path, Value::CreateIntegerValue(setting)); + // Remove the settings dictionary if it is empty. + if (settings_dictionary->empty()) { + all_settings_dictionary->RemoveWithoutPathExpansion( + pattern_str, NULL); } } } - } // End scope of update. + } updating_preferences_ = false; ContentSettingsDetails details( @@ -505,12 +601,12 @@ void PrefProvider::ResetToDefaults() { DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); { - base::AutoLock auto_lock(lock()); - host_content_settings()->clear(); - incognito_settings()->clear(); + base::AutoLock auto_lock(lock_); + value_map_.Clear(); + incognito_value_map_.Clear(); } - if (!is_incognito()) { + if (!is_incognito_) { PrefService* prefs = profile_->GetPrefs(); updating_preferences_ = true; prefs->ClearPref(prefs::kContentSettingsPatterns); @@ -522,47 +618,47 @@ void PrefProvider::ClearAllContentSettingsRules( ContentSettingsType content_type) { DCHECK(kTypeNames[content_type] != NULL); // Don't call this for Geolocation. - DictionaryValue* all_settings_dictionary = NULL; - HostContentSettings* map_to_modify = incognito_settings(); - updating_preferences_ = true; { // Begin scope of update. DictionaryPrefUpdate update(profile_->GetPrefs(), prefs::kContentSettingsPatterns); - if (!is_incognito()) { + DictionaryValue* all_settings_dictionary = NULL; + OriginIdentifierValueMap* map_to_modify = &incognito_value_map_; + if (!is_incognito_) { all_settings_dictionary = update.Get(); - map_to_modify = host_content_settings(); + map_to_modify = &value_map_; } { - base::AutoLock auto_lock(lock()); - for (HostContentSettings::iterator i(map_to_modify->begin()); - i != map_to_modify->end(); ) { - if (RequiresResourceIdentifier(content_type) || - i->second.content_settings.settings[content_type] != - CONTENT_SETTING_DEFAULT) { - if (RequiresResourceIdentifier(content_type)) - i->second.content_settings_for_resources.clear(); - i->second.content_settings.settings[content_type] = - CONTENT_SETTING_DEFAULT; - std::string host(i->first); - if (AllDefault(i->second)) { - if (all_settings_dictionary) - all_settings_dictionary->RemoveWithoutPathExpansion(host, NULL); - map_to_modify->erase(i++); - } else if (all_settings_dictionary) { - DictionaryValue* host_settings_dictionary; + base::AutoLock auto_lock(lock_); + + OriginIdentifierValueMap::iterator entry(map_to_modify->begin()); + while (entry != map_to_modify->end()) { + if (entry->content_type == content_type) { + std::string pattern_str = CreatePatternString( + entry->item_pattern, entry->top_level_frame_pattern); + // Delete current |entry| and set |entry| to the next value map entry. + entry = map_to_modify->DeleteValue(entry); + + // Update the content settings preference. + if (all_settings_dictionary) { + // Update the settings dictionary. + DictionaryValue* settings_dictionary; bool found = all_settings_dictionary->GetDictionaryWithoutPathExpansion( - host, &host_settings_dictionary); + pattern_str, &settings_dictionary); DCHECK(found); - host_settings_dictionary->RemoveWithoutPathExpansion( + settings_dictionary->RemoveWithoutPathExpansion( kTypeNames[content_type], NULL); - ++i; + // Remove empty dictionaries. + if (settings_dictionary->empty()) + all_settings_dictionary->RemoveWithoutPathExpansion(pattern_str, + NULL); } } else { - ++i; + // No action is required, so move to the next value map entry. + ++entry; } } } @@ -593,7 +689,7 @@ void PrefProvider::Observe( return; } - if (!is_incognito()) { + if (!is_incognito_) { ContentSettingsDetails details(ContentSettingsPattern(), CONTENT_SETTINGS_TYPE_DEFAULT, std::string()); @@ -615,52 +711,98 @@ PrefProvider::~PrefProvider() { // Private void PrefProvider::ReadExceptions(bool overwrite) { - base::AutoLock auto_lock(lock()); + base::AutoLock auto_lock(lock_); PrefService* prefs = profile_->GetPrefs(); const DictionaryValue* all_settings_dictionary = prefs->GetDictionary(prefs::kContentSettingsPatterns); if (overwrite) - host_content_settings()->clear(); + value_map_.Clear(); updating_preferences_ = true; - // Careful: The returned value could be NULL if the pref has never been set. if (all_settings_dictionary != NULL) { DictionaryPrefUpdate update(prefs, prefs::kContentSettingsPatterns); DictionaryValue* mutable_settings; scoped_ptr<DictionaryValue> mutable_settings_scope; - if (!is_incognito()) { + if (!is_incognito_) { mutable_settings = update.Get(); } else { // Create copy as we do not want to persist anything in OTR prefs. mutable_settings = all_settings_dictionary->DeepCopy(); mutable_settings_scope.reset(mutable_settings); } - // Convert all Unicode patterns into punycode form, then read. CanonicalizeContentSettingsExceptions(mutable_settings); for (DictionaryValue::key_iterator i(mutable_settings->begin_keys()); i != mutable_settings->end_keys(); ++i) { - const std::string& pattern(*i); - if (!ContentSettingsPattern::LegacyFromString(pattern).IsValid()) + const std::string& pattern_str(*i); + ContentSettingsPattern pattern = + ContentSettingsPattern::FromString(pattern_str); + if (!pattern.IsValid()) LOG(WARNING) << "Invalid pattern stored in content settings"; - DictionaryValue* pattern_settings_dictionary = NULL; + + // Get settings dictionary for the current pattern string, and read + // settings from the dictionary. + DictionaryValue* settings_dictionary = NULL; bool found = mutable_settings->GetDictionaryWithoutPathExpansion( - pattern, &pattern_settings_dictionary); + pattern_str, &settings_dictionary); DCHECK(found); - ExtendedContentSettings extended_settings; - GetSettingsFromDictionary(pattern_settings_dictionary, - &extended_settings.content_settings); - GetResourceSettingsFromDictionary( - pattern_settings_dictionary, - &extended_settings.content_settings_for_resources); + for (DictionaryValue::key_iterator i(settings_dictionary->begin_keys()); + i != settings_dictionary->end_keys(); + ++i) { + const std::string& content_type_str(*i); + ContentSettingsType content_type = StringToContentSettingsType( + content_type_str); + if (content_type == CONTENT_SETTINGS_TYPE_DEFAULT) { + NOTREACHED(); + LOG(WARNING) << "Skip settings for invalid content settings type '" + << content_type_str << "'"; + continue; + } - (*host_content_settings())[pattern] = extended_settings; + if (RequiresResourceIdentifier(content_type)) { + DictionaryValue* resource_dictionary = NULL; + bool found = settings_dictionary->GetDictionary( + content_type_str, &resource_dictionary); + DCHECK(found); + for (DictionaryValue::key_iterator j( + resource_dictionary->begin_keys()); + j != resource_dictionary->end_keys(); + ++j) { + const std::string& resource_identifier(*j); + int setting = CONTENT_SETTING_DEFAULT; + found = resource_dictionary->GetIntegerWithoutPathExpansion( + resource_identifier, &setting); + DCHECK(found); + setting = ClickToPlayFixup(content_type, + ContentSetting(setting)); + value_map_.SetValue(pattern, + pattern, + content_type, + resource_identifier, + Value::CreateIntegerValue(setting)); + } + } else { + int setting = CONTENT_SETTING_DEFAULT; + bool found = settings_dictionary->GetIntegerWithoutPathExpansion( + content_type_str, &setting); + DCHECK(found); + setting = FixObsoleteCookiePromptMode(content_type, + ContentSetting(setting)); + setting = ClickToPlayFixup(content_type, + ContentSetting(setting)); + value_map_.SetValue(pattern, + pattern, + content_type, + ResourceIdentifier(""), + Value::CreateIntegerValue(setting)); + } + } } } updating_preferences_ = false; @@ -676,7 +818,7 @@ void PrefProvider::CanonicalizeContentSettingsExceptions( i != all_settings_dictionary->end_keys(); ++i) { const std::string& pattern(*i); const std::string canonicalized_pattern = - ContentSettingsPattern::LegacyFromString(pattern).ToString(); + ContentSettingsPattern::FromString(pattern).ToString(); if (canonicalized_pattern.empty() || canonicalized_pattern == pattern) continue; @@ -710,65 +852,6 @@ void PrefProvider::CanonicalizeContentSettingsExceptions( } } -void PrefProvider::GetSettingsFromDictionary( - const DictionaryValue* dictionary, - ContentSettings* settings) { - for (DictionaryValue::key_iterator i(dictionary->begin_keys()); - i != dictionary->end_keys(); ++i) { - const std::string& content_type(*i); - for (size_t type = 0; type < arraysize(kTypeNames); ++type) { - if ((kTypeNames[type] != NULL) && (kTypeNames[type] == content_type)) { - int setting = CONTENT_SETTING_DEFAULT; - bool found = dictionary->GetIntegerWithoutPathExpansion(content_type, - &setting); - DCHECK(found); - settings->settings[type] = IntToContentSetting(setting); - break; - } - } - } - // Migrate obsolete cookie prompt mode. - if (settings->settings[CONTENT_SETTINGS_TYPE_COOKIES] == - CONTENT_SETTING_ASK) - settings->settings[CONTENT_SETTINGS_TYPE_COOKIES] = CONTENT_SETTING_BLOCK; - - settings->settings[CONTENT_SETTINGS_TYPE_PLUGINS] = - ClickToPlayFixup(CONTENT_SETTINGS_TYPE_PLUGINS, - settings->settings[CONTENT_SETTINGS_TYPE_PLUGINS]); -} - -void PrefProvider::GetResourceSettingsFromDictionary( - const DictionaryValue* dictionary, - ResourceContentSettings* settings) { - for (DictionaryValue::key_iterator i(dictionary->begin_keys()); - i != dictionary->end_keys(); ++i) { - const std::string& content_type(*i); - for (size_t type = 0; type < arraysize(kResourceTypeNames); ++type) { - if ((kResourceTypeNames[type] != NULL) && - (kResourceTypeNames[type] == content_type)) { - DictionaryValue* resource_dictionary = NULL; - bool found = dictionary->GetDictionary(content_type, - &resource_dictionary); - DCHECK(found); - for (DictionaryValue::key_iterator j(resource_dictionary->begin_keys()); - j != resource_dictionary->end_keys(); ++j) { - const std::string& resource_identifier(*j); - int setting = CONTENT_SETTING_DEFAULT; - bool found = resource_dictionary->GetIntegerWithoutPathExpansion( - resource_identifier, &setting); - DCHECK(found); - (*settings)[ContentSettingsTypeResourceIdentifierPair( - ContentSettingsType(type), resource_identifier)] = - ClickToPlayFixup(ContentSettingsType(type), - ContentSetting(setting)); - } - - break; - } - } - } -} - void PrefProvider::NotifyObservers( const ContentSettingsDetails& details) { DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); @@ -801,23 +884,48 @@ void PrefProvider::MigrateObsoletePerhostPref(PrefService* prefs) { i != all_settings_dictionary->end_keys(); ++i) { const std::string& host(*i); ContentSettingsPattern pattern = - ContentSettingsPattern::LegacyFromString( + ContentSettingsPattern::FromString( std::string(ContentSettingsPattern::kDomainWildcard) + host); DictionaryValue* host_settings_dictionary = NULL; bool found = all_settings_dictionary->GetDictionaryWithoutPathExpansion( host, &host_settings_dictionary); DCHECK(found); - ContentSettings settings; - GetSettingsFromDictionary(host_settings_dictionary, &settings); - for (int j = 0; j < CONTENT_SETTINGS_NUM_TYPES; ++j) { - if (settings.settings[j] != CONTENT_SETTING_DEFAULT && - !RequiresResourceIdentifier(ContentSettingsType(j))) { - SetContentSetting( - pattern, - pattern, - ContentSettingsType(j), - "", - settings.settings[j]); + + for (DictionaryValue::key_iterator i( + host_settings_dictionary->begin_keys()); + i != host_settings_dictionary->end_keys(); + ++i) { + const std::string& content_type_str(*i); + ContentSettingsType content_type = + StringToContentSettingsType(content_type_str); + + if (content_type == CONTENT_SETTINGS_TYPE_DEFAULT) { + NOTREACHED(); + LOG(DFATAL) << "Skip settings for invalid content settings type '" + << content_type_str << "'"; + continue; + } + + if (!RequiresResourceIdentifier(content_type)) { + int setting_int_value = CONTENT_SETTING_DEFAULT; + bool found = + host_settings_dictionary->GetIntegerWithoutPathExpansion( + content_type_str, &setting_int_value); + DCHECK(found); + ContentSetting setting = IntToContentSetting(setting_int_value); + + setting = FixObsoleteCookiePromptMode(content_type, setting); + setting = ClickToPlayFixup(content_type, setting); + + // TODO(markusheintz): Maybe this check can be removed. + if (setting != CONTENT_SETTING_DEFAULT) { + SetContentSetting( + pattern, + pattern, + content_type, + "", + setting); + } } } } @@ -833,8 +941,8 @@ void PrefProvider::MigrateObsoletePopupsPref(PrefService* prefs) { i != whitelist_pref->end(); ++i) { std::string host; (*i)->GetAsString(&host); - SetContentSetting(ContentSettingsPattern::LegacyFromString(host), - ContentSettingsPattern::LegacyFromString(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.h b/chrome/browser/content_settings/content_settings_pref_provider.h index 479ddd1..4e00ae5 100644 --- a/chrome/browser/content_settings/content_settings_pref_provider.h +++ b/chrome/browser/content_settings/content_settings_pref_provider.h @@ -14,8 +14,9 @@ #include "base/basictypes.h" #include "base/synchronization/lock.h" -#include "chrome/browser/content_settings/content_settings_base_provider.h" +#include "chrome/browser/content_settings/content_settings_origin_identifier_value_map.h" #include "chrome/browser/content_settings/content_settings_provider.h" +#include "chrome/browser/content_settings/content_settings_utils.h" #include "chrome/browser/prefs/pref_change_registrar.h" #include "content/common/notification_observer.h" #include "content/common/notification_registrar.h" @@ -99,7 +100,7 @@ class PrefDefaultProvider : public DefaultProviderInterface, // Content settings provider that provides content settings from the user // preference. -class PrefProvider : public BaseProvider, +class PrefProvider : public ProviderInterface, public NotificationObserver { public: static void RegisterUserPrefs(PrefService* prefs); @@ -107,6 +108,7 @@ class PrefProvider : public BaseProvider, explicit PrefProvider(Profile* profile); virtual ~PrefProvider(); + // ProviderInterface implementations. virtual void SetContentSetting( const ContentSettingsPattern& requesting_pattern, const ContentSettingsPattern& embedding_pattern, @@ -114,20 +116,30 @@ class PrefProvider : public BaseProvider, const ResourceIdentifier& resource_identifier, ContentSetting content_setting); + virtual ContentSetting GetContentSetting( + const GURL& requesting_url, + const GURL& embedding_url, + ContentSettingsType content_type, + const ResourceIdentifier& resource_identifier) const; + + virtual void GetAllContentSettingsRules( + ContentSettingsType content_type, + const ResourceIdentifier& resource_identifier, + Rules* content_setting_rules) const; + virtual void ClearAllContentSettingsRules( ContentSettingsType content_type); virtual void ResetToDefaults(); - // BaseProvider implementations. - virtual void Init(); - // NotificationObserver implementation. virtual void Observe(NotificationType type, const NotificationSource& source, const NotificationDetails& details); private: + void Init(); + void ReadExceptions(bool overwrite); // Various migration methods (old cookie, popup and per-host data gets @@ -138,20 +150,14 @@ class PrefProvider : public BaseProvider, void CanonicalizeContentSettingsExceptions( DictionaryValue* all_settings_dictionary); - void GetSettingsFromDictionary( - const DictionaryValue* dictionary, - ContentSettings* settings); - - void GetResourceSettingsFromDictionary( - const DictionaryValue* dictionary, - ResourceContentSettings* settings); - void NotifyObservers(const ContentSettingsDetails& details); void UnregisterObservers(); Profile* profile_; + bool is_incognito_; + PrefChangeRegistrar pref_change_registrar_; NotificationRegistrar notification_registrar_; @@ -162,6 +168,14 @@ class PrefProvider : public BaseProvider, // Do not fire any Notifications as long as we are in the constructor. bool initializing_; + OriginIdentifierValueMap value_map_; + + OriginIdentifierValueMap incognito_value_map_; + + // Used around accesses to the value map objects to guarantee + // thread safety. + mutable base::Lock lock_; + DISALLOW_COPY_AND_ASSIGN(PrefProvider); }; diff --git a/chrome/browser/content_settings/host_content_settings_map.cc b/chrome/browser/content_settings/host_content_settings_map.cc index e2b95c4..b226a6e 100644 --- a/chrome/browser/content_settings/host_content_settings_map.cc +++ b/chrome/browser/content_settings/host_content_settings_map.cc @@ -260,34 +260,33 @@ void HostContentSettingsMap::GetSettingsForOneType( const std::string& resource_identifier, SettingsForOneType* settings) const { DCHECK(settings); - settings->clear(); - // Collect content_settings::Rules for the given content_type and // resource_identifier from the content settings providers. - Rules content_settings_rules; + std::map<std::string, PatternSettingPair> + pattern_str_pattern_setting_pair_map; for (ConstProviderIterator provider = content_settings_providers_.begin(); - provider != content_settings_providers_.end(); - ++provider) { - // TODO(markusheintz): Only the rules that are applied should be collected. - // Merge rules. - // TODO(markusheintz): GetAllContentSettingsRules should maybe not clear the - // passed vector in case rule sets are just unified. + provider != content_settings_providers_.end(); + ++provider) { Rules rules; (*provider)->GetAllContentSettingsRules( content_type, resource_identifier, &rules); - content_settings_rules.insert(content_settings_rules.end(), - rules.begin(), - rules.end()); + // TODO(markusheintz): Only the rules that are applied should be collected. + for (Rules::iterator rule = rules.begin(); + rule != rules.end(); + ++rule) { + const ContentSettingsPattern& pattern(rule->requesting_url_pattern); + pattern_str_pattern_setting_pair_map[pattern.ToString()] = + PatternSettingPair(pattern, rule->content_setting); + } } - // convert Rules to SettingsForOneType - for (const_rules_iterator rule_iterator = - content_settings_rules.begin(); - rule_iterator != content_settings_rules.end(); - ++rule_iterator) { - settings->push_back(std::make_pair(ContentSettingsPattern( - rule_iterator->requesting_url_pattern), - rule_iterator->content_setting)); + settings->clear(); + // Rely on the maps iterator to sort the rules. + for (std::map<std::string, PatternSettingPair>::iterator i( + pattern_str_pattern_setting_pair_map.begin()); + i != pattern_str_pattern_setting_pair_map.end(); + ++i) { + settings->push_back(i->second); } } @@ -321,11 +320,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(ContentSettingsPattern::LegacyFromURLNoWildcard(url), + SetContentSetting(ContentSettingsPattern::FromURLNoWildcard(url), content_type, resource_identifier, CONTENT_SETTING_DEFAULT); - SetContentSetting(ContentSettingsPattern::LegacyFromURL(url), + SetContentSetting(ContentSettingsPattern::FromURL(url), content_type, resource_identifier, setting); diff --git a/chrome/browser/ui/content_settings/content_setting_bubble_model_unittest.cc b/chrome/browser/ui/content_settings/content_setting_bubble_model_unittest.cc index 1320096..fcf5818 100644 --- a/chrome/browser/ui/content_settings/content_setting_bubble_model_unittest.cc +++ b/chrome/browser/ui/content_settings/content_setting_bubble_model_unittest.cc @@ -111,6 +111,10 @@ TEST_F(ContentSettingBubbleModelTest, MultiplePlugins) { HostContentSettingsMap* map = profile_->GetHostContentSettingsMap(); std::string fooPlugin = "foo"; std::string barPlugin = "bar"; + + // Navigating to some sample url prevents the GetURL method from returning an + // invalid empty URL. + contents()->NavigateAndCommit(GURL("http://www.example.com")); GURL url = contents()->GetURL(); map->AddExceptionForURL(url, CONTENT_SETTINGS_TYPE_PLUGINS, diff --git a/chrome/browser/ui/webui/options/content_settings_handler.cc b/chrome/browser/ui/webui/options/content_settings_handler.cc index a135bd6..68b4716 100644 --- a/chrome/browser/ui/webui/options/content_settings_handler.cc +++ b/chrome/browser/ui/webui/options/content_settings_handler.cc @@ -662,7 +662,7 @@ void ContentSettingsHandler::RemoveException(const ListValue* args) { // got destroyed before we received this message. if (settings_map) { settings_map->SetContentSetting( - ContentSettingsPattern::LegacyFromString(pattern), + ContentSettingsPattern::FromString(pattern), ContentSettingsTypeFromGroupName(type_string), "", CONTENT_SETTING_DEFAULT); @@ -697,7 +697,7 @@ void ContentSettingsHandler::SetException(const ListValue* args) { if (!settings_map) return; - settings_map->SetContentSetting(ContentSettingsPattern::LegacyFromString( + settings_map->SetContentSetting(ContentSettingsPattern::FromString( pattern), type, "", @@ -715,7 +715,7 @@ void ContentSettingsHandler::CheckExceptionPatternValidity( CHECK(args->GetString(arg_i++, &pattern_string)); ContentSettingsPattern pattern = - ContentSettingsPattern::LegacyFromString(pattern_string); + 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 bf4c2ce..90e9c38 100644 --- a/chrome/chrome_browser.gypi +++ b/chrome/chrome_browser.gypi @@ -761,6 +761,8 @@ 'browser/content_settings/content_settings_extension_provider.h', 'browser/content_settings/content_settings_notification_provider.cc', 'browser/content_settings/content_settings_notification_provider.h', + 'browser/content_settings/content_settings_origin_identifier_value_map.cc', + 'browser/content_settings/content_settings_origin_identifier_value.h', 'browser/content_settings/content_settings_pattern.cc', 'browser/content_settings/content_settings_pattern.h', 'browser/content_settings/content_settings_pattern_parser.cc', diff --git a/chrome/chrome_tests.gypi b/chrome/chrome_tests.gypi index e7cd17d..4c633ae 100644 --- a/chrome/chrome_tests.gypi +++ b/chrome/chrome_tests.gypi @@ -1351,6 +1351,7 @@ 'browser/command_updater_unittest.cc', 'browser/content_settings/content_settings_mock_provider.cc', 'browser/content_settings/content_settings_mock_provider.h', + 'browser/content_settings/content_settings_origin_identifier_value_map_unittest.cc', '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', |