OLD | NEW |
1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. |
2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
4 | 4 |
5 #include "extensions/browser/api/web_request/web_request_api.h" | 5 #include "extensions/browser/api/web_request/web_request_api.h" |
6 | 6 |
7 #include <stddef.h> | 7 #include <stddef.h> |
8 | 8 |
9 #include <algorithm> | 9 #include <algorithm> |
10 #include <memory> | 10 #include <memory> |
(...skipping 379 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
390 std::string sub_event_name; | 390 std::string sub_event_name; |
391 RequestFilter filter; | 391 RequestFilter filter; |
392 int extra_info_spec; | 392 int extra_info_spec; |
393 int embedder_process_id; | 393 int embedder_process_id; |
394 int web_view_instance_id; | 394 int web_view_instance_id; |
395 base::WeakPtr<IPC::Sender> ipc_sender; | 395 base::WeakPtr<IPC::Sender> ipc_sender; |
396 mutable std::set<uint64_t> blocked_requests; | 396 mutable std::set<uint64_t> blocked_requests; |
397 | 397 |
398 // Comparator to work with std::set. | 398 // Comparator to work with std::set. |
399 bool operator<(const EventListener& that) const { | 399 bool operator<(const EventListener& that) const { |
400 return std::tie(extension_id, sub_event_name, web_view_instance_id, | 400 if (extension_id != that.extension_id) |
401 embedder_process_id) < | 401 return extension_id < that.extension_id; |
402 std::tie(that.extension_id, that.sub_event_name, | 402 |
403 that.web_view_instance_id, that.embedder_process_id); | 403 if (sub_event_name != that.sub_event_name) |
| 404 return sub_event_name < that.sub_event_name; |
| 405 |
| 406 if (web_view_instance_id != that.web_view_instance_id) |
| 407 return web_view_instance_id < that.web_view_instance_id; |
| 408 |
| 409 if (web_view_instance_id == 0) { |
| 410 // Do not filter by process ID for non-webviews, because this comparator |
| 411 // is also used to find and remove an event listener when an extension is |
| 412 // unloaded. At this point, the event listener cannot be mapped back to |
| 413 // the original process, so 0 is used instead of the actual process ID. |
| 414 if (embedder_process_id == 0 || that.embedder_process_id == 0) |
| 415 return false; |
| 416 } |
| 417 |
| 418 if (embedder_process_id != that.embedder_process_id) |
| 419 return embedder_process_id < that.embedder_process_id; |
| 420 |
| 421 return false; |
404 } | 422 } |
405 | 423 |
406 EventListener() | 424 EventListener() |
407 : histogram_value(events::UNKNOWN), | 425 : histogram_value(events::UNKNOWN), |
408 extra_info_spec(0), | 426 extra_info_spec(0), |
409 embedder_process_id(0), | 427 embedder_process_id(0), |
410 web_view_instance_id(0) {} | 428 web_view_instance_id(0) {} |
411 }; | 429 }; |
412 | 430 |
413 // Contains info about requests that are blocked waiting for a response from | 431 // Contains info about requests that are blocked waiting for a response from |
(...skipping 708 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1122 } | 1140 } |
1123 | 1141 |
1124 if (ContainsKey(listeners_[browser_context][event_name], listener)) { | 1142 if (ContainsKey(listeners_[browser_context][event_name], listener)) { |
1125 // This is likely an abuse of the API by a malicious extension. | 1143 // This is likely an abuse of the API by a malicious extension. |
1126 return false; | 1144 return false; |
1127 } | 1145 } |
1128 listeners_[browser_context][event_name].insert(listener); | 1146 listeners_[browser_context][event_name].insert(listener); |
1129 return true; | 1147 return true; |
1130 } | 1148 } |
1131 | 1149 |
1132 int ExtensionWebRequestEventRouter::GetListenerCountForTesting( | |
1133 void* browser_context, | |
1134 const std::string& event_name) { | |
1135 return listeners_[browser_context][event_name].size(); | |
1136 } | |
1137 | |
1138 void ExtensionWebRequestEventRouter::RemoveEventListener( | 1150 void ExtensionWebRequestEventRouter::RemoveEventListener( |
1139 void* browser_context, | 1151 void* browser_context, |
1140 const std::string& extension_id, | 1152 const std::string& extension_id, |
1141 const std::string& sub_event_name, | 1153 const std::string& sub_event_name, |
1142 int embedder_process_id, | 1154 int embedder_process_id, |
1143 int web_view_instance_id) { | 1155 int web_view_instance_id) { |
1144 std::string event_name = EventRouter::GetBaseEventName(sub_event_name); | 1156 std::string event_name = EventRouter::GetBaseEventName(sub_event_name); |
1145 DCHECK(IsWebRequestEvent(event_name)); | 1157 DCHECK(IsWebRequestEvent(event_name)); |
1146 | 1158 |
1147 std::set<EventListener>& event_listeners = | |
1148 listeners_[browser_context][event_name]; | |
1149 | |
1150 EventListener listener; | 1159 EventListener listener; |
1151 listener.extension_id = extension_id; | 1160 listener.extension_id = extension_id; |
1152 listener.sub_event_name = sub_event_name; | 1161 listener.sub_event_name = sub_event_name; |
| 1162 listener.embedder_process_id = embedder_process_id; |
| 1163 listener.web_view_instance_id = web_view_instance_id; |
1153 | 1164 |
1154 if (web_view_instance_id != 0) { | 1165 std::set<EventListener>& event_listeners = |
1155 listener.embedder_process_id = embedder_process_id; | 1166 listeners_[browser_context][event_name]; |
1156 listener.web_view_instance_id = web_view_instance_id; | |
1157 } else { | |
1158 for (const EventListener& l : event_listeners) { | |
1159 if (l.extension_id == extension_id && l.sub_event_name == sub_event_name) | |
1160 listener.embedder_process_id = l.embedder_process_id; | |
1161 } | |
1162 } | |
1163 | |
1164 // It's possible for AddEventListener to fail asynchronously. In that case, | 1167 // It's possible for AddEventListener to fail asynchronously. In that case, |
1165 // the renderer believes the listener exists, while the browser does not. | 1168 // the renderer believes the listener exists, while the browser does not. |
1166 // Ignore a RemoveEventListener in that case. | 1169 // Ignore a RemoveEventListener in that case. |
1167 std::set<EventListener>::const_iterator it = event_listeners.find(listener); | 1170 std::set<EventListener>::const_iterator it = event_listeners.find(listener); |
1168 if (it == event_listeners.end()) | 1171 if (it == event_listeners.end()) |
1169 return; | 1172 return; |
1170 | 1173 |
| 1174 #if defined(OS_WIN) |
| 1175 // Debugging https://crbug.com/589735 |
| 1176 // Please post crash reports at the following lines to the above issue. |
| 1177 unsigned event_listener_count = event_listeners.count(listener); |
| 1178 CHECK_GE(event_listener_count, 0u); |
| 1179 CHECK_GE(event_listener_count, 1u); |
| 1180 CHECK_LE(event_listener_count, 2u); |
| 1181 CHECK_EQ(event_listener_count, 1u); |
| 1182 CHECK(content::BrowserThread::CurrentlyOn(content::BrowserThread::IO)); |
| 1183 #endif // OS_WIN |
1171 CHECK_EQ(event_listeners.count(listener), 1u) << | 1184 CHECK_EQ(event_listeners.count(listener), 1u) << |
1172 "extension=" << extension_id << " event=" << event_name; | 1185 "extension=" << extension_id << " event=" << event_name; |
1173 | 1186 |
1174 // Unblock any request that this event listener may have been blocking. | 1187 // Unblock any request that this event listener may have been blocking. |
1175 for (uint64_t id : it->blocked_requests) | 1188 for (uint64_t id : it->blocked_requests) |
1176 DecrementBlockCount(browser_context, extension_id, event_name, id, NULL); | 1189 DecrementBlockCount(browser_context, extension_id, event_name, id, NULL); |
1177 | 1190 |
1178 event_listeners.erase(listener); | 1191 event_listeners.erase(listener); |
1179 | 1192 |
1180 helpers::ClearCacheOnNavigation(); | 1193 helpers::ClearCacheOnNavigation(); |
(...skipping 1071 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2252 // Continue gracefully. | 2265 // Continue gracefully. |
2253 RunSync(); | 2266 RunSync(); |
2254 } | 2267 } |
2255 | 2268 |
2256 bool WebRequestHandlerBehaviorChangedFunction::RunSync() { | 2269 bool WebRequestHandlerBehaviorChangedFunction::RunSync() { |
2257 helpers::ClearCacheOnNavigation(); | 2270 helpers::ClearCacheOnNavigation(); |
2258 return true; | 2271 return true; |
2259 } | 2272 } |
2260 | 2273 |
2261 } // namespace extensions | 2274 } // namespace extensions |
OLD | NEW |