[Problem/Bug]: Invoked Async HostObject method that returns null crashes WebView
What happened?
The bug was found in more complex project, but I reproduced it in the most simple way possible in separate clear WPF project. I added only WebView2 there and added HostObject by calling AddHostObjectToScript with code below:
...
Loaded="Window_Loaded">
<Grid>
<wv2:WebView2 x:Name="webView2" Source="https://google.com" />
</Grid>
</Window>
private async void Window_Loaded(object sender, RoutedEventArgs e)
{
await webView2.EnsureCoreWebView2Async();
webView2.CoreWebView2.AddHostObjectToScript("bridge", new BridgeHostObject());
}
To explore all basic possibilities the BridgeHostObject has following four methods
[ComVisible(true)]
public class BridgeHostObject
{
public string TestMethodA()
{
return "";
}
public async Task<string> TestMethodB()
{
return "";
}
public string TestMethodC()
{
return null;
}
public async Task<string> TestMethodD()
{
return null;
}
}
Only the last one TestMethodD causes the application to crash with following StackTrace:
> EmbeddedBrowserWebView.dll!embedded_browser_webview_current::EmbeddedBrowserHost::PostMethodCallCommon() Unknown
EmbeddedBrowserWebView.dll!embedded_browser_webview_current::EmbeddedBrowserHost::PostMethodCall(int,class std::__Cr::basic_string<char,struct std::__Cr::char_traits<char>,class std::__Cr::allocator<char> > const &,class std::__Cr::basic_string<char,struct std::__Cr::char_traits<char>,class std::__Cr::allocator<char> > const &,class std::__Cr::optional<class std::__Cr::basic_string<char,struct std::__Cr::char_traits<char>,class std::__Cr::allocator<char> > > const &,int) Unknown
EmbeddedBrowserWebView.dll!embedded_browser::mojom::HostStubDispatch::Accept(class embedded_browser::mojom::Host *,class mojo::Message *) Unknown
EmbeddedBrowserWebView.dll!mojo::internal::MultiplexRouter::CloseEndpointHandle(unsigned int,class std::__Cr::optional<struct mojo::DisconnectReason> const &) Unknown
EmbeddedBrowserWebView.dll!mojo::MessageDispatcher::Accept(class mojo::Message *) Unknown
EmbeddedBrowserWebView.dll!mojo::InterfaceEndpointClient::HandleIncomingMessage(class mojo::Message *) Unknown
EmbeddedBrowserWebView.dll!mojo::internal::MultiplexRouter::ProcessIncomingMessage() Unknown
EmbeddedBrowserWebView.dll!mojo::internal::MultiplexRouter::Accept(class mojo::Message *) Unknown
EmbeddedBrowserWebView.dll!mojo::MessageDispatcher::Accept(class mojo::Message *) Unknown
EmbeddedBrowserWebView.dll!mojo::Connector::DispatchMessageW() Unknown
EmbeddedBrowserWebView.dll!mojo::Connector::ReadAllAvailableMessages() Unknown
EmbeddedBrowserWebView.dll!base::internal::Invoker<base::internal::FunctorTraits<void (mojo::Connector::*)(const char *, unsigned int),mojo::Connector *,const char *const &>,base::internal::BindState<1,1,0,void (mojo::Connector::*)(const char *, unsigned int),base::internal::UnretainedWrapper<mojo::Connector,base::unretained_traits::MayNotDangle,0>,base::internal::UnretainedWrapper<const char,base::unretained_traits::MayNotDangle,0>>,void (unsigned int)>::Run() Unknown
EmbeddedBrowserWebView.dll!base::RepeatingCallback<void (unsigned int, const mojo::HandleSignalsState &)>::Run() Unknown
EmbeddedBrowserWebView.dll!base::RepeatingCallback<void (unsigned int, const mojo::HandleSignalsState &)>::Run() Unknown
EmbeddedBrowserWebView.dll!mojo::SimpleWatcher::OnHandleReady() Unknown
EmbeddedBrowserWebView.dll!base::TaskAnnotator::RunTaskImpl(struct base::PendingTask &) Unknown
EmbeddedBrowserWebView.dll!base::TaskAnnotator::RunTask<>() Unknown
EmbeddedBrowserWebView.dll!embedded_browser_webview::internal::AppTaskRunner::DoWork() Unknown
EmbeddedBrowserWebView.dll!embedded_browser_webview::internal::AppTaskRunner::MessageCallback() Unknown
EmbeddedBrowserWebView.dll!base::RepeatingCallback<bool (unsigned int, unsigned long long, long long, long long *)>::Run() Unknown
EmbeddedBrowserWebView.dll!base::win::MessageWindow::WindowProc() Unknown
EmbeddedBrowserWebView.dll!base::win::WrappedWindowProc<&base::win::MessageWindow::WindowProc>() Unknown
user32.dll!UserCallWinProcCheckWow() Unknown
user32.dll!DispatchMessageWorker() Unknown
[External Code]
[Inline Frame] hostpolicy.dll!coreclr_t::execute_assembly(int) Line 109 C++
hostpolicy.dll!run_app_for_context(const hostpolicy_context_t & context, int argc, const wchar_t * * argv) Line 256 C++
hostpolicy.dll!run_app(const int argc, const wchar_t * * argv) Line 285 C++
hostpolicy.dll!corehost_main(const int argc, const wchar_t * * argv) Line 426 C++
Importance
Important. My app's user experience is significantly compromised.
Runtime Channel
Stable release (WebView2 Runtime)
Runtime Version
123.0.2420.47
SDK Version
1.0.2420.47
Framework
WPF
Operating System
Windows 11
OS Version
Edition Windows 11 Enterprise Version 22H2 Installed on 11. 4. 2024 OS build 22621.3447 Experience Windows Feature Experience Pack 1000.22688.1000.0
Repro steps
- Create simple application with the code in the description above
- Start the application
- Right click the WebView2 element and go to Inspect->Console
- Run
await chrome.webview.hostObjects.bridge.TestMethodD()
Expected behavior: returned null value as it successfully happens for example for TestMethodC
Actual behavior: Crash of the application with the StackTrace in the description above
Repros in Edge Browser
No, issue does not reproduce in the corresponding Edge version
Regression
Don't know
Last working version (if regression)
No response
@Mirzek
Does the TestMethodD() crashes also when we return a null value instead of null Task?
public async Task<string> TestMethodD()
{
return Task.FromResult(null);
}
This one wasn't compilable, but when changed to following it still crashes the same.
public async Task<string> TestMethodD()
{
return await Task.FromResult<string>(null);
}
It is a bug in WebView2. An internal work item has been created and the issue is being worked on. Will update this when the fix is ready. The fix would be inside WebView2 SDK, so you would have to update the app to pick up the new SDK when it is released.
@LiangTheDev thanks a lot for such timely response to this issue.
And @Mirzek thank for reporting this.
The fix has been checked in. It may take a while to be released.
It should be in newer WebView2 SDK with version > 1.0.2562.0. We also made a change in WebView2 Runtime that would avoid the crash for apps using older SDK (only avoid crash, not correct behavior). That fix would be available in newer Edge builds with version >= 126.0.2562.0.