diff --git a/libcef/browser/browser_platform_delegate.cc b/libcef/browser/browser_platform_delegate.cc index d269b9d98..58919cb95 100644 --- a/libcef/browser/browser_platform_delegate.cc +++ b/libcef/browser/browser_platform_delegate.cc @@ -5,12 +5,30 @@ #include "libcef/browser/browser_platform_delegate.h" #include "libcef/browser/alloy/alloy_browser_host_impl.h" +#include "libcef/browser/thread_util.h" #include "base/logging.h" +#include "chrome/browser/platform_util.h" +#include "chrome/browser/shell_integration.h" #include "content/public/browser/render_view_host.h" #include "content/public/browser/render_widget_host.h" #include "content/public/browser/render_widget_host_view.h" +namespace { + +void ExecuteExternalProtocol(const GURL& url) { + CEF_REQUIRE_BLOCKING(); + + // Check that an application is associated with the scheme. + if (shell_integration::GetApplicationNameForScheme(url).empty()) { + return; + } + + CEF_POST_TASK(TID_UI, base::BindOnce(&platform_util::OpenExternal, url)); +} + +} // namespace + CefBrowserPlatformDelegate::CefBrowserPlatformDelegate() = default; CefBrowserPlatformDelegate::~CefBrowserPlatformDelegate() { @@ -225,6 +243,11 @@ bool CefBrowserPlatformDelegate::IsNeverComposited( return false; } +// static +void CefBrowserPlatformDelegate::HandleExternalProtocol(const GURL& url) { + CEF_POST_USER_VISIBLE_TASK(base::BindOnce(ExecuteExternalProtocol, url)); +} + CefEventHandle CefBrowserPlatformDelegate::GetEventHandle( const content::NativeWebKeyboardEvent& event) const { DCHECK(false); diff --git a/libcef/browser/native/browser_platform_delegate_native_linux.cc b/libcef/browser/native/browser_platform_delegate_native_linux.cc index fb22d77a4..400c3799c 100644 --- a/libcef/browser/native/browser_platform_delegate_native_linux.cc +++ b/libcef/browser/native/browser_platform_delegate_native_linux.cc @@ -233,9 +233,6 @@ bool CefBrowserPlatformDelegateNativeLinux::HandleKeyboardEvent( return false; } -// static -void CefBrowserPlatformDelegate::HandleExternalProtocol(const GURL& url) {} - CefEventHandle CefBrowserPlatformDelegateNativeLinux::GetEventHandle( const content::NativeWebKeyboardEvent& event) const { // TODO(cef): We need to return an XEvent* from this method, but diff --git a/libcef/browser/native/browser_platform_delegate_native_mac.mm b/libcef/browser/native/browser_platform_delegate_native_mac.mm index f734ec711..ed1dd9768 100644 --- a/libcef/browser/native/browser_platform_delegate_native_mac.mm +++ b/libcef/browser/native/browser_platform_delegate_native_mac.mm @@ -462,9 +462,6 @@ bool CefBrowserPlatformDelegateNativeMac::HandleKeyboardEvent( return false; } -// static -void CefBrowserPlatformDelegate::HandleExternalProtocol(const GURL& url) {} - CefEventHandle CefBrowserPlatformDelegateNativeMac::GetEventHandle( const content::NativeWebKeyboardEvent& event) const { return CAST_NSEVENT_TO_CEF_EVENT_HANDLE(event.os_event); diff --git a/libcef/browser/native/browser_platform_delegate_native_win.cc b/libcef/browser/native/browser_platform_delegate_native_win.cc index 842f7c81d..94ce35677 100644 --- a/libcef/browser/native/browser_platform_delegate_native_win.cc +++ b/libcef/browser/native/browser_platform_delegate_native_win.cc @@ -18,7 +18,6 @@ #include "base/files/file_util.h" #include "base/path_service.h" #include "base/strings/utf_string_conversions.h" -#include "base/win/registry.h" #include "base/win/win_util.h" #include "content/public/browser/native_web_keyboard_event.h" #include "third_party/blink/public/common/input/web_mouse_event.h" @@ -60,70 +59,6 @@ void WriteTempFileAndView(const std::string& data) { ui::win::OpenFileViaShell(tmp_file); } -bool HasExternalHandler(const std::string& scheme) { - base::win::RegKey key; - const std::wstring registry_path = - base::ASCIIToWide(scheme + "\\shell\\open\\command"); - key.Open(HKEY_CLASSES_ROOT, registry_path.c_str(), KEY_READ); - if (key.Valid()) { - DWORD size = 0; - key.ReadValue(NULL, NULL, &size, NULL); - if (size > 2) { - // ShellExecute crashes the process when the command is empty. - // We check for "2" because it always returns the trailing NULL. - return true; - } - } - - return false; -} - -// Match the logic in chrome/browser/platform_util_win.cc -// OpenExternalOnWorkerThread. -void ExecuteExternalProtocol(const GURL& url) { - CEF_REQUIRE_BLOCKING(); - - if (!HasExternalHandler(url.scheme())) { - return; - } - - // Quote the input scheme to be sure that the command does not have - // parameters unexpected by the external program. This url should already - // have been escaped. - std::string escaped_url = url.spec(); - escaped_url.insert(0, "\""); - escaped_url += "\""; - - // According to Mozilla in uriloader/exthandler/win/nsOSHelperAppService.cpp: - // "Some versions of windows (Win2k before SP3, Win XP before SP1) crash in - // ShellExecute on long URLs (bug 161357 on bugzilla.mozilla.org). IE 5 and 6 - // support URLS of 2083 chars in length, 2K is safe." - // - // It may be possible to increase this. https://crbug.com/727909 - const size_t kMaxUrlLength = 2048; - if (escaped_url.length() > kMaxUrlLength) { - return; - } - - // Specify %windir%\system32 as the CWD so that any new proc spawned does not - // inherit this proc's CWD. Without this, uninstalls may be broken by a - // long-lived child proc that holds a handle to the browser's version - // directory (the browser's CWD). A process's CWD is in the standard list of - // directories to search when loading a DLL, and precedes the system directory - // when safe DLL search mode is disabled (not the default). Setting the CWD to - // the system directory is a nice way to mitigate a potential DLL search order - // hijack for processes that don't implement their own mitigation. - base::FilePath system_dir; - base::PathService::Get(base::DIR_SYSTEM, &system_dir); - if (reinterpret_cast(ShellExecuteA( - NULL, "open", escaped_url.c_str(), NULL, - system_dir.AsUTF8Unsafe().c_str(), SW_SHOWNORMAL)) <= 32) { - // On failure, it may be good to display a message to the user. - // https://crbug.com/727913 - return; - } -} - gfx::Rect GetDisplayWorkAreaNearestPoint(gfx::Point dip_point) { const auto display = display::Screen::GetScreen()->GetDisplayNearestPoint(dip_point); @@ -483,11 +418,6 @@ bool CefBrowserPlatformDelegateNativeWin::HandleKeyboardEvent( } } -// static -void CefBrowserPlatformDelegate::HandleExternalProtocol(const GURL& url) { - CEF_POST_USER_VISIBLE_TASK(base::BindOnce(ExecuteExternalProtocol, url)); -} - CefEventHandle CefBrowserPlatformDelegateNativeWin::GetEventHandle( const content::NativeWebKeyboardEvent& event) const { if (!event.os_event) {