diff options
25 files changed, 335 insertions, 473 deletions
diff --git a/chrome/browser/chrome_content_browser_client.cc b/chrome/browser/chrome_content_browser_client.cc index 111dd03..d5dd276 100644 --- a/chrome/browser/chrome_content_browser_client.cc +++ b/chrome/browser/chrome_content_browser_client.cc @@ -17,6 +17,7 @@ #include "chrome/browser/chrome_benchmarking_message_filter.h" #include "chrome/browser/chrome_plugin_message_filter.h" #include "chrome/browser/chrome_quota_permission_context.h" +#include "chrome/browser/content_settings/content_settings_utils.h" #include "chrome/browser/content_settings/cookie_settings.h" #include "chrome/browser/content_settings/tab_specific_content_settings.h" #include "chrome/browser/download/download_util.h" @@ -320,10 +321,10 @@ void ChromeContentBrowserClient::BrowserRenderProcessHostCreated( profile->IsOffTheRecord())); SendExtensionWebRequestStatusToHost(host); - ContentSettingsForOneType settings; - HostContentSettingsMap* map = profile->GetHostContentSettingsMap(); - map->GetSettingsForOneType(CONTENT_SETTINGS_TYPE_IMAGES, "", &settings); - host->Send(new ChromeViewMsg_SetImageSettingRules(settings)); + + RendererContentSettingRules rules; + GetRendererContentSettingRules(profile->GetHostContentSettingsMap(), &rules); + host->Send(new ChromeViewMsg_SetContentSettingRules(rules)); } void ChromeContentBrowserClient::PluginProcessHostCreated( diff --git a/chrome/browser/content_settings/content_settings_default_provider.cc b/chrome/browser/content_settings/content_settings_default_provider.cc index d1ff977..0451577 100644 --- a/chrome/browser/content_settings/content_settings_default_provider.cc +++ b/chrome/browser/content_settings/content_settings_default_provider.cc @@ -109,7 +109,7 @@ DefaultProvider::DefaultProvider(PrefService* prefs, bool incognito) // Read global defaults. ReadDefaultSettings(true); - if (default_content_settings_.settings[CONTENT_SETTINGS_TYPE_COOKIES] == + if (default_content_settings_[CONTENT_SETTINGS_TYPE_COOKIES] == CONTENT_SETTING_BLOCK) { UserMetrics::RecordAction( UserMetricsAction("CookieBlockingEnabledPerDefault")); @@ -161,12 +161,12 @@ void DefaultProvider::SetContentSetting( base::AutoLock lock(lock_); if (setting == CONTENT_SETTING_DEFAULT || setting == kDefaultSettings[content_type]) { - default_content_settings_.settings[content_type] = + default_content_settings_[content_type] = kDefaultSettings[content_type]; default_settings_dictionary->RemoveWithoutPathExpansion(dictionary_path, NULL); } else { - default_content_settings_.settings[content_type] = setting; + default_content_settings_[content_type] = setting; default_settings_dictionary->SetWithoutPathExpansion( dictionary_path, Value::CreateIntegerValue(setting)); } @@ -193,8 +193,7 @@ RuleIterator* DefaultProvider::GetRuleIterator( bool incognito) const { base::AutoLock lock(lock_); if (resource_identifier.empty()) { - return new DefaultRuleIterator( - default_content_settings_.settings[content_type]); + return new DefaultRuleIterator(default_content_settings_[content_type]); } else { return new EmptyRuleIterator(); } @@ -254,27 +253,29 @@ void DefaultProvider::ReadDefaultSettings(bool overwrite) { const DictionaryValue* default_settings_dictionary = prefs_->GetDictionary(prefs::kDefaultContentSettings); - if (overwrite) - default_content_settings_ = ContentSettings(); + if (overwrite) { + for (int i = 0; i < CONTENT_SETTINGS_NUM_TYPES; ++i) + default_content_settings_[i] = CONTENT_SETTING_DEFAULT; + } // Careful: The returned value could be NULL if the pref has never been set. if (default_settings_dictionary) { GetSettingsFromDictionary(default_settings_dictionary, - &default_content_settings_); + default_content_settings_); } ForceDefaultsToBeExplicit(); } void DefaultProvider::ForceDefaultsToBeExplicit() { for (int i = 0; i < CONTENT_SETTINGS_NUM_TYPES; ++i) { - if (default_content_settings_.settings[i] == CONTENT_SETTING_DEFAULT) - default_content_settings_.settings[i] = kDefaultSettings[i]; + if (default_content_settings_[i] == CONTENT_SETTING_DEFAULT) + default_content_settings_[i] = kDefaultSettings[i]; } } void DefaultProvider::GetSettingsFromDictionary( const DictionaryValue* dictionary, - ContentSettings* settings) { + ContentSetting* settings) { for (DictionaryValue::key_iterator i(dictionary->begin_keys()); i != dictionary->end_keys(); ++i) { const std::string& content_type(*i); @@ -284,19 +285,18 @@ void DefaultProvider::GetSettingsFromDictionary( bool found = dictionary->GetIntegerWithoutPathExpansion(content_type, &setting); DCHECK(found); - settings->settings[type] = IntToContentSetting(setting); + 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; + if (settings[CONTENT_SETTINGS_TYPE_COOKIES] == CONTENT_SETTING_ASK) + settings[CONTENT_SETTINGS_TYPE_COOKIES] = CONTENT_SETTING_BLOCK; - settings->settings[CONTENT_SETTINGS_TYPE_PLUGINS] = + settings[CONTENT_SETTINGS_TYPE_PLUGINS] = ClickToPlayFixup(CONTENT_SETTINGS_TYPE_PLUGINS, - settings->settings[CONTENT_SETTINGS_TYPE_PLUGINS]); + settings[CONTENT_SETTINGS_TYPE_PLUGINS]); } void DefaultProvider::MigrateObsoleteNotificationPref() { diff --git a/chrome/browser/content_settings/content_settings_default_provider.h b/chrome/browser/content_settings/content_settings_default_provider.h index f4a9c34..f9ddaff 100644 --- a/chrome/browser/content_settings/content_settings_default_provider.h +++ b/chrome/browser/content_settings/content_settings_default_provider.h @@ -57,7 +57,7 @@ class DefaultProvider : public ObservableProvider, private: // Sets the fields of |settings| based on the values in |dictionary|. void GetSettingsFromDictionary(const base::DictionaryValue* dictionary, - ContentSettings* settings); + ContentSetting* settings); // Forces the default settings to be explicitly set instead of themselves // being CONTENT_SETTING_DEFAULT. @@ -71,7 +71,7 @@ class DefaultProvider : public ObservableProvider, void MigrateObsoleteGeolocationPref(); // Copies of the pref data, so that we can read it on the IO thread. - ContentSettings default_content_settings_; + ContentSetting default_content_settings_[CONTENT_SETTINGS_NUM_TYPES]; PrefService* prefs_; 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 50e56ff..edefe97 100644 --- a/chrome/browser/content_settings/content_settings_pref_provider_unittest.cc +++ b/chrome/browser/content_settings/content_settings_pref_provider_unittest.cc @@ -53,15 +53,6 @@ void ExpectObsoleteGeolocationSetting( namespace content_settings { -bool SettingsEqual(const ContentSettings& settings1, - const ContentSettings& settings2) { - for (int i = 0; i < CONTENT_SETTINGS_NUM_TYPES; ++i) { - if (settings1.settings[i] != settings2.settings[i]) - return false; - } - return true; -} - class DeadlockCheckerThread : public base::PlatformThread::Delegate { public: explicit DeadlockCheckerThread(PrefProvider* provider) diff --git a/chrome/browser/content_settings/content_settings_utils.cc b/chrome/browser/content_settings/content_settings_utils.cc index 2338507..de814d9 100644 --- a/chrome/browser/content_settings/content_settings_utils.cc +++ b/chrome/browser/content_settings/content_settings_utils.cc @@ -14,8 +14,10 @@ #include "base/values.h" #include "chrome/browser/content_settings/content_settings_provider.h" #include "chrome/browser/content_settings/content_settings_rule.h" +#include "chrome/browser/content_settings/host_content_settings_map.h" #include "chrome/common/chrome_switches.h" #include "chrome/common/content_settings_pattern.h" +#include "chrome/common/render_messages.h" #include "googleurl/src/gurl.h" namespace { @@ -194,4 +196,12 @@ ContentSetting GetContentSetting(const ProviderInterface* provider, return ValueToContentSetting(value.get()); } +void GetRendererContentSettingRules(const HostContentSettingsMap* map, + RendererContentSettingRules* rules) { + map->GetSettingsForOneType(CONTENT_SETTINGS_TYPE_IMAGES, "", + &(rules->image_rules)); + map->GetSettingsForOneType(CONTENT_SETTINGS_TYPE_JAVASCRIPT, "", + &(rules->script_rules)); +} + } // namespace content_settings diff --git a/chrome/browser/content_settings/content_settings_utils.h b/chrome/browser/content_settings/content_settings_utils.h index 4fae58c..4b0e81b 100644 --- a/chrome/browser/content_settings/content_settings_utils.h +++ b/chrome/browser/content_settings/content_settings_utils.h @@ -17,6 +17,7 @@ class Value; } class GURL; +class HostContentSettingsMap; namespace content_settings { @@ -85,6 +86,11 @@ ContentSetting GetContentSetting( const std::string& resource_identifier, bool include_incognito); +// Populates |rules| with content setting rules for content types that are +// handled by the renderer. +void GetRendererContentSettingRules(const HostContentSettingsMap* map, + RendererContentSettingRules* rules); + } // namespace content_settings #endif // CHROME_BROWSER_CONTENT_SETTINGS_CONTENT_SETTINGS_UTILS_H_ diff --git a/chrome/browser/content_settings/host_content_settings_map.cc b/chrome/browser/content_settings/host_content_settings_map.cc index b0baa04..2c09ad2 100644 --- a/chrome/browser/content_settings/host_content_settings_map.cc +++ b/chrome/browser/content_settings/host_content_settings_map.cc @@ -163,16 +163,6 @@ ContentSetting HostContentSettingsMap::GetDefaultContentSetting( return CONTENT_SETTING_DEFAULT; } -ContentSettings HostContentSettingsMap::GetDefaultContentSettings() const { - ContentSettings output(CONTENT_SETTING_DEFAULT); - for (int i = 0; i < CONTENT_SETTINGS_NUM_TYPES; ++i) { - if (!ContentTypeHasCompoundValue(ContentSettingsType(i))) - output.settings[i] = GetDefaultContentSetting(ContentSettingsType(i), - NULL); - } - return output; -} - ContentSetting HostContentSettingsMap::GetContentSetting( const GURL& primary_url, const GURL& secondary_url, @@ -183,23 +173,6 @@ ContentSetting HostContentSettingsMap::GetContentSetting( return content_settings::ValueToContentSetting(value.get()); } -ContentSettings HostContentSettingsMap::GetContentSettings( - const GURL& primary_url) const { - ContentSettings output; - // If we require a resource identifier, set the content settings to default, - // otherwise make the defaults explicit. Values for content type - // CONTENT_SETTINGS_TYPE_AUTO_SELECT_CERTIFICATE can't be mapped to the type - // |ContentSetting|. So we ignore them here. - for (int j = 0; j < CONTENT_SETTINGS_NUM_TYPES; ++j) { - ContentSettingsType type = ContentSettingsType(j); - if (!ContentTypeHasCompoundValue(type)) { - output.settings[j] = GetContentSetting( - primary_url, primary_url, ContentSettingsType(j), std::string()); - } - } - return output; -} - void HostContentSettingsMap::GetSettingsForOneType( ContentSettingsType content_type, const std::string& resource_identifier, diff --git a/chrome/browser/content_settings/host_content_settings_map.h b/chrome/browser/content_settings/host_content_settings_map.h index 7c91008..a6f8700 100644 --- a/chrome/browser/content_settings/host_content_settings_map.h +++ b/chrome/browser/content_settings/host_content_settings_map.h @@ -60,11 +60,6 @@ class HostContentSettingsMap ContentSetting GetDefaultContentSetting(ContentSettingsType content_type, std::string* provider_id) const; - // Returns the default settings for all content types. - // - // This may be called on any thread. - ContentSettings GetDefaultContentSettings() const; - // Returns a single |ContentSetting| which applies to the given URLs. Note // that certain internal schemes are whitelisted. For |CONTENT_TYPE_COOKIES|, // |CookieSettings| should be used instead. For content types that can't be @@ -98,14 +93,6 @@ class HostContentSettingsMap const std::string& resource_identifier, content_settings::SettingInfo* info) const; - // Returns all ContentSettings which apply to the given |primary_url|. For - // content setting types that require an additional resource identifier, the - // default content setting is returned. - // - // This may be called on any thread. - ContentSettings GetContentSettings( - const GURL& primary_url) const; - // For a given content type, returns all patterns with a non-default setting, // mapped to their actual settings, in the precedence order of the rules. // |settings| must be a non-NULL outparam. 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 0965bc3..44fd8db 100644 --- a/chrome/browser/content_settings/host_content_settings_map_unittest.cc +++ b/chrome/browser/content_settings/host_content_settings_map_unittest.cc @@ -26,23 +26,6 @@ using content::BrowserThread; using ::testing::_; -namespace { - -bool SettingsEqual(const ContentSettings& settings1, - const ContentSettings& settings2) { - for (int i = 0; i < CONTENT_SETTINGS_NUM_TYPES; ++i) { - if (settings1.settings[i] != settings2.settings[i]) { - LOG(ERROR) << "type: " << i - << " [expected: " << settings1.settings[i] - << " actual: " << settings2.settings[i] << "]"; - return false; - } - } - return true; -} - -} // namespace - class HostContentSettingsMapTest : public testing::Test { public: HostContentSettingsMapTest() : ui_thread_(BrowserThread::UI, &message_loop_) { @@ -126,48 +109,51 @@ TEST_F(HostContentSettingsMapTest, IndividualSettings) { host, host, CONTENT_SETTINGS_TYPE_PLUGINS, "")); // Check returning all settings for a host. - ContentSettings desired_settings; - desired_settings.settings[CONTENT_SETTINGS_TYPE_COOKIES] = - CONTENT_SETTING_ALLOW; host_content_settings_map->SetContentSetting( pattern, ContentSettingsPattern::Wildcard(), CONTENT_SETTINGS_TYPE_IMAGES, std::string(), CONTENT_SETTING_DEFAULT); - desired_settings.settings[CONTENT_SETTINGS_TYPE_IMAGES] = - CONTENT_SETTING_ALLOW; + EXPECT_EQ(CONTENT_SETTING_ALLOW, + host_content_settings_map->GetContentSetting( + host, host, CONTENT_SETTINGS_TYPE_IMAGES, "")); host_content_settings_map->SetContentSetting( pattern, ContentSettingsPattern::Wildcard(), CONTENT_SETTINGS_TYPE_JAVASCRIPT, std::string(), CONTENT_SETTING_BLOCK); - desired_settings.settings[CONTENT_SETTINGS_TYPE_JAVASCRIPT] = - CONTENT_SETTING_BLOCK; + EXPECT_EQ(CONTENT_SETTING_BLOCK, + host_content_settings_map->GetContentSetting( + host, host, CONTENT_SETTINGS_TYPE_JAVASCRIPT, "")); host_content_settings_map->SetContentSetting( pattern, ContentSettingsPattern::Wildcard(), CONTENT_SETTINGS_TYPE_PLUGINS, std::string(), CONTENT_SETTING_ALLOW); - desired_settings.settings[CONTENT_SETTINGS_TYPE_PLUGINS] = - CONTENT_SETTING_ALLOW; - desired_settings.settings[CONTENT_SETTINGS_TYPE_POPUPS] = - CONTENT_SETTING_BLOCK; - desired_settings.settings[CONTENT_SETTINGS_TYPE_GEOLOCATION] = - CONTENT_SETTING_ASK; - desired_settings.settings[CONTENT_SETTINGS_TYPE_NOTIFICATIONS] = - CONTENT_SETTING_ASK; - desired_settings.settings[CONTENT_SETTINGS_TYPE_INTENTS] = - CONTENT_SETTING_ASK; - desired_settings.settings[CONTENT_SETTINGS_TYPE_FULLSCREEN] = - CONTENT_SETTING_ASK; - desired_settings.settings[CONTENT_SETTINGS_TYPE_MOUSELOCK] = - CONTENT_SETTING_ASK; - ContentSettings settings = - host_content_settings_map->GetContentSettings(host); - EXPECT_TRUE(SettingsEqual(desired_settings, settings)); + EXPECT_EQ(CONTENT_SETTING_ALLOW, + host_content_settings_map->GetContentSetting( + host, host, CONTENT_SETTINGS_TYPE_PLUGINS, "")); + EXPECT_EQ(CONTENT_SETTING_BLOCK, + host_content_settings_map->GetContentSetting( + host, host, CONTENT_SETTINGS_TYPE_POPUPS, "")); + EXPECT_EQ(CONTENT_SETTING_ASK, + host_content_settings_map->GetContentSetting( + host, host, CONTENT_SETTINGS_TYPE_GEOLOCATION, "")); + EXPECT_EQ(CONTENT_SETTING_ASK, + host_content_settings_map->GetContentSetting( + host, host, CONTENT_SETTINGS_TYPE_NOTIFICATIONS, "")); + EXPECT_EQ(CONTENT_SETTING_ASK, + host_content_settings_map->GetContentSetting( + host, host, CONTENT_SETTINGS_TYPE_INTENTS, "")); + EXPECT_EQ(CONTENT_SETTING_ASK, + host_content_settings_map->GetContentSetting( + host, host, CONTENT_SETTINGS_TYPE_FULLSCREEN, "")); + EXPECT_EQ(CONTENT_SETTING_ASK, + host_content_settings_map->GetContentSetting( + host, host, CONTENT_SETTINGS_TYPE_MOUSELOCK, "")); // Check returning all hosts for a setting. ContentSettingsPattern pattern2 = @@ -603,48 +589,36 @@ TEST_F(HostContentSettingsMapTest, NestedSettings) { host_content_settings_map->SetDefaultContentSetting( CONTENT_SETTINGS_TYPE_JAVASCRIPT, CONTENT_SETTING_BLOCK); - ContentSettings desired_settings; - desired_settings.settings[CONTENT_SETTINGS_TYPE_COOKIES] = - CONTENT_SETTING_BLOCK; - desired_settings.settings[CONTENT_SETTINGS_TYPE_IMAGES] = - CONTENT_SETTING_BLOCK; - desired_settings.settings[CONTENT_SETTINGS_TYPE_JAVASCRIPT] = - CONTENT_SETTING_BLOCK; - desired_settings.settings[CONTENT_SETTINGS_TYPE_PLUGINS] = - CONTENT_SETTING_BLOCK; - desired_settings.settings[CONTENT_SETTINGS_TYPE_POPUPS] = - CONTENT_SETTING_BLOCK; - desired_settings.settings[CONTENT_SETTINGS_TYPE_GEOLOCATION] = - CONTENT_SETTING_ASK; - desired_settings.settings[CONTENT_SETTINGS_TYPE_NOTIFICATIONS] = - CONTENT_SETTING_ASK; - desired_settings.settings[CONTENT_SETTINGS_TYPE_INTENTS] = - CONTENT_SETTING_ASK; - desired_settings.settings[CONTENT_SETTINGS_TYPE_FULLSCREEN] = - CONTENT_SETTING_ASK; - desired_settings.settings[CONTENT_SETTINGS_TYPE_MOUSELOCK] = - CONTENT_SETTING_ASK; - ContentSettings settings = - host_content_settings_map->GetContentSettings(host); - EXPECT_TRUE(SettingsEqual(desired_settings, settings)); - EXPECT_EQ(desired_settings.settings[CONTENT_SETTINGS_TYPE_COOKIES], - settings.settings[CONTENT_SETTINGS_TYPE_COOKIES]); - EXPECT_EQ(desired_settings.settings[CONTENT_SETTINGS_TYPE_IMAGES], - settings.settings[CONTENT_SETTINGS_TYPE_IMAGES]); - EXPECT_EQ(desired_settings.settings[CONTENT_SETTINGS_TYPE_PLUGINS], - settings.settings[CONTENT_SETTINGS_TYPE_PLUGINS]); - EXPECT_EQ(desired_settings.settings[CONTENT_SETTINGS_TYPE_POPUPS], - settings.settings[CONTENT_SETTINGS_TYPE_POPUPS]); - EXPECT_EQ(desired_settings.settings[CONTENT_SETTINGS_TYPE_GEOLOCATION], - settings.settings[CONTENT_SETTINGS_TYPE_GEOLOCATION]); - EXPECT_EQ(desired_settings.settings[CONTENT_SETTINGS_TYPE_COOKIES], - settings.settings[CONTENT_SETTINGS_TYPE_COOKIES]); - EXPECT_EQ(desired_settings.settings[CONTENT_SETTINGS_TYPE_INTENTS], - settings.settings[CONTENT_SETTINGS_TYPE_INTENTS]); - EXPECT_EQ(desired_settings.settings[CONTENT_SETTINGS_TYPE_FULLSCREEN], - settings.settings[CONTENT_SETTINGS_TYPE_FULLSCREEN]); - EXPECT_EQ(desired_settings.settings[CONTENT_SETTINGS_TYPE_MOUSELOCK], - settings.settings[CONTENT_SETTINGS_TYPE_MOUSELOCK]); + EXPECT_EQ(CONTENT_SETTING_BLOCK, + host_content_settings_map->GetContentSetting( + host, host, CONTENT_SETTINGS_TYPE_COOKIES, "")); + EXPECT_EQ(CONTENT_SETTING_BLOCK, + host_content_settings_map->GetContentSetting( + host, host, CONTENT_SETTINGS_TYPE_IMAGES, "")); + EXPECT_EQ(CONTENT_SETTING_BLOCK, + host_content_settings_map->GetContentSetting( + host, host, CONTENT_SETTINGS_TYPE_JAVASCRIPT, "")); + EXPECT_EQ(CONTENT_SETTING_BLOCK, + host_content_settings_map->GetContentSetting( + host, host, CONTENT_SETTINGS_TYPE_PLUGINS, "")); + EXPECT_EQ(CONTENT_SETTING_BLOCK, + host_content_settings_map->GetContentSetting( + host, host, CONTENT_SETTINGS_TYPE_POPUPS, "")); + EXPECT_EQ(CONTENT_SETTING_ASK, + host_content_settings_map->GetContentSetting( + host, host, CONTENT_SETTINGS_TYPE_GEOLOCATION, "")); + EXPECT_EQ(CONTENT_SETTING_ASK, + host_content_settings_map->GetContentSetting( + host, host, CONTENT_SETTINGS_TYPE_NOTIFICATIONS, "")); + EXPECT_EQ(CONTENT_SETTING_ASK, + host_content_settings_map->GetContentSetting( + host, host, CONTENT_SETTINGS_TYPE_INTENTS, "")); + EXPECT_EQ(CONTENT_SETTING_ASK, + host_content_settings_map->GetContentSetting( + host, host, CONTENT_SETTINGS_TYPE_FULLSCREEN, "")); + EXPECT_EQ(CONTENT_SETTING_ASK, + host_content_settings_map->GetContentSetting( + host, host, CONTENT_SETTINGS_TYPE_MOUSELOCK, "")); } TEST_F(HostContentSettingsMapTest, OffTheRecord) { @@ -814,10 +788,9 @@ TEST_F(HostContentSettingsMapTest, ResourceIdentifier) { ContentSetting default_plugin_setting = host_content_settings_map->GetDefaultContentSetting( CONTENT_SETTINGS_TYPE_PLUGINS, NULL); - ContentSettings settings = - host_content_settings_map->GetContentSettings(host); EXPECT_EQ(default_plugin_setting, - settings.settings[CONTENT_SETTINGS_TYPE_PLUGINS]); + host_content_settings_map->GetContentSetting( + host, host, CONTENT_SETTINGS_TYPE_PLUGINS, "")); // If no resource-specific content settings are defined, the setting should be // DEFAULT. diff --git a/chrome/browser/content_settings/mock_settings_observer.cc b/chrome/browser/content_settings/mock_settings_observer.cc index a0cc5b1..a281a1d 100644 --- a/chrome/browser/content_settings/mock_settings_observer.cc +++ b/chrome/browser/content_settings/mock_settings_observer.cc @@ -34,5 +34,6 @@ void MockSettingsObserver::Observe( settings_details->update_all()); // This checks that calling a Get function from an observer doesn't // deadlock. - map->GetContentSettings(GURL("http://random-hostname.com/")); + GURL url("http://random-hostname.com/"); + map->GetContentSetting(url, url, CONTENT_SETTINGS_TYPE_IMAGES, ""); } diff --git a/chrome/browser/content_settings/tab_specific_content_settings.cc b/chrome/browser/content_settings/tab_specific_content_settings.cc index 09735ce..3009f25 100644 --- a/chrome/browser/content_settings/tab_specific_content_settings.cc +++ b/chrome/browser/content_settings/tab_specific_content_settings.cc @@ -16,6 +16,7 @@ #include "chrome/browser/browsing_data_indexed_db_helper.h" #include "chrome/browser/browsing_data_local_storage_helper.h" #include "chrome/browser/content_settings/content_settings_details.h" +#include "chrome/browser/content_settings/content_settings_utils.h" #include "chrome/browser/content_settings/host_content_settings_map.h" #include "chrome/browser/cookies_tree_model.h" #include "chrome/browser/profiles/profile.h" @@ -430,15 +431,6 @@ void TabSpecificContentSettings::DidNavigateMainFrame( } } -void TabSpecificContentSettings::RenderViewCreated( - RenderViewHost* render_view_host) { - Profile* profile = - Profile::FromBrowserContext(tab_contents()->browser_context()); - HostContentSettingsMap* map = profile->GetHostContentSettingsMap(); - render_view_host->Send(new ChromeViewMsg_SetDefaultContentSettings( - map->GetDefaultContentSettings())); -} - void TabSpecificContentSettings::DidStartProvisionalLoadForFrame( int64 frame_id, bool is_main_frame, @@ -485,14 +477,10 @@ void TabSpecificContentSettings::Observe( settings_details.ptr()->primary_pattern().Matches(entry_url)) { Profile* profile = Profile::FromBrowserContext(tab_contents()->browser_context()); - HostContentSettingsMap* map = profile->GetHostContentSettingsMap(); - Send(new ChromeViewMsg_SetDefaultContentSettings( - map->GetDefaultContentSettings())); - Send(new ChromeViewMsg_SetContentSettingsForCurrentURL( - entry_url, map->GetContentSettings(entry_url))); - ContentSettingsForOneType settings; - map->GetSettingsForOneType(CONTENT_SETTINGS_TYPE_IMAGES, "", &settings); - Send(new ChromeViewMsg_SetImageSettingRules(settings)); + RendererContentSettingRules rules; + GetRendererContentSettingRules(profile->GetHostContentSettingsMap(), + &rules); + Send(new ChromeViewMsg_SetContentSettingRules(rules)); } } diff --git a/chrome/browser/content_settings/tab_specific_content_settings.h b/chrome/browser/content_settings/tab_specific_content_settings.h index 22db73d..40d1069 100644 --- a/chrome/browser/content_settings/tab_specific_content_settings.h +++ b/chrome/browser/content_settings/tab_specific_content_settings.h @@ -163,7 +163,6 @@ class TabSpecificContentSettings : public TabContentsObserver, virtual void DidNavigateMainFrame( const content::LoadCommittedDetails& details, const ViewHostMsg_FrameNavigate_Params& params) OVERRIDE; - virtual void RenderViewCreated(RenderViewHost* render_view_host) OVERRIDE; virtual void DidStartProvisionalLoadForFrame( int64 frame_id, bool is_main_frame, diff --git a/chrome/browser/renderer_host/chrome_resource_dispatcher_host_delegate.cc b/chrome/browser/renderer_host/chrome_resource_dispatcher_host_delegate.cc index 35231bb..3d86c7c 100644 --- a/chrome/browser/renderer_host/chrome_resource_dispatcher_host_delegate.cc +++ b/chrome/browser/renderer_host/chrome_resource_dispatcher_host_delegate.cc @@ -333,16 +333,6 @@ void ChromeResourceDispatcherHostDelegate::OnResponseStarted( } } - // We must send the content settings for the URL before sending response - // headers to the renderer. - const content::ResourceContext& resource_context = filter->resource_context(); - ProfileIOData* io_data = - reinterpret_cast<ProfileIOData*>(resource_context.GetUserData(NULL)); - HostContentSettingsMap* map = io_data->GetHostContentSettingsMap(); - filter->Send(new ChromeViewMsg_SetContentSettingsForLoadingURL( - info->route_id(), request->url(), - map->GetContentSettings(request->url()))); - // See if the response contains the X-Auto-Login header. If so, this was // a request for a login page, and the server is allowing the browser to // suggest auto-login, if available. diff --git a/chrome/common/content_settings.cc b/chrome/common/content_settings.cc index ecf26f8..8b28f4b 100644 --- a/chrome/common/content_settings.cc +++ b/chrome/common/content_settings.cc @@ -10,16 +10,6 @@ ContentSetting IntToContentSetting(int content_setting) { CONTENT_SETTING_DEFAULT : static_cast<ContentSetting>(content_setting); } -ContentSettings::ContentSettings() { - for (int i = 0; i < CONTENT_SETTINGS_NUM_TYPES; ++i) - settings[i] = CONTENT_SETTING_DEFAULT; -} - -ContentSettings::ContentSettings(ContentSetting default_setting) { - for (int i = 0; i < CONTENT_SETTINGS_NUM_TYPES; ++i) - settings[i] = default_setting; -} - ContentSettingPatternSource::ContentSettingPatternSource( const ContentSettingsPattern& primary_pattern, const ContentSettingsPattern& secondary_pattern, @@ -33,3 +23,7 @@ ContentSettingPatternSource::ContentSettingPatternSource( incognito(incognito) {} ContentSettingPatternSource::ContentSettingPatternSource() {} + +RendererContentSettingRules::RendererContentSettingRules() {} + +RendererContentSettingRules::~RendererContentSettingRules() {} diff --git a/chrome/common/content_settings.h b/chrome/common/content_settings.h index ec500b6..6e015ee 100644 --- a/chrome/common/content_settings.h +++ b/chrome/common/content_settings.h @@ -27,14 +27,6 @@ enum ContentSetting { // prefs off disk. ContentSetting IntToContentSetting(int content_setting); -// Aggregates the permissions for the different content types. -struct ContentSettings { - ContentSettings(); - explicit ContentSettings(ContentSetting default_setting); - - ContentSetting settings[CONTENT_SETTINGS_NUM_TYPES]; -}; - struct ContentSettingPatternSource { ContentSettingPatternSource(const ContentSettingsPattern& primary_pattern, const ContentSettingsPattern& secondary_patttern, @@ -51,6 +43,13 @@ struct ContentSettingPatternSource { typedef std::vector<ContentSettingPatternSource> ContentSettingsForOneType; +struct RendererContentSettingRules { + RendererContentSettingRules(); + ~RendererContentSettingRules(); + ContentSettingsForOneType image_rules; + ContentSettingsForOneType script_rules; +}; + namespace content_settings { // Enum containing the various source for content settings. Settings can be diff --git a/chrome/common/render_messages.cc b/chrome/common/render_messages.cc index 39c6705..726f082 100644 --- a/chrome/common/render_messages.cc +++ b/chrome/common/render_messages.cc @@ -6,26 +6,6 @@ namespace IPC { -void ParamTraits<ContentSettings>::Write( - Message* m, const ContentSettings& settings) { - for (size_t i = 0; i < arraysize(settings.settings); ++i) - WriteParam(m, settings.settings[i]); -} - -bool ParamTraits<ContentSettings>::Read( - const Message* m, void** iter, ContentSettings* r) { - for (size_t i = 0; i < arraysize(r->settings); ++i) { - if (!ReadParam(m, iter, &r->settings[i])) - return false; - } - return true; -} - -void ParamTraits<ContentSettings>::Log( - const ContentSettings& p, std::string* l) { - l->append("<ContentSettings>"); -} - void ParamTraits<ContentSettingsPattern>::Write( Message* m, const ContentSettingsPattern& pattern) { pattern.WriteToMessage(m); diff --git a/chrome/common/render_messages.h b/chrome/common/render_messages.h index 1d7b41d..54b5be3 100644 --- a/chrome/common/render_messages.h +++ b/chrome/common/render_messages.h @@ -98,14 +98,6 @@ struct ParamTraits<gfx::NativeView> { #endif // defined(OS_POSIX) && !defined(USE_AURA) template <> -struct ParamTraits<ContentSettings> { - typedef ContentSettings param_type; - static void Write(Message* m, const param_type& p); - static bool Read(const Message* m, void** iter, param_type* r); - static void Log(const param_type& p, std::string* l); -}; - -template <> struct ParamTraits<ContentSettingsPattern> { typedef ContentSettingsPattern param_type; static void Write(Message* m, const param_type& p); @@ -148,6 +140,11 @@ IPC_STRUCT_TRAITS_BEGIN(ContentSettingPatternSource) IPC_STRUCT_TRAITS_MEMBER(incognito) IPC_STRUCT_TRAITS_END() +IPC_STRUCT_TRAITS_BEGIN(RendererContentSettingRules) + IPC_STRUCT_TRAITS_MEMBER(image_rules) + IPC_STRUCT_TRAITS_MEMBER(script_rules) +IPC_STRUCT_TRAITS_END() + IPC_STRUCT_TRAITS_BEGIN(ThumbnailScore) IPC_STRUCT_TRAITS_MEMBER(boring_score) IPC_STRUCT_TRAITS_MEMBER(good_clipping) @@ -226,28 +223,9 @@ IPC_MESSAGE_CONTROL1(ChromeViewMsg_VisitedLink_Add, std::vector<uint64>) // re-calculated. IPC_MESSAGE_CONTROL0(ChromeViewMsg_VisitedLink_Reset) -// Set the content settings for a particular url that the renderer is in the -// process of loading. This will be stored, to be used if the load commits -// and ignored otherwise. -IPC_MESSAGE_ROUTED2(ChromeViewMsg_SetContentSettingsForLoadingURL, - GURL /* url */, - ContentSettings /* content_settings */) - -// Set the content settings for a particular url, so all render views -// displaying this host url update their content settings to match. -IPC_MESSAGE_CONTROL2(ChromeViewMsg_SetContentSettingsForCurrentURL, - GURL /* url */, - ContentSettings /* content_settings */) - -// Set the content settings for a particular url that the renderer is in the -// process of loading. This will be stored, to be used if the load commits -// and ignored otherwise. -IPC_MESSAGE_CONTROL1(ChromeViewMsg_SetDefaultContentSettings, - ContentSettings /* content_settings */) - -// Set the content settings for images. -IPC_MESSAGE_CONTROL1(ChromeViewMsg_SetImageSettingRules, - ContentSettingsForOneType /* rules */) +// Set the content setting rules stored by the renderer. +IPC_MESSAGE_CONTROL1(ChromeViewMsg_SetContentSettingRules, + RendererContentSettingRules /* rules */) // Tells the render view to load all blocked plugins. IPC_MESSAGE_ROUTED0(ChromeViewMsg_LoadBlockedPlugins) diff --git a/chrome/renderer/chrome_content_renderer_client.cc b/chrome/renderer/chrome_content_renderer_client.cc index 2ebbb3d..6d5817a8 100644 --- a/chrome/renderer/chrome_content_renderer_client.cc +++ b/chrome/renderer/chrome_content_renderer_client.cc @@ -217,10 +217,8 @@ void ChromeContentRendererClient::RenderViewCreated( ContentSettingsObserver* content_settings = new ContentSettingsObserver(render_view); if (chrome_observer_.get()) { - content_settings->SetDefaultContentSettings( - chrome_observer_->default_content_settings()); - content_settings->SetImageSettingRules( - chrome_observer_->image_setting_rules()); + content_settings->SetContentSettingRules( + chrome_observer_->content_setting_rules()); } new ExtensionHelper(render_view, extension_dispatcher_.get()); new PageLoadHistograms(render_view, histogram_snapshots_.get()); diff --git a/chrome/renderer/chrome_render_process_observer.cc b/chrome/renderer/chrome_render_process_observer.cc index db2e8f7..bdf5ee4 100644 --- a/chrome/renderer/chrome_render_process_observer.cc +++ b/chrome/renderer/chrome_render_process_observer.cc @@ -106,30 +106,6 @@ class RendererResourceDelegate : public content::ResourceDispatcherDelegate { DISALLOW_COPY_AND_ASSIGN(RendererResourceDelegate); }; -class RenderViewContentSettingsSetter : public content::RenderViewVisitor { - public: - RenderViewContentSettingsSetter(const GURL& url, - const ContentSettings& content_settings) - : url_(url), - content_settings_(content_settings) { - } - - virtual bool Visit(content::RenderView* render_view) { - if (GURL(render_view->GetWebView()->mainFrame()->document().url()) == - url_) { - ContentSettingsObserver::Get(render_view)->SetContentSettings( - content_settings_); - } - return true; - } - - private: - GURL url_; - ContentSettings content_settings_; - - DISALLOW_COPY_AND_ASSIGN(RenderViewContentSettingsSetter); -}; - #if defined(OS_WIN) static base::win::IATPatchFunction g_iat_patch_createdca; HDC WINAPI CreateDCAPatch(LPCSTR driver_name, @@ -263,12 +239,6 @@ bool ChromeRenderProcessObserver::OnControlMessageReceived( IPC_BEGIN_MESSAGE_MAP(ChromeRenderProcessObserver, message) IPC_MESSAGE_HANDLER(ChromeViewMsg_SetIsIncognitoProcess, OnSetIsIncognitoProcess) - IPC_MESSAGE_HANDLER(ChromeViewMsg_SetDefaultContentSettings, - OnSetDefaultContentSettings) - IPC_MESSAGE_HANDLER(ChromeViewMsg_SetContentSettingsForCurrentURL, - OnSetContentSettingsForCurrentURL) - IPC_MESSAGE_HANDLER(ChromeViewMsg_SetImageSettingRules, - OnSetImageSettingRules) IPC_MESSAGE_HANDLER(ChromeViewMsg_SetCacheCapacities, OnSetCacheCapacities) IPC_MESSAGE_HANDLER(ChromeViewMsg_ClearCache, OnClearCache) IPC_MESSAGE_HANDLER(ChromeViewMsg_SetFieldTrialGroup, OnSetFieldTrialGroup) @@ -284,6 +254,8 @@ bool ChromeRenderProcessObserver::OnControlMessageReceived( IPC_MESSAGE_HANDLER(ChromeViewMsg_GetCacheResourceStats, OnGetCacheResourceStats) IPC_MESSAGE_HANDLER(ChromeViewMsg_PurgeMemory, OnPurgeMemory) + IPC_MESSAGE_HANDLER(ChromeViewMsg_SetContentSettingRules, + OnSetContentSettingRules) IPC_MESSAGE_UNHANDLED(handled = false) IPC_END_MESSAGE_MAP() return handled; @@ -298,21 +270,9 @@ void ChromeRenderProcessObserver::OnSetIsIncognitoProcess( is_incognito_process_ = is_incognito_process; } -void ChromeRenderProcessObserver::OnSetContentSettingsForCurrentURL( - const GURL& url, - const ContentSettings& content_settings) { - RenderViewContentSettingsSetter setter(url, content_settings); - content::RenderView::ForEach(&setter); -} - -void ChromeRenderProcessObserver::OnSetDefaultContentSettings( - const ContentSettings& content_settings) { - default_content_settings_ = content_settings; -} - -void ChromeRenderProcessObserver::OnSetImageSettingRules( - const ContentSettingsForOneType& settings) { - image_setting_rules_ = settings; +void ChromeRenderProcessObserver::OnSetContentSettingRules( + const RendererContentSettingRules& rules) { + content_setting_rules_ = rules; } void ChromeRenderProcessObserver::OnSetCacheCapacities(size_t min_dead_capacity, @@ -425,12 +385,7 @@ void ChromeRenderProcessObserver::ExecutePendingClearCache() { } } -const ContentSettingsForOneType* -ChromeRenderProcessObserver::image_setting_rules() const { - return &image_setting_rules_; -} - -const ContentSettings* -ChromeRenderProcessObserver::default_content_settings() const { - return &default_content_settings_; +const RendererContentSettingRules* +ChromeRenderProcessObserver::content_setting_rules() const { + return &content_setting_rules_; } diff --git a/chrome/renderer/chrome_render_process_observer.h b/chrome/renderer/chrome_render_process_observer.h index e3ba711..ed4805e 100644 --- a/chrome/renderer/chrome_render_process_observer.h +++ b/chrome/renderer/chrome_render_process_observer.h @@ -41,13 +41,9 @@ class ChromeRenderProcessObserver : public content::RenderProcessObserver { // any 'clear cache' commands that were delayed until the next navigation. void ExecutePendingClearCache(); - // Returns a pointer to the default content settings owned by + // Returns a pointer to the content setting rules owned by // |ChromeRenderProcessObserver|. - const ContentSettings* default_content_settings() const; - - // Returns a pointer to the image setting rules owned by - // |ChromeRenderProcessObserver|. - const ContentSettingsForOneType* image_setting_rules() const; + const RendererContentSettingRules* content_setting_rules() const; private: // RenderProcessObserver implementation. @@ -57,8 +53,7 @@ class ChromeRenderProcessObserver : public content::RenderProcessObserver { void OnSetIsIncognitoProcess(bool is_incognito_process); void OnSetContentSettingsForCurrentURL( const GURL& url, const ContentSettings& content_settings); - void OnSetDefaultContentSettings(const ContentSettings& content_settings); - void OnSetImageSettingRules(const ContentSettingsForOneType& settings); + void OnSetContentSettingRules(const RendererContentSettingRules& rules); void OnSetCacheCapacities(size_t min_dead_capacity, size_t max_dead_capacity, size_t capacity); @@ -79,8 +74,7 @@ class ChromeRenderProcessObserver : public content::RenderProcessObserver { chrome::ChromeContentRendererClient* client_; // If true, the web cache shall be cleared before the next navigation event. bool clear_cache_pending_; - ContentSettings default_content_settings_; - ContentSettingsForOneType image_setting_rules_; + RendererContentSettingRules content_setting_rules_; DISALLOW_COPY_AND_ASSIGN(ChromeRenderProcessObserver); }; diff --git a/chrome/renderer/chrome_render_view_observer.cc b/chrome/renderer/chrome_render_view_observer.cc index 2fd19c5..fef6187 100644 --- a/chrome/renderer/chrome_render_view_observer.cc +++ b/chrome/renderer/chrome_render_view_observer.cc @@ -423,6 +423,15 @@ bool ChromeRenderViewObserver::allowScript(WebFrame* frame, return content_settings_->AllowScript(frame, enabled_per_settings); } +bool ChromeRenderViewObserver::allowScriptFromSource( + WebFrame* frame, + bool enabled_per_settings, + const WebURL& script_url) { + return content_settings_->AllowScriptFromSource(frame, + enabled_per_settings, + script_url); +} + bool ChromeRenderViewObserver::allowScriptExtension( WebFrame* frame, const WebString& extension_name, int extension_group) { return extension_dispatcher_->AllowScriptExtension( diff --git a/chrome/renderer/chrome_render_view_observer.h b/chrome/renderer/chrome_render_view_observer.h index fa32e12..0a8dec0 100644 --- a/chrome/renderer/chrome_render_view_observer.h +++ b/chrome/renderer/chrome_render_view_observer.h @@ -88,6 +88,9 @@ class ChromeRenderViewObserver : public content::RenderViewObserver, bool enabled_per_settings) OVERRIDE; virtual bool allowScript(WebKit::WebFrame* frame, bool enabled_per_settings) OVERRIDE; + virtual bool allowScriptFromSource(WebKit::WebFrame* frame, + bool enabled_per_settings, + const WebKit::WebURL& script_url) OVERRIDE; virtual bool allowScriptExtension(WebKit::WebFrame* frame, const WebKit::WebString& extension_name, int extension_group) OVERRIDE; diff --git a/chrome/renderer/content_settings_observer.cc b/chrome/renderer/content_settings_observer.cc index a8bdecb..0f77276 100644 --- a/chrome/renderer/content_settings_observer.cc +++ b/chrome/renderer/content_settings_observer.cc @@ -58,18 +58,40 @@ GURL GetOriginOrURL(const WebFrame* frame) { // The the |top_origin| is unique ("null") e.g., for file:// URLs. Use the // document URL as the primary URL in those cases. if (top_origin == "null") - return frame->document().url(); + return frame->top()->document().url(); return GURL(top_origin); } +ContentSetting GetContentSettingFromRules( + const ContentSettingsForOneType& rules, + const WebFrame* frame, + const GURL& secondary_url) { + ContentSettingsForOneType::const_iterator it; + // If there is only one rule, it's the default rule and we don't need to match + // the patterns. + if (rules.size() == 1) { + DCHECK(rules[0].primary_pattern == ContentSettingsPattern::Wildcard()); + DCHECK(rules[0].secondary_pattern == ContentSettingsPattern::Wildcard()); + return rules[0].setting; + } + const GURL& primary_url = GetOriginOrURL(frame); + for (it = rules.begin(); it != rules.end(); ++it) { + if (it->primary_pattern.Matches(primary_url) && + it->secondary_pattern.Matches(secondary_url)) { + return it->setting; + } + } + NOTREACHED(); + return CONTENT_SETTING_DEFAULT; +} + } // namespace ContentSettingsObserver::ContentSettingsObserver( content::RenderView* render_view) : content::RenderViewObserver(render_view), content::RenderViewObserverTracker<ContentSettingsObserver>(render_view), - default_content_settings_(NULL), - image_setting_rules_(NULL), + content_setting_rules_(NULL), plugins_temporarily_allowed_(false) { ClearBlockedContentSettings(); } @@ -77,26 +99,9 @@ ContentSettingsObserver::ContentSettingsObserver( ContentSettingsObserver::~ContentSettingsObserver() { } -void ContentSettingsObserver::SetContentSettings( - const ContentSettings& settings) { - current_content_settings_ = settings; -} - -void ContentSettingsObserver::SetDefaultContentSettings( - const ContentSettings* settings) { - default_content_settings_ = settings; -} - -void ContentSettingsObserver::SetImageSettingRules( - const ContentSettingsForOneType* image_setting_rules) { - image_setting_rules_ = image_setting_rules; -} - -ContentSetting ContentSettingsObserver::GetContentSetting( - ContentSettingsType type) { - // Don't call this for plug-ins. - DCHECK_NE(CONTENT_SETTINGS_TYPE_PLUGINS, type); - return current_content_settings_.settings[type]; +void ContentSettingsObserver::SetContentSettingRules( + const RendererContentSettingRules* content_setting_rules) { + content_setting_rules_ = content_setting_rules; } void ContentSettingsObserver::DidBlockContentType( @@ -120,8 +125,6 @@ bool ContentSettingsObserver::OnMessageReceived(const IPC::Message& message) { // blocked plugin. IPC_MESSAGE_HANDLER_GENERIC(ChromeViewMsg_LoadBlockedPlugins, OnLoadBlockedPlugins(); handled = false) - IPC_MESSAGE_HANDLER(ChromeViewMsg_SetContentSettingsForLoadingURL, - OnSetContentSettingsForLoadingURL) IPC_MESSAGE_UNHANDLED(handled = false) IPC_END_MESSAGE_MAP() return handled; @@ -135,54 +138,19 @@ void ContentSettingsObserver::DidCommitProvisionalLoad( NavigationState* state = NavigationState::FromDataSource(frame->dataSource()); if (!state->was_within_same_page()) { // Clear "block" flags for the new page. This needs to happen before any of - // allowScripts(), allowImage(), allowPlugins() is called for the new page - // so that these functions can correctly detect that a piece of content - // flipped from "not blocked" to "blocked". + // |AllowScript()|, |AllowScriptFromSource()|, |AllowImage()|, or + // |AllowPlugins()| is called for the new page so that these functions can + // correctly detect that a piece of content flipped from "not blocked" to + // "blocked". ClearBlockedContentSettings(); plugins_temporarily_allowed_ = false; } GURL url = frame->document().url(); - - if (frame->document().securityOrigin().toString() == "null" && - !url.SchemeIs(chrome::kFileScheme)) { - // The Frame has a unique security origin. Instead of granting the frame - // privileges based on it's URL, we fall back to the default content - // settings. - - // We exempt file URLs here because we sandbox them by default, but folks - // might reasonably want to supply non-default content settings for various - // file URLs. - if (default_content_settings_) - SetContentSettings(*default_content_settings_); - return; - } - // If we start failing this DCHECK, please makes sure we don't regress // this bug: http://code.google.com/p/chromium/issues/detail?id=79304 - DCHECK(!url.SchemeIs(chrome::kDataScheme)); - - // Set content settings. Default them from the parent window if one exists. - // This makes sure about:blank windows work as expected. - HostContentSettings::iterator host_content_settings = - host_content_settings_.find(url); - if (host_content_settings != host_content_settings_.end()) { - SetContentSettings(host_content_settings->second); - - // These content settings were merely recorded transiently for this load. - // We can erase them now. If at some point we reload this page, the - // browser will send us new, up-to-date content settings. - host_content_settings_.erase(host_content_settings); - } else if (frame->opener()) { - // The opener's view is not guaranteed to be non-null (it could be - // detached from its page but not yet destructed). - if (WebView* opener_view = frame->opener()->view()) { - content::RenderView* opener = - content::RenderView::FromWebView(opener_view); - ContentSettingsObserver* observer = ContentSettingsObserver::Get(opener); - SetContentSettings(observer->current_content_settings_); - } - } + DCHECK(frame->document().securityOrigin().toString() == "null" || + !url.SchemeIs(chrome::kDataScheme)); } bool ContentSettingsObserver::AllowDatabase(WebFrame* frame, @@ -220,19 +188,11 @@ bool ContentSettingsObserver::AllowImage(WebFrame* frame, return true; bool allow = enabled_per_settings; - const GURL& primary_url = GetOriginOrURL(frame); - GURL secondary_url(image_url); - if (image_setting_rules_ && - enabled_per_settings) { - ContentSettingsForOneType::const_iterator it; - for (it = image_setting_rules_->begin(); - it != image_setting_rules_->end(); ++it) { - if (it->primary_pattern.Matches(primary_url) && - it->secondary_pattern.Matches(secondary_url)) { - allow = (it->setting != CONTENT_SETTING_BLOCK); - break; - } - } + if (content_setting_rules_ && enabled_per_settings) { + GURL secondary_url(image_url); + allow = GetContentSettingFromRules( + content_setting_rules_->image_rules, + frame, secondary_url) != CONTENT_SETTING_BLOCK; } if (!allow) @@ -262,15 +222,47 @@ bool ContentSettingsObserver::AllowPlugins(WebFrame* frame, bool ContentSettingsObserver::AllowScript(WebFrame* frame, bool enabled_per_settings) { - if (enabled_per_settings && - AllowContentType(CONTENT_SETTINGS_TYPE_JAVASCRIPT)) { - return true; + if (!enabled_per_settings) + return false; + + std::map<WebFrame*, bool>::const_iterator it = + cached_script_permissions_.find(frame); + if (it != cached_script_permissions_.end()) + return it->second; + + // Evaluate the content setting rules before + // |IsWhitelistedForContentSettings|; if there is only the default rule + // allowing all scripts, it's quicker this way. + bool allow = true; + if (content_setting_rules_) { + ContentSetting setting = GetContentSettingFromRules( + content_setting_rules_->script_rules, + frame, + GURL(frame->document().securityOrigin().toString())); + allow = setting != CONTENT_SETTING_BLOCK; } + allow = allow || IsWhitelistedForContentSettings(frame); - if (IsWhitelistedForContentSettings(frame)) - return true; + cached_script_permissions_[frame] = allow; + return allow; +} - return false; // Other protocols fall through here. +bool ContentSettingsObserver::AllowScriptFromSource( + WebFrame* frame, + bool enabled_per_settings, + const WebKit::WebURL& script_url) { + if (!enabled_per_settings) + return false; + + bool allow = true; + if (content_setting_rules_) { + ContentSetting setting = GetContentSettingFromRules( + content_setting_rules_->script_rules, + frame, + GURL(script_url)); + allow = setting != CONTENT_SETTING_BLOCK; + } + return allow || IsWhitelistedForContentSettings(frame); } bool ContentSettingsObserver::AllowStorage(WebFrame* frame, bool local) { @@ -303,25 +295,13 @@ void ContentSettingsObserver::DidNotAllowScript(WebFrame* frame) { DidBlockContentType(CONTENT_SETTINGS_TYPE_JAVASCRIPT, std::string()); } -void ContentSettingsObserver::OnSetContentSettingsForLoadingURL( - const GURL& url, - const ContentSettings& content_settings) { - host_content_settings_[url] = content_settings; -} - void ContentSettingsObserver::OnLoadBlockedPlugins() { plugins_temporarily_allowed_ = true; } -bool ContentSettingsObserver::AllowContentType( - ContentSettingsType settings_type) { - // CONTENT_SETTING_ASK is only valid for cookies. - return current_content_settings_.settings[settings_type] != - CONTENT_SETTING_BLOCK; -} - void ContentSettingsObserver::ClearBlockedContentSettings() { for (size_t i = 0; i < arraysize(content_blocked_); ++i) content_blocked_[i] = false; cached_storage_permissions_.clear(); + cached_script_permissions_.clear(); } diff --git a/chrome/renderer/content_settings_observer.h b/chrome/renderer/content_settings_observer.h index acff53b..947333e 100644 --- a/chrome/renderer/content_settings_observer.h +++ b/chrome/renderer/content_settings_observer.h @@ -15,6 +15,7 @@ class GURL; namespace WebKit { +class WebFrame; class WebSecurityOrigin; class WebURL; } @@ -27,21 +28,11 @@ class ContentSettingsObserver explicit ContentSettingsObserver(content::RenderView* render_view); virtual ~ContentSettingsObserver(); - // Sets the content settings that back allowScripts() and allowPlugins(). - void SetContentSettings(const ContentSettings& settings); - - // Sets the default content settings that back allowScripts() and - // allowPlugins(). - void SetDefaultContentSettings(const ContentSettings* settings); - - // Sets the image setting rules which back |allowImage()|. The - // |ContentSettingsForOneType| object must outlive this + // Sets the content setting rules which back |AllowImage()|, |AllowScript()|, + // and |AllowScriptFromSource()|. |content_setting_rules| must outlive this // |ContentSettingsObserver|. - void SetImageSettingRules( - const ContentSettingsForOneType* image_setting_rules); - - // Returns the setting for the given type. - ContentSetting GetContentSetting(ContentSettingsType type); + void SetContentSettingRules( + const RendererContentSettingRules* content_setting_rules); bool plugins_temporarily_allowed() { return plugins_temporarily_allowed_; @@ -68,6 +59,8 @@ class ContentSettingsObserver const WebKit::WebSecurityOrigin& origin); bool AllowPlugins(WebKit::WebFrame* frame, bool enabled_per_settings); bool AllowScript(WebKit::WebFrame* frame, bool enabled_per_settings); + bool AllowScriptFromSource(WebKit::WebFrame* frame, bool enabled_per_settings, + const WebKit::WebURL& script_url); bool AllowStorage(WebKit::WebFrame* frame, bool local); void DidNotAllowPlugins(WebKit::WebFrame* frame); void DidNotAllowScript(WebKit::WebFrame* frame); @@ -79,33 +72,16 @@ class ContentSettingsObserver bool is_new_navigation); // Message handlers. - void OnSetContentSettingsForLoadingURL( - const GURL& url, - const ContentSettings& content_settings); void OnLoadBlockedPlugins(); - // Helper method that returns if the user wants to block content of type - // |content_type|. - bool AllowContentType(ContentSettingsType settings_type); - // Resets the |content_blocked_| array. void ClearBlockedContentSettings(); - typedef std::map<GURL, ContentSettings> HostContentSettings; - HostContentSettings host_content_settings_; - - // A pointer to the most up-to-date view of the default content - // settings. Normally, they are owned by |ChromeRenderProcessObserver|. In the - // tests they are owned by the caller of |SetDefaultContentSettings|. - const ContentSettings* default_content_settings_; - - // Stores if loading of scripts and plugins is allowed. - ContentSettings current_content_settings_; - - // Stores the rules for image content settings. Normally, they are owned by - // |ChromeRenderProcessObserver|. In the tests they are owned by the caller of - // |SetImageSettingRules|. - const ContentSettingsForOneType* image_setting_rules_; + // A pointer to content setting rules stored by the renderer. Normally, the + // |RendererContentSettingRules| object is owned by + // |ChromeRenderProcessObserver|. In the tests it is owned by the caller of + // |SetContentSettingRules|. + const RendererContentSettingRules* content_setting_rules_; // Stores if images, scripts, and plugins have actually been blocked. bool content_blocked_[CONTENT_SETTINGS_NUM_TYPES]; @@ -114,6 +90,9 @@ class ContentSettingsObserver typedef std::pair<GURL, bool> StoragePermissionsKey; std::map<StoragePermissionsKey, bool> cached_storage_permissions_; + // Caches the result of |AllowScript|. + std::map<WebKit::WebFrame*, bool> cached_script_permissions_; + bool plugins_temporarily_allowed_; DISALLOW_COPY_AND_ASSIGN(ContentSettingsObserver); diff --git a/chrome/renderer/content_settings_observer_browsertest.cc b/chrome/renderer/content_settings_observer_browsertest.cc index 4bd9805..d05df62 100644 --- a/chrome/renderer/content_settings_observer_browsertest.cc +++ b/chrome/renderer/content_settings_observer_browsertest.cc @@ -106,13 +106,18 @@ TEST_F(ChromeRenderViewTest, JSBlockSentAfterPageLoad) { LoadHTML(html.c_str()); // 2. Block JavaScript. - ContentSettings settings; - for (int i = 0; i < CONTENT_SETTINGS_NUM_TYPES; ++i) - settings.settings[i] = CONTENT_SETTING_ALLOW; - settings.settings[CONTENT_SETTINGS_TYPE_JAVASCRIPT] = CONTENT_SETTING_BLOCK; + RendererContentSettingRules content_setting_rules; + ContentSettingsForOneType& script_setting_rules = + content_setting_rules.script_rules; + script_setting_rules.push_back( + ContentSettingPatternSource( + ContentSettingsPattern::Wildcard(), + ContentSettingsPattern::Wildcard(), + CONTENT_SETTING_BLOCK, + "", + false)); ContentSettingsObserver* observer = ContentSettingsObserver::Get(view_); - observer->SetContentSettings(settings); - observer->SetDefaultContentSettings(&settings); + observer->SetContentSettingRules(&content_setting_rules); // Make sure no pending messages are in the queue. ProcessPendingMessages(); @@ -145,14 +150,7 @@ TEST_F(ChromeRenderViewTest, PluginsTemporarilyAllowed) { // Load some HTML. LoadHTML("<html>Foo</html>"); - // Block plugins. - ContentSettings settings; - for (int i = 0; i < CONTENT_SETTINGS_NUM_TYPES; ++i) - settings.settings[i] = CONTENT_SETTING_ALLOW; - settings.settings[CONTENT_SETTINGS_TYPE_PLUGINS] = CONTENT_SETTING_BLOCK; ContentSettingsObserver* observer = ContentSettingsObserver::Get(view_); - observer->SetContentSettings(settings); - observer->SetDefaultContentSettings(&settings); EXPECT_FALSE(observer->plugins_temporarily_allowed()); // Temporarily allow plugins. @@ -175,7 +173,9 @@ TEST_F(ChromeRenderViewTest, ImagesBlockedByDefault) { LoadHTML("<html>Foo</html>"); // Set the default image blocking setting. - ContentSettingsForOneType image_setting_rules; + RendererContentSettingRules content_setting_rules; + ContentSettingsForOneType& image_setting_rules = + content_setting_rules.image_rules; image_setting_rules.push_back( ContentSettingPatternSource(ContentSettingsPattern::Wildcard(), ContentSettingsPattern::Wildcard(), @@ -184,7 +184,7 @@ TEST_F(ChromeRenderViewTest, ImagesBlockedByDefault) { false)); ContentSettingsObserver* observer = ContentSettingsObserver::Get(view_); - observer->SetImageSettingRules(&image_setting_rules); + observer->SetContentSettingRules(&content_setting_rules); EXPECT_CALL(mock_observer, OnContentBlocked(CONTENT_SETTINGS_TYPE_IMAGES, std::string())); EXPECT_FALSE(observer->AllowImage(GetMainFrame(), @@ -216,7 +216,9 @@ TEST_F(ChromeRenderViewTest, ImagesAllowedByDefault) { LoadHTML("<html>Foo</html>"); // Set the default image blocking setting. - ContentSettingsForOneType image_setting_rules; + RendererContentSettingRules content_setting_rules; + ContentSettingsForOneType& image_setting_rules = + content_setting_rules.image_rules; image_setting_rules.push_back( ContentSettingPatternSource(ContentSettingsPattern::Wildcard(), ContentSettingsPattern::Wildcard(), @@ -225,7 +227,7 @@ TEST_F(ChromeRenderViewTest, ImagesAllowedByDefault) { false)); ContentSettingsObserver* observer = ContentSettingsObserver::Get(view_); - observer->SetImageSettingRules(&image_setting_rules); + observer->SetContentSettingRules(&content_setting_rules); EXPECT_CALL( mock_observer, OnContentBlocked(CONTENT_SETTINGS_TYPE_IMAGES, std::string())).Times(0); @@ -248,3 +250,75 @@ TEST_F(ChromeRenderViewTest, ImagesAllowedByDefault) { true, mock_observer.image_url_)); ::testing::Mock::VerifyAndClearExpectations(&observer); } + +TEST_F(ChromeRenderViewTest, ContentSettingsBlockScripts) { + // Set the content settings for scripts. + RendererContentSettingRules content_setting_rules; + ContentSettingsForOneType& script_setting_rules = + content_setting_rules.script_rules; + script_setting_rules.push_back( + ContentSettingPatternSource( + ContentSettingsPattern::Wildcard(), + ContentSettingsPattern::Wildcard(), + CONTENT_SETTING_BLOCK, + "", + false)); + + ContentSettingsObserver* observer = ContentSettingsObserver::Get(view_); + observer->SetContentSettingRules(&content_setting_rules); + + // Load a page which contains a script. + std::string html = "<html>" + "<head>" + "<script src='data:foo'></script>" + "</head>" + "<body>" + "</body>" + "</html>"; + LoadHTML(html.c_str()); + + // Verify that the script was blocked. + bool was_blocked = false; + for (size_t i = 0; i < render_thread_->sink().message_count(); ++i) { + const IPC::Message* msg = render_thread_->sink().GetMessageAt(i); + if (msg->type() == ChromeViewHostMsg_ContentBlocked::ID) + was_blocked = true; + } + EXPECT_TRUE(was_blocked); +} + +TEST_F(ChromeRenderViewTest, ContentSettingsAllowScripts) { + // Set the content settings for scripts. + RendererContentSettingRules content_setting_rules; + ContentSettingsForOneType& script_setting_rules = + content_setting_rules.script_rules; + script_setting_rules.push_back( + ContentSettingPatternSource( + ContentSettingsPattern::Wildcard(), + ContentSettingsPattern::Wildcard(), + CONTENT_SETTING_ALLOW, + "", + false)); + + ContentSettingsObserver* observer = ContentSettingsObserver::Get(view_); + observer->SetContentSettingRules(&content_setting_rules); + + // Load a page which contains a script. + std::string html = "<html>" + "<head>" + "<script src='data:foo'></script>" + "</head>" + "<body>" + "</body>" + "</html>"; + LoadHTML(html.c_str()); + + // Verify that the script was not blocked. + bool was_blocked = false; + for (size_t i = 0; i < render_thread_->sink().message_count(); ++i) { + const IPC::Message* msg = render_thread_->sink().GetMessageAt(i); + if (msg->type() == ChromeViewHostMsg_ContentBlocked::ID) + was_blocked = true; + } + EXPECT_FALSE(was_blocked); +} |