diff --git a/third_party/blink/renderer/core/frame/web_frame_widget_impl.cc b/third_party/blink/renderer/core/frame/web_frame_widget_impl.cc index 1395aa71a377c..c82566ccad845 100644 --- a/third_party/blink/renderer/core/frame/web_frame_widget_impl.cc +++ b/third_party/blink/renderer/core/frame/web_frame_widget_impl.cc @@ -1939,6 +1939,12 @@ void WebFrameWidgetImpl::UpdateVisualProperties( gfx::Size old_visible_viewport_size = widget_base_->VisibleViewportSize(); ApplyVisualPropertiesSizing(visual_properties); + // ApplyVisualPropertiesSizing() may synchronously dispatch JS (the legacy + // `orientationchange` event) whose handler can detach this widget's local + // root and Close() this WebFrameWidgetImpl, resetting `widget_base_`. + if (!widget_base_) { + return; + } if (old_visible_viewport_size != widget_base_->VisibleViewportSize()) { ForEachLocalFrameControlledByWidget( @@ -2064,6 +2070,12 @@ void WebFrameWidgetImpl::ApplyVisualPropertiesSizing( widget_base_->UpdateSurfaceAndScreenInfo( visual_properties.local_surface_id.value_or(viz::LocalSurfaceId()), new_compositor_viewport_pixel_rect, visual_properties.screen_infos); + // UpdateSurfaceAndScreenInfo() may synchronously dispatch JS (the legacy + // `orientationchange` event) whose handler can detach this widget's local + // root and Close() this WebFrameWidgetImpl, resetting `widget_base_`. + if (!widget_base_) { + return; + } // Store this even when auto-resizing, it is the size of the full viewport // used for clipping, and this value is propagated down the Widget diff --git a/third_party/blink/renderer/platform/widget/widget_base.cc b/third_party/blink/renderer/platform/widget/widget_base.cc index 70a4733201db9..781b2b046b68f 100644 --- a/third_party/blink/renderer/platform/widget/widget_base.cc +++ b/third_party/blink/renderer/platform/widget/widget_base.cc @@ -1844,8 +1844,16 @@ void WidgetBase::UpdateSurfaceAndScreenInfo( screen_infos_.current().display_color_spaces); } - if (orientation_changed) + if (orientation_changed) { + // OrientationChanged() may synchronously dispatch the legacy + // `orientationchange` DOM event (Android), whose handler can detach this + // widget's local-root frame and free `this` via WebFrameWidgetImpl::Close. + auto weak_this = weak_ptr_factory_.GetWeakPtr(); client_->OrientationChanged(); + if (!weak_this) { + return; + } + } client_->DidUpdateSurfaceAndScreen(previous_original_screen_infos); }