Title: [143492] branches/chromium/1364

Diff

Copied: branches/chromium/1364/LayoutTests/fast/dynamic/continuation-detach-crash-expected.txt (from rev 142500, trunk/LayoutTests/fast/dynamic/continuation-detach-crash-expected.txt) (0 => 143492)


--- branches/chromium/1364/LayoutTests/fast/dynamic/continuation-detach-crash-expected.txt	                        (rev 0)
+++ branches/chromium/1364/LayoutTests/fast/dynamic/continuation-detach-crash-expected.txt	2013-02-20 21:20:17 UTC (rev 143492)
@@ -0,0 +1,5 @@
+Bug 107189: Regression(r131539): Heap-use-after-free in WebCore::RenderBlock::willBeDestroyed
+
+This test has PASSED if it didn't CRASH.
+
+

Copied: branches/chromium/1364/LayoutTests/fast/dynamic/continuation-detach-crash.html (from rev 142500, trunk/LayoutTests/fast/dynamic/continuation-detach-crash.html) (0 => 143492)


--- branches/chromium/1364/LayoutTests/fast/dynamic/continuation-detach-crash.html	                        (rev 0)
+++ branches/chromium/1364/LayoutTests/fast/dynamic/continuation-detach-crash.html	2013-02-20 21:20:17 UTC (rev 143492)
@@ -0,0 +1,37 @@
+<!DOCTYPE html>
+<style>
+    .class1 { -webkit-column-span: all; }
+    .class2 > .class3 { float: right; content: open-quote; }
+    .class3:last-of-type { -webkit-column-width: 1px; }
+    .class3:nth-last-child(2n+10000000000000000) { -webkit-column-span: all;</style>
+<script>
+if (window.testRunner)
+    testRunner.dumpAsText();
+
+function crash() {
+    test1 = document.createElement('header');
+    test2 = document.createElement('footer');
+    test3 = document.createElement('address');
+    test3.setAttribute('class', 'class1');
+    test1.appendChild(test3);
+    test4 = document.createElement('nav');
+    test4.setAttribute('class', 'class3');
+    document.documentElement.appendChild(test4);
+    test5 = document.createElement('dt');
+    test5.setAttribute('class', 'class2');
+    test6 = document.createElement('a');
+    document.documentElement.appendChild(test6);
+    test7 = document.createElement('div');
+    test7.setAttribute('class', 'class3');
+    test5.appendChild(test7);
+    test5.appendChild(test1);
+    test4.appendChild(test5);
+    document.documentElement.offsetTop;
+    test5.setAttribute('class', 'class3');
+    document.documentElement.offsetTop;
+    test2.appendChild(test6);
+}
+window._onload_ = crash;
+</script>
+<p><a href="" 107189</a>: Regression(r131539): Heap-use-after-free in WebCore::RenderBlock::willBeDestroyed</p>
+<p>This test has PASSED if it didn't CRASH.</p>

Modified: branches/chromium/1364/Source/WebCore/dom/ContainerNode.cpp (143491 => 143492)


--- branches/chromium/1364/Source/WebCore/dom/ContainerNode.cpp	2013-02-20 21:15:41 UTC (rev 143491)
+++ branches/chromium/1364/Source/WebCore/dom/ContainerNode.cpp	2013-02-20 21:20:17 UTC (rev 143492)
@@ -794,9 +794,9 @@
 
 void ContainerNode::detach()
 {
-    Node::detach();
     detachChildren();
     clearChildNeedsStyleRecalc();
+    Node::detach();
 }
 
 void ContainerNode::childrenChanged(bool changedByParser, Node*, Node*, int childCountDelta)

Modified: branches/chromium/1364/Source/WebCore/dom/Node.cpp (143491 => 143492)


--- branches/chromium/1364/Source/WebCore/dom/Node.cpp	2013-02-20 21:15:41 UTC (rev 143491)
+++ branches/chromium/1364/Source/WebCore/dom/Node.cpp	2013-02-20 21:20:17 UTC (rev 143492)
@@ -1108,24 +1108,10 @@
     detachingNode = this;
 #endif
 
-    if (renderer()) {
+    if (renderer())
         renderer()->destroyAndCleanupAnonymousWrappers();
-#ifndef NDEBUG
-        for (Node* node = this; node; node = NodeTraversal::next(node, this)) {
-            RenderObject* renderer = node->renderer();
-            // RenderFlowThread and the top layer remove elements from the regular tree
-            // hierarchy. They will be cleaned up when we call detach on them.
-#if ENABLE(DIALOG_ELEMENT)
-            ASSERT(!renderer || renderer->inRenderFlowThread() || (renderer->enclosingLayer()->isInTopLayerSubtree()));
-#else
-            ASSERT(!renderer || renderer->inRenderFlowThread());
-#endif
-        }
-#endif
-    }
+    setRenderer(0);
 
-    ASSERT(!renderer());
-
     Document* doc = document();
     if (isUserActionElement()) {
         if (hovered())

Modified: branches/chromium/1364/Source/WebCore/rendering/RenderObject.cpp (143491 => 143492)


--- branches/chromium/1364/Source/WebCore/rendering/RenderObject.cpp	2013-02-20 21:15:41 UTC (rev 143491)
+++ branches/chromium/1364/Source/WebCore/rendering/RenderObject.cpp	2013-02-20 21:20:17 UTC (rev 143492)
@@ -2386,11 +2386,6 @@
     if (AXObjectCache::accessibilityEnabled())
         document()->axObjectCache()->remove(this);
 
-    // Continuation and first-letter can generate several renderers associated with a single node.
-    // We only want to clear the node's renderer if we are the associated renderer.
-    if (node() && node()->renderer() == this)
-        node()->setRenderer(0);
-
 #ifndef NDEBUG
     if (!documentBeingDestroyed() && view() && view()->hasRenderNamedFlowThreads()) {
         // After remove, the object and the associated information should not be in any flow thread.
@@ -2524,18 +2519,6 @@
             break;
     }
 
-    // We repaint, so that the area exposed when this object disappears gets repainted properly.
-    // FIXME: A RenderObject with RenderLayer should probably repaint through it as getting the
-    // repaint rects is O(1) through a RenderLayer (assuming it's up-to-date).
-    if (destroyRoot->everHadLayout()) {
-        if (destroyRoot->isBody())
-            destroyRoot->view()->repaint();
-        else {
-            destroyRoot->repaint();
-            destroyRoot->repaintOverhangingFloats(true);
-        }
-    }
-
     destroyRoot->destroy();
 
     // WARNING: |this| is deleted here.

Modified: branches/chromium/1364/Source/WebCore/rendering/RenderObjectChildList.cpp (143491 => 143492)


--- branches/chromium/1364/Source/WebCore/rendering/RenderObjectChildList.cpp	2013-02-20 21:15:41 UTC (rev 143491)
+++ branches/chromium/1364/Source/WebCore/rendering/RenderObjectChildList.cpp	2013-02-20 21:20:17 UTC (rev 143492)
@@ -46,10 +46,13 @@
         if (firstChild()->isListMarker() || (firstChild()->style()->styleType() == FIRST_LETTER && !firstChild()->isText()))
             firstChild()->remove();  // List markers are owned by their enclosing list and so don't get destroyed by this container. Similarly, first letters are destroyed by their remaining text fragment.
         else if (firstChild()->isRunIn() && firstChild()->node()) {
+            firstChild()->node()->setRenderer(0);
             firstChild()->node()->setNeedsStyleRecalc();
             firstChild()->destroy();
         } else {
             // Destroy any anonymous children remaining in the render tree, as well as implicit (shadow) DOM elements like those used in the engine-based text fields.
+            if (firstChild()->node())
+                firstChild()->node()->setRenderer(0);
             firstChild()->destroy();
         }
     }
@@ -63,11 +66,14 @@
         toRenderBox(oldChild)->removeFloatingOrPositionedChildFromBlockLists();
 
     // So that we'll get the appropriate dirty bit set (either that a normal flow child got yanked or
-    // that a positioned child got yanked).
+    // that a positioned child got yanked). We also repaint, so that the area exposed when the child
+    // disappears gets repainted properly.
     if (!owner->documentBeingDestroyed() && notifyRenderer && oldChild->everHadLayout()) {
         oldChild->setNeedsLayoutAndPrefWidthsRecalc();
         // We only repaint |oldChild| if we have a RenderLayer as its visual overflow may not be tracked by its parent.
-        if (oldChild->hasLayer())
+        if (oldChild->isBody())
+            owner->view()->repaint();
+        else
             oldChild->repaint();
     }
 

Modified: branches/chromium/1364/Source/WebCore/rendering/RenderTextFragment.cpp (143491 => 143492)


--- branches/chromium/1364/Source/WebCore/rendering/RenderTextFragment.cpp	2013-02-20 21:15:41 UTC (rev 143491)
+++ branches/chromium/1364/Source/WebCore/rendering/RenderTextFragment.cpp	2013-02-20 21:20:17 UTC (rev 143492)
@@ -85,7 +85,10 @@
         ASSERT(!m_contentString);
         m_firstLetter->destroy();
         m_firstLetter = 0;
-        ASSERT(!node() || node()->renderer() == this);
+        if (Node* t = node()) {
+            ASSERT(!t->renderer());
+            t->setRenderer(this);
+        }
     }
 }
 
_______________________________________________
webkit-changes mailing list
webkit-changes@lists.webkit.org
https://lists.webkit.org/mailman/listinfo/webkit-changes

Reply via email to