Title: [121001] trunk
Revision
121001
Author
[email protected]
Date
2012-06-21 21:01:57 -0700 (Thu, 21 Jun 2012)

Log Message

Crash in RenderBlock::layoutPositionedObjects.
https://bugs.webkit.org/show_bug.cgi?id=89599

Reviewed by Julien Chaffraix.

Source/WebCore:

Test: fast/table/table-split-positioned-object-crash.html

* rendering/RenderBlock.cpp:
(WebCore::RenderBlock::splitBlocks): no longer need to explicitly call
removePositionedObjects, since it is part of moveChildrenTo.
* rendering/RenderBlock.h:
(WebCore::RenderBlock::hasPositionedObjects): helper to tell if we have
positioned objects in our list.
* rendering/RenderBox.cpp:
(WebCore::RenderBox::splitAnonymousBoxesAroundChild): Like r102263, this
condition was wrong and while moving children across completely different
trees, we need fullRemoveInsert as true.
* rendering/RenderBoxModelObject.cpp:
(WebCore::RenderBoxModelObject::moveChildTo): see code comment.
(WebCore::RenderBoxModelObject::moveChildrenTo): see code comment.

LayoutTests:

* fast/table/table-split-positioned-object-crash-expected.txt: Added.
* fast/table/table-split-positioned-object-crash.html: Added.

Modified Paths

Added Paths

Diff

Modified: trunk/LayoutTests/ChangeLog (121000 => 121001)


--- trunk/LayoutTests/ChangeLog	2012-06-22 03:51:01 UTC (rev 121000)
+++ trunk/LayoutTests/ChangeLog	2012-06-22 04:01:57 UTC (rev 121001)
@@ -1,3 +1,13 @@
+2012-06-21  Abhishek Arya  <[email protected]>
+
+        Crash in RenderBlock::layoutPositionedObjects.
+        https://bugs.webkit.org/show_bug.cgi?id=89599
+
+        Reviewed by Julien Chaffraix.
+
+        * fast/table/table-split-positioned-object-crash-expected.txt: Added.
+        * fast/table/table-split-positioned-object-crash.html: Added.
+
 2012-06-21  Tony Gentilcore  <[email protected]>
 
         [Chromium][Win] Missing trailing newlines in one text test expectation, debug only

Added: trunk/LayoutTests/fast/table/table-split-positioned-object-crash-expected.txt (0 => 121001)


--- trunk/LayoutTests/fast/table/table-split-positioned-object-crash-expected.txt	                        (rev 0)
+++ trunk/LayoutTests/fast/table/table-split-positioned-object-crash-expected.txt	2012-06-22 04:01:57 UTC (rev 121001)
@@ -0,0 +1,3 @@
+WebKit Bug 89599 - Crash in RenderBlock::layoutPositionedObjects.
+Test passes if it does not crash.
+

Added: trunk/LayoutTests/fast/table/table-split-positioned-object-crash.html (0 => 121001)


--- trunk/LayoutTests/fast/table/table-split-positioned-object-crash.html	                        (rev 0)
+++ trunk/LayoutTests/fast/table/table-split-positioned-object-crash.html	2012-06-22 04:01:57 UTC (rev 121001)
@@ -0,0 +1,35 @@
+<!DOCTYPE html>
+<html>
+WebKit Bug 89599 - Crash in RenderBlock::layoutPositionedObjects.<br />
+Test passes if it does not crash.
+<style>
+table { position: relative; }
+.span:last-child { position: relative; }
+</style>
+<script>
+if (window.layoutTestController)
+    layoutTestController.dumpAsText();
+
+function crash() {
+    table = document.createElement('table');
+    document.documentElement.appendChild(table);
+    
+    span1 = document.createElement('span');
+    span2 = document.createElement('span');
+    span3 = document.createElement('span');
+    span3.setAttribute('class', 'span');
+    span4 = document.createElement('span');
+    span4.style.position = 'absolute';
+    span3.appendChild(span4);
+
+    table.appendChild(span1);
+    table.appendChild(span2);
+    table.appendChild(span3);
+
+    document.documentElement.offsetTop;
+    span2.style.display = 'table-header-group';
+    span3.style.display = 'block'
+}
+window._onload_ = crash;
+</script>
+</html>
Property changes on: trunk/LayoutTests/fast/table/table-split-positioned-object-crash.html
___________________________________________________________________

Added: svn:executable

Modified: trunk/Source/WebCore/ChangeLog (121000 => 121001)


--- trunk/Source/WebCore/ChangeLog	2012-06-22 03:51:01 UTC (rev 121000)
+++ trunk/Source/WebCore/ChangeLog	2012-06-22 04:01:57 UTC (rev 121001)
@@ -1,3 +1,26 @@
+2012-06-21  Abhishek Arya  <[email protected]>
+
+        Crash in RenderBlock::layoutPositionedObjects.
+        https://bugs.webkit.org/show_bug.cgi?id=89599
+
+        Reviewed by Julien Chaffraix.
+
+        Test: fast/table/table-split-positioned-object-crash.html
+
+        * rendering/RenderBlock.cpp:
+        (WebCore::RenderBlock::splitBlocks): no longer need to explicitly call
+        removePositionedObjects, since it is part of moveChildrenTo.
+        * rendering/RenderBlock.h:
+        (WebCore::RenderBlock::hasPositionedObjects): helper to tell if we have
+        positioned objects in our list.
+        * rendering/RenderBox.cpp:
+        (WebCore::RenderBox::splitAnonymousBoxesAroundChild): Like r102263, this
+        condition was wrong and while moving children across completely different 
+        trees, we need fullRemoveInsert as true.
+        * rendering/RenderBoxModelObject.cpp:
+        (WebCore::RenderBoxModelObject::moveChildTo): see code comment.
+        (WebCore::RenderBoxModelObject::moveChildrenTo): see code comment. 
+
 2012-06-21  Kwang Yul Seo  <[email protected]>
 
         Make HTMLDocumentParser::create(DocumentFragment*,Element*, FragmentScriptingPermission) private.

Modified: trunk/Source/WebCore/rendering/RenderBlock.cpp (121000 => 121001)


--- trunk/Source/WebCore/rendering/RenderBlock.cpp	2012-06-22 03:51:01 UTC (rev 121000)
+++ trunk/Source/WebCore/rendering/RenderBlock.cpp	2012-06-22 04:01:57 UTC (rev 121001)
@@ -568,14 +568,6 @@
     if (beforeChild && childrenInline())
         deleteLineBoxTree();
 
-    // We have to remove the descendant child from our positioned objects list
-    // before we do the split and move some of the children to cloneBlock. Since
-    // we are doing layout anyway, it is easier to blow away the entire list, than
-    // traversing down the subtree looking for positioned childs and then remove them
-    // from our positioned objects list.
-    if (beforeChild)
-        removePositionedObjects(0);
-
     // Now take all of the children from beforeChild to the end and remove
     // them from |this| and place them in the clone.
     moveChildrenTo(cloneBlock, beforeChild, 0, true);
@@ -629,12 +621,6 @@
             currChildNextSibling = 0; // We destroyed the last child, so now we need to update
                                       // the value of currChildNextSibling.
 
-        // It is possible that positioned objects under blockCurr are going to be moved to cloneBlock.
-        // Since we are doing layout anyway, it is easier to blow away the entire list, than
-        // traversing down the subtree looking for positioned children and then remove them
-        // from our positioned objects list.
-        blockCurr->removePositionedObjects(0);
-
         // Now we need to take all of the children starting from the first child
         // *after* currChild and append them all to the clone.
         blockCurr->moveChildrenTo(cloneBlock, currChildNextSibling, 0, true);

Modified: trunk/Source/WebCore/rendering/RenderBlock.h (121000 => 121001)


--- trunk/Source/WebCore/rendering/RenderBlock.h	2012-06-22 03:51:01 UTC (rev 121000)
+++ trunk/Source/WebCore/rendering/RenderBlock.h	2012-06-22 04:01:57 UTC (rev 121001)
@@ -104,6 +104,7 @@
 
     typedef ListHashSet<RenderBox*, 4> PositionedObjectsListHashSet;
     PositionedObjectsListHashSet* positionedObjects() const { return m_positionedObjects.get(); }
+    bool hasPositionedObjects() const { return m_positionedObjects && !m_positionedObjects->isEmpty(); }
 
     void addPercentHeightDescendant(RenderBox*);
     static void removePercentHeightDescendant(RenderBox*);

Modified: trunk/Source/WebCore/rendering/RenderBox.cpp (121000 => 121001)


--- trunk/Source/WebCore/rendering/RenderBox.cpp	2012-06-22 03:51:01 UTC (rev 121000)
+++ trunk/Source/WebCore/rendering/RenderBox.cpp	2012-06-22 04:01:57 UTC (rev 121001)
@@ -3979,7 +3979,7 @@
             postBox->setChildrenInline(boxToSplit->childrenInline());
             RenderBox* parentBox = toRenderBox(boxToSplit->parent());
             parentBox->virtualChildren()->insertChildNode(parentBox, postBox, boxToSplit->nextSibling());
-            boxToSplit->moveChildrenTo(postBox, beforeChild, 0, boxToSplit->hasLayer());
+            boxToSplit->moveChildrenTo(postBox, beforeChild, 0, true);
 
             markBoxForRelayoutAfterSplit(boxToSplit);
             markBoxForRelayoutAfterSplit(postBox);

Modified: trunk/Source/WebCore/rendering/RenderBoxModelObject.cpp (121000 => 121001)


--- trunk/Source/WebCore/rendering/RenderBoxModelObject.cpp	2012-06-22 03:51:01 UTC (rev 121000)
+++ trunk/Source/WebCore/rendering/RenderBoxModelObject.cpp	2012-06-22 04:01:57 UTC (rev 121001)
@@ -2758,6 +2758,11 @@
 
 void RenderBoxModelObject::moveChildTo(RenderBoxModelObject* toBoxModelObject, RenderObject* child, RenderObject* beforeChild, bool fullRemoveInsert)
 {
+    // FIXME: We need a performant way to handle clearing positioned objects from our list that are
+    // in |child|'s subtree so we could just clear them here. Because of this, we assume that callers
+    // have cleared their positioned objects list for child moves (!fullRemoveInsert) to avoid any badness.
+    ASSERT(!fullRemoveInsert || !isRenderBlock() || !toRenderBlock(this)->hasPositionedObjects());
+
     ASSERT(this == child->parent());
     ASSERT(!beforeChild || toBoxModelObject == beforeChild->parent());
     if (fullRemoveInsert && (toBoxModelObject->isRenderBlock() || toBoxModelObject->isRenderInline())) {
@@ -2770,6 +2775,15 @@
 
 void RenderBoxModelObject::moveChildrenTo(RenderBoxModelObject* toBoxModelObject, RenderObject* startChild, RenderObject* endChild, RenderObject* beforeChild, bool fullRemoveInsert)
 {
+    // This condition is rarely hit since this function is usually called on
+    // anonymous blocks which can no longer carry positioned objects (see r120761)
+    // or when fullRemoveInsert is false.
+    if (fullRemoveInsert && isRenderBlock()) {
+        RenderBlock* block = toRenderBlock(this);
+        if (block->hasPositionedObjects())
+            block->removePositionedObjects(0);
+    }
+
     ASSERT(!beforeChild || toBoxModelObject == beforeChild->parent());
     for (RenderObject* child = startChild; child && child != endChild; ) {
         // Save our next sibling as moveChildTo will clear it.
_______________________________________________
webkit-changes mailing list
[email protected]
http://lists.webkit.org/mailman/listinfo.cgi/webkit-changes

Reply via email to