Chromium Code Reviews| Index: extensions/browser/event_router.cc |
| diff --git a/extensions/browser/event_router.cc b/extensions/browser/event_router.cc |
| index 14cc9d6ba4e7a012290404bb71d176660ca18d98..d9b801e63df21766e519a7b0863865855cdc6ffa 100644 |
| --- a/extensions/browser/event_router.cc |
| +++ b/extensions/browser/event_router.cc |
| @@ -12,6 +12,7 @@ |
| #include "base/stl_util.h" |
| #include "base/values.h" |
| #include "chrome/browser/chrome_notification_types.h" |
| +#include "content/public/browser/child_process_security_policy.h" |
| #include "content/public/browser/notification_service.h" |
| #include "content/public/browser/render_process_host.h" |
| #include "extensions/browser/api_activity_monitor.h" |
| @@ -512,47 +513,73 @@ void EventRouter::DispatchLazyEvent( |
| void EventRouter::DispatchEventToProcess(const std::string& extension_id, |
| content::RenderProcessHost* process, |
| const linked_ptr<Event>& event) { |
| + BrowserContext* listener_context = process->GetBrowserContext(); |
| + ProcessMap* process_map = ProcessMap::Get(listener_context); |
| + |
| const Extension* extension = |
| ExtensionRegistry::Get(browser_context_)->enabled_extensions().GetByID( |
| extension_id); |
| + // NOTE: |extension| being NULL does not necessarily imply that this event |
| + // shouldn't be dispatched. Events can be dispatched to WebUI as well. |
| - // The extension could have been removed, but we do not unregister it until |
| - // the extension process is unloaded. |
| - if (!extension) |
| - return; |
| - |
| - BrowserContext* listener_context = process->GetBrowserContext(); |
| - ProcessMap* process_map = ProcessMap::Get(listener_context); |
| - // If the event is privileged, only send to extension processes. Otherwise, |
| - // it's OK to send to normal renderers (e.g., for content scripts). |
| - if (!process_map->Contains(extension->id(), process->GetID()) && |
| - !ExtensionAPI::GetSharedInstance()->IsAvailableInUntrustedContext( |
| - event->event_name, extension)) { |
| + if (!extension && !extension_id.empty()) { |
| + // Trying to dispatch an event to an extension that doesn't exist. The |
| + // extension could have been removed, but we do not unregister it until the |
| + // extension process is unloaded. |
| return; |
| } |
| - // If the event is restricted to a URL, only dispatch if the extension has |
| - // permission for it (or if the event originated from itself). |
| - if (!event->event_url.is_empty() && |
| - event->event_url.host() != extension->id() && |
| - !extension->permissions_data() |
| - ->active_permissions() |
| - ->HasEffectiveAccessToURL(event->event_url)) { |
| - return; |
| - } |
| + if (extension) { |
| + // Dispatching event to an extension. |
| + // If the event is privileged, only send to extension processes. Otherwise, |
| + // it's OK to send to normal renderers (e.g., for content scripts). |
| + if (!process_map->Contains(extension->id(), process->GetID()) && |
| + !ExtensionAPI::GetSharedInstance()->IsAvailableInUntrustedContext( |
| + event->event_name, extension)) { |
| + return; |
| + } |
| + |
| + // If the event is restricted to a URL, only dispatch if the extension has |
| + // permission for it (or if the event originated from itself). |
| + if (!event->event_url.is_empty() && |
| + event->event_url.host() != extension->id() && |
| + !extension->permissions_data() |
| + ->active_permissions() |
| + ->HasEffectiveAccessToURL(event->event_url)) { |
| + return; |
| + } |
| - if (!CanDispatchEventToBrowserContext(listener_context, extension, event)) |
| + if (!CanDispatchEventToBrowserContext(listener_context, extension, event)) { |
| + return; |
| + } |
| + } else if (content::ChildProcessSecurityPolicy::GetInstance() |
| + ->HasWebUIBindings(process->GetID())) { |
| + // Dispatching event to WebUI. |
| + if (!ExtensionAPI::GetSharedInstance()->IsAvailableToWebUI( |
|
Charlie Reis
2014/07/22 21:10:24
Good, I'm glad we have a whitelist of available AP
|
| + event->event_name)) { |
| + return; |
| + } |
| + } else { |
| + // Dispatching event to a webpage - however, all such events (e.g. |
| + // messaging) don't go through EventRouter so this should be impossible. |
|
Charlie Reis
2014/07/22 21:10:24
"should be impossible:" Should this be a NOTREACHE
not at google - send to devlin
2014/07/22 23:42:32
NOTREACHED sgtm.
|
| return; |
| + } |
| if (!event->will_dispatch_callback.is_null()) { |
| - event->will_dispatch_callback.Run(listener_context, extension, |
| - event->event_args.get()); |
| + event->will_dispatch_callback.Run( |
| + listener_context, extension, event->event_args.get()); |
| } |
| - DispatchExtensionMessage(process, listener_context, extension->id(), |
| - event->event_name, event->event_args.get(), |
| - event->user_gesture, event->filter_info); |
| - IncrementInFlightEvents(listener_context, extension); |
| + DispatchExtensionMessage(process, |
| + listener_context, |
| + extension_id, |
| + event->event_name, |
| + event->event_args.get(), |
| + event->user_gesture, |
| + event->filter_info); |
| + |
| + if (extension) |
| + IncrementInFlightEvents(listener_context, extension); |
| } |
| bool EventRouter::CanDispatchEventToBrowserContext( |