mirror of
https://github.com/electron/electron.git
synced 2026-05-02 03:00:22 -04:00
fix: crash in AutofillPopup teardown (#51317)
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 <charles@charleskerr.com>
This commit is contained in:
@@ -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<std::u16string>& values,
|
||||
const std::vector<std::u16string>& 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) {
|
||||
|
||||
@@ -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());
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user