Title: [116653] trunk
Revision
116653
Author
[email protected]
Date
2012-05-10 09:44:26 -0700 (Thu, 10 May 2012)

Log Message

Crash in InsertParagraphSeparatorCommand::doApply.
https://bugs.webkit.org/show_bug.cgi?id=84995

Reviewed by Ryosuke Niwa.

Source/WebCore:

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):

LayoutTests:

* editing/inserting/insert-paragraph-seperator-crash-expected.txt: Added.
* editing/inserting/insert-paragraph-seperator-crash.html: Added.

Modified Paths

Added Paths

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&);
_______________________________________________
webkit-changes mailing list
[email protected]
http://lists.webkit.org/mailman/listinfo.cgi/webkit-changes

Reply via email to