Reviewed by Anders.
authorantti <antti@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Fri, 31 Aug 2007 22:09:03 +0000 (22:09 +0000)
committerantti <antti@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Fri, 31 Aug 2007 22:09:03 +0000 (22:09 +0000)
        Fix <rdar://problem/5452943>
        REGRESSION (r25283): Reproducible crash in HTMLObjectElement::getInstance under guard malloc

        Calling updateLayoutIgnorePendingStylesheets() may do arbitrary things to render tree so
        no RenderObjects can be cached over it.

        * html/HTMLEmbedElement.cpp:
        (WebCore::findWidgetRenderer):
        (WebCore::HTMLEmbedElement::getInstance):
        * html/HTMLObjectElement.cpp:
        (WebCore::HTMLObjectElement::getInstance):

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

WebCore/ChangeLog
WebCore/html/HTMLEmbedElement.cpp
WebCore/html/HTMLObjectElement.cpp

index 2269d72c75e5ef44a8349f4714c7856d16763555..5fadd64f485f638368c5b26306308086c7808a5b 100644 (file)
@@ -1,3 +1,19 @@
+2007-08-31  Antti Koivisto  <antti@apple.com>
+
+        Reviewed by Anders.
+
+        Fix <rdar://problem/5452943>
+        REGRESSION (r25283): Reproducible crash in HTMLObjectElement::getInstance under guard malloc
+        
+        Calling updateLayoutIgnorePendingStylesheets() may do arbitrary things to render tree so
+        no RenderObjects can be cached over it.
+
+        * html/HTMLEmbedElement.cpp:
+        (WebCore::findWidgetRenderer):
+        (WebCore::HTMLEmbedElement::getInstance):
+        * html/HTMLObjectElement.cpp:
+        (WebCore::HTMLObjectElement::getInstance):
+
 2007-08-31  Anders Carlsson  <andersca@apple.com>
 
         Reviewed by Mitz.
index 2dd2b33035767c1b1c9c837d002f322247691fd3..4a232b4e0da92bd07a12eb97a9910dba01a81e26 100644 (file)
@@ -57,6 +57,17 @@ HTMLEmbedElement::~HTMLEmbedElement()
 }
 
 #if USE(JAVASCRIPTCORE_BINDINGS)
+static inline RenderWidget* findWidgetRenderer(const Node* n) 
+{
+    if (!n->renderer())
+        do
+            n = n->parentNode();
+        while (n && !n->hasTagName(objectTag));
+    
+    return (n && n->renderer() && n->renderer()->isWidget()) 
+        ? static_cast<RenderWidget*>(n->renderer()) : 0;
+}
+    
 KJS::Bindings::Instance *HTMLEmbedElement::getInstance() const
 {
     Frame* frame = document()->frame();
@@ -66,29 +77,15 @@ KJS::Bindings::Instance *HTMLEmbedElement::getInstance() const
     if (m_instance)
         return m_instance.get();
     
-    RenderObject *r = renderer();
-    if (!r) {
-        Node *p = parentNode();
-        
-        while (p) {
-            if (p->hasTagName(objectTag)) {
-                r = p->renderer();
-                break;
-            }
-            
-            p = p->parentNode();
-        }
-    }
-
-    if (r && r->isWidget()) {
-        RenderWidget* renderWidget = static_cast<RenderWidget*>(r);
-        
-        if (!renderWidget->widget())
-            document()->updateLayoutIgnorePendingStylesheets();
-        
-        if (Widget* widget = renderWidget->widget()) 
-            m_instance = frame->createScriptInstanceForWidget(widget);
+    RenderWidget* renderWidget = findWidgetRenderer(this);
+    if (renderWidget && !renderWidget->widget()) {
+        document()->updateLayoutIgnorePendingStylesheets();
+        renderWidget = findWidgetRenderer(this);
     }
+    
+    if (renderWidget && renderWidget->widget()) 
+        m_instance = frame->createScriptInstanceForWidget(renderWidget->widget());
+    
     return m_instance.get();
 }
 #endif
index 8b56a18a43ee06326cec54dd6bba00fda38afddb..fc2934f138a43a41b646ff0362b323ff871a0881 100644 (file)
@@ -81,17 +81,13 @@ KJS::Bindings::Instance *HTMLObjectElement::getInstance() const
     if (m_instance)
         return m_instance.get();
 
-    RenderObject* r = renderer();
-
-    if (r && r->isWidget()) {
-        RenderWidget* renderWidget = static_cast<RenderWidget*>(r);
-            
-        if (!renderWidget->widget())
-            document()->updateLayoutIgnorePendingStylesheets();
-          
-        if (Widget* widget = renderWidget->widget()) 
-            m_instance = frame->createScriptInstanceForWidget(widget);
-    }
+    RenderWidget* renderWidget = (renderer() && renderer()->isWidget()) ? static_cast<RenderWidget*>(renderer()) : 0;
+    if (renderWidget && !renderWidget->widget()) {
+        document()->updateLayoutIgnorePendingStylesheets();
+        renderWidget = (renderer() && renderer()->isWidget()) ? static_cast<RenderWidget*>(renderer()) : 0;
+    }          
+    if (renderWidget && renderWidget->widget()) 
+        m_instance = frame->createScriptInstanceForWidget(renderWidget->widget());
 
     return m_instance.get();
 }