Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(28)

Side by Side Diff: extensions/browser/api/web_request/web_request_api.cc

Issue 864893003: <webview>: Fix WebRequest API crash (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Fixed tests Created 5 years, 11 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
« no previous file with comments | « chrome/browser/extensions/api/web_request/web_request_api_unittest.cc ('k') | no next file » | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
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 <algorithm> 7 #include <algorithm>
8 8
9 #include "base/bind.h" 9 #include "base/bind.h"
10 #include "base/bind_helpers.h" 10 #include "base/bind_helpers.h"
(...skipping 440 matching lines...) Expand 10 before | Expand all | Expand 10 after
451 // NOTE(benjhayden) New APIs should not use this sub_event_name trick! It does 451 // NOTE(benjhayden) New APIs should not use this sub_event_name trick! It does
452 // not play well with event pages. See downloads.onDeterminingFilename and 452 // not play well with event pages. See downloads.onDeterminingFilename and
453 // ExtensionDownloadsEventRouter for an alternative approach. 453 // ExtensionDownloadsEventRouter for an alternative approach.
454 struct ExtensionWebRequestEventRouter::EventListener { 454 struct ExtensionWebRequestEventRouter::EventListener {
455 std::string extension_id; 455 std::string extension_id;
456 std::string extension_name; 456 std::string extension_name;
457 std::string sub_event_name; 457 std::string sub_event_name;
458 RequestFilter filter; 458 RequestFilter filter;
459 int extra_info_spec; 459 int extra_info_spec;
460 int embedder_process_id; 460 int embedder_process_id;
461 int webview_instance_id; 461 int web_view_instance_id;
462 base::WeakPtr<IPC::Sender> ipc_sender; 462 base::WeakPtr<IPC::Sender> ipc_sender;
463 mutable std::set<uint64> blocked_requests; 463 mutable std::set<uint64> blocked_requests;
464 464
465 // Comparator to work with std::set. 465 // Comparator to work with std::set.
466 bool operator<(const EventListener& that) const { 466 bool operator<(const EventListener& that) const {
467 if (extension_id < that.extension_id) 467 if (extension_id != that.extension_id)
468 return true; 468 return extension_id < that.extension_id;
469 if (extension_id == that.extension_id && 469
470 sub_event_name < that.sub_event_name) 470 if (sub_event_name != that.sub_event_name)
471 return true; 471 return sub_event_name < that.sub_event_name;
472
473 if (embedder_process_id != that.embedder_process_id)
474 return embedder_process_id < that.embedder_process_id;
475
476 if (web_view_instance_id != that.web_view_instance_id)
477 return web_view_instance_id < that.web_view_instance_id;
478
472 return false; 479 return false;
473 } 480 }
474 481
475 EventListener() : extra_info_spec(0) {} 482 EventListener() :
483 extra_info_spec(0),
484 embedder_process_id(0),
485 web_view_instance_id(0) {}
476 }; 486 };
477 487
478 // Contains info about requests that are blocked waiting for a response from 488 // Contains info about requests that are blocked waiting for a response from
479 // an extension. 489 // an extension.
480 struct ExtensionWebRequestEventRouter::BlockedRequest { 490 struct ExtensionWebRequestEventRouter::BlockedRequest {
481 // The request that is being blocked. 491 // The request that is being blocked.
482 net::URLRequest* request; 492 net::URLRequest* request;
483 493
484 // Whether the request originates from an incognito tab. 494 // Whether the request originates from an incognito tab.
485 bool is_incognito; 495 bool is_incognito;
(...skipping 786 matching lines...) Expand 10 before | Expand all | Expand 10 after
1272 1282
1273 bool ExtensionWebRequestEventRouter::AddEventListener( 1283 bool ExtensionWebRequestEventRouter::AddEventListener(
1274 void* browser_context, 1284 void* browser_context,
1275 const std::string& extension_id, 1285 const std::string& extension_id,
1276 const std::string& extension_name, 1286 const std::string& extension_name,
1277 const std::string& event_name, 1287 const std::string& event_name,
1278 const std::string& sub_event_name, 1288 const std::string& sub_event_name,
1279 const RequestFilter& filter, 1289 const RequestFilter& filter,
1280 int extra_info_spec, 1290 int extra_info_spec,
1281 int embedder_process_id, 1291 int embedder_process_id,
1282 int webview_instance_id, 1292 int web_view_instance_id,
1283 base::WeakPtr<IPC::Sender> ipc_sender) { 1293 base::WeakPtr<IPC::Sender> ipc_sender) {
1284 if (!IsWebRequestEvent(event_name)) 1294 if (!IsWebRequestEvent(event_name))
1285 return false; 1295 return false;
1286 1296
1287 EventListener listener; 1297 EventListener listener;
1288 listener.extension_id = extension_id; 1298 listener.extension_id = extension_id;
1289 listener.extension_name = extension_name; 1299 listener.extension_name = extension_name;
1290 listener.sub_event_name = sub_event_name; 1300 listener.sub_event_name = sub_event_name;
1291 listener.filter = filter; 1301 listener.filter = filter;
1292 listener.extra_info_spec = extra_info_spec; 1302 listener.extra_info_spec = extra_info_spec;
1293 listener.ipc_sender = ipc_sender; 1303 listener.ipc_sender = ipc_sender;
1294 listener.embedder_process_id = embedder_process_id; 1304 listener.embedder_process_id = embedder_process_id;
1295 listener.webview_instance_id = webview_instance_id; 1305 listener.web_view_instance_id = web_view_instance_id;
1296 if (listener.webview_instance_id) { 1306 if (listener.web_view_instance_id) {
1297 content::RecordAction( 1307 content::RecordAction(
1298 base::UserMetricsAction("WebView.WebRequest.AddListener")); 1308 base::UserMetricsAction("WebView.WebRequest.AddListener"));
1299 } 1309 }
1300 1310
1301 if (listeners_[browser_context][event_name].count(listener) != 0u) { 1311 if (listeners_[browser_context][event_name].count(listener) != 0u) {
1302 // This is likely an abuse of the API by a malicious extension. 1312 // This is likely an abuse of the API by a malicious extension.
1303 return false; 1313 return false;
1304 } 1314 }
1305 listeners_[browser_context][event_name].insert(listener); 1315 listeners_[browser_context][event_name].insert(listener);
1306 return true; 1316 return true;
(...skipping 30 matching lines...) Expand all
1337 1347
1338 listeners_[browser_context][event_name].erase(listener); 1348 listeners_[browser_context][event_name].erase(listener);
1339 1349
1340 helpers::ClearCacheOnNavigation(); 1350 helpers::ClearCacheOnNavigation();
1341 } 1351 }
1342 1352
1343 void ExtensionWebRequestEventRouter::RemoveWebViewEventListeners( 1353 void ExtensionWebRequestEventRouter::RemoveWebViewEventListeners(
1344 void* browser_context, 1354 void* browser_context,
1345 const std::string& extension_id, 1355 const std::string& extension_id,
1346 int embedder_process_id, 1356 int embedder_process_id,
1347 int webview_instance_id) { 1357 int web_view_instance_id) {
1348 // Iterate over all listeners of all WebRequest events to delete 1358 // Iterate over all listeners of all WebRequest events to delete
1349 // any listeners that belong to the provided <webview>. 1359 // any listeners that belong to the provided <webview>.
1350 ListenerMapForBrowserContext& map_for_browser_context = 1360 ListenerMapForBrowserContext& map_for_browser_context =
1351 listeners_[browser_context]; 1361 listeners_[browser_context];
1352 for (ListenerMapForBrowserContext::iterator event_iter = 1362 for (ListenerMapForBrowserContext::iterator event_iter =
1353 map_for_browser_context.begin(); 1363 map_for_browser_context.begin();
1354 event_iter != map_for_browser_context.end(); ++event_iter) { 1364 event_iter != map_for_browser_context.end(); ++event_iter) {
1355 std::vector<EventListener> listeners_to_delete; 1365 std::vector<EventListener> listeners_to_delete;
1356 std::set<EventListener>& listeners = event_iter->second; 1366 std::set<EventListener>& listeners = event_iter->second;
1357 for (std::set<EventListener>::iterator listener_iter = listeners.begin(); 1367 for (std::set<EventListener>::iterator listener_iter = listeners.begin();
1358 listener_iter != listeners.end(); ++listener_iter) { 1368 listener_iter != listeners.end(); ++listener_iter) {
1359 const EventListener& listener = *listener_iter; 1369 const EventListener& listener = *listener_iter;
1360 if (listener.embedder_process_id == embedder_process_id && 1370 if (listener.embedder_process_id == embedder_process_id &&
1361 listener.webview_instance_id == webview_instance_id) 1371 listener.web_view_instance_id == web_view_instance_id)
1362 listeners_to_delete.push_back(listener); 1372 listeners_to_delete.push_back(listener);
1363 } 1373 }
1364 for (size_t i = 0; i < listeners_to_delete.size(); ++i) { 1374 for (size_t i = 0; i < listeners_to_delete.size(); ++i) {
1365 EventListener& listener = listeners_to_delete[i]; 1375 EventListener& listener = listeners_to_delete[i];
1366 content::BrowserThread::PostTask( 1376 content::BrowserThread::PostTask(
1367 content::BrowserThread::UI, 1377 content::BrowserThread::UI,
1368 FROM_HERE, 1378 FROM_HERE,
1369 base::Bind(&RemoveEventListenerOnUI, 1379 base::Bind(&RemoveEventListenerOnUI,
1370 browser_context, 1380 browser_context,
1371 listener.sub_event_name, 1381 listener.sub_event_name,
(...skipping 103 matching lines...) Expand 10 before | Expand all | Expand 10 after
1475 for (std::set<EventListener>::iterator it = listeners.begin(); 1485 for (std::set<EventListener>::iterator it = listeners.begin();
1476 it != listeners.end(); ++it) { 1486 it != listeners.end(); ++it) {
1477 if (!it->ipc_sender.get()) { 1487 if (!it->ipc_sender.get()) {
1478 // The IPC sender has been deleted. This listener will be removed soon 1488 // The IPC sender has been deleted. This listener will be removed soon
1479 // via a call to RemoveEventListener. For now, just skip it. 1489 // via a call to RemoveEventListener. For now, just skip it.
1480 continue; 1490 continue;
1481 } 1491 }
1482 1492
1483 if (is_web_view_guest && 1493 if (is_web_view_guest &&
1484 (it->embedder_process_id != web_view_info.embedder_process_id || 1494 (it->embedder_process_id != web_view_info.embedder_process_id ||
1485 it->webview_instance_id != web_view_info.instance_id)) 1495 it->web_view_instance_id != web_view_info.instance_id))
1486 continue; 1496 continue;
1487 1497
1488 if (!it->filter.urls.is_empty() && !it->filter.urls.MatchesURL(url)) 1498 if (!it->filter.urls.is_empty() && !it->filter.urls.MatchesURL(url))
1489 continue; 1499 continue;
1490 if (web_request_event_router_delegate_ && 1500 if (web_request_event_router_delegate_ &&
1491 web_request_event_router_delegate_->OnGetMatchingListenersImplCheck( 1501 web_request_event_router_delegate_->OnGetMatchingListenersImplCheck(
1492 it->filter.tab_id, it->filter.window_id, request)) 1502 it->filter.tab_id, it->filter.window_id, request))
1493 continue; 1503 continue;
1494 if (!it->filter.types.empty() && 1504 if (!it->filter.types.empty() &&
1495 std::find(it->filter.types.begin(), it->filter.types.end(), 1505 std::find(it->filter.types.begin(), it->filter.types.end(),
(...skipping 702 matching lines...) Expand 10 before | Expand all | Expand 10 after
2198 ExtensionWebRequestEventRouter::ExtraInfoSpec::InitFromValue( 2208 ExtensionWebRequestEventRouter::ExtraInfoSpec::InitFromValue(
2199 *value, &extra_info_spec)); 2209 *value, &extra_info_spec));
2200 } 2210 }
2201 2211
2202 std::string event_name; 2212 std::string event_name;
2203 EXTENSION_FUNCTION_VALIDATE(args_->GetString(3, &event_name)); 2213 EXTENSION_FUNCTION_VALIDATE(args_->GetString(3, &event_name));
2204 2214
2205 std::string sub_event_name; 2215 std::string sub_event_name;
2206 EXTENSION_FUNCTION_VALIDATE(args_->GetString(4, &sub_event_name)); 2216 EXTENSION_FUNCTION_VALIDATE(args_->GetString(4, &sub_event_name));
2207 2217
2208 int webview_instance_id = 0; 2218 int web_view_instance_id = 0;
2209 EXTENSION_FUNCTION_VALIDATE(args_->GetInteger(5, &webview_instance_id)); 2219 EXTENSION_FUNCTION_VALIDATE(args_->GetInteger(5, &web_view_instance_id));
2210 2220
2211 base::WeakPtr<extensions::ExtensionMessageFilter> ipc_sender = 2221 base::WeakPtr<extensions::ExtensionMessageFilter> ipc_sender =
2212 ipc_sender_weak(); 2222 ipc_sender_weak();
2213 int embedder_process_id = 2223 int embedder_process_id =
2214 ipc_sender.get() ? ipc_sender->render_process_id() : -1; 2224 ipc_sender.get() && web_view_instance_id > 0 ?
2225 ipc_sender->render_process_id() : 0;
2215 2226
2216 const Extension* extension = 2227 const Extension* extension =
2217 extension_info_map()->extensions().GetByID(extension_id_safe()); 2228 extension_info_map()->extensions().GetByID(extension_id_safe());
2218 std::string extension_name = 2229 std::string extension_name =
2219 extension ? extension->name() : extension_id_safe(); 2230 extension ? extension->name() : extension_id_safe();
2220 2231
2221 if (webview_instance_id == 0) { 2232 if (!web_view_instance_id) {
2222 // We check automatically whether the extension has the 'webRequest' 2233 // We check automatically whether the extension has the 'webRequest'
2223 // permission. For blocking calls we require the additional permission 2234 // permission. For blocking calls we require the additional permission
2224 // 'webRequestBlocking'. 2235 // 'webRequestBlocking'.
2225 if ((extra_info_spec & 2236 if ((extra_info_spec &
2226 (ExtensionWebRequestEventRouter::ExtraInfoSpec::BLOCKING | 2237 (ExtensionWebRequestEventRouter::ExtraInfoSpec::BLOCKING |
2227 ExtensionWebRequestEventRouter::ExtraInfoSpec::ASYNC_BLOCKING)) && 2238 ExtensionWebRequestEventRouter::ExtraInfoSpec::ASYNC_BLOCKING)) &&
2228 !extension->permissions_data()->HasAPIPermission( 2239 !extension->permissions_data()->HasAPIPermission(
2229 extensions::APIPermission::kWebRequestBlocking)) { 2240 extensions::APIPermission::kWebRequestBlocking)) {
2230 error_ = keys::kBlockingPermissionRequired; 2241 error_ = keys::kBlockingPermissionRequired;
2231 return false; 2242 return false;
(...skipping 10 matching lines...) Expand all
2242 .is_empty()) { 2253 .is_empty()) {
2243 error_ = keys::kHostPermissionsRequired; 2254 error_ = keys::kHostPermissionsRequired;
2244 return false; 2255 return false;
2245 } 2256 }
2246 } 2257 }
2247 2258
2248 bool success = 2259 bool success =
2249 ExtensionWebRequestEventRouter::GetInstance()->AddEventListener( 2260 ExtensionWebRequestEventRouter::GetInstance()->AddEventListener(
2250 profile_id(), extension_id_safe(), extension_name, 2261 profile_id(), extension_id_safe(), extension_name,
2251 event_name, sub_event_name, filter, extra_info_spec, 2262 event_name, sub_event_name, filter, extra_info_spec,
2252 embedder_process_id, webview_instance_id, ipc_sender_weak()); 2263 embedder_process_id, web_view_instance_id, ipc_sender_weak());
2253 EXTENSION_FUNCTION_VALIDATE(success); 2264 EXTENSION_FUNCTION_VALIDATE(success);
2254 2265
2255 helpers::ClearCacheOnNavigation(); 2266 helpers::ClearCacheOnNavigation();
2256 2267
2257 if (!extension_id_safe().empty()) { 2268 if (!extension_id_safe().empty()) {
2258 BrowserThread::PostTask(BrowserThread::UI, FROM_HERE, 2269 BrowserThread::PostTask(BrowserThread::UI, FROM_HERE,
2259 base::Bind(&helpers::NotifyWebRequestAPIUsed, 2270 base::Bind(&helpers::NotifyWebRequestAPIUsed,
2260 profile_id(), extension_id_safe())); 2271 profile_id(), extension_id_safe()));
2261 } 2272 }
2262 2273
(...skipping 192 matching lines...) Expand 10 before | Expand all | Expand 10 after
2455 base::Bind(&WarningService::NotifyWarningsOnUI, profile_id(), warnings)); 2466 base::Bind(&WarningService::NotifyWarningsOnUI, profile_id(), warnings));
2456 2467
2457 // Continue gracefully. 2468 // Continue gracefully.
2458 RunSync(); 2469 RunSync();
2459 } 2470 }
2460 2471
2461 bool WebRequestHandlerBehaviorChangedFunction::RunSync() { 2472 bool WebRequestHandlerBehaviorChangedFunction::RunSync() {
2462 helpers::ClearCacheOnNavigation(); 2473 helpers::ClearCacheOnNavigation();
2463 return true; 2474 return true;
2464 } 2475 }
OLDNEW
« no previous file with comments | « chrome/browser/extensions/api/web_request/web_request_api_unittest.cc ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698