cefsharp / cefsharp/CefSharp

[invalid] custom popup hosting / lifespan with Wpf.HwndHost causes crash on popup with ChromeStyle

Aperta
#4,980 2 commenti 0 reazioni 0 assegnatari Vedi su GitHub
Lingua principale
C#
Stelle
10.3k
Fork
2.9k
Merge medio
5g 22h
PR unite (30g)
4

Descrizione

### Is there an existing issue for this?

- [X] 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)
```cpp
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::Set(const _cef_browser_settings_t & source, bool copy) Line 108 C++
[Inline Frame] libcef.dll!CefStructBase::operator=(const _cef_browser_settings_t & s) Line 116 C++
[Inline Frame] libcef.dll!CefStructBase::operator=(const CefStructBase & s) Line 112 C++
libcef.dll!CefBrowserInfoManager::WebContentsCreated(const GURL & target_url, const content::GlobalRenderFrameHostId & opener_global_id, CefStructBase & settings, scoped_refptr & client, std::__Cr::unique_ptr> & platform_delegate, scoped_refptr & 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,std::__Cr::allocator> & 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 params, base::OnceCallback)> callback) Line 9144 C++
libcef.dll!content::mojom::FrameHostStubDispatch::AcceptWithResponder(content::mojom::FrameHost * impl, mojo::Message * message, std::__Cr::unique_ptr> responder) Line 5736 C++
libcef.dll!content::mojom::FrameHostStub>::AcceptWithResponder(mojo::Message * message, std::__Cr::unique_ptr> 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::Invoke(void(IPC::ChannelAssociatedGroupController::*)(unsigned int, unsigned int, IPC::`anonymous namespace'::ScopedUrgentMessageNotification) method, scoped_refptr && 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,0,1,2,3>::MakeItSo(void(IPC::ChannelAssociatedGroupController::*)(unsigned int, unsigned int, IPC::`anonymous namespace'::ScopedUrgentMessageNotification) && functor, std::__Cr::tuple,unsigned int,unsigned int,IPC::(anonymous namespace)::ScopedUrgentMessageNotification> && bound) Line 930 C++
[Inline Frame] libcef.dll!base::internal::Invoker,base::internal::BindState<1,1,0,void (IPC::ChannelAssociatedGroupController::*)(unsigned int, unsigned int, IPC::(anonymous namespace)::ScopedUrgentMessageNotification),scoped_refptr,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,unsigned int,unsigned int,IPC::(anonymous namespace)::ScopedUrgentMessageNotification> && bound, std::__Cr::integer_sequence) Line 1067 C++
libcef.dll!base::internal::Invoker,base::internal::BindState<1,1,0,void (IPC::ChannelAssociatedGroupController::*)(unsigned int, unsigned int, IPC::(anonymous namespace)::ScopedUrgentMessageNotification),scoped_refptr,unsigned int,unsigned int,IPC::(anonymous namespace)::ScopedUrgentMessageNotification>,void ()>::RunOnce(base::internal::BindStateBase * base) Line 980 C++
[Inline Frame] libcef.dll!base::OnceCallback::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:: && 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](https://github.com/chromiumembedded/cef/blob/e513077eaca4097e2283cb70bcd72c804a6ee922/libcef/browser/browser_info_manager.cc#L668) 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.

Guida per i contributori

Apri la guida per i contributori

Direzione di ricerca

Inizia da CefSharp.Wpf.Example/Views/BrowserTabView.xaml.cs intorno alle righe 129–183 e riproduci un popup target=_blank usando Wpf.HwndHost con ChromeStyle. Confronta il flusso del popup con i riferimenti CEF browser_info_manager.cc e determina il comportamento rilevante relativo all’hosting o al ciclo di vita. Il lavoro è completato quando il popup ospitato non va più in crash in questo scenario.

Scritto dal modello di indicizzazione a partire dal testo della issue.

Valutazione

Stack tecnologico
cpp, csharp
Ambito
desktop
Tipo di issue
Bug
Difficoltà
5/5
Tempo stimato
Più di una settimana
Stato di attività
Ferma
Chiarezza
Da chiarire
Idoneità per principianti
20/100

Ricevi le nuove issue nella tua casella

Un breve riepilogo di issue GitHub adatte ai principianti.