Reviewed by Eric Seidel.
authormitz <mitz@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Wed, 24 Oct 2007 01:51:04 +0000 (01:51 +0000)
committermitz <mitz@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Wed, 24 Oct 2007 01:51:04 +0000 (01:51 +0000)
        - fix http://bugs.webkit.org/show_bug.cgi?id=15405
          ASSERTION FAILED: d->m_view && !d->m_view->needsLayout() in Frame::Paint

        Calling updateWidget() during attach() led to arbitrary (plugin and resource load delegate)
        code execution under attach(). The fix is to use the mechanism that's already in place for
        deferring updateWidget() until after layout.

        * html/HTMLEmbedElement.cpp:
        (WebCore::HTMLEmbedElement::attach): Replaced call to updateWidget() with call to updateWidgetSoon()
        * html/HTMLObjectElement.cpp:
        (WebCore::HTMLObjectElement::attach): Ditto.
        * manual-tests/paint-during-plugin-attach.html: Added.
        * rendering/RenderPartObject.cpp:
        (WebCore::RenderPartObject::updateWidgetSoon): Added this function that schedules the
        updateWidget() call for after the next layout.
        * rendering/RenderPartObject.h:

git-svn-id: https://svn.webkit.org/repository/webkit/trunk@26941 268f45cc-cd09-0410-ab3c-d52691b4dbfc

WebCore/ChangeLog
WebCore/html/HTMLEmbedElement.cpp
WebCore/html/HTMLObjectElement.cpp
WebCore/manual-tests/paint-during-plugin-attach.html [new file with mode: 0644]
WebCore/rendering/RenderPartObject.cpp
WebCore/rendering/RenderPartObject.h

index 346a120a8d667090d0e5d7d6b159446dc4413281..01722701062f148d881b45569018dd53b17f811f 100644 (file)
@@ -1,3 +1,24 @@
+2007-10-23  Dan Bernstein  <mitz@apple.com>
+
+        Reviewed by Eric Seidel.
+
+        - fix http://bugs.webkit.org/show_bug.cgi?id=15405
+          ASSERTION FAILED: d->m_view && !d->m_view->needsLayout() in Frame::Paint
+
+        Calling updateWidget() during attach() led to arbitrary (plugin and resource load delegate)
+        code execution under attach(). The fix is to use the mechanism that's already in place for
+        deferring updateWidget() until after layout.
+
+        * html/HTMLEmbedElement.cpp:
+        (WebCore::HTMLEmbedElement::attach): Replaced call to updateWidget() with call to updateWidgetSoon()
+        * html/HTMLObjectElement.cpp:
+        (WebCore::HTMLObjectElement::attach): Ditto.
+        * manual-tests/paint-during-plugin-attach.html: Added.
+        * rendering/RenderPartObject.cpp:
+        (WebCore::RenderPartObject::updateWidgetSoon): Added this function that schedules the
+        updateWidget() call for after the next layout.
+        * rendering/RenderPartObject.h:
+
 2007-10-23  Adam Roben  <aroben@apple.com>
 
         Fix the behavior of pathByAppendingComponent when path is empty
index b76c2a900c4735b2bf7eb63b01ac256f28302ab8..fc82a7d6ca5e741e7899ceeb21c9807151ea0fea 100644 (file)
@@ -156,7 +156,7 @@ void HTMLEmbedElement::attach()
     HTMLPlugInElement::attach();
 
     if (renderer())
-        static_cast<RenderPartObject*>(renderer())->updateWidget(true);
+        static_cast<RenderPartObject*>(renderer())->updateWidgetSoon();
 }
 
 void HTMLEmbedElement::detach()
index 2d98d57741dd83811fb7ce43fd83d7faebc38bea..3ac3f56677b543f9226beacbb453b72236653919 100644 (file)
@@ -186,7 +186,7 @@ void HTMLObjectElement::attach()
                 // Set m_needWidgetUpdate to false before calling updateWidget because updateWidget may cause
                 // this method or recalcStyle (which also calls updateWidget) to be called.
                 m_needWidgetUpdate = false;
-                static_cast<RenderPartObject*>(renderer())->updateWidget(true);
+                static_cast<RenderPartObject*>(renderer())->updateWidgetSoon();
             } else {
                 m_needWidgetUpdate = true;
                 setChanged();
diff --git a/WebCore/manual-tests/paint-during-plugin-attach.html b/WebCore/manual-tests/paint-during-plugin-attach.html
new file mode 100644 (file)
index 0000000..2cb18bf
--- /dev/null
@@ -0,0 +1,30 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN"
+        "http://www.w3.org/TR/html4/strict.dtd">
+<html lang="en">
+<head>
+</head>
+<body>
+<p><b>BUG ID:</b> <a href="http://bugs.webkit.org/show_bug.cgi?id=15405">Bugzilla bug 15405</a> ASSERTION FAILED: d->m_view && !d->m_view->needsLayout() in Frame::Paint</p>
+
+<p id="test" style="background-color:skyblue; padding:3px;"><b>STEPS TO TEST:</b> 
+Open this page with a debug build of WebKit, and click the Test button below.
+</p>
+
+<p id="success" style="background-color:palegreen; padding:3px;"><b>TEST PASS:</b> 
+A new window will open with a sheet saying Safari cannot find the Internet plug-in. You will be able to click the Cancel button and close the window.
+</p>
+
+<p id="failure" style="background-color:#FF3300; padding:3px;"><b>TEST FAIL:</b>  
+A new window will open with a sheet saying Safari cannot find the Internet plug-in, then Safari will crash due to an assertion failure.
+</p>
+
+<script>
+    function insertObject()
+    {
+        var objectMarkup = '<object type="application/x-fake-plugin"></object>';
+        open("data:text/html," + objectMarkup + "No assertion failure means the test passed.", "Test");
+    }
+</script>
+<button onclick="insertObject()">Test</button>
+</body>
+</html>
index bdaa579369fe8ce772274a7785684afbfbda0ae5..6becc5025b8feae666ffb979f69419f75926da07 100644 (file)
@@ -280,6 +280,12 @@ void RenderPartObject::layout()
     setNeedsLayout(false);
 }
 
+void RenderPartObject::updateWidgetSoon()
+{
+    if (m_view)
+        m_view->addWidgetToUpdate(this);
+}
+
 void RenderPartObject::viewCleared()
 {
     if (element() && m_widget && m_widget->isFrameView()) {
index 2b1803c19b471f29f39d7d2c1a974ef1c5288842..c262ef8ebfaf997b193e21ac7a4953a6c5394b33 100644 (file)
@@ -38,6 +38,7 @@ public:
 
     virtual void layout();
     void updateWidget(bool onlyCreateNonPlugins);
+    void updateWidgetSoon();
 
     virtual void viewCleared();
 };