Changeset 73279 in webkit


Ignore:
Timestamp:
Dec 3, 2010 11:26:22 AM (13 years ago)
Author:
rniwa@webkit.org
Message:

2010-12-03 Ryosuke Niwa <rniwa@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@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.
Location:
trunk
Files:
8 added
5 edited

Legend:

Unmodified
Added
Removed
  • trunk/LayoutTests/ChangeLog

    r73278 r73279  
     12010-12-03  Ryosuke Niwa  <rniwa@webkit.org>
     2
     3        Reviewed by Darin Adler.
     4
     5        REGRESSION: Crash when deleting text after textarea's value is modified on input event
     6        https://bugs.webkit.org/show_bug.cgi?id=49962
     7
     8        Added tests to ensure inserting and deleting a character inside input or textarea
     9        succeeds even if the value of those elements have been rewritten by its input event handler.
     10
     11        * editing/input/set-value-on-input-and-delete-expected.txt: Added.
     12        * editing/input/set-value-on-input-and-delete.html: Added.
     13        * editing/input/set-value-on-input-and-forward-delete-expected.txt: Added.
     14        * editing/input/set-value-on-input-and-forward-delete.html: Added.
     15        * editing/input/set-value-on-input-and-type-input-expected.txt: Added.
     16        * editing/input/set-value-on-input-and-type-input.html: Added.
     17        * editing/input/set-value-on-input-and-type-textarea-expected.txt: Added.
     18        * editing/input/set-value-on-input-and-type-textarea.html: Added.
     19
    1202010-12-03  Sam Weinig  <sam@webkit.org>
    221
  • trunk/WebCore/ChangeLog

    r73276 r73279  
     12010-12-03  Ryosuke Niwa  <rniwa@webkit.org>
     2
     3        Reviewed by Darin Adler.
     4
     5        REGRESSION: Crash when deleting text after textarea's value is modified on input event
     6        https://bugs.webkit.org/show_bug.cgi?id=49962
     7
     8        The crash was caused by TypingCommand::deleteKeyPressed's reusing a typing command for
     9        textarea's shadow DOM after its input event handler rewrote the value set by the typing command.
     10        Because the reused typing command's ending selection was pointing at a shadow node
     11        that has been detached from the document when the event handler set the new value,
     12        rootEditableElement of the ending selection was null and caused the crash.
     13
     14        Fixed the bug by updating the ending selection of the last typing command when it differsfrom
     15        that of the current selection held by the SelectionController in TypingCommand::deleteKeyPressed.
     16        Also fixed similar bugs in forwardDeleteKeyPressed and insertText, and insertTextRunWithoutNewlines.
     17
     18        Tests: editing/input/set-value-on-input-and-delete.html
     19               editing/input/set-value-on-input-and-forward-delete.html
     20               editing/input/set-value-on-input-and-type-input.html
     21               editing/input/set-value-on-input-and-type-textarea.html
     22
     23        * editing/InsertTextCommand.h: Added TypingCommand as a friend because it needs to update selection.
     24        * editing/TypingCommand.cpp:
     25        (WebCore::TypingCommand::deleteKeyPressed): Updates the last typing command's selection as needed.
     26        (WebCore::TypingCommand::forwardDeleteKeyPressed): Ditto.
     27        (WebCore::TypingCommand::insertText): Ditto.
     28        (WebCore::TypingCommand::updateSelectionIfDifferentFromCurrentSelection): Added.
     29        (WebCore::TypingCommand::insertTextRunWithoutNewlines): Updates InsertTextCommand's selection as needed.
     30        * editing/TypingCommand.h:
     31
    1322010-12-03  Daniel Cheng  <dcheng@chromium.org>
    233
  • trunk/WebCore/editing/InsertTextCommand.h

    r55271 r73279  
    5555
    5656    unsigned m_charactersAdded;
     57
     58    friend class TypingCommand;
    5759};
    5860
  • trunk/WebCore/editing/TypingCommand.cpp

    r72469 r73279  
    9292    EditCommand* lastEditCommand = frame->editor()->lastEditCommand();
    9393    if (granularity == CharacterGranularity && isOpenForMoreTypingCommand(lastEditCommand)) {
     94        updateSelectionIfDifferentFromCurrentSelection(static_cast<TypingCommand*>(lastEditCommand), frame);
    9495        static_cast<TypingCommand*>(lastEditCommand)->deleteKeyPressed(granularity, killRing);
    9596        return;
     
    111112    EditCommand* lastEditCommand = frame->editor()->lastEditCommand();
    112113    if (granularity == CharacterGranularity && isOpenForMoreTypingCommand(lastEditCommand)) {
     114        updateSelectionIfDifferentFromCurrentSelection(static_cast<TypingCommand*>(lastEditCommand), frame);
    113115        static_cast<TypingCommand*>(lastEditCommand)->forwardDeleteKeyPressed(granularity, killRing);
    114116        return;
     
    120122}
    121123
     124void TypingCommand::updateSelectionIfDifferentFromCurrentSelection(TypingCommand* typingCommand, Frame* frame)
     125{
     126    ASSERT(frame);
     127    VisibleSelection currentSelection = frame->selection()->selection();
     128    if (currentSelection == typingCommand->endingSelection())
     129        return;
     130   
     131    typingCommand->setStartingSelection(currentSelection);
     132    typingCommand->setEndingSelection(currentSelection);
     133}
     134   
     135
    122136void TypingCommand::insertText(Document* document, const String& text, bool selectInsertedText, bool insertedTextIsComposition)
    123137{
     
    130144}
    131145
     146// FIXME: We shouldn't need to take selectionForInsertion. It should be identical to SelectionController's current selection.
    132147void TypingCommand::insertText(Document* document, const String& text, const VisibleSelection& selectionForInsertion, bool selectInsertedText, bool insertedTextIsComposition)
    133148{
     
    164179    if (isOpenForMoreTypingCommand(lastEditCommand.get())) {
    165180        TypingCommand* lastTypingCommand = static_cast<TypingCommand*>(lastEditCommand.get());
    166         if (changeSelection) {
     181        if (lastTypingCommand->endingSelection() != selectionForInsertion) {
    167182            lastTypingCommand->setStartingSelection(selectionForInsertion);
    168183            lastTypingCommand->setEndingSelection(selectionForInsertion);
    169184        }
    170185        lastTypingCommand->insertText(newText, selectInsertedText);
    171         if (changeSelection) {
    172             lastTypingCommand->setEndingSelection(currentSelection);
    173             frame->selection()->setSelection(currentSelection);
    174         }
    175186        return;
    176187    }
     
    371382        command = InsertTextCommand::create(document());
    372383        applyCommandToComposite(command);
     384    }
     385    if (endingSelection() != command->endingSelection()) {
     386        command->setStartingSelection(endingSelection());
     387        command->setEndingSelection(endingSelection());
    373388    }
    374389    command->input(text, selectInsertedText);
  • trunk/WebCore/editing/TypingCommand.h

    r68613 r73279  
    8282    virtual bool preservesTypingStyle() const { return m_preservesTypingStyle; }
    8383
     84    static void updateSelectionIfDifferentFromCurrentSelection(TypingCommand*, Frame*);
     85
    8486    void updatePreservesTypingStyle(ETypingCommand);
    8587    void markMisspellingsAfterTyping(ETypingCommand);
Note: See TracChangeset for help on using the changeset viewer.