Copying and pasting trivial H2 content causes a crash in firstPositionInNode
authormmaxfield@apple.com <mmaxfield@apple.com@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Wed, 23 Jul 2014 02:19:55 +0000 (02:19 +0000)
committermmaxfield@apple.com <mmaxfield@apple.com@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Wed, 23 Jul 2014 02:19:55 +0000 (02:19 +0000)
https://bugs.webkit.org/show_bug.cgi?id=134897

Reviewed by Ryosuke Niwa.

Source/WebCore:
ReplaceSelectionCommand::makeInsertedContentRoundTrippableWithHTMLTreeBuilder() attempts
to move pasted headings out of existed headings, with out regard to if the existing
heading is the contenteditable root.

Test: editing/pasteboard/heading-crash.html

* editing/ReplaceSelectionCommand.cpp:
(WebCore::ReplaceSelectionCommand::makeInsertedContentRoundTrippableWithHTMLTreeBuilder):

LayoutTests:
Copy and paste text from one heading to another. Make sure there is no crash.

* editing/pasteboard/heading-crash-expected.txt: Added.
* editing/pasteboard/heading-crash.html: Added.

git-svn-id: https://svn.webkit.org/repository/webkit/trunk@171383 268f45cc-cd09-0410-ab3c-d52691b4dbfc

LayoutTests/ChangeLog
LayoutTests/editing/pasteboard/heading-crash-expected.txt [new file with mode: 0644]
LayoutTests/editing/pasteboard/heading-crash.html [new file with mode: 0644]
Source/WebCore/ChangeLog
Source/WebCore/editing/ReplaceSelectionCommand.cpp
Source/WebCore/editing/ReplaceSelectionCommand.h

index f778bd0..2fcbffa 100644 (file)
@@ -1,3 +1,15 @@
+2014-07-16  Myles C. Maxfield  <mmaxfield@apple.com>
+
+        Copying and pasting trivial H2 content causes a crash in firstPositionInNode
+        https://bugs.webkit.org/show_bug.cgi?id=134897
+
+        Reviewed by Ryosuke Niwa.
+
+        Copy and paste text from one heading to another. Make sure there is no crash.
+
+        * editing/pasteboard/heading-crash-expected.txt: Added.
+        * editing/pasteboard/heading-crash.html: Added.
+
 2014-07-22  Filip Pizlo  <fpizlo@apple.com>
 
         Merge r169148, r169185, r169188, r169578, r169582, r169584, r169588, r169753 from ftlopt.
diff --git a/LayoutTests/editing/pasteboard/heading-crash-expected.txt b/LayoutTests/editing/pasteboard/heading-crash-expected.txt
new file mode 100644 (file)
index 0000000..7d0f14c
--- /dev/null
@@ -0,0 +1,6 @@
+The following test does a copy and a paste from one heading to another heading. The test is successful if there is no crash.
+
+Destination should say Copy This Text:
+| <span>
+|   id="source"
+|   "Copy This Text<#selection-caret>"
diff --git a/LayoutTests/editing/pasteboard/heading-crash.html b/LayoutTests/editing/pasteboard/heading-crash.html
new file mode 100644 (file)
index 0000000..b315139
--- /dev/null
@@ -0,0 +1,27 @@
+<!DOCTYPE html>
+<html>
+<head>
+</head>
+<body>
+<script src="../editing.js"></script>
+<script src="../../resources/dump-as-markup.js"></script>
+<h2 id="source" contenteditable="true">Copy This Text</h2>
+<h2 id="destination" contenteditable="true">Paste Here</h2>
+<script>
+    if (window.testRunner)
+        testRunner.dumpAsText();
+
+    var source = document.getElementById("source");
+    var destination = document.getElementById("destination");
+
+    source.focus();
+    selectAllCommand();
+    copyCommand();
+    destination.focus();
+    selectAllCommand();
+    pasteCommand();
+
+    Markup.description("The following test does a copy and a paste from one heading to another heading. The test is successful if there is no crash.");
+    Markup.dump(destination, 'Destination should say Copy This Text');
+</script>
+</html>
index b8985d7..8f80584 100644 (file)
@@ -1,3 +1,19 @@
+2014-07-16  Myles C. Maxfield  <mmaxfield@apple.com>
+
+        Copying and pasting trivial H2 content causes a crash in firstPositionInNode
+        https://bugs.webkit.org/show_bug.cgi?id=134897
+
+        Reviewed by Ryosuke Niwa.
+
+        ReplaceSelectionCommand::makeInsertedContentRoundTrippableWithHTMLTreeBuilder() attempts
+        to move pasted headings out of existed headings, with out regard to if the existing
+        heading is the contenteditable root.
+
+        Test: editing/pasteboard/heading-crash.html
+
+        * editing/ReplaceSelectionCommand.cpp:
+        (WebCore::ReplaceSelectionCommand::makeInsertedContentRoundTrippableWithHTMLTreeBuilder):
+
 2014-07-22  Ryuan Choi  <ryuan.choi@samsung.com>
 
         Remove dead APIs from TiledBackingStore
index 6c062b5..d019d21 100644 (file)
@@ -619,7 +619,7 @@ static bool isProhibitedParagraphChild(const AtomicString& name)
     return elements.get().contains(name);
 }
 
-void ReplaceSelectionCommand::makeInsertedContentRoundTrippableWithHTMLTreeBuilder(const InsertedNodes& insertedNodes)
+void ReplaceSelectionCommand::makeInsertedContentRoundTrippableWithHTMLTreeBuilder(InsertedNodes& insertedNodes)
 {
     RefPtr<Node> pastEndNode = insertedNodes.pastLastLeaf();
     RefPtr<Node> next;
@@ -638,8 +638,15 @@ void ReplaceSelectionCommand::makeInsertedContentRoundTrippableWithHTMLTreeBuild
         }
 
         if (isHeaderElement(node.get())) {
-            if (auto* headerElement = highestEnclosingNodeOfType(positionInParentBeforeNode(node.get()), isHeaderElement))
-                moveNodeOutOfAncestor(node, headerElement);
+            auto* headerElement = highestEnclosingNodeOfType(positionInParentBeforeNode(node.get()), isHeaderElement);
+            if (headerElement) {
+                if (headerElement->parentNode() && headerElement->parentNode()->isContentRichlyEditable())
+                    moveNodeOutOfAncestor(node, headerElement);
+                else {
+                    HTMLElement* newSpanElement = replaceElementWithSpanPreservingChildrenAndAttributes(toHTMLElement(node.get()));
+                    insertedNodes.didReplaceNode(node.get(), newSpanElement);
+                }
+            }
         }
     }
 }
index 755991b..f71b11c 100644 (file)
@@ -89,7 +89,7 @@ private:
     void removeUnrenderedTextNodesAtEnds(InsertedNodes&);
     
     void removeRedundantStylesAndKeepStyleSpanInline(InsertedNodes&);
-    void makeInsertedContentRoundTrippableWithHTMLTreeBuilder(const InsertedNodes&);
+    void makeInsertedContentRoundTrippableWithHTMLTreeBuilder(InsertedNodes&);
     void moveNodeOutOfAncestor(PassRefPtr<Node>, PassRefPtr<Node> ancestor);
     void handleStyleSpans(InsertedNodes&);
     void handlePasteAsQuotationNode();