| 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;
|
| +}
|
|
|