Title: [96012] branches/chromium/835
Revision
96012
Author
[email protected]
Date
2011-09-26 15:45:37 -0700 (Mon, 26 Sep 2011)

Log Message

Merge 95054 - Source/WebCore: Fixes several bugs when adding CounterNodes to a tree which can cause asymetrical relationships.

BUG=92226
Review URL: http://codereview.chromium.org/8048004

Modified Paths

Added Paths

Diff

Copied: branches/chromium/835/LayoutTests/fast/css/counters/counter-reparent-table-children-crash-expected.txt (from rev 95054, trunk/LayoutTests/fast/css/counters/counter-reparent-table-children-crash-expected.txt) (0 => 96012)


--- branches/chromium/835/LayoutTests/fast/css/counters/counter-reparent-table-children-crash-expected.txt	                        (rev 0)
+++ branches/chromium/835/LayoutTests/fast/css/counters/counter-reparent-table-children-crash-expected.txt	2011-09-26 22:45:37 UTC (rev 96012)
@@ -0,0 +1 @@
+PASS: Malformed table counters do not cause crash

Copied: branches/chromium/835/LayoutTests/fast/css/counters/counter-reparent-table-children-crash.html (from rev 95054, trunk/LayoutTests/fast/css/counters/counter-reparent-table-children-crash.html) (0 => 96012)


--- branches/chromium/835/LayoutTests/fast/css/counters/counter-reparent-table-children-crash.html	                        (rev 0)
+++ branches/chromium/835/LayoutTests/fast/css/counters/counter-reparent-table-children-crash.html	2011-09-26 22:45:37 UTC (rev 96012)
@@ -0,0 +1,31 @@
+<html>
+<style>
+td {
+    counter-increment: list-item;
+}
+</style>
+<script>
+if (window.layoutTestController) {
+    layoutTestController.waitUntilDone();
+}
+
+function crash() {
+    document.body.innerHTML = "PASS: Malformed table counters do not cause crash";
+    if (window.layoutTestController) {
+        layoutTestController.notifyDone();
+        layoutTestController.dumpAsText();
+    }
+}
+</script>
+<body _onload_="crash()">
+    <table>
+        <tbody>
+            <td>
+        </tbody>
+        <ol>re-parent me</ol>
+        <ol>re-parent me</ol>
+            </td>
+        <td></td>
+    </table>
+</body>
+</html>

Modified: branches/chromium/835/Source/WebCore/rendering/CounterNode.cpp (96011 => 96012)


--- branches/chromium/835/Source/WebCore/rendering/CounterNode.cpp	2011-09-26 22:44:41 UTC (rev 96011)
+++ branches/chromium/835/Source/WebCore/rendering/CounterNode.cpp	2011-09-26 22:45:37 UTC (rev 96012)
@@ -238,7 +238,10 @@
     ASSERT(!newChild->m_parent);
     ASSERT(!newChild->m_previousSibling);
     ASSERT(!newChild->m_nextSibling);
-    ASSERT(!refChild || refChild->m_parent == this);
+    // If the refChild is not our child we can not complete the request. This hardens against bugs in RenderCounter.
+    // When renderers are reparented it may request that we insert counter nodes improperly.
+    if (refChild && refChild->m_parent != this)
+        return;
 
     if (newChild->m_hasResetType) {
         while (m_lastChild != refChild)
@@ -274,32 +277,43 @@
             next->recount();
         return;
     }
+    // If the new child is the last in the sibling list we must set the parent's lastChild.
+    if (!newChild->m_nextSibling)
+        m_lastChild = newChild;
 
     // The code below handles the case when a formerly root increment counter is loosing its root position
     // and therefore its children become next siblings.
     CounterNode* last = newChild->m_lastChild;
     CounterNode* first = newChild->m_firstChild;
 
-    newChild->m_nextSibling = first;
-    first->m_previousSibling = newChild;
-    // The case when the original next sibling of the inserted node becomes a child of
-    // one of the former children of the inserted node is not handled as it is believed
-    // to be impossible since:
-    // 1. if the increment counter node lost it's root position as a result of another
-    //    counter node being created, it will be inserted as the last child so next is null.
-    // 2. if the increment counter node lost it's root position as a result of a renderer being
-    //    inserted into the document's render tree, all its former children counters are attached
-    //    to children of the inserted renderer and hence cannot be in scope for counter nodes
-    //    attached to renderers that were already in the document's render tree.
-    last->m_nextSibling = next;
-    if (next)
-        next->m_previousSibling = last;
-    else
-        m_lastChild = last;
-    for (next = first; ; next = next->m_nextSibling) {
-        next->m_parent = this;
-        if (last == next)
-            break;
+    if (first) {
+        ASSERT(last);
+        newChild->m_nextSibling = first;
+        if (m_lastChild == newChild)
+            m_lastChild = last;
+
+        first->m_previousSibling = newChild;
+    
+        // The case when the original next sibling of the inserted node becomes a child of
+        // one of the former children of the inserted node is not handled as it is believed
+        // to be impossible since:
+        // 1. if the increment counter node lost it's root position as a result of another
+        //    counter node being created, it will be inserted as the last child so next is null.
+        // 2. if the increment counter node lost it's root position as a result of a renderer being
+        //    inserted into the document's render tree, all its former children counters are attached
+        //    to children of the inserted renderer and hence cannot be in scope for counter nodes
+        //    attached to renderers that were already in the document's render tree.
+        last->m_nextSibling = next;
+        if (next) {
+            ASSERT(next->m_previousSibling == newChild);
+            next->m_previousSibling = last;
+        } else
+            m_lastChild = last;
+        for (next = first; ; next = next->m_nextSibling) {
+            next->m_parent = this;
+            if (last == next)
+                break;
+        }
     }
     newChild->m_firstChild = 0;
     newChild->m_lastChild = 0;

Modified: branches/chromium/835/Source/WebCore/rendering/RenderCounter.cpp (96011 => 96012)


--- branches/chromium/835/Source/WebCore/rendering/RenderCounter.cpp	2011-09-26 22:44:41 UTC (rev 96011)
+++ branches/chromium/835/Source/WebCore/rendering/RenderCounter.cpp	2011-09-26 22:45:37 UTC (rev 96012)
@@ -323,7 +323,11 @@
                         // We are not a reset node or the previous reset must be on an ancestor of our owner renderer
                         // hence we must be a child of that reset counter.
                         parent = currentCounter;
-                        ASSERT(previousSibling->parent() == currentCounter);
+                        // In some cases renders can be reparented (ex. nodes inside a table but not in a column or row).
+                        // In these cases the identified previousSibling will be invalid as its parent is different from
+                        // our identified parent.
+                        if (previousSibling->parent() != currentCounter)
+                            previousSibling = 0;
                         return true;
                     }
                     // CurrentCounter, the counter at the EndSearchRenderer, is not reset.
@@ -439,10 +443,8 @@
         if (!currentCounter)
             continue;
         skipDescendants = true;
-        if (currentCounter->parent()) {
-            ASSERT(newNode->firstChild());
+        if (currentCounter->parent())
             continue;
-        }
         if (stayWithin == parentElement(currentRenderer) && currentCounter->hasResetType())
             break;
         newNode->insertAfter(currentCounter, newNode->lastChild(), identifier);
_______________________________________________
webkit-changes mailing list
[email protected]
http://lists.webkit.org/mailman/listinfo.cgi/webkit-changes

Reply via email to