Index: chrome/browser/external_protocol/external_protocol_handler.cc |
diff --git a/chrome/browser/external_protocol/external_protocol_handler.cc b/chrome/browser/external_protocol/external_protocol_handler.cc |
index 78334d9e362f9eb323201965f96a44430301fb9e..f6f3c0b1d998e743769e645c55ccfd52d999570a 100644 |
--- a/chrome/browser/external_protocol/external_protocol_handler.cc |
+++ b/chrome/browser/external_protocol/external_protocol_handler.cc |
@@ -27,6 +27,11 @@ |
using content::BrowserThread; |
+// Whether we accept requests for launching external protocols. This is set to |
+// false every time an external protocol is requested, and set back to true on |
+// each user gesture. This variable should only be accessed from the UI thread. |
+static bool g_accept_requests = true; |
+ |
namespace { |
// Functions enabling unit testing. Using a NULL delegate will use the default |
@@ -44,13 +49,11 @@ ShellIntegration::DefaultProtocolClientWorker* CreateShellWorker( |
ExternalProtocolHandler::BlockState GetBlockStateWithDelegate( |
const std::string& scheme, |
- ExternalProtocolHandler::Delegate* delegate, |
- bool initiated_by_user_gesture) { |
+ ExternalProtocolHandler::Delegate* delegate) { |
if (!delegate) |
- return ExternalProtocolHandler::GetBlockState(scheme, |
- initiated_by_user_gesture); |
+ return ExternalProtocolHandler::GetBlockState(scheme); |
- return delegate->GetBlockState(scheme, initiated_by_user_gesture); |
+ return delegate->GetBlockState(scheme); |
} |
void RunExternalProtocolDialogWithDelegate( |
@@ -200,9 +203,9 @@ void ExternalProtocolHandler::PrepopulateDictionary( |
// static |
ExternalProtocolHandler::BlockState ExternalProtocolHandler::GetBlockState( |
- const std::string& scheme, |
- bool initiated_by_user_gesture) { |
- if (!initiated_by_user_gesture) |
+ const std::string& scheme) { |
+ // If we are being carpet bombed, block the request. |
+ if (!g_accept_requests) |
return BLOCK; |
if (scheme.length() == 1) { |
@@ -249,27 +252,26 @@ void ExternalProtocolHandler::SetBlockState(const std::string& scheme, |
} |
// static |
-void ExternalProtocolHandler::LaunchUrlWithDelegate( |
- const GURL& url, |
- int render_process_host_id, |
- int tab_contents_id, |
- Delegate* delegate, |
- bool initiated_by_user_gesture) { |
+void ExternalProtocolHandler::LaunchUrlWithDelegate(const GURL& url, |
+ int render_process_host_id, |
+ int tab_contents_id, |
+ Delegate* delegate) { |
DCHECK(base::MessageLoopForUI::IsCurrent()); |
// Escape the input scheme to be sure that the command does not |
// have parameters unexpected by the external program. |
std::string escaped_url_string = net::EscapeExternalHandlerValue(url.spec()); |
GURL escaped_url(escaped_url_string); |
- BlockState block_state = GetBlockStateWithDelegate(escaped_url.scheme(), |
- delegate, |
- initiated_by_user_gesture); |
+ BlockState block_state = |
+ GetBlockStateWithDelegate(escaped_url.scheme(), delegate); |
if (block_state == BLOCK) { |
if (delegate) |
delegate->BlockRequest(); |
return; |
} |
+ g_accept_requests = false; |
+ |
// The worker creates tasks with references to itself and puts them into |
// message loops. When no tasks are left it will delete the observer and |
// eventually be deleted itself. |
@@ -306,3 +308,9 @@ void ExternalProtocolHandler::LaunchUrlWithoutSecurityCheck( |
void ExternalProtocolHandler::RegisterPrefs(PrefRegistrySimple* registry) { |
registry->RegisterDictionaryPref(prefs::kExcludedSchemes); |
} |
+ |
+// static |
+void ExternalProtocolHandler::PermitLaunchUrl() { |
+ DCHECK(base::MessageLoopForUI::IsCurrent()); |
+ g_accept_requests = true; |
+} |