• mitz@apple.com's avatar
    WebCore: https://bugs.webkit.org/show_bug.cgi?id=31070 · 9915160d
    mitz@apple.com authored
    Fix <rdar://problem/7194735> Crashes at RenderText::RenderText()
    Fix <rdar://problem/6937089> Crashes at RenderWidget::destroy()
    Reviewed by Anders Carlsson and Beth Dakin.
    Tests: plugins/attach-during-destroy.html
    These crashes were caused by plug-in code running during detach(),
    causing re-entry into RenderWidget::destroy() in one case and a call
    into attach() in the other. The fix is to prevent plug-in code from
    being called at certain unsafe times (during attach(), detach(), and
    recalcStyle()) by deferring changes to the widget hierarchy.
    * dom/Document.cpp:
    (WebCore::Document::recalcStyle): Suspend widget hierarchy updates
        during style recalculation.
    * dom/Element.cpp:
    (WebCore::Element::attach): Suspend widget hierarchy updates during
    (WebCore::Element::detach): Suspend widget hierarchy updates during
    * rendering/RenderWidget.cpp:
    (WebCore::widgetNewParentMap): Returns a static map of pending changes
        to the widget hierarchy.
    (WebCore::RenderWidget::suspendWidgetHierarchyUpdates): Increments the
        suspend count.
    (WebCore::RenderWidget::resumeWidgetHierarchyUpdates): Decrements the
        suspend count. If the count is going to be zero, updates the widget
        hierarchy by executing the pending changes stored in the map.
    (WebCore::moveWidgetToParentSoon): Updates the widget hierarchy
        immediately or makes or updates an entry in the map, depending on
        whether updates are suspended.
    (WebCore::RenderWidget::destroy): Removed earlier bandaid fix for
    (WebCore::RenderWidget::setWidgetGeometry): Assert that widget updates
        are not suspended, because this function updates the widget’s
        bounds, which can result in arbitrary native and JavaScript code
        execution. I think this assertion is true thanks to some deferred-
        update mechanisms that have already been deployed in other places
        in the code.
    (WebCore::RenderWidget::setWidget): Call moveWidgetToParentSoon instead
        of changing the widget hierarchy directly.
    * rendering/RenderWidget.h: Declared suspendWidgetHierarchyUpdates()
        and resumeWidgetHierarchyUpdates().
    WebKitTools: https://bugs.webkit.org/show_bug.cgi?id=31070
    Reviewed by Anders Carlsson and Beth Dakin.
    Added an 'ondestroy' parameter to the test plug-in. When the plug-in is
    destroyed, it executes the value of the 'ondestroy' parameter as a
    * DumpRenderTree/TestNetscapePlugIn.subproj/PluginObject.cpp:
    (pluginAllocate): Initialize onDestroy.
    * DumpRenderTree/TestNetscapePlugIn.subproj/PluginObject.h: Define
    * DumpRenderTree/TestNetscapePlugIn.subproj/main.cpp:
    (NPP_New): Set onDestroy to the value of the 'ondestroy' parameter, if
    (NPP_Destroy): Execute the value of 'ondestroy' as a script.
    LayoutTests: https://bugs.webkit.org/show_bug.cgi?id=31070
    Test for <rdar://problem/7194735> Crashes at RenderText::RenderText()
    Test for <rdar://problem/6937089> Crashes at RenderWidget::destroy()
    Reviewed by Anders Carlsson and Beth Dakin.
    * plugins/attach-during-destroy-expected.txt: Added.
    * plugins/attach-during-destroy.html: Added.
    * plugins/destroy-reentry-expected.txt: Added.
    * plugins/destroy-reentry.html: Added.
    git-svn-id: http://svn.webkit.org/repository/webkit/trunk@50470 268f45cc-cd09-0410-ab3c-d52691b4dbfc