summaryrefslogtreecommitdiffstats
path: root/Source
diff options
context:
space:
mode:
authorSteve Block <steveblock@google.com>2012-04-27 18:41:23 +0100
committerSteve Block <steveblock@google.com>2012-04-27 18:45:37 +0100
commit1cc46c0cf78d80f6cd0c8cd5093906c782be5691 (patch)
treef44337065dffe75987632d8afa1bac2fddd93dd2 /Source
parent3818681c85a025afd8aa203937b66d7c01ac1a8b (diff)
downloadexternal_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.cpp37
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)