diff options
author | Steve Block <steveblock@google.com> | 2012-04-27 18:41:23 +0100 |
---|---|---|
committer | Steve Block <steveblock@google.com> | 2012-04-27 18:45:37 +0100 |
commit | 1cc46c0cf78d80f6cd0c8cd5093906c782be5691 (patch) | |
tree | f44337065dffe75987632d8afa1bac2fddd93dd2 /Source | |
parent | 3818681c85a025afd8aa203937b66d7c01ac1a8b (diff) | |
download | external_webkit-1cc46c0cf78d80f6cd0c8cd5093906c782be5691.zip external_webkit-1cc46c0cf78d80f6cd0c8cd5093906c782be5691.tar.gz external_webkit-1cc46c0cf78d80f6cd0c8cd5093906c782be5691.tar.bz2 |
Cherry-pick WebKit change r90130 to fix a rendering crash
See http://trac.webkit.org/changeset/90130
Bug: 6328929
Change-Id: Iee0df9f81e1b73de0e1922b3b24e224389db8fa3
Diffstat (limited to 'Source')
-rw-r--r-- | Source/WebCore/dom/Range.cpp | 37 |
1 files changed, 21 insertions, 16 deletions
diff --git a/Source/WebCore/dom/Range.cpp b/Source/WebCore/dom/Range.cpp index 268687f..37d0193 100644 --- a/Source/WebCore/dom/Range.cpp +++ b/Source/WebCore/dom/Range.cpp @@ -623,7 +623,9 @@ static inline Node* childOfCommonRootBeforeOffset(Node* container, unsigned offs { ASSERT(container); ASSERT(commonRoot); - ASSERT(commonRoot->contains(container)); + + if (!commonRoot->contains(container)) + return 0; if (container == commonRoot) { container = container->firstChild(); @@ -674,7 +676,7 @@ PassRefPtr<DocumentFragment> Range::processContents(ActionType action, Exception if (ec) return 0; - Node* commonRoot = commonAncestorContainer(ec); + RefPtr<Node> commonRoot = commonAncestorContainer(ec); if (ec) return 0; ASSERT(commonRoot); @@ -685,8 +687,8 @@ PassRefPtr<DocumentFragment> Range::processContents(ActionType action, Exception } // 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: @@ -705,29 +707,32 @@ PassRefPtr<DocumentFragment> Range::processContents(ActionType action, Exception // // 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; @@ -742,7 +747,7 @@ PassRefPtr<DocumentFragment> Range::processContents(ActionType action, Exception 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); } @@ -832,7 +837,7 @@ PassRefPtr<Node> Range::processContentsBetweenOffsets(ActionType action, PassRef break; } - return result; + return result.release(); } void Range::processNodes(ActionType action, Vector<RefPtr<Node> >& nodes, PassRefPtr<Node> oldContainer, PassRefPtr<Node> newContainer, ExceptionCode& ec) @@ -902,7 +907,7 @@ PassRefPtr<Node> Range::processAncestorsAndTheirSiblings(ActionType action, Node firstChildInAncestorToProcess = direction == ProcessContentsForward ? ancestor->nextSibling() : ancestor->previousSibling(); } - return clonedContainer; + return clonedContainer.release(); } PassRefPtr<DocumentFragment> Range::extractContents(ExceptionCode& ec) |