Crash in deleteInsignificantText
authorrniwa@webkit.org <rniwa@webkit.org@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Wed, 15 Feb 2012 01:23:49 +0000 (01:23 +0000)
committerrniwa@webkit.org <rniwa@webkit.org@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Wed, 15 Feb 2012 01:23:49 +0000 (01:23 +0000)
https://bugs.webkit.org/show_bug.cgi?id=78567

Reviewed by Eric Seidel.

Source/WebCore:

Fix the crash. Also update layout at the beginning of each call to deleteInsignificantText
since the previous call may have mutated the DOM.

Test: editing/inserting/delete-insignificant-text-crash.html

* editing/CompositeEditCommand.cpp:
(WebCore::CompositeEditCommand::deleteInsignificantText):

LayoutTests:

Add a regression test.

* editing/inserting/delete-insignificant-text-crash.html: Added.
* editing/inserting/delete-insignificant-text-crash.txt: Added.

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

LayoutTests/ChangeLog
LayoutTests/editing/inserting/delete-insignificant-text-crash-expected.txt [new file with mode: 0644]
LayoutTests/editing/inserting/delete-insignificant-text-crash.html [new file with mode: 0644]
Source/WebCore/ChangeLog
Source/WebCore/editing/CompositeEditCommand.cpp

index f3baa60..43e9ca5 100644 (file)
@@ -1,3 +1,15 @@
+2012-02-14  Ryosuke Niwa  <rniwa@webkit.org>
+
+        Crash in deleteInsignificantText
+        https://bugs.webkit.org/show_bug.cgi?id=78567
+
+        Reviewed by Eric Seidel.
+
+        Add a regression test.
+
+        * editing/inserting/delete-insignificant-text-crash.html: Added.
+        * editing/inserting/delete-insignificant-text-crash.txt: Added.
+
 2012-02-14  Noel Gordon  <noel.gordon@gmail.com>
 
         [chromium] Rebaseline JPEG image results after r107389
diff --git a/LayoutTests/editing/inserting/delete-insignificant-text-crash-expected.txt b/LayoutTests/editing/inserting/delete-insignificant-text-crash-expected.txt
new file mode 100644 (file)
index 0000000..af609de
--- /dev/null
@@ -0,0 +1,3 @@
+This tests deleting a node in DOMCharacterDataModified doesn't result in a crash.
+
+PASS
diff --git a/LayoutTests/editing/inserting/delete-insignificant-text-crash.html b/LayoutTests/editing/inserting/delete-insignificant-text-crash.html
new file mode 100644 (file)
index 0000000..cc93630
--- /dev/null
@@ -0,0 +1,29 @@
+<!DOCTYPE html>
+<html>
+<body>
+<p>This tests deleting a node in DOMCharacterDataModified doesn't result in a crash.</p>
+<div id="test" contenteditable></div>
+<script>
+
+if (window.layoutTestController)
+    layoutTestController.dumpAsText();
+
+var test = document.getElementById('test');
+test.appendChild(document.createTextNode('a  '));
+test.appendChild(document.createTextNode('  '));
+test.appendChild(document.createTextNode('b'));
+test.appendChild(document.createTextNode('  '));
+getSelection().setPosition(test.firstChild.nextSibling, 0);
+document.body.addEventListener('DOMCharacterDataModified', function () {
+    test.removeChild(test.firstChild.nextSibling);
+    if (window.GCController)
+        GCController.collect();
+}, false);
+document.execCommand("InsertText", false, "c");
+
+test.textContent = '';
+document.writeln('PASS');
+
+</script>
+</body>
+</html>
index d4f618f..6ad88a1 100644 (file)
@@ -1,3 +1,18 @@
+2012-02-14  Ryosuke Niwa  <rniwa@webkit.org>
+
+        Crash in deleteInsignificantText
+        https://bugs.webkit.org/show_bug.cgi?id=78567
+
+        Reviewed by Eric Seidel.
+
+        Fix the crash. Also update layout at the beginning of each call to deleteInsignificantText
+        since the previous call may have mutated the DOM.
+
+        Test: editing/inserting/delete-insignificant-text-crash.html
+
+        * editing/CompositeEditCommand.cpp:
+        (WebCore::CompositeEditCommand::deleteInsignificantText):
+
 2012-02-14  Levi Weintraub  <leviw@chromium.org>
 
         Prepare RenderLayerBacking and RenderLayerCompositor for subpixel layout
index 35645e8..f576571 100644 (file)
@@ -698,6 +698,8 @@ void CompositeEditCommand::deleteInsignificantText(PassRefPtr<Text> textNode, un
     if (!textNode || start >= end)
         return;
 
+    document()->updateLayout();
+
     RenderText* textRenderer = toRenderText(textNode->renderer());
     if (!textRenderer)
         return;
@@ -780,18 +782,20 @@ void CompositeEditCommand::deleteInsignificantText(const Position& start, const
     if (comparePositions(start, end) >= 0)
         return;
 
-    Node* next;
-    for (Node* node = start.deprecatedNode(); node; node = next) {
-        next = node->traverseNextNode();
-        if (node->isTextNode()) {
-            Text* textNode = toText(node);
-            int startOffset = node == start.deprecatedNode() ? start.deprecatedEditingOffset() : 0;
-            int endOffset = node == end.deprecatedNode() ? end.deprecatedEditingOffset() : static_cast<int>(textNode->length());
-            deleteInsignificantText(textNode, startOffset, endOffset);
-        }
+    Vector<RefPtr<Text> > nodes;
+    for (Node* node = start.deprecatedNode(); node; node = node->traverseNextNode()) {
+        if (node->isTextNode())
+            nodes.append(toText(node));
         if (node == end.deprecatedNode())
             break;
     }
+
+    for (size_t i = 0; i < nodes.size(); ++i) {
+        Text* textNode = nodes[i].get();
+        int startOffset = textNode == start.deprecatedNode() ? start.deprecatedEditingOffset() : 0;
+        int endOffset = textNode == end.deprecatedNode() ? end.deprecatedEditingOffset() : static_cast<int>(textNode->length());
+        deleteInsignificantText(textNode, startOffset, endOffset);
+    }
 }
 
 void CompositeEditCommand::deleteInsignificantTextDownstream(const Position& pos)