Index: chrome/browser/extensions/api/web_request/web_request_api.cc |
diff --git a/chrome/browser/extensions/api/web_request/web_request_api.cc b/chrome/browser/extensions/api/web_request/web_request_api.cc |
index d1da6838450407fe8b53c19c763247235d140591..1e312d8f44b17e00e64376b8a4f2c791e273de3e 100644 |
--- a/chrome/browser/extensions/api/web_request/web_request_api.cc |
+++ b/chrome/browser/extensions/api/web_request/web_request_api.cc |
@@ -80,6 +80,9 @@ namespace declarative_keys = extensions::declarative_webrequest_constants; |
namespace { |
+const char kWebRequest[] = "webRequest"; |
+const char kWebView[] = "webview"; |
+ |
// List of all the webRequest events. |
const char* const kWebRequestEvents[] = { |
keys::kOnBeforeRedirectEvent, |
@@ -124,8 +127,11 @@ const char* GetRequestStageAsString( |
} |
bool IsWebRequestEvent(const std::string& event_name) { |
+ std::string web_request_event_name(event_name); |
+ if (web_request_event_name.find(kWebView) != std::string::npos) |
+ web_request_event_name.replace(0, sizeof(kWebView) - 1, kWebRequest); |
return std::find(kWebRequestEvents, ARRAYEND(kWebRequestEvents), |
- event_name) != ARRAYEND(kWebRequestEvents); |
+ web_request_event_name) != ARRAYEND(kWebRequestEvents); |
} |
// Returns whether |request| has been triggered by an extension in |
@@ -375,8 +381,9 @@ struct ExtensionWebRequestEventRouter::EventListener { |
std::string sub_event_name; |
RequestFilter filter; |
int extra_info_spec; |
- int target_process_id; |
- int target_route_id; |
+ int caller_process_id; |
Matt Perry
2013/02/06 22:40:24
nit: embedder_process_id
Fady Samuel
2013/05/15 21:58:53
Done.
|
+ int caller_routing_id; |
+ int web_view_instance_id; |
base::WeakPtr<IPC::Sender> ipc_sender; |
mutable std::set<uint64> blocked_requests; |
@@ -1137,9 +1144,11 @@ bool ExtensionWebRequestEventRouter::AddEventListener( |
const std::string& sub_event_name, |
const RequestFilter& filter, |
int extra_info_spec, |
- int target_process_id, |
- int target_route_id, |
+ int caller_process_id, |
+ int caller_routing_id, |
+ int web_view_instance_id, |
base::WeakPtr<IPC::Sender> ipc_sender) { |
+ |
if (!IsWebRequestEvent(event_name)) |
return false; |
@@ -1150,8 +1159,9 @@ bool ExtensionWebRequestEventRouter::AddEventListener( |
listener.filter = filter; |
listener.extra_info_spec = extra_info_spec; |
listener.ipc_sender = ipc_sender; |
- listener.target_process_id = target_process_id; |
- listener.target_route_id = target_route_id; |
+ listener.caller_process_id = caller_process_id; |
+ listener.caller_routing_id = caller_routing_id; |
+ listener.web_view_instance_id = web_view_instance_id; |
if (listeners_[profile][event_name].count(listener) != 0u) { |
// This is likely an abuse of the API by a malicious extension. |
@@ -1197,6 +1207,44 @@ void ExtensionWebRequestEventRouter::RemoveEventListener( |
helpers::ClearCacheOnNavigation(); |
} |
+void ExtensionWebRequestEventRouter::RemoveWebViewEventListeners( |
Matt Perry
2013/02/06 22:40:24
Are you sure this is necessary? When a context goe
Fady Samuel
2013/05/15 21:58:53
Yes, this is necessary because the listeners a <we
Matt Perry
2013/05/16 21:16:38
I don't understand what you mean.
To clarify my c
|
+ void* profile, |
+ const std::string& extension_id, |
+ int embedder_process_id, |
+ int embedder_routing_id, |
+ int web_view_instance_id) { |
+ // Iterate over all listeners of all WebRequest events to delete |
+ // any listeners that belong to the provided <webview>. |
+ bool found_listeners = false; |
+ ListenerMapForProfile& map_for_profile = listeners_[profile]; |
+ for (ListenerMapForProfile::iterator event_iter = map_for_profile.begin(); |
+ event_iter != map_for_profile.end(); ++event_iter) { |
+ std::vector<EventListener> listeners_to_delete; |
+ const std::string& event_name = event_iter->first; |
+ std::set<EventListener>& listeners = event_iter->second; |
+ for (std::set<EventListener>::iterator listener_iter = listeners.begin(); |
+ listener_iter != listeners.end(); ++listener_iter) { |
+ const EventListener& listener = *listener_iter; |
+ if (listener.caller_process_id == embedder_process_id && |
+ listener.caller_routing_id == embedder_routing_id && |
+ listener.web_view_instance_id == web_view_instance_id) |
+ listeners_to_delete.push_back(listener); |
+ } |
+ for (size_t i = 0; i < listeners_to_delete.size(); ++i) { |
+ found_listeners = true; |
+ EventListener& listener = listeners_to_delete[i]; |
+ listeners.erase(listeners_to_delete[i]); |
+ // Unblock any request that this event listener may have been blocking. |
+ for (std::set<uint64>::iterator it = listener.blocked_requests.begin(); |
+ it != listener.blocked_requests.end(); ++it) { |
+ DecrementBlockCount(profile, extension_id, event_name, *it, NULL); |
+ } |
+ } |
+ } |
+ if (found_listeners) |
+ helpers::ClearCacheOnNavigation(); |
+} |
+ |
void ExtensionWebRequestEventRouter::OnOTRProfileCreated( |
void* original_profile, void* otr_profile) { |
cross_profile_map_[original_profile] = otr_profile; |
@@ -1274,10 +1322,15 @@ void ExtensionWebRequestEventRouter::GetMatchingListenersImpl( |
int* extra_info_spec, |
std::vector<const ExtensionWebRequestEventRouter::EventListener*>* |
matching_listeners) { |
+ std::string web_request_event_name(event_name); |
ExtensionRendererState::WebViewInfo web_view_info; |
bool is_guest = ExtensionRendererState::GetInstance()-> |
GetWebViewInfo(render_process_host_id, routing_id, &web_view_info); |
- std::set<EventListener>& listeners = listeners_[profile][event_name]; |
+ if (is_guest) |
+ web_request_event_name.replace(0, sizeof(kWebRequest) - 1, kWebView); |
+ |
+ std::set<EventListener>& listeners = |
+ listeners_[profile][web_request_event_name]; |
for (std::set<EventListener>::iterator it = listeners.begin(); |
it != listeners.end(); ++it) { |
if (!it->ipc_sender.get()) { |
@@ -1286,8 +1339,10 @@ void ExtensionWebRequestEventRouter::GetMatchingListenersImpl( |
continue; |
} |
- if (is_guest && (it->target_process_id != render_process_host_id|| |
- it->target_route_id != routing_id)) |
+ if (is_guest && |
+ (it->caller_process_id != web_view_info.embedder_process_id || |
+ it->caller_routing_id != web_view_info.embedder_routing_id || |
+ it->web_view_instance_id != web_view_info.web_view_instance_id)) |
continue; |
if (!it->filter.urls.is_empty() && !it->filter.urls.MatchesURL(url)) |
@@ -1301,7 +1356,7 @@ void ExtensionWebRequestEventRouter::GetMatchingListenersImpl( |
resource_type) == it->filter.types.end()) |
continue; |
- if (!WebRequestPermissions::CanExtensionAccessURL( |
+ if (!is_guest && !WebRequestPermissions::CanExtensionAccessURL( |
extension_info_map, it->extension_id, url, crosses_incognito, true)) |
continue; |
@@ -1826,14 +1881,21 @@ bool WebRequestAddEventListener::RunImpl() { |
std::string sub_event_name; |
EXTENSION_FUNCTION_VALIDATE(args_->GetString(4, &sub_event_name)); |
+ int web_view_instance_id = 0; |
+ EXTENSION_FUNCTION_VALIDATE(args_->GetInteger(5, &web_view_instance_id)); |
+ |
+ int caller_process_id = ipc_sender()->render_process_id(); |
+ int caller_routing_id = routing_id(); |
+ |
const Extension* extension = |
extension_info_map()->extensions().GetByID(extension_id()); |
std::string extension_name = extension ? extension->name() : extension_id(); |
+ bool is_guest = web_view_instance_id != 0; |
// We check automatically whether the extension has the 'webRequest' |
// permission. For blocking calls we require the additional permission |
// 'webRequestBlocking'. |
- if ((extra_info_spec & |
+ if ((!is_guest && extra_info_spec & |
(ExtensionWebRequestEventRouter::ExtraInfoSpec::BLOCKING | |
ExtensionWebRequestEventRouter::ExtraInfoSpec::ASYNC_BLOCKING)) && |
!extension->HasAPIPermission( |
@@ -1848,7 +1910,7 @@ bool WebRequestAddEventListener::RunImpl() { |
// http://www.example.com/bar/*. |
// For this reason we do only a coarse check here to warn the extension |
// developer if he does something obviously wrong. |
- if (extension->GetEffectiveHostPermissions().is_empty()) { |
+ if (!is_guest && extension->GetEffectiveHostPermissions().is_empty()) { |
error_ = keys::kHostPermissionsRequired; |
return false; |
} |
@@ -1856,8 +1918,9 @@ bool WebRequestAddEventListener::RunImpl() { |
bool success = |
ExtensionWebRequestEventRouter::GetInstance()->AddEventListener( |
profile_id(), extension_id(), extension_name, |
- event_name, sub_event_name, filter, |
- extra_info_spec, -1, -1, ipc_sender_weak()); |
+ event_name, sub_event_name, filter, extra_info_spec, |
+ caller_process_id, caller_routing_id, web_view_instance_id, |
+ ipc_sender_weak()); |
EXTENSION_FUNCTION_VALIDATE(success); |
helpers::ClearCacheOnNavigation(); |