From cd4ebc497a20cc893bb2d4f3de3541cf3e3d6d92 Mon Sep 17 00:00:00 2001 From: "trop[bot]" <37223003+trop[bot]@users.noreply.github.com> Date: Sun, 26 Apr 2026 08:50:34 -0500 Subject: [PATCH] fix: crash in AutofillPopup teardown (#51317) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Fix a crash in AutofillPopupView::Show() when the popup tried to show itself after the parent's native view had already gone away during teardown. 2026-04-23T20:44:32.7015810Z Received signal 11 SEGV_ACCERR 000000000160 2026-04-23T20:44:32.9322010Z 4 Electron Framework ... views::Widget::IsVisible() const + 28 2026-04-23T20:44:32.9528810Z 6 Electron Framework ... electron::AutofillPopupView::Show() + 200 2026-04-23T20:44:32.9632090Z 7 Electron Framework ... electron::AutofillPopup::CreateView(...) + 1380 2026-04-23T20:44:32.9749770Z 8 Electron Framework ... electron::AutofillDriver::ShowAutofillPopup(...) + 736 2026-04-23T20:44:33.0015220Z ✗ Electron tests failed with kill signal SIGSEGV. Co-authored-by: trop[bot] <37223003+trop[bot]@users.noreply.github.com> Co-authored-by: Charles Kerr --- shell/browser/ui/autofill_popup.cc | 30 ++++++++++++++----- shell/browser/ui/views/autofill_popup_view.cc | 19 +++++++++--- 2 files changed, 38 insertions(+), 11 deletions(-) diff --git a/shell/browser/ui/autofill_popup.cc b/shell/browser/ui/autofill_popup.cc index 2c266f8427..2640425fdf 100644 --- a/shell/browser/ui/autofill_popup.cc +++ b/shell/browser/ui/autofill_popup.cc @@ -172,20 +172,30 @@ void AutofillPopup::CreateView(content::RenderFrameHost* frame_host, bool offscreen, views::View* parent, const gfx::RectF& r) { + DCHECK(parent); + Hide(); + // A Widget can outlive its NativeWidget during teardown. + // Do not create a child popup once the parent native view is gone. + views::Widget* parent_widget = parent->GetWidget(); + if (!parent_widget || parent_widget->IsClosed() || + !parent_widget->GetNativeView()) { + return; + } + frame_host_ = frame_host; element_bounds_ = gfx::ToEnclosedRect(r); - gfx::Vector2d height_offset(0, element_bounds_.height()); - gfx::Point menu_position(element_bounds_.origin() + height_offset); + gfx::Vector2d height_offset{0, element_bounds_.height()}; + gfx::Point menu_position{element_bounds_.origin() + height_offset}; views::View::ConvertPointToScreen(parent, &menu_position); - popup_bounds_ = gfx::Rect(menu_position, element_bounds_.size()); + popup_bounds_ = gfx::Rect{menu_position, element_bounds_.size()}; parent_ = parent; parent_->AddObserver(this); - view_ = new AutofillPopupView(this, parent->GetWidget()); + view_ = new AutofillPopupView{this, parent_widget}; if (offscreen) { auto* rwhv = embedder_frame_host ? embedder_frame_host->GetView() @@ -212,13 +222,19 @@ void AutofillPopup::Hide() { void AutofillPopup::SetItems(const std::vector& values, const std::vector& labels) { - DCHECK(view_); values_ = values; labels_ = labels; + + if (!view_) + return; + UpdatePopupBounds(); view_->OnSuggestionsChanged(); - if (view_) // could be hidden after the change - view_->DoUpdateBoundsAndRedrawPopup(); + + if (!view_) + return; + + view_->DoUpdateBoundsAndRedrawPopup(); } void AutofillPopup::AcceptSuggestion(int index) { diff --git a/shell/browser/ui/views/autofill_popup_view.cc b/shell/browser/ui/views/autofill_popup_view.cc index 630c22dbcb..f61f873730 100644 --- a/shell/browser/ui/views/autofill_popup_view.cc +++ b/shell/browser/ui/views/autofill_popup_view.cc @@ -69,9 +69,16 @@ AutofillPopupView::~AutofillPopupView() { void AutofillPopupView::Show() { if (!popup_) return; - bool visible = parent_widget_->IsVisible(); - visible = visible || view_proxy_; - if (!visible || parent_widget_->IsClosed()) + + DCHECK(parent_widget_); + + // The parent Widget can outlive its NativeWidget during teardown. + // Don't initialize the popup after the native parent view is gone. + if (parent_widget_->IsClosed() || !parent_widget_->GetNativeView()) + return; + + const bool visible = view_proxy_ || parent_widget_->IsVisible(); + if (!visible) return; const bool initialize_widget = !GetWidget(); @@ -234,10 +241,14 @@ void AutofillPopupView::DoUpdateBoundsAndRedrawPopup() { if (!popup_) return; + views::Widget* const widget = GetWidget(); + if (!widget) + return; + // Clamp popup_bounds_ to ensure it's never zero-width. popup_->popup_bounds_.Union( gfx::Rect(popup_->popup_bounds_.origin(), gfx::Size(1, 1))); - GetWidget()->SetBounds(popup_->popup_bounds_); + widget->SetBounds(popup_->popup_bounds_); if (view_proxy_.get()) { view_proxy_->SetBounds(popup_->popup_bounds_in_view()); }