Diff
Modified: trunk/LayoutTests/ChangeLog (116652 => 116653)
--- trunk/LayoutTests/ChangeLog 2012-05-10 16:38:13 UTC (rev 116652)
+++ trunk/LayoutTests/ChangeLog 2012-05-10 16:44:26 UTC (rev 116653)
@@ -1,3 +1,13 @@
+2012-05-10 Abhishek Arya <[email protected]>
+
+ Crash in InsertParagraphSeparatorCommand::doApply.
+ https://bugs.webkit.org/show_bug.cgi?id=84995
+
+ Reviewed by Ryosuke Niwa.
+
+ * editing/inserting/insert-paragraph-seperator-crash-expected.txt: Added.
+ * editing/inserting/insert-paragraph-seperator-crash.html: Added.
+
2012-05-10 Joe Thomas <[email protected]>
[CSS3 Backgrounds and Borders] Add background-size to the background shorthand
Added: trunk/LayoutTests/editing/inserting/insert-paragraph-seperator-crash-expected.txt (0 => 116653)
--- trunk/LayoutTests/editing/inserting/insert-paragraph-seperator-crash-expected.txt (rev 0)
+++ trunk/LayoutTests/editing/inserting/insert-paragraph-seperator-crash-expected.txt 2012-05-10 16:44:26 UTC (rev 116653)
@@ -0,0 +1 @@
+PASS. WebKit didn't crash.
Added: trunk/LayoutTests/editing/inserting/insert-paragraph-seperator-crash.html (0 => 116653)
--- trunk/LayoutTests/editing/inserting/insert-paragraph-seperator-crash.html (rev 0)
+++ trunk/LayoutTests/editing/inserting/insert-paragraph-seperator-crash.html 2012-05-10 16:44:26 UTC (rev 116653)
@@ -0,0 +1,34 @@
+<!DOCTYPE html>
+<html>
+<script>
+if (window.layoutTestController)
+ layoutTestController.dumpAsText();
+
+function handler() {
+ var element = event.srcElement;
+ document.execCommand('Undo', false, false);
+ element.parentNode.removeChild(element);
+ var em = document.getElementById('em');
+ var span = document.getElementById('span');
+ em.insertBefore(element, span);
+ document.execCommand('JustifyFull', false, false);
+}
+document.addEventListener("DOMCharacterDataModified", handler, true);
+
+window._onload_ = function() {
+ var selection = window.getSelection();
+ document.execCommand("SelectAll", false, false)
+ var element = document.getElementById("ruby");
+ element.innerHTML = "<em id='em'>^x?x<span id='span'>x&'x";
+ selection.deleteFromDocument();
+ selection.deleteFromDocument();
+ document.designMode = "on";
+ document.execCommand('JustifyRight', false, false);
+ document.execCommand('InsertHorizontalRule', false, '');
+ document.documentElement.innerHTML = "PASS. WebKit didn't crash.";
+};
+</script>
+<ruby id="ruby">
+<a>A</a>
+</ruby>
+</html>
Property changes on: trunk/LayoutTests/editing/inserting/insert-paragraph-seperator-crash.html
___________________________________________________________________
Added: svn:executable
Modified: trunk/Source/WebCore/ChangeLog (116652 => 116653)
--- trunk/Source/WebCore/ChangeLog 2012-05-10 16:38:13 UTC (rev 116652)
+++ trunk/Source/WebCore/ChangeLog 2012-05-10 16:44:26 UTC (rev 116653)
@@ -1,3 +1,29 @@
+2012-05-10 Abhishek Arya <[email protected]>
+
+ Crash in InsertParagraphSeparatorCommand::doApply.
+ https://bugs.webkit.org/show_bug.cgi?id=84995
+
+ Reviewed by Ryosuke Niwa.
+
+ Test: editing/inserting/insert-paragraph-seperator-crash.html
+
+ * editing/DeleteSelectionCommand.cpp:
+ (WebCore::DeleteSelectionCommand::mergeParagraphs): no need of static cast, since
+ type of enclosingBlock returned is already Element*.
+ * editing/IndentOutdentCommand.cpp:
+ (WebCore::IndentOutdentCommand::tryIndentingAsListItem): no need of static cast, since
+ type of enclosingBlock returned is already Element*.
+ * editing/InsertParagraphSeparatorCommand.cpp:
+ (WebCore::InsertParagraphSeparatorCommand::doApply): RefPtr startBlock to guard against
+ mutation events.
+ * editing/htmlediting.cpp:
+ (WebCore::enclosingBlock): make sure type of enclosingNode is an element before doing
+ the static cast. This was already failing in a couple of layout tests. Also, isBlock
+ check already exists in the function call to enclosingNodeOfType, so don't need it
+ again on enclosingNode's renderer.
+ * editing/htmlediting.h:
+ (WebCore):
+
2012-05-10 Allan Sandfeld Jensen <[email protected]>
TouchAdjustment doesn't correct for scroll-offsets.
Modified: trunk/Source/WebCore/editing/DeleteSelectionCommand.cpp (116652 => 116653)
--- trunk/Source/WebCore/editing/DeleteSelectionCommand.cpp 2012-05-10 16:38:13 UTC (rev 116652)
+++ trunk/Source/WebCore/editing/DeleteSelectionCommand.cpp 2012-05-10 16:44:26 UTC (rev 116653)
@@ -581,7 +581,7 @@
// m_downstreamEnd's block has been emptied out by deletion. There is no content inside of it to
// move, so just remove it.
- Element* endBlock = static_cast<Element*>(enclosingBlock(m_downstreamEnd.deprecatedNode()));
+ Element* endBlock = enclosingBlock(m_downstreamEnd.deprecatedNode());
if (!endBlock || !endBlock->contains(startOfParagraphToMove.deepEquivalent().deprecatedNode()) || !startOfParagraphToMove.deepEquivalent().deprecatedNode()) {
removeNode(enclosingBlock(m_downstreamEnd.deprecatedNode()));
return;
Modified: trunk/Source/WebCore/editing/IndentOutdentCommand.cpp (116652 => 116653)
--- trunk/Source/WebCore/editing/IndentOutdentCommand.cpp 2012-05-10 16:38:13 UTC (rev 116652)
+++ trunk/Source/WebCore/editing/IndentOutdentCommand.cpp 2012-05-10 16:44:26 UTC (rev 116653)
@@ -65,7 +65,7 @@
return false;
// Find the block that we want to indent. If it's not a list item (e.g., a div inside a list item), we bail out.
- Element* selectedListItem = static_cast<Element*>(enclosingBlock(lastNodeInSelectedParagraph));
+ Element* selectedListItem = enclosingBlock(lastNodeInSelectedParagraph);
// FIXME: we need to deal with the case where there is no li (malformed HTML)
if (!selectedListItem->hasTagName(liTag))
Modified: trunk/Source/WebCore/editing/InsertParagraphSeparatorCommand.cpp (116652 => 116653)
--- trunk/Source/WebCore/editing/InsertParagraphSeparatorCommand.cpp 2012-05-10 16:38:13 UTC (rev 116652)
+++ trunk/Source/WebCore/editing/InsertParagraphSeparatorCommand.cpp 2012-05-10 16:44:26 UTC (rev 116653)
@@ -164,17 +164,15 @@
}
// FIXME: The parentAnchoredEquivalent conversion needs to be moved into enclosingBlock.
- Node* startBlockNode = enclosingBlock(insertionPosition.parentAnchoredEquivalent().containerNode());
+ RefPtr<Element> startBlock = enclosingBlock(insertionPosition.parentAnchoredEquivalent().containerNode());
Position canonicalPos = VisiblePosition(insertionPosition).deepEquivalent();
- Element* startBlock = static_cast<Element*>(startBlockNode);
- if (!startBlockNode
- || !startBlockNode->isElementNode()
- || !startBlock->nonShadowBoundaryParentNode()
- || isTableCell(startBlock)
- || startBlock->hasTagName(formTag)
- // FIXME: If the node is hidden, we don't have a canonical position so we will do the wrong thing for tables and <hr>. https://bugs.webkit.org/show_bug.cgi?id=40342
- || (!canonicalPos.isNull() && canonicalPos.deprecatedNode()->renderer() && canonicalPos.deprecatedNode()->renderer()->isTable())
- || (!canonicalPos.isNull() && canonicalPos.deprecatedNode()->hasTagName(hrTag))) {
+ if (!startBlock
+ || !startBlock->nonShadowBoundaryParentNode()
+ || isTableCell(startBlock.get())
+ || startBlock->hasTagName(formTag)
+ // FIXME: If the node is hidden, we don't have a canonical position so we will do the wrong thing for tables and <hr>. https://bugs.webkit.org/show_bug.cgi?id=40342
+ || (!canonicalPos.isNull() && canonicalPos.deprecatedNode()->renderer() && canonicalPos.deprecatedNode()->renderer()->isTable())
+ || (!canonicalPos.isNull() && canonicalPos.deprecatedNode()->hasTagName(hrTag))) {
applyCommandToComposite(InsertLineBreakCommand::create(document()));
return;
}
@@ -206,7 +204,7 @@
if (startBlock == startBlock->rootEditableElement()) {
blockToInsert = createDefaultParagraphElement(document());
nestNewBlock = true;
- } else if (shouldUseDefaultParagraphElement(startBlock))
+ } else if (shouldUseDefaultParagraphElement(startBlock.get()))
blockToInsert = createDefaultParagraphElement(document());
else
blockToInsert = startBlock->cloneElementWithoutChildren();
@@ -234,16 +232,16 @@
// Most of the time we want to stay at the nesting level of the startBlock (e.g., when nesting within lists). However,
// for div nodes, this can result in nested div tags that are hard to break out of.
- Element* siblingNode = startBlock;
+ Element* siblingNode = startBlock.get();
if (blockToInsert->hasTagName(divTag))
- siblingNode = highestVisuallyEquivalentDivBelowRoot(startBlock);
+ siblingNode = highestVisuallyEquivalentDivBelowRoot(startBlock.get());
insertNodeAfter(blockToInsert, siblingNode);
}
// Recreate the same structure in the new paragraph.
Vector<Element*> ancestors;
- getAncestorsInsideBlock(positionOutsideTabSpan(insertionPosition).deprecatedNode(), startBlock, ancestors);
+ getAncestorsInsideBlock(positionOutsideTabSpan(insertionPosition).deprecatedNode(), startBlock.get(), ancestors);
RefPtr<Element> parent = cloneHierarchyUnderNewBlock(ancestors, blockToInsert);
appendBlockPlaceholder(parent);
@@ -262,7 +260,7 @@
insertionPosition = positionOutsideTabSpan(insertionPosition);
if (isFirstInBlock && !nestNewBlock)
- refNode = startBlock;
+ refNode = startBlock.get();
else if (isFirstInBlock && nestNewBlock) {
// startBlock should always have children, otherwise isLastInBlock would be true and it's handled above.
ASSERT(startBlock->firstChild());
@@ -282,7 +280,7 @@
// Recreate the same structure in the new paragraph.
Vector<Element*> ancestors;
- getAncestorsInsideBlock(positionAvoidingSpecialElementBoundary(positionOutsideTabSpan(insertionPosition)).deprecatedNode(), startBlock, ancestors);
+ getAncestorsInsideBlock(positionAvoidingSpecialElementBoundary(positionOutsideTabSpan(insertionPosition)).deprecatedNode(), startBlock.get(), ancestors);
appendBlockPlaceholder(cloneHierarchyUnderNewBlock(ancestors, blockToInsert));
@@ -342,6 +340,10 @@
}
}
+ // If we got detached due to mutation events, just bail out.
+ if (!startBlock->parentNode())
+ return;
+
// Put the added block in the tree.
if (nestNewBlock)
appendNode(blockToInsert.get(), startBlock);
@@ -364,9 +366,9 @@
else {
Node* splitTo = insertionPosition.containerNode();
if (splitTo->isTextNode() && insertionPosition.offsetInContainerNode() >= caretMaxOffset(splitTo))
- splitTo = splitTo->traverseNextNode(startBlock);
+ splitTo = splitTo->traverseNextNode(startBlock.get());
ASSERT(splitTo);
- splitTreeToNode(splitTo, startBlock);
+ splitTreeToNode(splitTo, startBlock.get());
for (n = startBlock->firstChild(); n; n = n->nextSibling()) {
if (comparePositions(VisiblePosition(insertionPosition), positionBeforeNode(n)) <= 0)
@@ -397,7 +399,7 @@
}
setEndingSelection(VisibleSelection(firstPositionInNode(blockToInsert.get()), DOWNSTREAM, endingSelection().isDirectional()));
- applyStyleAfterInsertion(startBlock);
+ applyStyleAfterInsertion(startBlock.get());
}
} // namespace WebCore
Modified: trunk/Source/WebCore/editing/htmlediting.cpp (116652 => 116653)
--- trunk/Source/WebCore/editing/htmlediting.cpp 2012-05-10 16:38:13 UTC (rev 116652)
+++ trunk/Source/WebCore/editing/htmlediting.cpp 2012-05-10 16:44:26 UTC (rev 116653)
@@ -310,9 +310,10 @@
// FIXME: Pass a position to this function. The enclosing block of [table, x] for example, should be the
// block that contains the table and not the table, and this function should be the only one responsible for
// knowing about these kinds of special cases.
-Node* enclosingBlock(Node* node, EditingBoundaryCrossingRule rule)
+Element* enclosingBlock(Node* node, EditingBoundaryCrossingRule rule)
{
- return static_cast<Element*>(enclosingNodeOfType(firstPositionInOrBeforeNode(node), isBlock, rule));
+ Node* enclosingNode = enclosingNodeOfType(firstPositionInOrBeforeNode(node), isBlock, rule);
+ return enclosingNode && enclosingNode->isElementNode() ? toElement(enclosingNode) : 0;
}
TextDirection directionOfEnclosingBlock(const Position& position)
Modified: trunk/Source/WebCore/editing/htmlediting.h (116652 => 116653)
--- trunk/Source/WebCore/editing/htmlediting.h 2012-05-10 16:38:13 UTC (rev 116652)
+++ trunk/Source/WebCore/editing/htmlediting.h 2012-05-10 16:44:26 UTC (rev 116653)
@@ -61,7 +61,7 @@
Node* highestNodeToRemoveInPruning(Node*);
Node* lowestEditableAncestor(Node*);
-Node* enclosingBlock(Node*, EditingBoundaryCrossingRule = CannotCrossEditingBoundary);
+Element* enclosingBlock(Node*, EditingBoundaryCrossingRule = CannotCrossEditingBoundary);
Node* enclosingTableCell(const Position&);
Node* enclosingEmptyListItem(const VisiblePosition&);
Node* enclosingAnchorElement(const Position&);