Index: Source/WebCore/dom/Range.cpp |
=================================================================== |
--- Source/WebCore/dom/Range.cpp (revision 90844) |
+++ Source/WebCore/dom/Range.cpp (working copy) |
@@ -628,7 +628,9 @@ |
{ |
ASSERT(container); |
ASSERT(commonRoot); |
- ASSERT(commonRoot->contains(container)); |
+ |
+ if (!commonRoot->contains(container)) |
+ return 0; |
if (container == commonRoot) { |
container = container->firstChild(); |
@@ -682,7 +684,7 @@ |
if (ec) |
return 0; |
- Node* commonRoot = commonAncestorContainer(ec); |
+ RefPtr<Node> commonRoot = commonAncestorContainer(ec); |
if (ec) |
return 0; |
ASSERT(commonRoot); |
@@ -693,8 +695,8 @@ |
} |
// what is the highest node that partially selects the start / end of the range? |
- Node* partialStart = highestAncestorUnderCommonRoot(m_start.container(), commonRoot); |
- Node* partialEnd = highestAncestorUnderCommonRoot(m_end.container(), commonRoot); |
+ RefPtr<Node> partialStart = highestAncestorUnderCommonRoot(m_start.container(), commonRoot.get()); |
+ RefPtr<Node> partialEnd = highestAncestorUnderCommonRoot(m_end.container(), commonRoot.get()); |
// Start and end containers are different. |
// There are three possibilities here: |
@@ -713,29 +715,32 @@ |
// |
// These are deleted, cloned, or extracted (i.e. both) depending on action. |
+ // Note that we are verifying that our common root hierarchy is still intact |
+ // after any DOM mutation event, at various stages below. See webkit bug 60350. |
+ |
RefPtr<Node> leftContents; |
- if (m_start.container() != commonRoot) { |
+ if (m_start.container() != commonRoot && commonRoot->contains(m_start.container())) { |
leftContents = processContentsBetweenOffsets(action, 0, m_start.container(), m_start.offset(), lengthOfContentsInNode(m_start.container()), ec); |
- leftContents = processAncestorsAndTheirSiblings(action, m_start.container(), ProcessContentsForward, leftContents, commonRoot, ec); |
+ leftContents = processAncestorsAndTheirSiblings(action, m_start.container(), ProcessContentsForward, leftContents, commonRoot.get(), ec); |
} |
RefPtr<Node> rightContents; |
- if (m_end.container() != commonRoot) { |
+ if (m_end.container() != commonRoot && commonRoot->contains(m_end.container())) { |
rightContents = processContentsBetweenOffsets(action, 0, m_end.container(), 0, m_end.offset(), ec); |
- rightContents = processAncestorsAndTheirSiblings(action, m_end.container(), ProcessContentsBackward, rightContents, commonRoot, ec); |
+ rightContents = processAncestorsAndTheirSiblings(action, m_end.container(), ProcessContentsBackward, rightContents, commonRoot.get(), ec); |
} |
// delete all children of commonRoot between the start and end container |
- Node* processStart = childOfCommonRootBeforeOffset(m_start.container(), m_start.offset(), commonRoot); |
- if (m_start.container() != commonRoot) // processStart contains nodes before m_start. |
+ RefPtr<Node> processStart = childOfCommonRootBeforeOffset(m_start.container(), m_start.offset(), commonRoot.get()); |
+ if (processStart && m_start.container() != commonRoot) // processStart contains nodes before m_start. |
processStart = processStart->nextSibling(); |
- Node* processEnd = childOfCommonRootBeforeOffset(m_end.container(), m_end.offset(), commonRoot); |
+ RefPtr<Node> processEnd = childOfCommonRootBeforeOffset(m_end.container(), m_end.offset(), commonRoot.get()); |
// Collapse the range, making sure that the result is not within a node that was partially selected. |
if (action == EXTRACT_CONTENTS || action == DELETE_CONTENTS) { |
- if (partialStart) |
+ if (partialStart && commonRoot->contains(partialStart.get())) |
setStart(partialStart->parentNode(), partialStart->nodeIndex() + 1, ec); |
- else if (partialEnd) |
+ else if (partialEnd && commonRoot->contains(partialEnd.get())) |
setStart(partialEnd->parentNode(), partialEnd->nodeIndex(), ec); |
if (ec) |
return 0; |
@@ -750,7 +755,7 @@ |
if (processStart) { |
NodeVector nodes; |
- for (Node* n = processStart; n && n != processEnd; n = n->nextSibling()) |
+ for (Node* n = processStart.get(); n && n != processEnd; n = n->nextSibling()) |
nodes.append(n); |
processNodes(action, nodes, commonRoot, fragment, ec); |
} |
@@ -841,7 +846,7 @@ |
break; |
} |
- return result; |
+ return result.release(); |
} |
void Range::processNodes(ActionType action, Vector<RefPtr<Node> >& nodes, PassRefPtr<Node> oldContainer, PassRefPtr<Node> newContainer, ExceptionCode& ec) |
@@ -906,7 +911,7 @@ |
firstChildInAncestorToProcess = direction == ProcessContentsForward ? ancestor->nextSibling() : ancestor->previousSibling(); |
} |
- return clonedContainer; |
+ return clonedContainer.release(); |
} |
PassRefPtr<DocumentFragment> Range::extractContents(ExceptionCode& ec) |