Index: Source/WebCore/rendering/CounterNode.cpp |
=================================================================== |
--- Source/WebCore/rendering/CounterNode.cpp (revision 96010) |
+++ Source/WebCore/rendering/CounterNode.cpp (working copy) |
@@ -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; |