mirror of
				https://bitbucket.org/chromiumembedded/cef
				synced 2025-06-05 21:39:12 +02:00 
			
		
		
		
	Add is_main_frame argument to CefRequestContextHandler::OnBeforePluginLoad (issue #2015)
This commit is contained in:
		| @@ -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<CefResourceContext*>(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<WebPluginInfo>& plugins) { | ||||
|   CefViewHostMsg_GetPluginInfo_Output output; | ||||
|   CefRefPtr<CefRequestContextHandler> handler = | ||||
|         browser_context_->GetHandler(); | ||||
|  | ||||
|   // This also fills in |actual_mime_type|. | ||||
|   std::unique_ptr<PluginMetadata> 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)) { | ||||
|   | ||||
| @@ -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); | ||||
|   | ||||
| @@ -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<CefResourceContext*>( | ||||
|       reinterpret_cast<const CefResourceContext*>(context)); | ||||
|  | ||||
|   bool allow_load = true; | ||||
|   if (resource_context->HasPluginLoadDecision(render_process_id, plugin->path, | ||||
|                                               &allow_load)) { | ||||
|     return allow_load; | ||||
|   } | ||||
|  | ||||
|   CefRefPtr<CefRequestContextHandler> 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<CefWebPluginInfoImpl> pluginInfo( | ||||
|         new CefWebPluginInfoImpl(*plugin)); | ||||
|   CefRefPtr<CefRequestContextHandler> 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<CefWebPluginInfoImpl> 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; | ||||
| } | ||||
|   | ||||
| @@ -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); | ||||
|   | ||||
		Reference in New Issue
	
	Block a user