diff options
author | bauerb@chromium.org <bauerb@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2011-10-19 12:59:20 +0000 |
---|---|---|
committer | bauerb@chromium.org <bauerb@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2011-10-19 12:59:20 +0000 |
commit | 610ca838d7afb9c551bb186888e2ebf25ca913e7 (patch) | |
tree | 54368d99af30410f51fa7cdaec4c06bd8389a762 | |
parent | 6d6fe593efe370ff53dbf9487fe393083162dbc6 (diff) | |
download | chromium_src-610ca838d7afb9c551bb186888e2ebf25ca913e7.zip chromium_src-610ca838d7afb9c551bb186888e2ebf25ca913e7.tar.gz chromium_src-610ca838d7afb9c551bb186888e2ebf25ca913e7.tar.bz2 |
Check for default content setting pattern when requiring user authorization for plug-ins.
We now check in the renderer if a plug-in is allowed by default, which is the case if the matching patterns are wildcards.
BUG=100581
TEST=see bug
Review URL: http://codereview.chromium.org/8334020
git-svn-id: svn://svn.chromium.org/chrome/trunk/src@106270 0039d316-1c4b-4281-b951-d872f2087c98
16 files changed, 247 insertions, 176 deletions
diff --git a/chrome/browser/content_settings/content_settings_utils.cc b/chrome/browser/content_settings/content_settings_utils.cc index 5abebd2..cdc8537c 100644 --- a/chrome/browser/content_settings/content_settings_utils.cc +++ b/chrome/browser/content_settings/content_settings_utils.cc @@ -120,77 +120,77 @@ bool ParseContentSettingValue(const base::Value* value, return *setting != CONTENT_SETTING_DEFAULT; } -base::Value* GetContentSettingValue(const ProviderInterface* provider, - const GURL& primary_url, - const GURL& secondary_url, - ContentSettingsType content_type, - const std::string& resource_identifier, - bool include_incognito) { +base::Value* GetContentSettingValueAndPatterns( + const ProviderInterface* provider, + const GURL& primary_url, + const GURL& secondary_url, + ContentSettingsType content_type, + const std::string& resource_identifier, + bool include_incognito, + ContentSettingsPattern* primary_pattern, + ContentSettingsPattern* secondary_pattern) { if (include_incognito) { // Check incognito-only specific settings. It's essential that the // |RuleIterator| gets out of scope before we get a rule iterator for the // normal mode. scoped_ptr<RuleIterator> incognito_rule_iterator( provider->GetRuleIterator(content_type, resource_identifier, true)); - base::Value* value = GetContentSettingValue( - incognito_rule_iterator.get(), primary_url, secondary_url); + base::Value* value = GetContentSettingValueAndPatterns( + incognito_rule_iterator.get(), primary_url, secondary_url, + primary_pattern, secondary_pattern); if (value) return value; } // No settings from the incognito; use the normal mode. scoped_ptr<RuleIterator> rule_iterator( provider->GetRuleIterator(content_type, resource_identifier, false)); - return GetContentSettingValue( - rule_iterator.get(), primary_url, secondary_url); -} - -ContentSetting GetContentSetting(const ProviderInterface* provider, - const GURL& primary_url, - const GURL& secondary_url, - ContentSettingsType content_type, - const std::string& resource_identifier, - bool include_incognito) { - if (include_incognito) { - // Check incognito-only specific settings. It's essential that the - // |RuleIterator| gets out of scope before we get a rule iterator for the - // normal mode. - scoped_ptr<RuleIterator> incognito_rule_iterator( - provider->GetRuleIterator(content_type, resource_identifier, true)); - ContentSetting setting = GetContentSetting( - incognito_rule_iterator.get(), primary_url, secondary_url); - if (setting != CONTENT_SETTING_DEFAULT) - return setting; - } - // No settings from the incognito; use the normal mode. - scoped_ptr<RuleIterator> rule_iterator( - provider->GetRuleIterator(content_type, resource_identifier, false)); - return GetContentSetting(rule_iterator.get(), primary_url, secondary_url); + return GetContentSettingValueAndPatterns( + rule_iterator.get(), primary_url, secondary_url, + primary_pattern, secondary_pattern); } -base::Value* GetContentSettingValue(RuleIterator* rule_iterator, - const GURL& primary_url, - const GURL& secondary_url) { +base::Value* GetContentSettingValueAndPatterns( + RuleIterator* rule_iterator, + const GURL& primary_url, + const GURL& secondary_url, + ContentSettingsPattern* primary_pattern, + ContentSettingsPattern* secondary_pattern) { while (rule_iterator->HasNext()) { const Rule& rule = rule_iterator->Next(); if (rule.primary_pattern.Matches(primary_url) && rule.secondary_pattern.Matches(secondary_url)) { + if (primary_pattern) + *primary_pattern = rule.primary_pattern; + if (secondary_pattern) + *secondary_pattern = rule.secondary_pattern; return rule.value.get()->DeepCopy(); } } return NULL; } -ContentSetting GetContentSetting(RuleIterator* rule_iterator, +base::Value* GetContentSettingValue(const ProviderInterface* provider, + const GURL& primary_url, + const GURL& secondary_url, + ContentSettingsType content_type, + const std::string& resource_identifier, + bool include_incognito) { + return GetContentSettingValueAndPatterns(provider, primary_url, secondary_url, + content_type, resource_identifier, + include_incognito, NULL, NULL); +} + +ContentSetting GetContentSetting(const ProviderInterface* provider, const GURL& primary_url, - const GURL& secondary_url) { - while (rule_iterator->HasNext()) { - const Rule& rule = rule_iterator->Next(); - if (rule.primary_pattern.Matches(primary_url) && - rule.secondary_pattern.Matches(secondary_url)) { - return ValueToContentSetting(rule.value.get()); - } - } - return CONTENT_SETTING_DEFAULT; + const GURL& secondary_url, + ContentSettingsType content_type, + const std::string& resource_identifier, + bool include_incognito) { + scoped_ptr<base::Value> value( + GetContentSettingValue(provider, primary_url, secondary_url, + content_type, resource_identifier, + include_incognito)); + return ValueToContentSetting(value.get()); } } // namespace content_settings diff --git a/chrome/browser/content_settings/content_settings_utils.h b/chrome/browser/content_settings/content_settings_utils.h index 6d40b72..4fae58c 100644 --- a/chrome/browser/content_settings/content_settings_utils.h +++ b/chrome/browser/content_settings/content_settings_utils.h @@ -52,15 +52,22 @@ std::string CreatePatternString( const ContentSettingsPattern& top_level_frame_pattern); // Caller takes the ownership of the returned |base::Value*|. -base::Value* GetContentSettingValue( +base::Value* GetContentSettingValueAndPatterns( RuleIterator* rule_iterator, const GURL& primary_url, - const GURL& secondary_url); + const GURL& secondary_url, + ContentSettingsPattern* primary_pattern, + ContentSettingsPattern* secondary_pattern); -ContentSetting GetContentSetting( - RuleIterator* rule_iterator, +base::Value* GetContentSettingValueAndPatterns( + const ProviderInterface* provider, const GURL& primary_url, - const GURL& secondary_url); + const GURL& secondary_url, + ContentSettingsType content_type, + const std::string& resource_identifier, + bool include_incognito, + ContentSettingsPattern* primary_pattern, + ContentSettingsPattern* secondary_pattern); base::Value* GetContentSettingValue( const ProviderInterface* provider, diff --git a/chrome/browser/content_settings/host_content_settings_map.cc b/chrome/browser/content_settings/host_content_settings_map.cc index b8b8af7..fb3a9a5 100644 --- a/chrome/browser/content_settings/host_content_settings_map.cc +++ b/chrome/browser/content_settings/host_content_settings_map.cc @@ -203,26 +203,23 @@ ContentSetting HostContentSettingsMap::GetCookieContentSetting( return CONTENT_SETTING_ALLOW; // First get any host-specific settings. - ContentSetting setting = CONTENT_SETTING_DEFAULT; + scoped_ptr<base::Value> value; for (ConstProviderIterator provider = content_settings_providers_.begin(); provider != content_settings_providers_.end(); ++provider) { if (provider->first == DEFAULT_PROVIDER) continue; - setting = content_settings::GetContentSetting(provider->second, - url, - first_party_url, - CONTENT_SETTINGS_TYPE_COOKIES, - std::string(), - is_off_the_record_); - if (setting != CONTENT_SETTING_DEFAULT) + value.reset(content_settings::GetContentSettingValueAndPatterns( + provider->second, url, first_party_url, CONTENT_SETTINGS_TYPE_COOKIES, + std::string(), is_off_the_record_, NULL, NULL)); + if (value.get()) break; } // If no explicit exception has been made and third-party cookies are blocked // by default, apply that rule. - if (setting == CONTENT_SETTING_DEFAULT && BlockThirdPartyCookies()) { + if (!value.get() && BlockThirdPartyCookies()) { bool strict = CommandLine::ForCurrentProcess()->HasSwitch( switches::kBlockReadingThirdPartyCookies); net::StaticCookiePolicy policy(strict ? @@ -235,14 +232,14 @@ ContentSetting HostContentSettingsMap::GetCookieContentSetting( rv = policy.CanGetCookies(url, first_party_url); DCHECK_NE(net::ERR_IO_PENDING, rv); if (rv != net::OK) - setting = CONTENT_SETTING_BLOCK; + return CONTENT_SETTING_BLOCK; } // If no other policy has changed the setting, use the default. - if (setting == CONTENT_SETTING_DEFAULT) - setting = GetDefaultContentSetting(CONTENT_SETTINGS_TYPE_COOKIES); + if (value.get()) + return content_settings::ValueToContentSetting(value.get()); - return setting; + return GetDefaultContentSetting(CONTENT_SETTINGS_TYPE_COOKIES); } ContentSetting HostContentSettingsMap::GetContentSetting( @@ -250,58 +247,45 @@ ContentSetting HostContentSettingsMap::GetContentSetting( const GURL& secondary_url, ContentSettingsType content_type, const std::string& resource_identifier) const { - DCHECK_NE(CONTENT_SETTINGS_TYPE_COOKIES, content_type); - DCHECK(content_settings::SupportsResourceIdentifier(content_type) || - resource_identifier.empty()); - - if (ShouldAllowAllContent(secondary_url, content_type)) - return CONTENT_SETTING_ALLOW; - - // Iterate through the list of providers and return the first non-NULL value - // that matches |primary_url| and |secondary_url|. - for (ConstProviderIterator provider = content_settings_providers_.begin(); - provider != content_settings_providers_.end(); - ++provider) { - ContentSetting provided_setting = content_settings::GetContentSetting( - provider->second, primary_url, secondary_url, content_type, - resource_identifier, is_off_the_record_); - if (provided_setting != CONTENT_SETTING_DEFAULT) - return provided_setting; - } - return CONTENT_SETTING_DEFAULT; + scoped_ptr<base::Value> value(GetContentSettingValue( + primary_url, secondary_url, content_type, resource_identifier, + NULL, NULL)); + return content_settings::ValueToContentSetting(value.get()); } -Value* HostContentSettingsMap::GetContentSettingValue( +base::Value* HostContentSettingsMap::GetContentSettingValue( const GURL& primary_url, const GURL& secondary_url, ContentSettingsType content_type, - const std::string& resource_identifier) const { + const std::string& resource_identifier, + ContentSettingsPattern* primary_pattern, + ContentSettingsPattern* secondary_pattern) const { + DCHECK_NE(CONTENT_SETTINGS_TYPE_COOKIES, content_type); + DCHECK(content_settings::SupportsResourceIdentifier(content_type) || + resource_identifier.empty()); + // Check if the scheme of the requesting url is whitelisted. if (ShouldAllowAllContent(secondary_url, content_type)) return Value::CreateIntegerValue(CONTENT_SETTING_ALLOW); - // First check if there are specific settings for the |primary_url| and - // |secondary_url|. The list of |content_settings_providers_| is ordered - // according to their priority. + // The list of |content_settings_providers_| is ordered according to their + // precedence. for (ConstProviderIterator provider = content_settings_providers_.begin(); provider != content_settings_providers_.end(); ++provider) { - base::Value* value = content_settings::GetContentSettingValue( + base::Value* value = content_settings::GetContentSettingValueAndPatterns( provider->second, primary_url, secondary_url, content_type, - resource_identifier, is_off_the_record_); + resource_identifier, is_off_the_record_, + primary_pattern, secondary_pattern); if (value) return value; } - - // For simple content types, the DefaultProvider should always return - // a setting. - DCHECK(ContentTypeHasCompoundValue(content_type)); return NULL; } ContentSettings HostContentSettingsMap::GetContentSettings( - const GURL& primary_url, - const GURL& secondary_url) const { + const GURL& primary_url, + const GURL& secondary_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 diff --git a/chrome/browser/content_settings/host_content_settings_map.h b/chrome/browser/content_settings/host_content_settings_map.h index e6831a1..540d987 100644 --- a/chrome/browser/content_settings/host_content_settings_map.h +++ b/chrome/browser/content_settings/host_content_settings_map.h @@ -75,28 +75,34 @@ class HostContentSettingsMap // 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 ContentSettingsTypes that - // require a resource identifier to be specified, the |resource_identifier| - // must be non-empty. - // - // This may be called on any thread. + // Returns a single |ContentSetting| which applies to the given URLs. + // Note that certain internal schemes are whitelisted. + // For |CONTENT_TYPE_COOKIES|, |GetCookieContentSetting| should be called, + // and for content types that can't be converted to a ContentSetting, + // |GetContentSettingValue| should be called. + // If there is no content setting, returns CONTENT_SETTING_DEFAULT. + // May be called on any thread. ContentSetting GetContentSetting( const GURL& primary_url, const GURL& secondary_url, ContentSettingsType content_type, const std::string& resource_identifier) const; - // Returns a content setting |Value| which applies to the given URLs. Note - // that certain internal schemes are whitelisted. Ownership of the returned - // |Value| is transfered to the caller. - // - // This may be called on any thread. + // Returns a single content setting |Value| which applies to the given URLs. + // If |primary_pattern| and |secondary_pattern| are not NULL, they are set to + // the patterns of the applying rule. + // Note that certain internal schemes are whitelisted. + // If there is no content setting, returns NULL and leaves |primary_pattern| + // and |secondary_pattern| unchanged. + // Otherwise transfers ownership of the resulting |Value| to the caller. + // May be called on any thread. base::Value* GetContentSettingValue( const GURL& primary_url, const GURL& secondary_url, ContentSettingsType content_type, - const std::string& resource_identifier) const; + const std::string& resource_identifier, + ContentSettingsPattern* primary_pattern, + ContentSettingsPattern* secondary_pattern) const; // Gets the content setting for cookies. This takes the third party cookie // flag into account, and therefore needs to know whether we read or write a diff --git a/chrome/browser/extensions/extension_content_settings_store_unittest.cc b/chrome/browser/extensions/extension_content_settings_store_unittest.cc index 6d58d3b..ccbc0e2 100644 --- a/chrome/browser/extensions/extension_content_settings_store_unittest.cc +++ b/chrome/browser/extensions/extension_content_settings_store_unittest.cc @@ -51,8 +51,10 @@ ContentSetting GetContentSettingFromStore( bool incognito) { scoped_ptr<content_settings::RuleIterator> rule_iterator ( store->GetRuleIterator(content_type, resource_identifier, incognito)); - return content_settings::GetContentSetting( - rule_iterator.get(), primary_url, secondary_url); + scoped_ptr<base::Value> setting( + content_settings::GetContentSettingValueAndPatterns( + rule_iterator.get(), primary_url, secondary_url, NULL, NULL)); + return content_settings::ValueToContentSetting(setting.get()); } void GetSettingsForOneTypeFromStore( diff --git a/chrome/browser/renderer_host/chrome_render_message_filter.cc b/chrome/browser/renderer_host/chrome_render_message_filter.cc index ce27cd4..0a0f914 100644 --- a/chrome/browser/renderer_host/chrome_render_message_filter.cc +++ b/chrome/browser/renderer_host/chrome_render_message_filter.cc @@ -9,6 +9,7 @@ #include "base/metrics/histogram.h" #include "chrome/browser/automation/automation_resource_message_filter.h" #include "chrome/browser/browser_process.h" +#include "chrome/browser/content_settings/content_settings_utils.h" #include "chrome/browser/content_settings/host_content_settings_map.h" #include "chrome/browser/content_settings/tab_specific_content_settings.h" #include "chrome/browser/extensions/extension_event_router.h" @@ -490,13 +491,19 @@ void ChromeRenderMessageFilter::OnAllowIndexedDB(int render_view_id, void ChromeRenderMessageFilter::OnGetPluginContentSetting( const GURL& policy_url, const std::string& resource, - ContentSetting* setting) { - *setting = host_content_settings_map_->GetContentSetting( - policy_url, policy_url, CONTENT_SETTINGS_TYPE_PLUGINS, resource); - if (*setting == CONTENT_SETTING_DEFAULT) { - *setting = host_content_settings_map_->GetContentSetting( - policy_url, policy_url, CONTENT_SETTINGS_TYPE_PLUGINS, std::string()); + ContentSetting* setting, + ContentSettingsPattern* primary_pattern, + ContentSettingsPattern* secondary_pattern) { + scoped_ptr<base::Value> value( + host_content_settings_map_->GetContentSettingValue( + policy_url, policy_url, CONTENT_SETTINGS_TYPE_PLUGINS, resource, + primary_pattern, secondary_pattern)); + if (!value.get()) { + value.reset(host_content_settings_map_->GetContentSettingValue( + policy_url, policy_url, CONTENT_SETTINGS_TYPE_PLUGINS, std::string(), + primary_pattern, secondary_pattern)); } + *setting = content_settings::ValueToContentSetting(value.get()); } struct ChromeRenderMessageFilter::GetPluginInfo_Params { diff --git a/chrome/browser/renderer_host/chrome_render_message_filter.h b/chrome/browser/renderer_host/chrome_render_message_filter.h index d84d9be..4f14d44 100644 --- a/chrome/browser/renderer_host/chrome_render_message_filter.h +++ b/chrome/browser/renderer_host/chrome_render_message_filter.h @@ -15,6 +15,7 @@ #include "third_party/WebKit/Source/WebKit/chromium/public/WebCache.h" struct ChromeViewHostMsg_GetPluginInfo_Status; +class ContentSettingsPattern; struct ExtensionHostMsg_Request_Params; class ExtensionInfoMap; class FilePath; @@ -123,7 +124,9 @@ class ChromeRenderMessageFilter : public BrowserMessageFilter { bool* allowed); void OnGetPluginContentSetting(const GURL& policy_url, const std::string& resource, - ContentSetting* setting); + ContentSetting* setting, + ContentSettingsPattern* primary_pattern, + ContentSettingsPattern* secondary_pattern); void OnGetPluginInfo(int render_view_id, const GURL& url, const GURL& top_origin_url, diff --git a/chrome/browser/tab_contents/tab_contents_ssl_helper.cc b/chrome/browser/tab_contents/tab_contents_ssl_helper.cc index 51fae9a..2b35346 100644 --- a/chrome/browser/tab_contents/tab_contents_ssl_helper.cc +++ b/chrome/browser/tab_contents/tab_contents_ssl_helper.cc @@ -214,10 +214,10 @@ void TabContentsSSLHelper::SelectClientCertificate( HostContentSettingsMap* map = tab_contents_->profile()->GetHostContentSettingsMap(); scoped_ptr<Value> filter(map->GetContentSettingValue( - requesting_url, - requesting_url, + requesting_url, requesting_url, CONTENT_SETTINGS_TYPE_AUTO_SELECT_CERTIFICATE, - std::string())); + std::string(), + NULL, NULL)); scoped_refptr<net::X509Certificate> selected_cert; if (filter.get()) { diff --git a/chrome/common/content_settings_pattern.cc b/chrome/common/content_settings_pattern.cc index b15f732..05a0fe9 100644 --- a/chrome/common/content_settings_pattern.cc +++ b/chrome/common/content_settings_pattern.cc @@ -10,11 +10,13 @@ #include "base/string_split.h" #include "base/string_util.h" #include "chrome/common/content_settings_pattern_parser.h" +#include "chrome/common/render_messages.h" #include "chrome/common/url_constants.h" #include "net/base/dns_util.h" #include "net/base/net_util.h" #include "googleurl/src/gurl.h" #include "googleurl/src/url_canon.h" +#include "ipc/ipc_message_utils.h" namespace { @@ -368,6 +370,17 @@ ContentSettingsPattern::ContentSettingsPattern( is_valid_(valid) { } +void ContentSettingsPattern::WriteToMessage(IPC::Message* m) const { + IPC::WriteParam(m, is_valid_); + IPC::WriteParam(m, parts_); +} + +bool ContentSettingsPattern::ReadFromMessage(const IPC::Message* m, + void** iter) { + return IPC::ReadParam(m, iter, &is_valid_) && + IPC::ReadParam(m, iter, &parts_); +} + bool ContentSettingsPattern::Matches( const GURL& url) const { // An invalid pattern matches nothing. diff --git a/chrome/common/content_settings_pattern.h b/chrome/common/content_settings_pattern.h index 7838141..6d61954 100644 --- a/chrome/common/content_settings_pattern.h +++ b/chrome/common/content_settings_pattern.h @@ -12,6 +12,7 @@ #include <string> #include "base/basictypes.h" +#include "base/gtest_prod_util.h" class GURL; @@ -19,6 +20,10 @@ namespace content_settings { class PatternParser; } +namespace IPC { +class Message; +} + // A pattern used in content setting rules. See |IsValid| for a description of // possible patterns. class ContentSettingsPattern { @@ -55,6 +60,40 @@ class ContentSettingsPattern { DISJOINT_ORDER_PRE = 2, }; + struct PatternParts { + PatternParts(); + ~PatternParts(); + + // Lowercase string of the URL scheme to match. This string is empty if the + // |is_scheme_wildcard| flag is set. + std::string scheme; + + // True if the scheme wildcard is set. + bool is_scheme_wildcard; + + // Normalized string that is either of the following: + // - IPv4 or IPv6 + // - hostname + // - domain + // - empty string if the |is_host_wildcard flag is set. + std::string host; + + // True if the domain wildcard is set. + bool has_domain_wildcard; + + // String with the port to match. This string is empty if the + // |is_port_wildcard| flag is set. + std::string port; + + // True if the port wildcard is set. + bool is_port_wildcard; + + // TODO(markusheintz): Needed for legacy reasons. Remove. Path + // specification. Only used for content settings pattern with a "file" + // scheme part. + std::string path; + }; + class BuilderInterface { public: virtual ~BuilderInterface() {} @@ -120,6 +159,10 @@ class ContentSettingsPattern { // patterns match nothing. ContentSettingsPattern(); + // Serializes the pattern to an IPC message or deserializes it. + void WriteToMessage(IPC::Message* m) const; + bool ReadFromMessage(const IPC::Message* m, void** iter); + // True if this is a valid pattern. bool IsValid() const { return is_valid_; } @@ -147,42 +190,8 @@ class ContentSettingsPattern { private: friend class content_settings::PatternParser; - friend class ContentSettingsPatternParserTest_SerializePatterns_Test; friend class Builder; - - struct PatternParts { - PatternParts(); - ~PatternParts(); - - // Lowercase string of the URL scheme to match. This string is empty if the - // |is_scheme_wildcard| flag is set. - std::string scheme; - - // True if the scheme wildcard is set. - bool is_scheme_wildcard; - - // Normalized string that is either of the following: - // - IPv4 or IPv6 - // - hostname - // - domain - // - empty string if the |is_host_wildcard flag is set. - std::string host; - - // True if the domain wildcard is set. - bool has_domain_wildcard; - - // String with the port to match. This string is empty if the - // |is_port_wildcard| flag is set. - std::string port; - - // True if the port wildcard is set. - bool is_port_wildcard; - - // TODO(markusheintz): Needed for legacy reasons. Remove. Path - // specification. Only used for content settings pattern with a "file" - // scheme part. - std::string path; - }; + FRIEND_TEST_ALL_PREFIXES(ContentSettingsPatternParserTest, SerializePatterns); class Builder : public BuilderInterface { public: diff --git a/chrome/common/render_messages.cc b/chrome/common/render_messages.cc index 7fd44d4..39c6705 100644 --- a/chrome/common/render_messages.cc +++ b/chrome/common/render_messages.cc @@ -26,4 +26,21 @@ void ParamTraits<ContentSettings>::Log( l->append("<ContentSettings>"); } +void ParamTraits<ContentSettingsPattern>::Write( + Message* m, const ContentSettingsPattern& pattern) { + pattern.WriteToMessage(m); +} + +bool ParamTraits<ContentSettingsPattern>::Read( + const Message* m, void** iter, ContentSettingsPattern* pattern) { + return pattern->ReadFromMessage(m, iter); +} + +void ParamTraits<ContentSettingsPattern>::Log( + const ContentSettingsPattern& p, std::string* l) { + l->append("<ContentSettingsPattern: "); + l->append(p.ToString()); + l->append(">"); +} + } // namespace IPC diff --git a/chrome/common/render_messages.h b/chrome/common/render_messages.h index 7e09b6e..5a23d0e 100644 --- a/chrome/common/render_messages.h +++ b/chrome/common/render_messages.h @@ -19,6 +19,7 @@ #include "base/values.h" #include "build/build_config.h" #include "chrome/common/common_param_traits.h" +#include "chrome/common/content_settings_pattern.h" #include "chrome/common/instant_types.h" #include "chrome/common/nacl_types.h" #include "chrome/common/search_provider.h" @@ -102,6 +103,14 @@ struct ParamTraits<ContentSettings> { 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); + static bool Read(const Message* m, void** iter, param_type* r); + static void Log(const param_type& p, std::string* l); +}; + } // namespace IPC #endif // CHROME_COMMON_RENDER_MESSAGES_H_ @@ -119,6 +128,16 @@ IPC_STRUCT_TRAITS_BEGIN(ChromeViewHostMsg_GetPluginInfo_Status) IPC_STRUCT_TRAITS_MEMBER(value) IPC_STRUCT_TRAITS_END() +IPC_STRUCT_TRAITS_BEGIN(ContentSettingsPattern::PatternParts) + IPC_STRUCT_TRAITS_MEMBER(scheme) + IPC_STRUCT_TRAITS_MEMBER(is_scheme_wildcard) + IPC_STRUCT_TRAITS_MEMBER(host) + IPC_STRUCT_TRAITS_MEMBER(has_domain_wildcard) + IPC_STRUCT_TRAITS_MEMBER(port) + IPC_STRUCT_TRAITS_MEMBER(is_port_wildcard) + IPC_STRUCT_TRAITS_MEMBER(path) +IPC_STRUCT_TRAITS_END() + IPC_STRUCT_TRAITS_BEGIN(ThumbnailScore) IPC_STRUCT_TRAITS_MEMBER(boring_score) IPC_STRUCT_TRAITS_MEMBER(good_clipping) @@ -401,10 +420,12 @@ IPC_SYNC_MESSAGE_CONTROL4_1(ChromeViewHostMsg_AllowIndexedDB, // neither blocked nor white-listed, which means that it's allowed // by default and can still be blocked if it's non-sandboxed. // -IPC_SYNC_MESSAGE_CONTROL2_1(ChromeViewHostMsg_GetPluginContentSetting, +IPC_SYNC_MESSAGE_CONTROL2_3(ChromeViewHostMsg_GetPluginContentSetting, GURL /* policy_url */, std::string /* resource */, - ContentSetting /* setting */) + ContentSetting /* setting */, + ContentSettingsPattern /* primary pattern */, + ContentSettingsPattern /* secondary pattern */) // Return information about a plugin for the given URL and MIME type. // In contrast to ViewHostMsg_GetPluginInfo in content/, this IPC call knows diff --git a/chrome/renderer/chrome_content_renderer_client.cc b/chrome/renderer/chrome_content_renderer_client.cc index 79f9d77..1a5e708 100644 --- a/chrome/renderer/chrome_content_renderer_client.cc +++ b/chrome/renderer/chrome_content_renderer_client.cc @@ -16,6 +16,7 @@ #include "chrome/common/chrome_content_client.h" #include "chrome/common/chrome_paths.h" #include "chrome/common/chrome_switches.h" +#include "chrome/common/content_settings_pattern.h" #include "chrome/common/external_ipc_fuzzer.h" #include "chrome/common/extensions/extension.h" #include "chrome/common/extensions/extension_constants.h" @@ -340,8 +341,11 @@ WebPlugin* ChromeContentRendererClient::CreatePlugin( ContentSettingsType content_type = CONTENT_SETTINGS_TYPE_PLUGINS; ContentSetting plugin_setting = CONTENT_SETTING_DEFAULT; std::string resource = group->identifier(); + ContentSettingsPattern primary_pattern; + ContentSettingsPattern secondary_pattern; render_view->Send(new ChromeViewHostMsg_GetPluginContentSetting( - frame->top()->document().url(), resource, &plugin_setting)); + frame->top()->document().url(), resource, + &plugin_setting, &primary_pattern, &secondary_pattern)); DCHECK(plugin_setting != CONTENT_SETTING_DEFAULT); WebPluginParams params(original_params); @@ -383,14 +387,14 @@ WebPlugin* ChromeContentRendererClient::CreatePlugin( } ContentSettingsObserver* observer = ContentSettingsObserver::Get(render_view); - ContentSetting host_setting = - observer->GetContentSetting(CONTENT_SETTINGS_TYPE_PLUGINS); + ContentSettingsPattern wildcard = ContentSettingsPattern::Wildcard(); if (group->RequiresAuthorization(plugin) && authorize_policy == CONTENT_SETTING_ASK && - (plugin_setting == CONTENT_SETTING_ALLOW || - plugin_setting == CONTENT_SETTING_ASK) && - host_setting == CONTENT_SETTING_DEFAULT) { + plugin_setting != CONTENT_SETTING_BLOCK && + primary_pattern == wildcard && + secondary_pattern == wildcard && + !observer->plugins_temporarily_allowed()) { render_view->Send(new ChromeViewHostMsg_BlockedOutdatedPlugin( render_view->GetRoutingId(), group->GetGroupName(), GURL())); return CreatePluginPlaceholder( @@ -408,7 +412,7 @@ WebPlugin* ChromeContentRendererClient::CreatePlugin( } if (plugin_setting == CONTENT_SETTING_ALLOW || - host_setting == CONTENT_SETTING_ALLOW || + observer->plugins_temporarily_allowed() || plugin.path.value() == webkit::npapi::kDefaultPluginLibraryName) { // Delay loading plugins if prerendering. if (prerender::PrerenderHelper::IsPrerendering(render_view)) { diff --git a/chrome/renderer/content_settings_observer.cc b/chrome/renderer/content_settings_observer.cc index a8d0e24..94150e6 100644 --- a/chrome/renderer/content_settings_observer.cc +++ b/chrome/renderer/content_settings_observer.cc @@ -77,10 +77,8 @@ void ContentSettingsObserver::SetDefaultContentSettings( ContentSetting ContentSettingsObserver::GetContentSetting( ContentSettingsType type) { - if (type == CONTENT_SETTINGS_TYPE_PLUGINS && - plugins_temporarily_allowed_) { - return CONTENT_SETTING_ALLOW; - } + // Don't call this for plug-ins. + DCHECK_NE(CONTENT_SETTINGS_TYPE_PLUGINS, type); return current_content_settings_.settings[type]; } diff --git a/chrome/renderer/content_settings_observer.h b/chrome/renderer/content_settings_observer.h index afe0bb9e..45f2125 100644 --- a/chrome/renderer/content_settings_observer.h +++ b/chrome/renderer/content_settings_observer.h @@ -38,6 +38,10 @@ class ContentSettingsObserver // Returns the setting for the given type. ContentSetting GetContentSetting(ContentSettingsType type); + bool plugins_temporarily_allowed() { + return plugins_temporarily_allowed_; + } + // Sends an IPC notification that the specified content type was blocked. // If the content type requires it, |resource_identifier| names the specific // resource that was blocked (the plugin path in the case of plugins), diff --git a/chrome/renderer/content_settings_observer_browsertest.cc b/chrome/renderer/content_settings_observer_browsertest.cc index bc11b17..ceaaee1 100644 --- a/chrome/renderer/content_settings_observer_browsertest.cc +++ b/chrome/renderer/content_settings_observer_browsertest.cc @@ -148,21 +148,17 @@ TEST_F(ChromeRenderViewTest, PluginsTemporarilyAllowed) { ContentSettingsObserver* observer = ContentSettingsObserver::Get(view_); observer->SetContentSettings(settings); ContentSettingsObserver::SetDefaultContentSettings(settings); - EXPECT_EQ(CONTENT_SETTING_BLOCK, - observer->GetContentSetting(CONTENT_SETTINGS_TYPE_PLUGINS)); + EXPECT_FALSE(observer->plugins_temporarily_allowed()); // Temporarily allow plugins. OnMessageReceived(ChromeViewMsg_LoadBlockedPlugins(MSG_ROUTING_NONE)); - EXPECT_EQ(CONTENT_SETTING_ALLOW, - observer->GetContentSetting(CONTENT_SETTINGS_TYPE_PLUGINS)); + EXPECT_TRUE(observer->plugins_temporarily_allowed()); // Simulate a navigation within the page. DidNavigateWithinPage(GetMainFrame(), true); - EXPECT_EQ(CONTENT_SETTING_ALLOW, - observer->GetContentSetting(CONTENT_SETTINGS_TYPE_PLUGINS)); + EXPECT_TRUE(observer->plugins_temporarily_allowed()); // Navigate to a different page. LoadHTML("<html>Bar</html>"); - EXPECT_EQ(CONTENT_SETTING_BLOCK, - observer->GetContentSetting(CONTENT_SETTINGS_TYPE_PLUGINS)); + EXPECT_FALSE(observer->plugins_temporarily_allowed()); } |