diff --git a/include/capi/cef_request_context_handler_capi.h b/include/capi/cef_request_context_handler_capi.h index 4e8a9c2aa..ddd4358ee 100644 --- a/include/capi/cef_request_context_handler_capi.h +++ b/include/capi/cef_request_context_handler_capi.h @@ -70,23 +70,25 @@ typedef struct _cef_request_context_handler_t { // Called on multiple browser process threads before a plugin instance is // loaded. |mime_type| is the mime type of the plugin that will be loaded. // |plugin_url| is the content URL that the plugin will load and may be NULL. - // |top_origin_url| is the URL for the top-level frame that contains the - // plugin when loading a specific plugin instance or NULL when building the - // initial list of enabled plugins for 'navigator.plugins' JavaScript state. - // |plugin_info| includes additional information about the plugin that will be - // loaded. |plugin_policy| is the recommended policy. Modify |plugin_policy| - // and return true (1) to change the policy. Return false (0) to use the - // recommended policy. The default plugin policy can be set at runtime using - // the `--plugin-policy=[allow|detect|block]` command-line flag. Decisions to - // mark a plugin as disabled by setting |plugin_policy| to - // PLUGIN_POLICY_DISABLED may be cached when |top_origin_url| is NULL. To - // purge the plugin list cache and potentially trigger new calls to this - // function call cef_request_tContext::PurgePluginListCache. + // |is_main_frame| will be true (1) if the plugin is being loaded in the main + // (top-level) frame, |top_origin_url| is the URL for the top-level frame that + // contains the plugin when loading a specific plugin instance or NULL when + // building the initial list of enabled plugins for 'navigator.plugins' + // JavaScript state. |plugin_info| includes additional information about the + // plugin that will be loaded. |plugin_policy| is the recommended policy. + // Modify |plugin_policy| and return true (1) to change the policy. Return + // false (0) to use the recommended policy. The default plugin policy can be + // set at runtime using the `--plugin-policy=[allow|detect|block]` command- + // line flag. Decisions to mark a plugin as disabled by setting + // |plugin_policy| to PLUGIN_POLICY_DISABLED may be cached when + // |top_origin_url| is NULL. To purge the plugin list cache and potentially + // trigger new calls to this function call + // cef_request_tContext::PurgePluginListCache. /// int (CEF_CALLBACK *on_before_plugin_load)( struct _cef_request_context_handler_t* self, const cef_string_t* mime_type, const cef_string_t* plugin_url, - const cef_string_t* top_origin_url, + int is_main_frame, const cef_string_t* top_origin_url, struct _cef_web_plugin_info_t* plugin_info, cef_plugin_policy_t* plugin_policy); } cef_request_context_handler_t; diff --git a/include/cef_request_context_handler.h b/include/cef_request_context_handler.h index c2d3c7af9..6996d9ede 100644 --- a/include/cef_request_context_handler.h +++ b/include/cef_request_context_handler.h @@ -64,22 +64,24 @@ class CefRequestContextHandler : public virtual CefBase { // Called on multiple browser process threads before a plugin instance is // loaded. |mime_type| is the mime type of the plugin that will be loaded. // |plugin_url| is the content URL that the plugin will load and may be empty. - // |top_origin_url| is the URL for the top-level frame that contains the - // plugin when loading a specific plugin instance or empty when building the - // initial list of enabled plugins for 'navigator.plugins' JavaScript state. - // |plugin_info| includes additional information about the plugin that will be - // loaded. |plugin_policy| is the recommended policy. Modify |plugin_policy| - // and return true to change the policy. Return false to use the recommended - // policy. The default plugin policy can be set at runtime using the - // `--plugin-policy=[allow|detect|block]` command-line flag. Decisions to mark - // a plugin as disabled by setting |plugin_policy| to PLUGIN_POLICY_DISABLED - // may be cached when |top_origin_url| is empty. To purge the plugin list - // cache and potentially trigger new calls to this method call - // CefRequestContext::PurgePluginListCache. + // |is_main_frame| will be true if the plugin is being loaded in the main + // (top-level) frame, |top_origin_url| is the URL for the top-level frame that + // contains the plugin when loading a specific plugin instance or empty when + // building the initial list of enabled plugins for 'navigator.plugins' + // JavaScript state. |plugin_info| includes additional information about the + // plugin that will be loaded. |plugin_policy| is the recommended policy. + // Modify |plugin_policy| and return true to change the policy. Return false + // to use the recommended policy. The default plugin policy can be set at + // runtime using the `--plugin-policy=[allow|detect|block]` command-line flag. + // Decisions to mark a plugin as disabled by setting |plugin_policy| to + // PLUGIN_POLICY_DISABLED may be cached when |top_origin_url| is empty. To + // purge the plugin list cache and potentially trigger new calls to this + // method call CefRequestContext::PurgePluginListCache. /// /*--cef(optional_param=plugin_url,optional_param=top_origin_url)--*/ virtual bool OnBeforePluginLoad(const CefString& mime_type, const CefString& plugin_url, + bool is_main_frame, const CefString& top_origin_url, CefRefPtr plugin_info, PluginPolicy* plugin_policy) { diff --git a/libcef/browser/plugins/plugin_info_message_filter.cc b/libcef/browser/plugins/plugin_info_message_filter.cc index 37cd9ff88..06827b8a9 100644 --- a/libcef/browser/plugins/plugin_info_message_filter.cc +++ b/libcef/browser/plugins/plugin_info_message_filter.cc @@ -138,7 +138,8 @@ CefPluginInfoMessageFilter::Context::Context( int render_process_id, CefBrowserContext* profile) : render_process_id_(render_process_id), - resource_context_(profile->GetResourceContext()), + resource_context_( + static_cast(profile->GetResourceContext())), host_content_settings_map_(profile->GetHostContentSettingsMap()) { #if BUILDFLAG(ENABLE_EXTENSIONS) if (extensions::ExtensionsEnabled()) @@ -198,6 +199,7 @@ CefPluginInfoMessageFilter::~CefPluginInfoMessageFilter() {} struct CefPluginInfoMessageFilter::GetPluginInfo_Params { int render_frame_id; GURL url; + bool is_main_frame; url::Origin main_frame_origin; std::string mime_type; }; @@ -205,12 +207,14 @@ struct CefPluginInfoMessageFilter::GetPluginInfo_Params { void CefPluginInfoMessageFilter::OnGetPluginInfo( int render_frame_id, const GURL& url, + bool is_main_frame, const url::Origin& main_frame_origin, const std::string& mime_type, IPC::Message* reply_msg) { GetPluginInfo_Params params = { render_frame_id, url, + is_main_frame, main_frame_origin, mime_type }; @@ -225,12 +229,10 @@ void CefPluginInfoMessageFilter::PluginsLoaded( IPC::Message* reply_msg, const std::vector& plugins) { CefViewHostMsg_GetPluginInfo_Output output; - CefRefPtr handler = - browser_context_->GetHandler(); // This also fills in |actual_mime_type|. std::unique_ptr plugin_metadata; - context_.FindEnabledPlugin(params, handler.get(), + context_.FindEnabledPlugin(params, &output.status, &output.plugin, &output.actual_mime_type, &plugin_metadata); @@ -383,7 +385,6 @@ void CefPluginInfoMessageFilter::Context::DecidePluginStatus( bool CefPluginInfoMessageFilter::Context::FindEnabledPlugin( const GetPluginInfo_Params& params, - CefRequestContextHandler* handler, CefViewHostMsg_GetPluginInfo_Status* status, WebPluginInfo* plugin, std::string* actual_mime_type, @@ -414,8 +415,10 @@ bool CefPluginInfoMessageFilter::Context::FindEnabledPlugin( *plugin_metadata = PluginFinder::GetInstance()->GetPluginMetadata(*plugin); DecidePluginStatus(params, *plugin, (*plugin_metadata).get(), status); - if (filter->IsPluginAvailable(handler, + if (filter->IsPluginAvailable(render_process_id_, + resource_context_, params.url, + params.is_main_frame, params.main_frame_origin, plugin, status)) { diff --git a/libcef/browser/plugins/plugin_info_message_filter.h b/libcef/browser/plugins/plugin_info_message_filter.h index 254c1167b..da8ff87b8 100644 --- a/libcef/browser/plugins/plugin_info_message_filter.h +++ b/libcef/browser/plugins/plugin_info_message_filter.h @@ -22,13 +22,12 @@ #include "ppapi/features/features.h" class CefBrowserContext; -class CefRequestContextHandler; +class CefResourceContext; struct CefViewHostMsg_GetPluginInfo_Output; enum class CefViewHostMsg_GetPluginInfo_Status; class GURL; namespace content { -class ResourceContext; struct WebPluginInfo; } @@ -59,7 +58,6 @@ class CefPluginInfoMessageFilter : public content::BrowserMessageFilter { CefViewHostMsg_GetPluginInfo_Status* status) const; bool FindEnabledPlugin( const GetPluginInfo_Params& params, - CefRequestContextHandler* handler, CefViewHostMsg_GetPluginInfo_Status* status, content::WebPluginInfo* plugin, std::string* actual_mime_type, @@ -75,7 +73,7 @@ class CefPluginInfoMessageFilter : public content::BrowserMessageFilter { private: int render_process_id_; - content::ResourceContext* resource_context_; + CefResourceContext* resource_context_; #if BUILDFLAG(ENABLE_EXTENSIONS) extensions::ExtensionRegistry* extension_registry_; #endif @@ -101,6 +99,7 @@ class CefPluginInfoMessageFilter : public content::BrowserMessageFilter { void OnGetPluginInfo(int render_frame_id, const GURL& url, + bool is_main_frame, const url::Origin& main_frame_origin, const std::string& mime_type, IPC::Message* reply_msg); diff --git a/libcef/browser/plugins/plugin_service_filter.cc b/libcef/browser/plugins/plugin_service_filter.cc index 7879ff91b..81c5afe24 100644 --- a/libcef/browser/plugins/plugin_service_filter.cc +++ b/libcef/browser/plugins/plugin_service_filter.cc @@ -22,27 +22,37 @@ bool CefPluginServiceFilter::IsPluginAvailable( int render_frame_id, const void* context, const GURL& url, + bool is_main_frame, const url::Origin& main_frame_origin, content::WebPluginInfo* plugin) { CefResourceContext* resource_context = const_cast( reinterpret_cast(context)); - - bool allow_load = true; - if (resource_context->HasPluginLoadDecision(render_process_id, plugin->path, - &allow_load)) { - return allow_load; - } - - CefRefPtr handler = resource_context->GetHandler(); CefViewHostMsg_GetPluginInfo_Status status = CefViewHostMsg_GetPluginInfo_Status::kAllowed; - allow_load = IsPluginAvailable(handler.get(), url, main_frame_origin, plugin, - &status); - resource_context->AddPluginLoadDecision(render_process_id, plugin->path, - allow_load); + // Perform origin check here because we're passing an empty origin value to + // IsPluginAvailable() below. + const GURL& policy_url = main_frame_origin.GetURL(); + if (!policy_url.is_empty() && + policy_url.scheme() == extensions::kExtensionScheme) { + // Always allow extension origins to load plugins. + // TODO(extensions): Revisit this decision once CEF supports more than just + // the PDF extension. + return true; + } - return allow_load; + // Blink requires this method to return a consistent value during renderer + // process initialization and page load, so we always call IsPluginAvailable() + // with an empty origin. If we return false then the plugin will not be listed + // in navigator.plugins and navigating to the plugin mime type will trigger + // the download code path. If we return true then individual plugin instance + // loads will be evaluated in CefContentRendererClient::OverrideCreatePlugin, + // which will result in a call to CefPluginInfoMessageFilter::PluginsLoaded to + // retrieve the actual load decision with a non-empty origin. That will + // determine whether the plugin load is allowed or the plugin placeholder is + // displayed. + return IsPluginAvailable(render_process_id, resource_context, url, + is_main_frame, url::Origin(), plugin, &status); } bool CefPluginServiceFilter::CanLoadPlugin(int render_process_id, @@ -51,8 +61,10 @@ bool CefPluginServiceFilter::CanLoadPlugin(int render_process_id, } bool CefPluginServiceFilter::IsPluginAvailable( - CefRequestContextHandler* handler, + int render_process_id, + CefResourceContext* resource_context, const GURL& url, + bool is_main_frame, const url::Origin& main_frame_origin, content::WebPluginInfo* plugin, CefViewHostMsg_GetPluginInfo_Status* status) { @@ -78,54 +90,70 @@ bool CefPluginServiceFilter::IsPluginAvailable( return true; } - if (handler) { - CefRefPtr pluginInfo( - new CefWebPluginInfoImpl(*plugin)); + CefRefPtr handler = resource_context->GetHandler(); + if (!handler) { + // No handler so go with the default plugin load decision. + return *status != CefViewHostMsg_GetPluginInfo_Status::kDisabled; + } - cef_plugin_policy_t plugin_policy = PLUGIN_POLICY_ALLOW; - switch (*status) { - case CefViewHostMsg_GetPluginInfo_Status::kAllowed: - plugin_policy = PLUGIN_POLICY_ALLOW; - break; - case CefViewHostMsg_GetPluginInfo_Status::kBlocked: - case CefViewHostMsg_GetPluginInfo_Status::kBlockedByPolicy: - case CefViewHostMsg_GetPluginInfo_Status::kOutdatedBlocked: - case CefViewHostMsg_GetPluginInfo_Status::kOutdatedDisallowed: - case CefViewHostMsg_GetPluginInfo_Status::kUnauthorized: - plugin_policy = PLUGIN_POLICY_BLOCK; - break; - case CefViewHostMsg_GetPluginInfo_Status::kDisabled: - plugin_policy = PLUGIN_POLICY_DISABLE; - break; - case CefViewHostMsg_GetPluginInfo_Status::kPlayImportantContent: - plugin_policy = PLUGIN_POLICY_DETECT_IMPORTANT; - break; - default: - NOTREACHED(); - break; - } + // Check for a cached plugin load decision. + if (resource_context->HasPluginLoadDecision( + render_process_id, plugin->path, + is_main_frame, main_frame_origin, status)) { + return *status != CefViewHostMsg_GetPluginInfo_Status::kDisabled; + } - if (handler->OnBeforePluginLoad(plugin->mime_types[0].mime_type, - url.possibly_invalid_spec(), - policy_url.possibly_invalid_spec(), - pluginInfo.get(), - &plugin_policy)) { - switch (plugin_policy) { - case PLUGIN_POLICY_ALLOW: - *status = CefViewHostMsg_GetPluginInfo_Status::kAllowed; - break; - case PLUGIN_POLICY_DETECT_IMPORTANT: - *status = CefViewHostMsg_GetPluginInfo_Status::kPlayImportantContent; - break; - case PLUGIN_POLICY_BLOCK: - *status = CefViewHostMsg_GetPluginInfo_Status::kBlocked; - break; - case PLUGIN_POLICY_DISABLE: - *status = CefViewHostMsg_GetPluginInfo_Status::kDisabled; - break; - } + CefRefPtr pluginInfo(new CefWebPluginInfoImpl(*plugin)); + + cef_plugin_policy_t plugin_policy = PLUGIN_POLICY_ALLOW; + switch (*status) { + case CefViewHostMsg_GetPluginInfo_Status::kAllowed: + plugin_policy = PLUGIN_POLICY_ALLOW; + break; + case CefViewHostMsg_GetPluginInfo_Status::kBlocked: + case CefViewHostMsg_GetPluginInfo_Status::kBlockedByPolicy: + case CefViewHostMsg_GetPluginInfo_Status::kOutdatedBlocked: + case CefViewHostMsg_GetPluginInfo_Status::kOutdatedDisallowed: + case CefViewHostMsg_GetPluginInfo_Status::kUnauthorized: + plugin_policy = PLUGIN_POLICY_BLOCK; + break; + case CefViewHostMsg_GetPluginInfo_Status::kDisabled: + plugin_policy = PLUGIN_POLICY_DISABLE; + break; + case CefViewHostMsg_GetPluginInfo_Status::kPlayImportantContent: + plugin_policy = PLUGIN_POLICY_DETECT_IMPORTANT; + break; + default: + NOTREACHED(); + break; + } + + if (handler->OnBeforePluginLoad(plugin->mime_types[0].mime_type, + url.possibly_invalid_spec(), + is_main_frame, + policy_url.possibly_invalid_spec(), + pluginInfo.get(), + &plugin_policy)) { + switch (plugin_policy) { + case PLUGIN_POLICY_ALLOW: + *status = CefViewHostMsg_GetPluginInfo_Status::kAllowed; + break; + case PLUGIN_POLICY_DETECT_IMPORTANT: + *status = CefViewHostMsg_GetPluginInfo_Status::kPlayImportantContent; + break; + case PLUGIN_POLICY_BLOCK: + *status = CefViewHostMsg_GetPluginInfo_Status::kBlocked; + break; + case PLUGIN_POLICY_DISABLE: + *status = CefViewHostMsg_GetPluginInfo_Status::kDisabled; + break; } } - return (*status != CefViewHostMsg_GetPluginInfo_Status::kDisabled); + // Cache the plugin load decision. + resource_context->AddPluginLoadDecision( + render_process_id, plugin->path, + is_main_frame, main_frame_origin, *status); + + return *status != CefViewHostMsg_GetPluginInfo_Status::kDisabled; } diff --git a/libcef/browser/plugins/plugin_service_filter.h b/libcef/browser/plugins/plugin_service_filter.h index cbfbfb94c..ef61eb0a3 100644 --- a/libcef/browser/plugins/plugin_service_filter.h +++ b/libcef/browser/plugins/plugin_service_filter.h @@ -11,7 +11,7 @@ #include "base/macros.h" -class CefRequestContextHandler; +class CefResourceContext; enum class CefViewHostMsg_GetPluginInfo_Status; class CefPluginServiceFilter : public content::PluginServiceFilter { @@ -25,6 +25,7 @@ class CefPluginServiceFilter : public content::PluginServiceFilter { int render_frame_id, const void* context, const GURL& url, + bool is_main_frame, const url::Origin& main_frame_origin, content::WebPluginInfo* plugin) override; @@ -34,8 +35,10 @@ class CefPluginServiceFilter : public content::PluginServiceFilter { // Returns false if the plugin is not found or disabled. May call // CefRequestContextHandler::OnBeforePluginLoad if possible/necessary. // See related discussion in issue #2015. - bool IsPluginAvailable(CefRequestContextHandler* handler, + bool IsPluginAvailable(int render_process_id, + CefResourceContext* resource_context, const GURL& url, + bool is_main_frame, const url::Origin& main_frame_origin, content::WebPluginInfo* plugin, CefViewHostMsg_GetPluginInfo_Status* status); diff --git a/libcef/browser/resource_context.cc b/libcef/browser/resource_context.cc index 247394085..e0105e204 100644 --- a/libcef/browser/resource_context.cc +++ b/libcef/browser/resource_context.cc @@ -124,31 +124,38 @@ void CefResourceContext::set_parent(CefResourceContext* parent) { void CefResourceContext::AddPluginLoadDecision( int render_process_id, const base::FilePath& plugin_path, - bool allow_load) { + bool is_main_frame, + const url::Origin& main_frame_origin, + CefViewHostMsg_GetPluginInfo_Status status) { CEF_REQUIRE_IOT(); DCHECK_GE(render_process_id, 0); DCHECK(!plugin_path.empty()); plugin_load_decision_map_.insert( - std::make_pair(std::make_pair(render_process_id, plugin_path), - allow_load)); + std::make_pair( + std::make_pair(std::make_pair(render_process_id, plugin_path), + std::make_pair(is_main_frame, main_frame_origin)), + status)); } bool CefResourceContext::HasPluginLoadDecision( int render_process_id, const base::FilePath& plugin_path, - bool* allow_load) const { + bool is_main_frame, + const url::Origin& main_frame_origin, + CefViewHostMsg_GetPluginInfo_Status* status) const { CEF_REQUIRE_IOT(); DCHECK_GE(render_process_id, 0); DCHECK(!plugin_path.empty()); PluginLoadDecisionMap::const_iterator it = plugin_load_decision_map_.find( - std::make_pair(render_process_id, plugin_path)); + std::make_pair(std::make_pair(render_process_id, plugin_path), + std::make_pair(is_main_frame, main_frame_origin))); if (it == plugin_load_decision_map_.end()) return false; - *allow_load = it->second; + *status = it->second; return true; } @@ -160,7 +167,7 @@ void CefResourceContext::ClearPluginLoadDecision(int render_process_id) { } else { PluginLoadDecisionMap::iterator it = plugin_load_decision_map_.begin(); while (it != plugin_load_decision_map_.end()) { - if (it->first.first == render_process_id) + if (it->first.first.first == render_process_id) it = plugin_load_decision_map_.erase(it); else ++it; diff --git a/libcef/browser/resource_context.h b/libcef/browser/resource_context.h index 01ae1024c..a211004dc 100644 --- a/libcef/browser/resource_context.h +++ b/libcef/browser/resource_context.h @@ -12,8 +12,10 @@ #include "content/public/browser/resource_context.h" #include "extensions/browser/info_map.h" #include "net/ssl/client_cert_store.h" +#include "url/origin.h" class CefURLRequestContextGetter; +enum class CefViewHostMsg_GetPluginInfo_Status; // Acts as a bridge for resource loading. Life span is controlled by // CefBrowserContext. Created on the UI thread but accessed and destroyed on the @@ -46,15 +48,16 @@ class CefResourceContext : public content::ResourceContext { // Remember the plugin load decision for plugin status requests that arrive // via CefPluginServiceFilter::IsPluginAvailable. - // TODO(cef): Per-frame decisions are not currently supported because - // Chromium does not pipe the frame id through to RenderFrameMessageFilter:: - // GetPluginsCallback. Fix this once https://crbug.com/626728#c15 is resolved. void AddPluginLoadDecision(int render_process_id, const base::FilePath& plugin_path, - bool allow_load); + bool is_main_frame, + const url::Origin& main_frame_origin, + CefViewHostMsg_GetPluginInfo_Status status); bool HasPluginLoadDecision(int render_process_id, const base::FilePath& plugin_path, - bool* allow_load) const; + bool is_main_frame, + const url::Origin& main_frame_origin, + CefViewHostMsg_GetPluginInfo_Status* status) const; // Clear the plugin load decisions associated with |render_process_id|, or all // plugin load decisions if |render_process_id| is -1. @@ -80,8 +83,11 @@ class CefResourceContext : public content::ResourceContext { scoped_refptr extension_info_map_; CefRefPtr handler_; - // Map (render_process_id, plugin_path) to plugin load decision. - typedef std::map, bool> + // Map (render_process_id, plugin_path, is_main_frame, main_frame_origin) to + // plugin load decision. + typedef std::map, + std::pair>, + CefViewHostMsg_GetPluginInfo_Status> PluginLoadDecisionMap; PluginLoadDecisionMap plugin_load_decision_map_; diff --git a/libcef/common/cef_messages.h b/libcef/common/cef_messages.h index 1cae35017..4551e44e5 100644 --- a/libcef/common/cef_messages.h +++ b/libcef/common/cef_messages.h @@ -231,10 +231,11 @@ IPC_STRUCT_END() // In contrast to ViewHostMsg_GetPluginInfo in content/, this IPC call knows // about specific reasons why a plugin can't be used, for example because it's // disabled. Based on ChromeViewHostMsg_GetPluginInfo. -IPC_SYNC_MESSAGE_CONTROL4_1(CefViewHostMsg_GetPluginInfo, +IPC_SYNC_MESSAGE_CONTROL5_1(CefViewHostMsg_GetPluginInfo, int /* render_frame_id */, GURL /* url */, - url::Origin /* top origin url */, + bool /* is_main_frame */, + url::Origin /* top_origin_url */, std::string /* mime_type */, CefViewHostMsg_GetPluginInfo_Output /* output */) diff --git a/libcef/renderer/content_renderer_client.cc b/libcef/renderer/content_renderer_client.cc index 96b90f7e2..f9e05ae9b 100644 --- a/libcef/renderer/content_renderer_client.cc +++ b/libcef/renderer/content_renderer_client.cc @@ -507,8 +507,8 @@ bool CefContentRendererClient::OverrideCreatePlugin( GURL url(params.url); CefViewHostMsg_GetPluginInfo_Output output; render_frame->Send(new CefViewHostMsg_GetPluginInfo( - render_frame->GetRoutingID(), url, frame->top()->getSecurityOrigin(), - orig_mime_type, &output)); + render_frame->GetRoutingID(), url, render_frame->IsMainFrame(), + frame->top()->getSecurityOrigin(), orig_mime_type, &output)); *plugin = CreatePlugin(render_frame, frame, params, output); return true; diff --git a/libcef/renderer/plugins/cef_plugin_placeholder.cc b/libcef/renderer/plugins/cef_plugin_placeholder.cc index 2da1cdf29..1bfd72c94 100644 --- a/libcef/renderer/plugins/cef_plugin_placeholder.cc +++ b/libcef/renderer/plugins/cef_plugin_placeholder.cc @@ -187,6 +187,7 @@ void CefPluginPlaceholder::PluginListChanged() { std::string mime_type(GetPluginParams().mimeType.utf8()); render_frame()->Send(new CefViewHostMsg_GetPluginInfo( routing_id(), GURL(GetPluginParams().url), + GetFrame()->parent() == nullptr, GetFrame()->top()->getSecurityOrigin(), mime_type, &output)); if (output.status == status_) return; diff --git a/libcef_dll/cpptoc/request_context_handler_cpptoc.cc b/libcef_dll/cpptoc/request_context_handler_cpptoc.cc index f2a585d1e..1ee0b8791 100644 --- a/libcef_dll/cpptoc/request_context_handler_cpptoc.cc +++ b/libcef_dll/cpptoc/request_context_handler_cpptoc.cc @@ -37,7 +37,8 @@ cef_cookie_manager_t* CEF_CALLBACK request_context_handler_get_cookie_manager( int CEF_CALLBACK request_context_handler_on_before_plugin_load( struct _cef_request_context_handler_t* self, const cef_string_t* mime_type, - const cef_string_t* plugin_url, const cef_string_t* top_origin_url, + const cef_string_t* plugin_url, int is_main_frame, + const cef_string_t* top_origin_url, struct _cef_web_plugin_info_t* plugin_info, cef_plugin_policy_t* plugin_policy) { // AUTO-GENERATED CONTENT - DELETE THIS COMMENT BEFORE MODIFYING @@ -63,6 +64,7 @@ int CEF_CALLBACK request_context_handler_on_before_plugin_load( bool _retval = CefRequestContextHandlerCppToC::Get(self)->OnBeforePluginLoad( CefString(mime_type), CefString(plugin_url), + is_main_frame?true:false, CefString(top_origin_url), CefWebPluginInfoCToCpp::Wrap(plugin_info), plugin_policy); diff --git a/libcef_dll/ctocpp/request_context_handler_ctocpp.cc b/libcef_dll/ctocpp/request_context_handler_ctocpp.cc index 681a332e9..783433d16 100644 --- a/libcef_dll/ctocpp/request_context_handler_ctocpp.cc +++ b/libcef_dll/ctocpp/request_context_handler_ctocpp.cc @@ -32,7 +32,7 @@ CefRefPtr CefRequestContextHandlerCToCpp::GetCookieManager() { } bool CefRequestContextHandlerCToCpp::OnBeforePluginLoad( - const CefString& mime_type, const CefString& plugin_url, + const CefString& mime_type, const CefString& plugin_url, bool is_main_frame, const CefString& top_origin_url, CefRefPtr plugin_info, PluginPolicy* plugin_policy) { cef_request_context_handler_t* _struct = GetStruct(); @@ -59,6 +59,7 @@ bool CefRequestContextHandlerCToCpp::OnBeforePluginLoad( int _retval = _struct->on_before_plugin_load(_struct, mime_type.GetStruct(), plugin_url.GetStruct(), + is_main_frame, top_origin_url.GetStruct(), CefWebPluginInfoCppToC::Wrap(plugin_info), plugin_policy); diff --git a/libcef_dll/ctocpp/request_context_handler_ctocpp.h b/libcef_dll/ctocpp/request_context_handler_ctocpp.h index 89101cc08..2a92d64e4 100644 --- a/libcef_dll/ctocpp/request_context_handler_ctocpp.h +++ b/libcef_dll/ctocpp/request_context_handler_ctocpp.h @@ -33,8 +33,8 @@ class CefRequestContextHandlerCToCpp // CefRequestContextHandler methods. CefRefPtr GetCookieManager() override; bool OnBeforePluginLoad(const CefString& mime_type, - const CefString& plugin_url, const CefString& top_origin_url, - CefRefPtr plugin_info, + const CefString& plugin_url, bool is_main_frame, + const CefString& top_origin_url, CefRefPtr plugin_info, PluginPolicy* plugin_policy) override; }; diff --git a/patch/patch.cfg b/patch/patch.cfg index af4cb25d7..fc50a013e 100644 --- a/patch/patch.cfg +++ b/patch/patch.cfg @@ -253,12 +253,6 @@ patches = [ 'name': 'storage_partition_1973', 'path': '../', }, - { - # Pass the render process id to PluginServiceFilter::IsPluginAvailable. - # https://bugs.chromium.org/p/chromium/issues/detail?id=626728#c15 - 'name': 'render_frame_message_filter_626728', - 'path': '../', - }, { # Don't add TestDesktopScreenX11 dependency on Linux. # Revert ui_controls_factory_desktop_aurax11.cc changes from @@ -315,4 +309,19 @@ patches = [ 'name': 'rwh_background_color_1984', 'path': '../', }, + { + # Pass is_main_frame to PluginServiceFilter::IsPluginAvailable. + # https://bitbucket.org/chromiumembedded/cef/issues/2015 + # + # Pass the render process id to PluginServiceFilter::IsPluginAvailable. + # https://bugs.chromium.org/p/chromium/issues/detail?id=626728#c15 + 'name': 'plugin_info_2015', + 'path': '../', + }, + { + # Pass is_main_frame to PluginServiceFilter::IsPluginAvailable. + # https://bitbucket.org/chromiumembedded/cef/issues/2015 + 'name': 'plugin_info_webkit_2015', + 'path': '../third_party/WebKit/', + }, ] diff --git a/patch/patches/content_nav_1129.patch b/patch/patches/content_nav_1129.patch index b3a8179ca..4cc45f8cc 100644 --- a/patch/patches/content_nav_1129.patch +++ b/patch/patches/content_nav_1129.patch @@ -38,23 +38,4 @@ index f2a854f..913e30c 100644 // Indicates if the Android MediaPlayer should be used instead of Chrome's // built in media player for the given |url|. Defaults to false. virtual bool ShouldUseMediaPlayerForURL(const GURL& url); -diff --git renderer/render_frame_impl.cc renderer/render_frame_impl.cc -index c0d7575..c1ea8e6 100644 ---- renderer/render_frame_impl.cc -+++ renderer/render_frame_impl.cc -@@ -5120,7 +5120,6 @@ WebNavigationPolicy RenderFrameImpl::decidePolicyForNavigation( - (pending_navigation_params_ && - !pending_navigation_params_->request_params.redirects.empty()); - --#ifdef OS_ANDROID - // The handlenavigation API is deprecated and will be removed once - // crbug.com/325351 is resolved. - if (GetContentClient()->renderer()->HandleNavigation( -@@ -5129,7 +5128,6 @@ WebNavigationPolicy RenderFrameImpl::decidePolicyForNavigation( - is_redirect)) { - return blink::WebNavigationPolicyIgnore; - } --#endif - - Referrer referrer( - RenderViewImpl::GetReferrerFromRequest(frame_, info.urlRequest)); +\ \ No newline at end of file diff --git a/patch/patches/plugin_info_2015.patch b/patch/patches/plugin_info_2015.patch new file mode 100644 index 000000000..9f2ed155a --- /dev/null +++ b/patch/patches/plugin_info_2015.patch @@ -0,0 +1,350 @@ +diff --git chrome/browser/download/download_target_determiner.cc chrome/browser/download/download_target_determiner.cc +index e1e662e..799e01e 100644 +--- chrome/browser/download/download_target_determiner.cc ++++ chrome/browser/download/download_target_determiner.cc +@@ -476,8 +476,8 @@ void IsHandledBySafePlugin(content::ResourceContext* resource_context, + content::PluginService* plugin_service = + content::PluginService::GetInstance(); + bool plugin_found = plugin_service->GetPluginInfo( +- -1, -1, resource_context, url, url::Origin(), mime_type, false, &is_stale, +- &plugin_info, &actual_mime_type); ++ -1, -1, resource_context, url, true, url::Origin(), mime_type, false, ++ &is_stale, &plugin_info, &actual_mime_type); + if (is_stale && stale_plugin_action == RETRY_IF_STALE_PLUGIN_LIST) { + // The GetPlugins call causes the plugin list to be refreshed. Once that's + // done we can retry the GetPluginInfo call. We break out of this cycle +diff --git chrome/browser/plugins/chrome_plugin_service_filter.cc chrome/browser/plugins/chrome_plugin_service_filter.cc +index cdb0cc8..5903927 100644 +--- chrome/browser/plugins/chrome_plugin_service_filter.cc ++++ chrome/browser/plugins/chrome_plugin_service_filter.cc +@@ -178,6 +178,7 @@ bool ChromePluginServiceFilter::IsPluginAvailable( + int render_frame_id, + const void* context, + const GURL& plugin_content_url, ++ bool is_main_frame, + const url::Origin& main_frame_origin, + content::WebPluginInfo* plugin) { + base::AutoLock auto_lock(lock_); +diff --git chrome/browser/plugins/chrome_plugin_service_filter.h chrome/browser/plugins/chrome_plugin_service_filter.h +index f8b651f..ec39f8d 100644 +--- chrome/browser/plugins/chrome_plugin_service_filter.h ++++ chrome/browser/plugins/chrome_plugin_service_filter.h +@@ -71,6 +71,7 @@ class ChromePluginServiceFilter : public content::PluginServiceFilter, + int render_frame_id, + const void* context, + const GURL& plugin_content_url, ++ bool is_main_frame, + const url::Origin& main_frame_origin, + content::WebPluginInfo* plugin) override; + +diff --git chrome/browser/plugins/plugin_info_message_filter.cc chrome/browser/plugins/plugin_info_message_filter.cc +index 3e0a715..dbc75d9 100644 +--- chrome/browser/plugins/plugin_info_message_filter.cc ++++ chrome/browser/plugins/plugin_info_message_filter.cc +@@ -446,8 +446,8 @@ bool PluginInfoMessageFilter::Context::FindEnabledPlugin( + for (; i < matching_plugins.size(); ++i) { + if (!filter || + filter->IsPluginAvailable(render_process_id_, render_frame_id, +- resource_context_, url, main_frame_origin, +- &matching_plugins[i])) { ++ resource_context_, url, true, ++ main_frame_origin, &matching_plugins[i])) { + break; + } + } +diff --git chrome/browser/ui/cocoa/drag_util.mm chrome/browser/ui/cocoa/drag_util.mm +index 4a3e00e..aca7f98 100644 +--- chrome/browser/ui/cocoa/drag_util.mm ++++ chrome/browser/ui/cocoa/drag_util.mm +@@ -52,7 +52,7 @@ BOOL IsSupportedFileURL(Profile* profile, const GURL& url) { + return PluginService::GetInstance()->GetPluginInfo( + -1, // process ID + MSG_ROUTING_NONE, // routing ID +- profile->GetResourceContext(), url, url::Origin(), mime_type, ++ profile->GetResourceContext(), url, true, url::Origin(), mime_type, + allow_wildcard, NULL, &plugin, NULL); + } + +diff --git chrome/browser/ui/views/tabs/browser_tab_strip_controller.cc chrome/browser/ui/views/tabs/browser_tab_strip_controller.cc +index 21c34be..5250ead 100644 +--- chrome/browser/ui/views/tabs/browser_tab_strip_controller.cc ++++ chrome/browser/ui/views/tabs/browser_tab_strip_controller.cc +@@ -575,6 +575,6 @@ void BrowserTabStripController::OnFindURLMimeTypeCompleted( + content::PluginService::GetInstance()->GetPluginInfo( + -1, // process ID + MSG_ROUTING_NONE, // routing ID +- model_->profile()->GetResourceContext(), url, url::Origin(), ++ model_->profile()->GetResourceContext(), url, true, url::Origin(), + mime_type, false, NULL, &plugin, NULL)); + } +diff --git content/browser/frame_host/render_frame_message_filter.cc content/browser/frame_host/render_frame_message_filter.cc +index 573b5d9..5f3d68b 100644 +--- content/browser/frame_host/render_frame_message_filter.cc ++++ content/browser/frame_host/render_frame_message_filter.cc +@@ -459,6 +459,7 @@ void RenderFrameMessageFilter::GetCookies(int render_frame_id, + + void RenderFrameMessageFilter::OnGetPlugins( + bool refresh, ++ bool is_main_frame, + const url::Origin& main_frame_origin, + IPC::Message* reply_msg) { + // Don't refresh if the specified threshold has not been passed. Note that +@@ -480,18 +481,19 @@ void RenderFrameMessageFilter::OnGetPlugins( + + PluginServiceImpl::GetInstance()->GetPlugins( + base::Bind(&RenderFrameMessageFilter::GetPluginsCallback, this, reply_msg, +- main_frame_origin)); ++ is_main_frame, main_frame_origin)); + } + + void RenderFrameMessageFilter::GetPluginsCallback( + IPC::Message* reply_msg, ++ bool is_main_frame, + const url::Origin& main_frame_origin, + const std::vector& all_plugins) { + // Filter the plugin list. + PluginServiceFilter* filter = PluginServiceImpl::GetInstance()->GetFilter(); + std::vector plugins; + +- int child_process_id = -1; ++ int child_process_id = render_process_id_; + int routing_id = MSG_ROUTING_NONE; + // In this loop, copy the WebPluginInfo (and do not use a reference) because + // the filter might mutate it. +@@ -500,7 +502,7 @@ void RenderFrameMessageFilter::GetPluginsCallback( + if (!filter || + filter->IsPluginAvailable(child_process_id, routing_id, + resource_context_, main_frame_origin.GetURL(), +- main_frame_origin, &plugin)) { ++ is_main_frame, main_frame_origin, &plugin)) { + plugins.push_back(plugin); + } + } +@@ -512,6 +514,7 @@ void RenderFrameMessageFilter::GetPluginsCallback( + void RenderFrameMessageFilter::OnGetPluginInfo( + int render_frame_id, + const GURL& url, ++ bool is_main_frame, + const url::Origin& main_frame_origin, + const std::string& mime_type, + bool* found, +@@ -520,8 +523,8 @@ void RenderFrameMessageFilter::OnGetPluginInfo( + bool allow_wildcard = true; + *found = plugin_service_->GetPluginInfo( + render_process_id_, render_frame_id, resource_context_, url, +- main_frame_origin, mime_type, allow_wildcard, nullptr, info, +- actual_mime_type); ++ is_main_frame, main_frame_origin, mime_type, allow_wildcard, nullptr, ++ info, actual_mime_type); + } + + void RenderFrameMessageFilter::OnOpenChannelToPepperPlugin( +diff --git content/browser/frame_host/render_frame_message_filter.h content/browser/frame_host/render_frame_message_filter.h +index fa7fe99..5fe9680 100644 +--- content/browser/frame_host/render_frame_message_filter.h ++++ content/browser/frame_host/render_frame_message_filter.h +@@ -125,13 +125,16 @@ class CONTENT_EXPORT RenderFrameMessageFilter + + #if defined(ENABLE_PLUGINS) + void OnGetPlugins(bool refresh, ++ bool is_main_frame, + const url::Origin& main_frame_origin, + IPC::Message* reply_msg); + void GetPluginsCallback(IPC::Message* reply_msg, ++ bool is_main_frame, + const url::Origin& main_frame_origin, + const std::vector& plugins); + void OnGetPluginInfo(int render_frame_id, + const GURL& url, ++ bool is_main_frame, + const url::Origin& main_frame_origin, + const std::string& mime_type, + bool* found, +diff --git content/browser/loader/mime_sniffing_resource_handler.cc content/browser/loader/mime_sniffing_resource_handler.cc +index 3e5e414..aa8e294 100644 +--- content/browser/loader/mime_sniffing_resource_handler.cc ++++ content/browser/loader/mime_sniffing_resource_handler.cc +@@ -432,8 +432,8 @@ bool MimeSniffingResourceHandler::CheckForPluginHandler( + WebPluginInfo plugin; + bool has_plugin = plugin_service_->GetPluginInfo( + info->GetChildID(), info->GetRenderFrameID(), info->GetContext(), +- request()->url(), url::Origin(), response_->head.mime_type, +- allow_wildcard, &stale, &plugin, NULL); ++ request()->url(), info->IsMainFrame(), url::Origin(), ++ response_->head.mime_type, allow_wildcard, &stale, &plugin, NULL); + + if (stale) { + // Refresh the plugins asynchronously. +diff --git content/browser/plugin_service_impl.cc content/browser/plugin_service_impl.cc +index 3eca335..72dfab6 100644 +--- content/browser/plugin_service_impl.cc ++++ content/browser/plugin_service_impl.cc +@@ -242,6 +242,7 @@ bool PluginServiceImpl::GetPluginInfo(int render_process_id, + int render_frame_id, + ResourceContext* context, + const GURL& url, ++ bool is_main_frame, + const url::Origin& main_frame_origin, + const std::string& mime_type, + bool allow_wildcard, +@@ -258,7 +259,8 @@ bool PluginServiceImpl::GetPluginInfo(int render_process_id, + for (size_t i = 0; i < plugins.size(); ++i) { + if (!filter_ || + filter_->IsPluginAvailable(render_process_id, render_frame_id, context, +- url, main_frame_origin, &plugins[i])) { ++ url, is_main_frame, main_frame_origin, ++ &plugins[i])) { + *info = plugins[i]; + if (actual_mime_type) + *actual_mime_type = mime_types[i]; +diff --git content/browser/plugin_service_impl.h content/browser/plugin_service_impl.h +index 71bbed2..0f72497 100644 +--- content/browser/plugin_service_impl.h ++++ content/browser/plugin_service_impl.h +@@ -69,6 +69,7 @@ class CONTENT_EXPORT PluginServiceImpl + int render_frame_id, + ResourceContext* context, + const GURL& url, ++ bool is_main_frame, + const url::Origin& main_frame_origin, + const std::string& mime_type, + bool allow_wildcard, +diff --git content/common/frame_messages.h content/common/frame_messages.h +index 3177bf6..9b4abe4 100644 +--- content/common/frame_messages.h ++++ content/common/frame_messages.h +@@ -1160,8 +1160,9 @@ IPC_MESSAGE_ROUTED1(FrameHostMsg_PepperStopsPlayback, + + // Used to get the list of plugins. |main_frame_origin| is used to handle + // exceptions for plugin content settings. +-IPC_SYNC_MESSAGE_CONTROL2_1(FrameHostMsg_GetPlugins, ++IPC_SYNC_MESSAGE_CONTROL3_1(FrameHostMsg_GetPlugins, + bool /* refresh*/, ++ bool /* is_main_frame */, + url::Origin /* main_frame_origin */, + std::vector /* plugins */) + +@@ -1169,9 +1170,10 @@ IPC_SYNC_MESSAGE_CONTROL2_1(FrameHostMsg_GetPlugins, + // type. If there is no matching plugin, |found| is false. + // |actual_mime_type| is the actual mime type supported by the + // found plugin. +-IPC_SYNC_MESSAGE_CONTROL4_3(FrameHostMsg_GetPluginInfo, ++IPC_SYNC_MESSAGE_CONTROL5_3(FrameHostMsg_GetPluginInfo, + int /* render_frame_id */, + GURL /* url */, ++ bool /* is_main_frame */, + url::Origin /* main_frame_origin */, + std::string /* mime_type */, + bool /* found */, +diff --git content/ppapi_plugin/ppapi_blink_platform_impl.cc content/ppapi_plugin/ppapi_blink_platform_impl.cc +index c4dc0cf..4fe3e1b 100644 +--- content/ppapi_plugin/ppapi_blink_platform_impl.cc ++++ content/ppapi_plugin/ppapi_blink_platform_impl.cc +@@ -210,6 +210,7 @@ blink::WebURLLoader* PpapiBlinkPlatformImpl::createURLLoader() { + + void PpapiBlinkPlatformImpl::getPluginList( + bool refresh, ++ bool isMainFrame, + const blink::WebSecurityOrigin& mainFrameOrigin, + blink::WebPluginListBuilder* builder) { + NOTREACHED(); +diff --git content/ppapi_plugin/ppapi_blink_platform_impl.h content/ppapi_plugin/ppapi_blink_platform_impl.h +index 9c2ba25..11a0839 100644 +--- content/ppapi_plugin/ppapi_blink_platform_impl.h ++++ content/ppapi_plugin/ppapi_blink_platform_impl.h +@@ -44,6 +44,7 @@ class PpapiBlinkPlatformImpl : public BlinkPlatformImpl { + blink::WebThemeEngine* themeEngine() override; + blink::WebURLLoader* createURLLoader() override; + void getPluginList(bool refresh, ++ bool isMainFrame, + const blink::WebSecurityOrigin& mainFrameOrigin, + blink::WebPluginListBuilder*) override; + blink::WebData loadResource(const char* name) override; +diff --git content/public/browser/plugin_service.h content/public/browser/plugin_service.h +index c404ac8..9dd87e7 100644 +--- content/public/browser/plugin_service.h ++++ content/public/browser/plugin_service.h +@@ -74,6 +74,7 @@ class PluginService { + int render_frame_id, + ResourceContext* context, + const GURL& url, ++ bool is_main_frame, + const url::Origin& main_frame_origin, + const std::string& mime_type, + bool allow_wildcard, +diff --git content/public/browser/plugin_service_filter.h content/public/browser/plugin_service_filter.h +index 3b610b1..7c439e0 100644 +--- content/public/browser/plugin_service_filter.h ++++ content/public/browser/plugin_service_filter.h +@@ -33,6 +33,7 @@ class PluginServiceFilter { + int render_frame_id, + const void* context, + const GURL& url, ++ bool is_main_frame, + const url::Origin& main_frame_origin, + WebPluginInfo* plugin) = 0; + +diff --git content/renderer/render_frame_impl.cc content/renderer/render_frame_impl.cc +index c0d7575..c723958 100644 +--- content/renderer/render_frame_impl.cc ++++ content/renderer/render_frame_impl.cc +@@ -2729,7 +2729,8 @@ blink::WebPlugin* RenderFrameImpl::createPlugin( + std::string mime_type; + bool found = false; + Send(new FrameHostMsg_GetPluginInfo( +- routing_id_, params.url, frame->top()->getSecurityOrigin(), ++ routing_id_, params.url, frame->parent() == nullptr, ++ frame->top()->getSecurityOrigin(), + params.mimeType.utf8(), &found, &info, &mime_type)); + if (!found) + return NULL; +@@ -5120,7 +5121,6 @@ WebNavigationPolicy RenderFrameImpl::decidePolicyForNavigation( + (pending_navigation_params_ && + !pending_navigation_params_->request_params.redirects.empty()); + +-#ifdef OS_ANDROID + // The handlenavigation API is deprecated and will be removed once + // crbug.com/325351 is resolved. + if (GetContentClient()->renderer()->HandleNavigation( +@@ -5129,7 +5129,6 @@ WebNavigationPolicy RenderFrameImpl::decidePolicyForNavigation( + is_redirect)) { + return blink::WebNavigationPolicyIgnore; + } +-#endif + + Referrer referrer( + RenderViewImpl::GetReferrerFromRequest(frame_, info.urlRequest)); +diff --git content/renderer/renderer_blink_platform_impl.cc content/renderer/renderer_blink_platform_impl.cc +index a0cdfa0..9a9ef85 100644 +--- content/renderer/renderer_blink_platform_impl.cc ++++ content/renderer/renderer_blink_platform_impl.cc +@@ -742,6 +742,7 @@ blink::WebMIDIAccessor* RendererBlinkPlatformImpl::createMIDIAccessor( + + void RendererBlinkPlatformImpl::getPluginList( + bool refresh, ++ bool isMainFrame, + const blink::WebSecurityOrigin& mainFrameOrigin, + blink::WebPluginListBuilder* builder) { + #if defined(ENABLE_PLUGINS) +@@ -749,7 +750,8 @@ void RendererBlinkPlatformImpl::getPluginList( + if (!plugin_refresh_allowed_) + refresh = false; + RenderThread::Get()->Send( +- new FrameHostMsg_GetPlugins(refresh, mainFrameOrigin, &plugins)); ++ new FrameHostMsg_GetPlugins(refresh, isMainFrame, mainFrameOrigin, ++ &plugins)); + for (const WebPluginInfo& plugin : plugins) { + builder->addPlugin( + plugin.name, plugin.desc, +diff --git content/renderer/renderer_blink_platform_impl.h content/renderer/renderer_blink_platform_impl.h +index 2783946..d5a61e5 100644 +--- content/renderer/renderer_blink_platform_impl.h ++++ content/renderer/renderer_blink_platform_impl.h +@@ -121,6 +121,7 @@ class CONTENT_EXPORT RendererBlinkPlatformImpl : public BlinkPlatformImpl { + const blink::WebURL& url, + const blink::WebURL& top_origin) override; + void getPluginList(bool refresh, ++ bool isMainFrame, + const blink::WebSecurityOrigin& mainFrameOrigin, + blink::WebPluginListBuilder* builder) override; + blink::WebPublicSuffixList* publicSuffixList() override; diff --git a/patch/patches/plugin_info_webkit_2015.patch b/patch/patches/plugin_info_webkit_2015.patch new file mode 100644 index 000000000..76b6d4e49 --- /dev/null +++ b/patch/patches/plugin_info_webkit_2015.patch @@ -0,0 +1,163 @@ +diff --git Source/core/dom/DOMImplementation.cpp Source/core/dom/DOMImplementation.cpp +index b6ef058..3f94993 100644 +--- Source/core/dom/DOMImplementation.cpp ++++ Source/core/dom/DOMImplementation.cpp +@@ -240,9 +240,9 @@ Document* DOMImplementation::createDocument(const String& type, + // For that reason, the origin must be retrieved directly from init.url(). + if (init.frame()->isMainFrame()) { + RefPtr origin = SecurityOrigin::create(init.url()); +- pluginData = init.frame()->page()->pluginData(origin.get()); ++ pluginData = init.frame()->page()->pluginData(true, origin.get()); + } else { +- pluginData = init.frame()->page()->pluginData( ++ pluginData = init.frame()->page()->pluginData(false, + init.frame()->tree().top()->securityContext()->getSecurityOrigin()); + } + } +diff --git Source/core/frame/LocalFrame.cpp Source/core/frame/LocalFrame.cpp +index 56f8733..23ae6ca 100644 +--- Source/core/frame/LocalFrame.cpp ++++ Source/core/frame/LocalFrame.cpp +@@ -907,6 +907,7 @@ PluginData* LocalFrame::pluginData() const { + if (!loader().allowPlugins(NotAboutToInstantiatePlugin)) + return nullptr; + return page()->pluginData( ++ isMainFrame(), + tree().top()->securityContext()->getSecurityOrigin()); + } + +diff --git Source/core/page/Page.cpp Source/core/page/Page.cpp +index b9f74b3..595d056 100644 +--- Source/core/page/Page.cpp ++++ Source/core/page/Page.cpp +@@ -248,16 +248,26 @@ void Page::refreshPlugins() { + + for (const Page* page : allPages()) { + // Clear out the page's plugin data. +- if (page->m_pluginData) +- page->m_pluginData = nullptr; ++ if (page->m_pluginDataMainFrame) ++ page->m_pluginDataMainFrame = nullptr; ++ if (page->m_pluginDataSubFrame) ++ page->m_pluginDataSubFrame = nullptr; + } + } + +-PluginData* Page::pluginData(SecurityOrigin* mainFrameOrigin) const { +- if (!m_pluginData || +- !mainFrameOrigin->isSameSchemeHostPort(m_pluginData->origin())) +- m_pluginData = PluginData::create(mainFrameOrigin); +- return m_pluginData.get(); ++PluginData* Page::pluginData(bool isMainFrame, ++ SecurityOrigin* mainFrameOrigin) const { ++ if (isMainFrame) { ++ if (!m_pluginDataMainFrame || ++ !mainFrameOrigin->isSameSchemeHostPort(m_pluginDataMainFrame->origin())) ++ m_pluginDataMainFrame = PluginData::create(true, mainFrameOrigin); ++ } else { ++ if (!m_pluginDataSubFrame || ++ !mainFrameOrigin->isSameSchemeHostPort(m_pluginDataSubFrame->origin())) ++ m_pluginDataSubFrame = PluginData::create(false, mainFrameOrigin); ++ } ++ ++ return isMainFrame ? m_pluginDataMainFrame.get() : m_pluginDataSubFrame.get(); + } + + void Page::setValidationMessageClient(ValidationMessageClient* client) { +diff --git Source/core/page/Page.h Source/core/page/Page.h +index 2c402f71..ec0ce4d 100644 +--- Source/core/page/Page.h ++++ Source/core/page/Page.h +@@ -127,7 +127,8 @@ class CORE_EXPORT Page final : public GarbageCollectedFinalized, + ViewportDescription viewportDescription() const; + + static void refreshPlugins(); +- PluginData* pluginData(SecurityOrigin* mainFrameOrigin) const; ++ PluginData* pluginData(bool isMainFrame, ++ SecurityOrigin* mainFrameOrigin) const; + + EditorClient& editorClient() const { return *m_editorClient; } + SpellCheckerClient& spellCheckerClient() const { +@@ -269,7 +270,8 @@ class CORE_EXPORT Page final : public GarbageCollectedFinalized, + // longer needed. + Member m_mainFrame; + +- mutable RefPtr m_pluginData; ++ mutable RefPtr m_pluginDataMainFrame; ++ mutable RefPtr m_pluginDataSubFrame; + + EditorClient* const m_editorClient; + SpellCheckerClient* const m_spellCheckerClient; +diff --git Source/platform/plugins/PluginData.cpp Source/platform/plugins/PluginData.cpp +index c37736f..0cecede 100644 +--- Source/platform/plugins/PluginData.cpp ++++ Source/platform/plugins/PluginData.cpp +@@ -30,11 +30,12 @@ + + namespace blink { + +-PluginData::PluginData(SecurityOrigin* mainFrameOrigin) +- : m_mainFrameOrigin(mainFrameOrigin) { ++PluginData::PluginData(bool isMainFrame, SecurityOrigin* mainFrameOrigin) ++ : m_isMainFrame(isMainFrame), ++ m_mainFrameOrigin(mainFrameOrigin) { + PluginListBuilder builder(&m_plugins); + Platform::current()->getPluginList( +- false, WebSecurityOrigin(m_mainFrameOrigin), &builder); ++ false, m_isMainFrame, WebSecurityOrigin(m_mainFrameOrigin), &builder); + + for (unsigned i = 0; i < m_plugins.size(); ++i) { + const PluginInfo& plugin = m_plugins[i]; +@@ -73,7 +74,8 @@ String PluginData::pluginNameForMimeType(const String& mimeType) const { + void PluginData::refreshBrowserSidePluginCache() { + Vector plugins; + PluginListBuilder builder(&plugins); +- Platform::current()->getPluginList(true, WebSecurityOrigin::createUnique(), ++ Platform::current()->getPluginList(true, true, ++ WebSecurityOrigin::createUnique(), + &builder); + } + +diff --git Source/platform/plugins/PluginData.h Source/platform/plugins/PluginData.h +index 0edfd70..a81c128 100644 +--- Source/platform/plugins/PluginData.h ++++ Source/platform/plugins/PluginData.h +@@ -52,8 +52,9 @@ class PLATFORM_EXPORT PluginData : public RefCounted { + WTF_MAKE_NONCOPYABLE(PluginData); + + public: +- static PassRefPtr create(SecurityOrigin* mainFrameOrigin) { +- return adoptRef(new PluginData(mainFrameOrigin)); ++ static PassRefPtr create(bool isMainFrame, ++ SecurityOrigin* mainFrameOrigin) { ++ return adoptRef(new PluginData(isMainFrame, mainFrameOrigin)); + } + + const Vector& plugins() const { return m_plugins; } +@@ -71,12 +72,13 @@ class PLATFORM_EXPORT PluginData : public RefCounted { + static void refreshBrowserSidePluginCache(); + + private: +- explicit PluginData(SecurityOrigin* mainFrameOrigin); ++ explicit PluginData(bool isMainFrame, SecurityOrigin* mainFrameOrigin); + const PluginInfo* pluginInfoForMimeType(const String& mimeType) const; + + Vector m_plugins; + Vector m_mimes; + Vector m_mimePluginIndices; ++ bool m_isMainFrame; + RefPtr m_mainFrameOrigin; + }; + +diff --git public/platform/Platform.h public/platform/Platform.h +index 747885a..60dd9cc 100644 +--- public/platform/Platform.h ++++ public/platform/Platform.h +@@ -369,6 +369,7 @@ class BLINK_PLATFORM_EXPORT Platform { + // satisfy this call. mainFrameOrigin is used by the browser process to + // filter plugins from the plugin list based on content settings. + virtual void getPluginList(bool refresh, ++ bool isMainFrame, + const WebSecurityOrigin& mainFrameOrigin, + WebPluginListBuilder*) {} + diff --git a/tests/cefclient/browser/root_window_manager.cc b/tests/cefclient/browser/root_window_manager.cc index 84c494f47..cddc5cec2 100644 --- a/tests/cefclient/browser/root_window_manager.cc +++ b/tests/cefclient/browser/root_window_manager.cc @@ -24,6 +24,7 @@ class ClientRequestContextHandler : public CefRequestContextHandler { bool OnBeforePluginLoad(const CefString& mime_type, const CefString& plugin_url, + bool is_main_frame, const CefString& top_origin_url, CefRefPtr plugin_info, PluginPolicy* plugin_policy) OVERRIDE { diff --git a/tests/ceftests/plugin_unittest.cc b/tests/ceftests/plugin_unittest.cc index c8eec34b3..d0ba891e8 100644 --- a/tests/ceftests/plugin_unittest.cc +++ b/tests/ceftests/plugin_unittest.cc @@ -40,6 +40,7 @@ class PluginBrowserTest : public client::ClientAppBrowser::Delegate { IMPLEMENT_REFCOUNTING(PluginBrowserTest); }; +const char kPdfTestOrigin[] = "http://tests/"; const char kPdfHtmlUrl[] = "http://tests/pdf.html"; const char kPdfDirectUrl[] = "http://tests/pdf.pdf"; @@ -113,32 +114,51 @@ class PluginTestHandler : public RoutingTestHandler, bool OnBeforePluginLoad(const CefString& mime_type, const CefString& plugin_url, + bool is_main_frame, const CefString& top_origin_url, CefRefPtr plugin_info, PluginPolicy* plugin_policy) override { const std::string& mime_type_str = mime_type; EXPECT_STREQ("application/pdf", mime_type_str.c_str()); + EXPECT_STREQ("chrome-extension://mhjfbmdgcfjbbpaeojofohoefgiehjai/", + plugin_info->GetPath().ToString().c_str()); if (top_origin_url.empty()) { - if (!handler_->got_on_before_plugin_empty_origin_) + if (!handler_->got_on_before_plugin_empty_origin_) { + // Checking for PDF support in the plugin frame (navigator.plugins + // listing, pdf load, etc). + EXPECT_EQ(handler_->HasDirectPluginLoad(), is_main_frame); handler_->got_on_before_plugin_empty_origin_.yes(); - else + } else if (handler_->HasNoList()) { + // When listing is disabled there should be an additional check in the + // main frame for the navigator.plugins listing. + if (!handler_->got_on_before_plugin_empty_origin2_) { + EXPECT_EQ(true, is_main_frame); + handler_->got_on_before_plugin_empty_origin2_.yes(); + } else { + NOTREACHED(); + } + } else { + // When listing is enabled there should only be the one check in the + // plugin frame. NOTREACHED(); + } if (handler_->HasNoList()) { // Remove the PDF plugin from the `navigator.plugins` list. *plugin_policy = PLUGIN_POLICY_DISABLE; return true; - } else { - // Ignore requests for building the plugin list. - return false; } + + // Ignore requests for building the plugin list. + return false; } - if (!handler_->got_on_before_plugin_load_pdf1_) - handler_->got_on_before_plugin_load_pdf1_.yes(); - else if (!handler_->got_on_before_plugin_load_pdf2_) - handler_->got_on_before_plugin_load_pdf2_.yes(); + // Should only get requests for the test origin. + EXPECT_STREQ(kPdfTestOrigin, top_origin_url.ToString().c_str()); + + if (!handler_->got_on_before_plugin_load_pdf_) + handler_->got_on_before_plugin_load_pdf_.yes(); else NOTREACHED(); @@ -152,6 +172,7 @@ class PluginTestHandler : public RoutingTestHandler, *plugin_policy = PLUGIN_POLICY_DISABLE; return true; } + return false; } @@ -171,6 +192,11 @@ class PluginTestHandler : public RoutingTestHandler, url_(url) { } + // Loading the PDF directly in the main frame instead of a sub-frame. + bool HasDirectPluginLoad() const { + return url_ == kPdfDirectUrl; + } + // Has a specified RequestContext but not necessarily a custom handler. bool HasRequestContext() const { return mode_ != GLOBAL_DEFAULT; @@ -525,11 +551,13 @@ class PluginTestHandler : public RoutingTestHandler, EXPECT_FALSE(got_on_before_plugin_empty_origin_); if (HasNoList()) { + EXPECT_TRUE(got_on_before_plugin_empty_origin2_); EXPECT_FALSE(got_pdf_plugin_found_); EXPECT_TRUE(got_pdf_plugin_missing_); EXPECT_FALSE(got_run_context_menu_); EXPECT_FALSE(got_context_menu_dismissed_); } else { + EXPECT_FALSE(got_on_before_plugin_empty_origin2_); EXPECT_TRUE(got_pdf_plugin_found_); EXPECT_FALSE(got_pdf_plugin_missing_); EXPECT_TRUE(got_run_context_menu_); @@ -544,10 +572,8 @@ class PluginTestHandler : public RoutingTestHandler, EXPECT_TRUE(got_on_load_end_pdf1_); EXPECT_TRUE(got_on_load_end_pdf2_); - if (HasRequestContextHandler()) { - EXPECT_TRUE(got_on_before_plugin_load_pdf1_); - EXPECT_TRUE(got_on_before_plugin_load_pdf2_); - } + if (HasRequestContextHandler()) + EXPECT_TRUE(got_on_before_plugin_load_pdf_); } } else if (url_ == kPdfDirectUrl) { // Load the PDF file directly. @@ -555,17 +581,14 @@ class PluginTestHandler : public RoutingTestHandler, EXPECT_TRUE(got_on_load_end_pdf1_); EXPECT_FALSE(got_on_load_end_pdf2_); - if (HasRequestContextHandler()) { - EXPECT_TRUE(got_on_before_plugin_load_pdf1_); - EXPECT_FALSE(got_on_before_plugin_load_pdf2_); - } + if (HasRequestContextHandler()) + EXPECT_TRUE(got_on_before_plugin_load_pdf_); } else { NOTREACHED(); } if (!HasRequestContextHandler() || HasNoList()) { - EXPECT_FALSE(got_on_before_plugin_load_pdf1_); - EXPECT_FALSE(got_on_before_plugin_load_pdf2_); + EXPECT_FALSE(got_on_before_plugin_load_pdf_); } TestHandler::DestroyTest(); @@ -575,8 +598,8 @@ class PluginTestHandler : public RoutingTestHandler, const std::string url_; TrackCallback got_on_before_plugin_empty_origin_; - TrackCallback got_on_before_plugin_load_pdf1_; - TrackCallback got_on_before_plugin_load_pdf2_; + TrackCallback got_on_before_plugin_empty_origin2_; + TrackCallback got_on_before_plugin_load_pdf_; TrackCallback got_on_load_end_html_; TrackCallback got_on_load_end_pdf1_; TrackCallback got_on_load_end_pdf2_;