Reviewed by Hyatt
authorbdakin <bdakin@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Sat, 11 Feb 2006 02:08:57 +0000 (02:08 +0000)
committerbdakin <bdakin@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Sat, 11 Feb 2006 02:08:57 +0000 (02:08 +0000)
        Fix for <rdar://problem/4149655> Frequently reported crash, repro
        at lastminute.se in khtml::RenderBlock::createLineBoxes

        Some crazy combination of an anonymous table, an inline form, and
        generated content caused table objects to be added to a flow and
        then split. This is very bad. Once the crash was fixed, there were
        still some rendering issues that this patch also fixes. We needed
        to make sure we only special case forms for non-CSS tables so that
        the form and generated content render as expected.

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

WebCore/ChangeLog
WebCore/rendering/RenderContainer.cpp
WebCore/rendering/RenderTable.cpp
WebCore/rendering/RenderTableRow.cpp
WebCore/rendering/RenderTableSection.cpp
WebCore/rendering/render_inline.cpp

index 7b31982..dea8ef2 100644 (file)
@@ -1,3 +1,31 @@
+2006-02-10  Beth Dakin  <bdakin@apple.com>
+
+        Reviewed by Hyatt
+
+        Fix for <rdar://problem/4149655> Frequently reported crash, repro 
+        at lastminute.se in khtml::RenderBlock::createLineBoxes
+
+        Some crazy combination of an anonymous table, an inline form, and 
+        generated content caused table objects to be added to a flow and 
+        then split. This is very bad. Once the crash was fixed, there were 
+        still some rendering issues that this patch also fixes. We needed 
+        to make sure we only special case forms for non-CSS tables so that 
+        the form and generated content render as expected.
+
+        * rendering/RenderContainer.cpp:
+        (WebCore::RenderContainer::appendChildNode): Assert that if we are 
+        a block flow, our child cannot be a table object.
+        (WebCore::RenderContainer::insertChildNode): Same.
+        * rendering/RenderTable.cpp:
+        (WebCore::RenderTable::addChild): Only special-case forms if we are 
+        not a CSS table.
+        * rendering/RenderTableRow.cpp:
+        (WebCore::RenderTableRow::addChild): Same.
+        * rendering/RenderTableSection.cpp:
+        (WebCore::RenderTableSection::addChild): Same.
+        * rendering/render_inline.cpp:
+        (WebCore::RenderInline::addChildToFlow): Here is the crash fix. Check to make sure our containing block is a block flow.
+
 2006-02-10  Darin Adler  <darin@apple.com>
 
         - fixed the build, this time for sure
index bf0258a..09101ca 100644 (file)
@@ -324,6 +324,7 @@ void RenderContainer::updatePseudoChild(RenderStyle::PseudoId type, RenderObject
 void RenderContainer::appendChildNode(RenderObject* newChild)
 {
     KHTMLAssert(newChild->parent() == 0);
+    KHTMLAssert(!isBlockFlow() || (!newChild->isTableSection() && !newChild->isTableRow() && !newChild->isTableCell()));
 
     newChild->setParent(this);
     RenderObject* lChild = lastChild();
@@ -370,6 +371,8 @@ void RenderContainer::insertChildNode(RenderObject* child, RenderObject* beforeC
        beforeChild = beforeChild->parent();
     KHTMLAssert(beforeChild->parent() == this);
 
+    KHTMLAssert(!isBlockFlow() || (!child->isTableSection() && !child->isTableRow() && !child->isTableCell()));
+
     if(beforeChild == firstChild())
         setFirstChild(child);
 
index 7b9fa7d..5f189bf 100644 (file)
@@ -95,6 +95,7 @@ void RenderTable::setStyle(RenderStyle *_style)
 void RenderTable::addChild(RenderObject* child, RenderObject* beforeChild)
 {
     bool wrapInAnonymousSection = true;
+    bool isTableElement = element() && element()->hasTagName(tableTag);
 
     switch (child->style()->display()) {
         case TABLE_CAPTION:
@@ -147,7 +148,7 @@ void RenderTable::addChild(RenderObject* child, RenderObject* beforeChild)
         case RUN_IN:
         case TABLE:
             // Allow a form to just sit at the top level.
-            wrapInAnonymousSection = !(child->element() && child->element()->hasTagName(formTag));
+            wrapInAnonymousSection = !isTableElement || !child->element() || !child->element()->hasTagName(formTag);
             break;
         }
 
index 7b407e2..c356051 100644 (file)
@@ -58,8 +58,10 @@ void RenderTableRow::setStyle(RenderStyle* style)
 
 void RenderTableRow::addChild(RenderObject* child, RenderObject* beforeChild)
 {
+    bool isTableRow = element() && element()->hasTagName(trTag);
+    
     if (!child->isTableCell()) {
-        if (child->element() && child->element()->hasTagName(formTag)) {
+        if (isTableRow && child->element() && child->element()->hasTagName(formTag)) {
             RenderContainer::addChild(child, beforeChild);
             return;
         }
index 92df6bf..dbd33b6 100644 (file)
@@ -76,8 +76,10 @@ void RenderTableSection::setStyle(RenderStyle* _style)
 
 void RenderTableSection::addChild(RenderObject* child, RenderObject* beforeChild)
 {
+    bool isTableSection = element() && (element()->hasTagName(theadTag) || element()->hasTagName(tbodyTag) || element()->hasTagName(tfootTag));
+
     if (!child->isTableRow()) {
-        if (child->element() && child->element()->hasTagName(formTag) && child->style()->display() != TABLE_CELL) {
+        if (isTableSection && child->element() && child->element()->hasTagName(formTag)) {
             RenderContainer::addChild(child, beforeChild);
             return;
         }
index 7e35966..ac64647 100644 (file)
@@ -81,8 +81,7 @@ void RenderInline::addChildToFlow(RenderObject* newChild, RenderObject* beforeCh
     if (!beforeChild && lastChild() && lastChild()->style()->styleType() == RenderStyle::AFTER)
         beforeChild = lastChild();
 
-    if (!newChild->isInline() && !newChild->isFloatingOrPositioned() )
-    {
+    if (!newChild->isInline() && !newChild->isFloatingOrPositioned() && containingBlock()->isBlockFlow()) {
         // We are placing a block inside an inline. We have to perform a split of this
         // inline into continuations.  This involves creating an anonymous block box to hold
         // |newChild|.  We then make that block box a continuation of this inline.  We take all of