From 3b8a3fad8f720fc6ee18d3cbbbef9e40cb377bab Mon Sep 17 00:00:00 2001 From: Toshihito Kikuchi Date: Fri, 28 Aug 2020 21:27:22 +0000 Subject: [PATCH] Bug 1657208 - Dynamic-load urlmon.dll for x86 system. r=freddyb,mhowell Our data indicates a few users of x86 system hit failure to load urlmon.dll for unknown reasons. Since we don't always require urlmon.dll, we delay-load it, which causes a crash if loading urlmon.dll fails. A proposed fix is to dynamically load urlmon.dll on x86. Differential Revision: https://phabricator.services.mozilla.com/D88534 --- dom/security/nsContentSecurityUtils.cpp | 6 +++--- widget/windows/UrlmonHeaderOnlyUtils.h | 3 ++- widget/windows/WinHeaderOnlyUtils.h | 17 +++++++++++++++++ 3 files changed, 22 insertions(+), 4 deletions(-) diff --git a/dom/security/nsContentSecurityUtils.cpp b/dom/security/nsContentSecurityUtils.cpp index 77b924960d3c..c3acac0c213f 100644 --- a/dom/security/nsContentSecurityUtils.cpp +++ b/dom/security/nsContentSecurityUtils.cpp @@ -303,9 +303,9 @@ FilenameTypeAndDetails nsContentSecurityUtils::FilenameToFilenameType( if (widget::WinUtils::PreparePathForTelemetry(strSanitizedPath, flags)) { DWORD cchDecodedUrl = INTERNET_MAX_URL_LENGTH; WCHAR szOut[INTERNET_MAX_URL_LENGTH]; - HRESULT hr = - ::CoInternetParseUrl(fileName.get(), PARSE_SCHEMA, 0, szOut, - INTERNET_MAX_URL_LENGTH, &cchDecodedUrl, 0); + HRESULT hr; + SAFECALL_URLMON_FUNC(CoInternetParseUrl, fileName.get(), PARSE_SCHEMA, 0, + szOut, INTERNET_MAX_URL_LENGTH, &cchDecodedUrl, 0); if (hr == S_OK && cchDecodedUrl) { nsAutoString sanitizedPathAndScheme; sanitizedPathAndScheme.Append(szOut); diff --git a/widget/windows/UrlmonHeaderOnlyUtils.h b/widget/windows/UrlmonHeaderOnlyUtils.h index e55af55c81f3..dd9209f78f04 100644 --- a/widget/windows/UrlmonHeaderOnlyUtils.h +++ b/widget/windows/UrlmonHeaderOnlyUtils.h @@ -48,7 +48,8 @@ inline LauncherResult<_bstr_t> UrlmonValidateUri(const wchar_t* aUri) { Uri_CREATE_CRACK_UNKNOWN_SCHEMES | Uri_CREATE_PRE_PROCESS_HTML_URI | Uri_CREATE_IE_SETTINGS; RefPtr uri; - HRESULT hr = CreateUri(aUri, flags, 0, getter_AddRefs(uri)); + HRESULT hr; + SAFECALL_URLMON_FUNC(CreateUri, aUri, flags, 0, getter_AddRefs(uri)); if (FAILED(hr)) { return LAUNCHER_ERROR_FROM_HRESULT(hr); } diff --git a/widget/windows/WinHeaderOnlyUtils.h b/widget/windows/WinHeaderOnlyUtils.h index 33747779f726..18599e1fc6db 100644 --- a/widget/windows/WinHeaderOnlyUtils.h +++ b/widget/windows/WinHeaderOnlyUtils.h @@ -51,6 +51,23 @@ typedef struct _FILE_ID_INFO { # define STATUS_SUCCESS ((NTSTATUS)0x00000000L) #endif // !defined(STATUS_SUCCESS) +// Our data indicates a few users of Win7 x86 hit failure to load urlmon.dll +// for unknown reasons. Since we don't always require urlmon.dll on Win7, +// we delay-load it, which causes a crash if loading urlmon.dll fails. This +// macro is to safely load and call urlmon's API graciously without crash. +#if defined(_X86_) +# define SAFECALL_URLMON_FUNC(FuncName, ...) \ + do { \ + static const mozilla::StaticDynamicallyLinkedFunctionPtr \ + func(L"urlmon.dll", #FuncName); \ + hr = \ + func ? func(__VA_ARGS__) : HRESULT_FROM_WIN32(ERROR_PROC_NOT_FOUND); \ + } while (0) +#else +# define SAFECALL_URLMON_FUNC(FuncName, ...) hr = ::FuncName(__VA_ARGS__) +#endif + namespace mozilla { class WindowsError final {