Do not crash when the descendant frame tree is destroyed during layout.
authorzalan@apple.com <zalan@apple.com@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Fri, 12 Jun 2015 02:49:12 +0000 (02:49 +0000)
committerzalan@apple.com <zalan@apple.com@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Fri, 12 Jun 2015 02:49:12 +0000 (02:49 +0000)
commit23d26887c616fc711c4aa8d3a8ba05ba350e8405
treecc66e8ef3ef8fc9719429a29bd90bca110f9aa1d
parentec0d077e40b3c2166f406938bb8f730adc097c2f
Do not crash when the descendant frame tree is destroyed during layout.
https://bugs.webkit.org/show_bug.cgi?id=144540
rdar://problem/20793184

Reviewed by Andreas Kling.

Source/WebCore:

Widget::setFrameRect(), through WebHTMLView layout, could trigger a style recalc, which in turn
could initiate an onBeforeLoad callback.
If javascript happens to destroy the current iframe in the onBeforeLoad callback, we lose the descendant
render tree, including the child FrameView (the iframe element's view). However the RenderIFrame
object stays protected until after the layout is done. (see protectRenderWidgetUntilLayoutIsDone())

Climbing back on the callstack, we need to make sure that
1. the root widget of the descendant render tree (FrameView) stays valid as long as it is needed.
2. RenderFrameBase::layoutWithFlattening() can handle the case when the associated widget (child FrameView) is set to nullptr.
(see RenderWidget::willBeDestroyed() -> setWidget(nullptr))

(and later, when layout is finished this (RenderIFrame) object gets destroyed too.)

Covered by fast/frames/flattening/crash-remove-iframe-during-object-beforeload.html.

* page/FrameView.cpp:
(WebCore::FrameView::setFrameRect):
(WebCore::FrameView::updateEmbeddedObject):
(WebCore::FrameView::updateWidgetPositions):
* platform/ScrollView.cpp:
(WebCore::ScrollView::setFrameRect):
* platform/mac/WidgetMac.mm:
(WebCore::Widget::setFrameRect):
* rendering/RenderFrameBase.cpp:
(WebCore::RenderFrameBase::layoutWithFlattening):
(WebCore::RenderFrameBase::childRenderView):
(WebCore::RenderFrameBase::peformLayoutWithFlattening):
* rendering/RenderFrameBase.h:
* rendering/RenderWidget.cpp:
(WebCore::RenderWidget::updateWidgetPosition):
* rendering/RenderWidget.h:

LayoutTests:

Unskip fast/frames/flattening/crash-remove-iframe-during-object-beforeload.html.

* TestExpectations:

git-svn-id: https://svn.webkit.org/repository/webkit/trunk@185484 268f45cc-cd09-0410-ab3c-d52691b4dbfc
LayoutTests/ChangeLog
LayoutTests/TestExpectations
Source/WebCore/ChangeLog
Source/WebCore/page/FrameView.cpp
Source/WebCore/platform/ScrollView.cpp
Source/WebCore/platform/mac/WidgetMac.mm
Source/WebCore/rendering/RenderFrameBase.cpp
Source/WebCore/rendering/RenderFrameBase.h
Source/WebCore/rendering/RenderWidget.cpp
Source/WebCore/rendering/RenderWidget.h