[SCM] WebKit Debian packaging branch, debian/experimental, updated. upstream/1.3.3-10851-g50815da

rniwa at webkit.org rniwa at webkit.org
Wed Dec 22 17:58:18 UTC 2010


The following commit has been merged in the debian/experimental branch:
commit 54a246d2af96945e51484405cd72e9f1a3704964
Author: rniwa at webkit.org <rniwa at webkit.org@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Date:   Fri Dec 3 19:26:22 2010 +0000

    2010-12-03  Ryosuke Niwa  <rniwa at webkit.org>
    
            Reviewed by Darin Adler.
    
            REGRESSION: Crash when deleting text after textarea's value is modified on input event
            https://bugs.webkit.org/show_bug.cgi?id=49962
    
            The crash was caused by TypingCommand::deleteKeyPressed's reusing a typing command for
            textarea's shadow DOM after its input event handler rewrote the value set by the typing command.
            Because the reused typing command's ending selection was pointing at a shadow node
            that has been detached from the document when the event handler set the new value,
            rootEditableElement of the ending selection was null and caused the crash.
    
            Fixed the bug by updating the ending selection of the last typing command when it differsfrom
            that of the current selection held by the SelectionController in TypingCommand::deleteKeyPressed.
            Also fixed similar bugs in forwardDeleteKeyPressed and insertText, and insertTextRunWithoutNewlines.
    
            Tests: editing/input/set-value-on-input-and-delete.html
                   editing/input/set-value-on-input-and-forward-delete.html
                   editing/input/set-value-on-input-and-type-input.html
                   editing/input/set-value-on-input-and-type-textarea.html
    
            * editing/InsertTextCommand.h: Added TypingCommand as a friend because it needs to update selection.
            * editing/TypingCommand.cpp:
            (WebCore::TypingCommand::deleteKeyPressed): Updates the last typing command's selection as needed.
            (WebCore::TypingCommand::forwardDeleteKeyPressed): Ditto.
            (WebCore::TypingCommand::insertText): Ditto.
            (WebCore::TypingCommand::updateSelectionIfDifferentFromCurrentSelection): Added.
            (WebCore::TypingCommand::insertTextRunWithoutNewlines): Updates InsertTextCommand's selection as needed.
            * editing/TypingCommand.h:
    2010-12-03  Ryosuke Niwa  <rniwa at webkit.org>
    
            Reviewed by Darin Adler.
    
            REGRESSION: Crash when deleting text after textarea's value is modified on input event
            https://bugs.webkit.org/show_bug.cgi?id=49962
    
            Added tests to ensure inserting and deleting a character inside input or textarea
            succeeds even if the value of those elements have been rewritten by its input event handler.
    
            * editing/input/set-value-on-input-and-delete-expected.txt: Added.
            * editing/input/set-value-on-input-and-delete.html: Added.
            * editing/input/set-value-on-input-and-forward-delete-expected.txt: Added.
            * editing/input/set-value-on-input-and-forward-delete.html: Added.
            * editing/input/set-value-on-input-and-type-input-expected.txt: Added.
            * editing/input/set-value-on-input-and-type-input.html: Added.
            * editing/input/set-value-on-input-and-type-textarea-expected.txt: Added.
            * editing/input/set-value-on-input-and-type-textarea.html: Added.
    
    
    git-svn-id: http://svn.webkit.org/repository/webkit/trunk@73279 268f45cc-cd09-0410-ab3c-d52691b4dbfc

diff --git a/LayoutTests/ChangeLog b/LayoutTests/ChangeLog
index 39aa719..b2c1d08 100644
--- a/LayoutTests/ChangeLog
+++ b/LayoutTests/ChangeLog
@@ -1,3 +1,22 @@
+2010-12-03  Ryosuke Niwa  <rniwa at webkit.org>
+
+        Reviewed by Darin Adler.
+
+        REGRESSION: Crash when deleting text after textarea's value is modified on input event
+        https://bugs.webkit.org/show_bug.cgi?id=49962
+
+        Added tests to ensure inserting and deleting a character inside input or textarea
+        succeeds even if the value of those elements have been rewritten by its input event handler.
+
+        * editing/input/set-value-on-input-and-delete-expected.txt: Added.
+        * editing/input/set-value-on-input-and-delete.html: Added.
+        * editing/input/set-value-on-input-and-forward-delete-expected.txt: Added.
+        * editing/input/set-value-on-input-and-forward-delete.html: Added.
+        * editing/input/set-value-on-input-and-type-input-expected.txt: Added.
+        * editing/input/set-value-on-input-and-type-input.html: Added.
+        * editing/input/set-value-on-input-and-type-textarea-expected.txt: Added.
+        * editing/input/set-value-on-input-and-type-textarea.html: Added.
+
 2010-12-03  Sam Weinig  <sam at webkit.org>
 
         Add missing expected results.
diff --git a/LayoutTests/editing/input/set-value-on-input-and-delete-expected.txt b/LayoutTests/editing/input/set-value-on-input-and-delete-expected.txt
new file mode 100644
index 0000000..63964ac
--- /dev/null
+++ b/LayoutTests/editing/input/set-value-on-input-and-delete-expected.txt
@@ -0,0 +1,4 @@
+This tests deleting a character after input event handler modified values of textarea. WebKit should not crash and you should see PASS below:
+
+
+PASS
diff --git a/LayoutTests/editing/input/set-value-on-input-and-delete.html b/LayoutTests/editing/input/set-value-on-input-and-delete.html
new file mode 100644
index 0000000..d37c101
--- /dev/null
+++ b/LayoutTests/editing/input/set-value-on-input-and-delete.html
@@ -0,0 +1,20 @@
+<!DOCTYPE html>
+<html>
+<body>
+<p>This tests deleting a character after input event handler modified values of textarea. WebKit should not crash and you should see PASS below:</p>
+<form><textarea oninput="this.value != '' ? this.value = 'b' : null">a</textarea></form>
+<script>
+
+if (window.layoutTestController)
+    layoutTestController.dumpAsText();
+
+var text = document.forms[0].elements[0];
+text.focus();
+text.setSelectionRange(text.value.length, text.value.length);
+document.execCommand('InsertLineBreak', false, null);
+document.execCommand('Delete', false, null);
+document.write(text.value == '' ? 'PASS' : 'FAIL');
+
+</script>
+</body>
+</html>
diff --git a/LayoutTests/editing/input/set-value-on-input-and-forward-delete-expected.txt b/LayoutTests/editing/input/set-value-on-input-and-forward-delete-expected.txt
new file mode 100644
index 0000000..99de07d
--- /dev/null
+++ b/LayoutTests/editing/input/set-value-on-input-and-forward-delete-expected.txt
@@ -0,0 +1,4 @@
+This tests forward-deleting a character after input event handler modified values of textarea. WebKit should not crash and you should see PASS below:
+
+
+PASS
diff --git a/LayoutTests/editing/input/set-value-on-input-and-forward-delete.html b/LayoutTests/editing/input/set-value-on-input-and-forward-delete.html
new file mode 100644
index 0000000..819015f
--- /dev/null
+++ b/LayoutTests/editing/input/set-value-on-input-and-forward-delete.html
@@ -0,0 +1,20 @@
+<!DOCTYPE html>
+<html>
+<body>
+<p>This tests forward-deleting a character after input event handler modified values of textarea. WebKit should not crash and you should see PASS below:</p>
+<form><textarea oninput="this.value != 'b' ? this.value = 'b' : null">a</textarea></form>
+<script>
+
+if (window.layoutTestController)
+    layoutTestController.dumpAsText();
+
+var text = document.forms[0].elements[0];
+text.focus();
+text.setSelectionRange(text.value.length, text.value.length);
+document.execCommand('InsertLineBreak', false, null);
+document.execCommand('ForwardDelete', false, null);
+document.write(text.value == 'b' ? 'PASS' : 'FAIL');
+
+</script>
+</body>
+</html>
diff --git a/LayoutTests/editing/input/set-value-on-input-and-type-input-expected.txt b/LayoutTests/editing/input/set-value-on-input-and-type-input-expected.txt
new file mode 100644
index 0000000..e843084
--- /dev/null
+++ b/LayoutTests/editing/input/set-value-on-input-and-type-input-expected.txt
@@ -0,0 +1,4 @@
+This tests typing a character after input event handler modified values of input element. WebKit should not crash and you should see PASS below:
+
+
+PASS
diff --git a/LayoutTests/editing/input/set-value-on-input-and-type-input.html b/LayoutTests/editing/input/set-value-on-input-and-type-input.html
new file mode 100644
index 0000000..af29d8d
--- /dev/null
+++ b/LayoutTests/editing/input/set-value-on-input-and-type-input.html
@@ -0,0 +1,20 @@
+<!DOCTYPE html>
+<html>
+<body>
+<p>This tests typing a character after input event handler modified values of input element. WebKit should not crash and you should see PASS below:</p>
+<form><input type="text" oninput="this.value == 'ab' ? this.value = '' : null" value="a"></form>
+<script>
+
+if (window.layoutTestController)
+    layoutTestController.dumpAsText();
+
+var text = document.forms[0].elements[0];
+text.focus();
+text.setSelectionRange(text.value.length, text.value.length);
+document.execCommand('InsertText', false, 'b');
+document.execCommand('InsertText', false, 'c');
+document.write(text.value == 'c' ? 'PASS' : 'FAIL');
+
+</script>
+</body>
+</html>
diff --git a/LayoutTests/editing/input/set-value-on-input-and-type-textarea-expected.txt b/LayoutTests/editing/input/set-value-on-input-and-type-textarea-expected.txt
new file mode 100644
index 0000000..4614e5b
--- /dev/null
+++ b/LayoutTests/editing/input/set-value-on-input-and-type-textarea-expected.txt
@@ -0,0 +1,4 @@
+This tests typing a character after input event handler modified values of textarea. WebKit should not crash and you should see PASS below:
+
+
+PASS
diff --git a/LayoutTests/editing/input/set-value-on-input-and-type-textarea.html b/LayoutTests/editing/input/set-value-on-input-and-type-textarea.html
new file mode 100644
index 0000000..6875d62
--- /dev/null
+++ b/LayoutTests/editing/input/set-value-on-input-and-type-textarea.html
@@ -0,0 +1,20 @@
+<!DOCTYPE html>
+<html>
+<body>
+<p>This tests typing a character after input event handler modified values of textarea. WebKit should not crash and you should see PASS below:</p>
+<form><textarea oninput="this.value == 'ab' ? this.value = '' : null">a</textarea></form>
+<script>
+
+if (window.layoutTestController)
+    layoutTestController.dumpAsText();
+
+var text = document.forms[0].elements[0];
+text.focus();
+text.setSelectionRange(text.value.length, text.value.length);
+document.execCommand('InsertText', false, 'b');
+document.execCommand('InsertText', false, 'c');
+document.write(text.value == 'c' ? 'PASS' : 'FAIL');
+
+</script>
+</body>
+</html>
diff --git a/WebCore/ChangeLog b/WebCore/ChangeLog
index 4d8b445..f10c313 100644
--- a/WebCore/ChangeLog
+++ b/WebCore/ChangeLog
@@ -1,3 +1,34 @@
+2010-12-03  Ryosuke Niwa  <rniwa at webkit.org>
+
+        Reviewed by Darin Adler.
+
+        REGRESSION: Crash when deleting text after textarea's value is modified on input event
+        https://bugs.webkit.org/show_bug.cgi?id=49962
+
+        The crash was caused by TypingCommand::deleteKeyPressed's reusing a typing command for
+        textarea's shadow DOM after its input event handler rewrote the value set by the typing command.
+        Because the reused typing command's ending selection was pointing at a shadow node
+        that has been detached from the document when the event handler set the new value,
+        rootEditableElement of the ending selection was null and caused the crash.
+
+        Fixed the bug by updating the ending selection of the last typing command when it differsfrom
+        that of the current selection held by the SelectionController in TypingCommand::deleteKeyPressed.
+        Also fixed similar bugs in forwardDeleteKeyPressed and insertText, and insertTextRunWithoutNewlines.
+
+        Tests: editing/input/set-value-on-input-and-delete.html
+               editing/input/set-value-on-input-and-forward-delete.html
+               editing/input/set-value-on-input-and-type-input.html
+               editing/input/set-value-on-input-and-type-textarea.html
+
+        * editing/InsertTextCommand.h: Added TypingCommand as a friend because it needs to update selection.
+        * editing/TypingCommand.cpp:
+        (WebCore::TypingCommand::deleteKeyPressed): Updates the last typing command's selection as needed.
+        (WebCore::TypingCommand::forwardDeleteKeyPressed): Ditto.
+        (WebCore::TypingCommand::insertText): Ditto.
+        (WebCore::TypingCommand::updateSelectionIfDifferentFromCurrentSelection): Added.
+        (WebCore::TypingCommand::insertTextRunWithoutNewlines): Updates InsertTextCommand's selection as needed.
+        * editing/TypingCommand.h:
+
 2010-12-03  Daniel Cheng  <dcheng at chromium.org>
 
         Reviewed by Tony Chang.
diff --git a/WebCore/editing/InsertTextCommand.h b/WebCore/editing/InsertTextCommand.h
index 650ca65..24c2454 100644
--- a/WebCore/editing/InsertTextCommand.h
+++ b/WebCore/editing/InsertTextCommand.h
@@ -54,6 +54,8 @@ private:
     bool performTrivialReplace(const String&, bool selectInsertedText);
 
     unsigned m_charactersAdded;
+
+    friend class TypingCommand;
 };
 
 } // namespace WebCore
diff --git a/WebCore/editing/TypingCommand.cpp b/WebCore/editing/TypingCommand.cpp
index c596353..3cc8705 100644
--- a/WebCore/editing/TypingCommand.cpp
+++ b/WebCore/editing/TypingCommand.cpp
@@ -91,6 +91,7 @@ void TypingCommand::deleteKeyPressed(Document *document, bool smartDelete, TextG
     
     EditCommand* lastEditCommand = frame->editor()->lastEditCommand();
     if (granularity == CharacterGranularity && isOpenForMoreTypingCommand(lastEditCommand)) {
+        updateSelectionIfDifferentFromCurrentSelection(static_cast<TypingCommand*>(lastEditCommand), frame);
         static_cast<TypingCommand*>(lastEditCommand)->deleteKeyPressed(granularity, killRing);
         return;
     }
@@ -110,6 +111,7 @@ void TypingCommand::forwardDeleteKeyPressed(Document *document, bool smartDelete
     
     EditCommand* lastEditCommand = frame->editor()->lastEditCommand();
     if (granularity == CharacterGranularity && isOpenForMoreTypingCommand(lastEditCommand)) {
+        updateSelectionIfDifferentFromCurrentSelection(static_cast<TypingCommand*>(lastEditCommand), frame);
         static_cast<TypingCommand*>(lastEditCommand)->forwardDeleteKeyPressed(granularity, killRing);
         return;
     }
@@ -119,6 +121,18 @@ void TypingCommand::forwardDeleteKeyPressed(Document *document, bool smartDelete
     typingCommand->apply();
 }
 
+void TypingCommand::updateSelectionIfDifferentFromCurrentSelection(TypingCommand* typingCommand, Frame* frame)
+{
+    ASSERT(frame);
+    VisibleSelection currentSelection = frame->selection()->selection();
+    if (currentSelection == typingCommand->endingSelection())
+        return;
+    
+    typingCommand->setStartingSelection(currentSelection);
+    typingCommand->setEndingSelection(currentSelection);
+}
+    
+
 void TypingCommand::insertText(Document* document, const String& text, bool selectInsertedText, bool insertedTextIsComposition)
 {
     ASSERT(document);
@@ -129,6 +143,7 @@ void TypingCommand::insertText(Document* document, const String& text, bool sele
     insertText(document, text, frame->selection()->selection(), selectInsertedText, insertedTextIsComposition);
 }
 
+// FIXME: We shouldn't need to take selectionForInsertion. It should be identical to SelectionController's current selection.
 void TypingCommand::insertText(Document* document, const String& text, const VisibleSelection& selectionForInsertion, bool selectInsertedText, bool insertedTextIsComposition)
 {
 #if REMOVE_MARKERS_UPON_EDITING
@@ -163,15 +178,11 @@ void TypingCommand::insertText(Document* document, const String& text, const Vis
     RefPtr<EditCommand> lastEditCommand = frame->editor()->lastEditCommand();
     if (isOpenForMoreTypingCommand(lastEditCommand.get())) {
         TypingCommand* lastTypingCommand = static_cast<TypingCommand*>(lastEditCommand.get());
-        if (changeSelection) {
+        if (lastTypingCommand->endingSelection() != selectionForInsertion) {
             lastTypingCommand->setStartingSelection(selectionForInsertion);
             lastTypingCommand->setEndingSelection(selectionForInsertion);
         }
         lastTypingCommand->insertText(newText, selectInsertedText);
-        if (changeSelection) {
-            lastTypingCommand->setEndingSelection(currentSelection);
-            frame->selection()->setSelection(currentSelection);
-        }
         return;
     }
 
@@ -371,6 +382,10 @@ void TypingCommand::insertTextRunWithoutNewlines(const String &text, bool select
         command = InsertTextCommand::create(document());
         applyCommandToComposite(command);
     }
+    if (endingSelection() != command->endingSelection()) {
+        command->setStartingSelection(endingSelection());
+        command->setEndingSelection(endingSelection());
+    }
     command->input(text, selectInsertedText);
     typingAddedToOpenCommand(InsertText);
 }
diff --git a/WebCore/editing/TypingCommand.h b/WebCore/editing/TypingCommand.h
index 60b5f2a..284ebc0 100644
--- a/WebCore/editing/TypingCommand.h
+++ b/WebCore/editing/TypingCommand.h
@@ -81,6 +81,8 @@ private:
     virtual bool isTypingCommand() const;
     virtual bool preservesTypingStyle() const { return m_preservesTypingStyle; }
 
+    static void updateSelectionIfDifferentFromCurrentSelection(TypingCommand*, Frame*);
+
     void updatePreservesTypingStyle(ETypingCommand);
     void markMisspellingsAfterTyping(ETypingCommand);
     void typingAddedToOpenCommand(ETypingCommand);

-- 
WebKit Debian packaging



More information about the Pkg-webkit-commits mailing list