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