Description
Is there an existing issue for this?
- I have searched both open/closed issues, no issue already exists.
CefSharp Version
130
Operating System
Windows 10
Architecture
x64
.Net Version
.net 6
Implementation
WPF
Reproduction Steps
We don't quite have HwndHost integrated into the main CefSharp sample yet but if we did then uncommenting https://github.com/cefsharp/CefSharp/blob/master/CefSharp.Wpf.Example/Views/BrowserTabView.xaml.cs#L129-L183 would result in the crash (note if trying to repro with external HwndHost need to add the experimental handlers to the inclusion).
Once you do so just open a new popup (ie target= _blank) and it will crash.
Expected behavior
Not Crash
Actual behavior
Crashes
Regression?
Doubt it
Known Workarounds
Unable to find any
Does this problem also occur in the CEF Sample Application
No
Other information
This might be a bug in CEF based on the cef code comments but I can't reproduce it so we might be calling down some wrong path. It doesn't happen with WPF (non HwndHost) (or seemingly WinForms) but if the CEF comment is right the flow would only be an issue with chrome style not alloy style windows. See below for more details.
The error occurs because the 'pending popup' var set to empty and then it trying to copy properties from that.
src is: 0x00000000000000a8
(this seems to be a CEF constant for empty for pending popup)
so: target->windowless_frame_rate = src->windowless_frame_rate; throws a read error
> libcef.dll!CefBrowserSettingsTraits::set(const _cef_browser_settings_t * src, _cef_browser_settings_t * target, bool copy) Line 500 C++
[Inline Frame] libcef.dll!CefStructBase<CefBrowserSettingsTraits>::Set(const _cef_browser_settings_t & source, bool copy) Line 108 C++
[Inline Frame] libcef.dll!CefStructBase<CefBrowserSettingsTraits>::operator=(const _cef_browser_settings_t & s) Line 116 C++
[Inline Frame] libcef.dll!CefStructBase<CefBrowserSettingsTraits>::operator=(const CefStructBase<CefBrowserSettingsTraits> & s) Line 112 C++
libcef.dll!CefBrowserInfoManager::WebContentsCreated(const GURL & target_url, const content::GlobalRenderFrameHostId & opener_global_id, CefStructBase<CefBrowserSettingsTraits> & settings, scoped_refptr<CefClient> & client, std::__Cr::unique_ptr<CefBrowserPlatformDelegate,std::__Cr::default_delete<CefBrowserPlatformDelegate>> & platform_delegate, scoped_refptr<CefDictionaryValue> & extra_info, content::WebContents * new_contents) Line 266 C++
libcef.dll!ChromeBrowserDelegate::WebContentsCreated(content::WebContents * source_contents, int opener_render_process_id, int opener_render_frame_id, const std::__Cr::basic_string<char,std::__Cr::char_traits<char>,std::__Cr::allocator<char>> & frame_name, const GURL & target_url, content::WebContents * new_contents) Line 508 C++
libcef.dll!content::WebContentsImpl::CreateNewWindow(content::RenderFrameHostImpl * opener, const content::mojom::CreateNewWindowParams & params, bool is_new_browsing_instance, bool has_user_gesture, content::SessionStorageNamespace * session_storage_namespace) Line 4862 C++
libcef.dll!content::RenderFrameHostImpl::CreateNewWindow(mojo::StructPtr<content::mojom::CreateNewWindowParams> params, base::OnceCallback<void (content::mojom::CreateNewWindowStatus, mojo::StructPtr<content::mojom::CreateNewWindowReply>)> callback) Line 9144 C++
libcef.dll!content::mojom::FrameHostStubDispatch::AcceptWithResponder(content::mojom::FrameHost * impl, mojo::Message * message, std::__Cr::unique_ptr<mojo::MessageReceiverWithStatus,std::__Cr::default_delete<mojo::MessageReceiverWithStatus>> responder) Line 5736 C++
libcef.dll!content::mojom::FrameHostStub<mojo::RawPtrImplRefTraits<content::mojom::FrameHost>>::AcceptWithResponder(mojo::Message * message, std::__Cr::unique_ptr<mojo::MessageReceiverWithStatus,std::__Cr::default_delete<mojo::MessageReceiverWithStatus>> responder) Line 860 C++
[Inline Frame] libcef.dll!mojo::InterfaceEndpointClient::HandleValidatedMessage(mojo::Message * message) Line 1005 C++
libcef.dll!mojo::InterfaceEndpointClient::HandleIncomingMessageThunk::Accept(mojo::Message * message) Line 371 C++
libcef.dll!mojo::MessageDispatcher::Accept(mojo::Message * message) Line 48 C++
libcef.dll!mojo::InterfaceEndpointClient::HandleIncomingMessage(mojo::Message * message) Line 724 C++
libcef.dll!IPC::ChannelAssociatedGroupController::AcceptSyncMessage(unsigned int interface_id, unsigned int message_id, IPC::`anonymous namespace'::ScopedUrgentMessageNotification scoped_urgent_message_notification) Line 1259 C++
[Inline Frame] libcef.dll!base::internal::DecayedFunctorTraits<void (IPC::ChannelAssociatedGroupController::*)(unsigned int, unsigned int, IPC::(anonymous namespace)::ScopedUrgentMessageNotification),IPC::ChannelAssociatedGroupController *&&,unsigned int &&,unsigned int &&,IPC::(anonymous namespace)::ScopedUrgentMessageNotification &&>::Invoke(void(IPC::ChannelAssociatedGroupController::*)(unsigned int, unsigned int, IPC::`anonymous namespace'::ScopedUrgentMessageNotification) method, scoped_refptr<IPC::ChannelAssociatedGroupController> && receiver_ptr, unsigned int && args, unsigned int && args, IPC::`anonymous namespace'::ScopedUrgentMessageNotification && args) Line 738 C++
[Inline Frame] libcef.dll!base::internal::InvokeHelper<0,base::internal::FunctorTraits<void (IPC::ChannelAssociatedGroupController::*&&)(unsigned int, unsigned int, IPC::(anonymous namespace)::ScopedUrgentMessageNotification),IPC::ChannelAssociatedGroupController *&&,unsigned int &&,unsigned int &&,IPC::(anonymous namespace)::ScopedUrgentMessageNotification &&>,void,0,1,2,3>::MakeItSo(void(IPC::ChannelAssociatedGroupController::*)(unsigned int, unsigned int, IPC::`anonymous namespace'::ScopedUrgentMessageNotification) && functor, std::__Cr::tuple<scoped_refptr<IPC::ChannelAssociatedGroupController>,unsigned int,unsigned int,IPC::(anonymous namespace)::ScopedUrgentMessageNotification> && bound) Line 930 C++
[Inline Frame] libcef.dll!base::internal::Invoker<base::internal::FunctorTraits<void (IPC::ChannelAssociatedGroupController::*&&)(unsigned int, unsigned int, IPC::(anonymous namespace)::ScopedUrgentMessageNotification),IPC::ChannelAssociatedGroupController *&&,unsigned int &&,unsigned int &&,IPC::(anonymous namespace)::ScopedUrgentMessageNotification &&>,base::internal::BindState<1,1,0,void (IPC::ChannelAssociatedGroupController::*)(unsigned int, unsigned int, IPC::(anonymous namespace)::ScopedUrgentMessageNotification),scoped_refptr<IPC::ChannelAssociatedGroupController>,unsigned int,unsigned int,IPC::(anonymous namespace)::ScopedUrgentMessageNotification>,void ()>::RunImpl(void(IPC::ChannelAssociatedGroupController::*)(unsigned int, unsigned int, IPC::`anonymous namespace'::ScopedUrgentMessageNotification) && functor, std::__Cr::tuple<scoped_refptr<IPC::ChannelAssociatedGroupController>,unsigned int,unsigned int,IPC::(anonymous namespace)::ScopedUrgentMessageNotification> && bound, std::__Cr::integer_sequence<unsigned long long,0,1,2,3>) Line 1067 C++
libcef.dll!base::internal::Invoker<base::internal::FunctorTraits<void (IPC::ChannelAssociatedGroupController::*&&)(unsigned int, unsigned int, IPC::(anonymous namespace)::ScopedUrgentMessageNotification),IPC::ChannelAssociatedGroupController *&&,unsigned int &&,unsigned int &&,IPC::(anonymous namespace)::ScopedUrgentMessageNotification &&>,base::internal::BindState<1,1,0,void (IPC::ChannelAssociatedGroupController::*)(unsigned int, unsigned int, IPC::(anonymous namespace)::ScopedUrgentMessageNotification),scoped_refptr<IPC::ChannelAssociatedGroupController>,unsigned int,unsigned int,IPC::(anonymous namespace)::ScopedUrgentMessageNotification>,void ()>::RunOnce(base::internal::BindStateBase * base) Line 980 C++
[Inline Frame] libcef.dll!base::OnceCallback<void ()>::Run() Line 156 C++
libcef.dll!base::TaskAnnotator::RunTaskImpl(base::PendingTask & pending_task) Line 203 C++
[Inline Frame] libcef.dll!base::TaskAnnotator::RunTask(perfetto::StaticString event_name, base::PendingTask & pending_task, base::sequence_manager::internal::ThreadControllerWithMessagePumpImpl::DoWorkImpl::<lambda_4> && args) Line 90 C++
[Inline Frame] libcef.dll!base::sequence_manager::internal::ThreadControllerWithMessagePumpImpl::DoWorkImpl(base::LazyNow * continuation_lazy_now) Line 470 C++
libcef.dll!base::sequence_manager::internal::ThreadControllerWithMessagePumpImpl::DoWork() Line 332 C++
libcef.dll!base::MessagePumpForUI::DoRunLoop() Line 260 C++
libcef.dll!base::MessagePumpWin::Run(base::MessagePump::Delegate * delegate) Line 85 C++
libcef.dll!base::sequence_manager::internal::ThreadControllerWithMessagePumpImpl::Run(bool application_tasks_allowed, base::TimeDelta timeout) Line 643 C++
libcef.dll!base::RunLoop::Run(const base::Location & location) Line 136 C++
libcef.dll!CefMainRunner::RunMessageLoop() Line 198 C++
libcef.dll!CefUIThread::ThreadMain() Line 106 C++
libcef.dll!base::`anonymous namespace'::ThreadFunc(void * params) Line 124 C++
kernel32.dll!00007ffbfa4d7374() Unknown
ntdll.dll!00007ffbfaedcc91() Unknown
The may be more telling is the code https://github.com/chromiumembedded/cef/blob/e513077eaca4097e2283cb70bcd72c804a6ee922/libcef/browser/browser_info_manager.cc#L318-L321
where it tries to get the pending popup information. If the comment saying GET_CUSTOM_WEB_CONTENTS_VIEW
should only be used with alloy style maybe that is why this happens? I doubt this specifically given it also does an alloy style check below on pending_popup so maybe it just means GET_CUSTOM_WEB_CONTENTS_VIEW is ignored if not alloy style. Either way poppendingpopup returns empty. If it does mean GET_CUSTOM_WEB_CONTENTS_VIEW shouldn't be called on chrome style then I figured I should be able to reproduce it with:
./cefclient.exe --no-sandbox --lang=en-US --remote-debugging-port=8088 --uncaught-exception-stack-size=10 --use-chrome-style-window --disable-features=EnableHangWatcher --disable-chrome-login-prompt --hide-crash-restore-bubble --enable-unsafe-extension-debugging --enable-experimental-extension-apis --no-proxy-server --cache-path=f:/cache/ --url=https://google.com --use-views
and doing the new popup test. This succeeds though both with and without the --use-default-popup
arg. The PopPendingPopup function does seem to handle chromestyle too.
I tried to repro in WinForms without success as well. I added CefSharpSettings.RuntimeStyle = CefRuntimeStyle.Chrome;
to program.cs and tried both the normal lifespan handler and setting it equal to browser.LifeSpanHandler = new WinFormsLifeSpanHandlerEx();
but I am not sure if that is really a full hosted popup. Without HandlerEx new tabs open fine no matter what target is set to or if shift is held on links (everything just opens as new tab). When set to HandlerEx things that should open in new window do nothing (but no crash), but holding control does cause new tabs to open properly on links.
Back to where it does crash I found if you hold control or shift it does not crash when clicking the link with target _blank. Similar to in the non HwndHost WPF version holding control/shift just causes links to open in the same tab. These just don't flow through the lifespan handler for popups.