Bug 55133

Summary: An inconsistency between HTMLTextAreaElement::m_value and RenderTextControl::text()
Product: WebKit Reporter: Kenichi Ishibashi <bashi>
Component: TextAssignee: Nobody <webkit-unassigned>
Status: RESOLVED INVALID    
Severity: Normal CC: ap, ddavidso, hamaji, jiapu.mail, rniwa
Priority: P2    
Version: 528+ (Nightly build)   
Hardware: PC   
OS: OS X 10.5   
URL: http://crbug.com/66848
Attachments:
Description Flags
A page to repro
none
workaround patch for http://crbug.com/66848 none

Description Kenichi Ishibashi 2011-02-24 04:50:07 PST
There could be an inconsistency between HTMLTextAreaElement::m_value and RenderTextControl::text() in some cases and it could cause strange bugs.

Suppose a textarea has focus. When a textInput event occur, the text is inserted into m_innerText of the textarea's renderer (RenderTextControl) by calling InsertTextCommand::input() from TypingCommand::insertTextRunWitoutNewlines(). At this point, m_value of HTMLTextAreaElement is not up-to-date so there is an inconsistency between them until calling setFormControlValueMatchesRenderer(false). The problem arises if style update occurs before calling setFormControlValueMatchesRenderer(false). If updateStyleIfNeeded() is called as a result of style update, RenderTextControlMultiLine::updateFromElement() is called and it sets the up-to-date value of the renderer to the m_value of textarea which is obsoleted. In most cases, style update doesn't occur before calling setFormControlValueMatchesRenderer(false), but in some cases, it happens.

An chromium bug reported at http://crbug.com/66848 is one of such cases. When textarea has an event listener that is fired by key events and changes its style attribute, updateStyleIfNeeded() could be called while there is the inconsistency. As the result, inputted text doesn't appear in the textarea. Here is a stack trace of such situation:

#0  WebCore::RenderTextControl::setInnerTextValue (this=0x45b73e8, innerTextValue="bar") at third_party/WebKit/Source/WebCore/rendering/RenderTextControl.cpp:183
#1  0x0000000001498c27 in WebCore::RenderTextControlMultiLine::updateFromElement (this=0x45b73e8) at third_party/WebKit/Source/WebCore/rendering/RenderTextControlMultiLine.cpp:107
#2  0x00000000005a3862 in WebCore::updateFromElementCallback (node=0x45b6af0) at third_party/WebKit/Source/WebCore/html/HTMLFormControlElement.cpp:222
#3  0x0000000000f693e0 in WebCore::ContainerNode::dispatchPostAttachCallbacks () at third_party/WebKit/Source/WebCore/dom/ContainerNode.cpp:707
#4  0x0000000000f69272 in WebCore::ContainerNode::resumePostAttachCallbacks (this=0x44d0e20) at third_party/WebKit/Source/WebCore/dom/ContainerNode.cpp:674
#5  0x0000000000f7e428 in WebCore::Document::recalcStyle (this=0x44d0e20, change=WebCore::Node::NoChange) at third_party/WebKit/Source/WebCore/dom/Document.cpp:1542
#6  0x0000000000f7e5d7 in WebCore::Document::updateStyleIfNeeded (this=0x44d0e20) at third_party/WebKit/Source/WebCore/dom/Document.cpp:1565
#7  0x0000000000f7e770 in WebCore::Document::updateLayout (this=0x44d0e20) at third_party/WebKit/Source/WebCore/dom/Document.cpp:1592
#8  0x0000000000f7e8c2 in WebCore::Document::updateLayoutIgnorePendingStylesheets (this=0x44d0e20) at third_party/WebKit/Source/WebCore/dom/Document.cpp:1628
#9  0x000000000107b0a8 in WebCore::VisiblePosition::canonicalPosition (this=0x7fffffffa190, passedPosition=...) at third_party/WebKit/Source/WebCore/editing/VisiblePosition.cpp:459
#10 0x000000000107971b in WebCore::VisiblePosition::init (this=0x7fffffffa190, position=..., affinity=WebCore::DOWNSTREAM) at third_party/WebKit/Source/WebCore/editing/VisiblePosition.cpp:61
#11 0x0000000001079571 in WebCore::VisiblePosition::VisiblePosition (this=0x7fffffffa190, pos=..., affinity=WebCore::DOWNSTREAM) at third_party/WebKit/Source/WebCore/editing/VisiblePosition.cpp:48
#12 0x0000000001076880 in WebCore::TypingCommand::markMisspellingsAfterTyping (this=0x45f2a20, commandType=WebCore::TypingCommand::InsertText) at third_party/WebKit/Source/WebCore/editing/TypingCommand.cpp:322
#13 0x00000000010769b9 in WebCore::TypingCommand::typingAddedToOpenCommand (this=0x45f2a20, commandTypeForAddedTyping=WebCore::TypingCommand::InsertText) at third_party/WebKit/Source/WebCore/editing/TypingCommand.cpp:348
#14 0x0000000001076d3a in WebCore::TypingCommand::insertTextRunWithoutNewlines (this=0x45f2a20, text="z", selectInsertedText=false) at third_party/WebKit/Source/WebCore/editing/TypingCommand.cpp:395
#15 0x0000000001076acc in WebCore::TypingCommand::insertText (this=0x45f2a20, text="z", selectInsertedText=false) at third_party/WebKit/Source/WebCore/editing/TypingCommand.cpp:369
#16 0x000000000107679b in WebCore::TypingCommand::doApply (this=0x45f2a20) at third_party/WebKit/Source/WebCore/editing/TypingCommand.cpp:293
#17 0x00000000010303e9 in WebCore::EditCommand::apply (this=0x45f2a20) at third_party/WebKit/Source/WebCore/editing/EditCommand.cpp:92
#18 0x0000000001030a4a in WebCore::applyCommand (command=...) at third_party/WebKit/Source/WebCore/editing/EditCommand.cpp:214
#19 0x00000000010760b6 in WebCore::TypingCommand::insertText (document=0x44d0e20, text="z", selectionForInsertion=..., selectInsertedText=false, compositionType=WebCore::TypingCommand::TextCompositionNone) at third_party/WebKit/Source/WebCore/editing/TypingCommand.cpp:198
(snip)

Basically, this problem can avoid calling setFormControlValueMatchesRenderer(false) immediately after updating text value of the renderer. IMHO, calling appliedEditing() just after calling InsertTextCommand::input() is the simplest way to do it, as Safari on SnowLoepard do. However, as the comments on https://bugs.webkit.org/show_bug.cgi?id=49523 describe, it somehow complicated.

I didn't investigated in detail, but I think this is the primary cause of bug 49523 and 46868.

I'd like to fix the problem by removing PLATFORM(MAC) from TypingCommand::typingAddedToOpenCommand() because I think it is simple and natural way to resolve the inconsistency. However, I'm not familiar with the code, I'd like to ask advice.

Thanks,
Comment 1 Kenichi Ishibashi 2011-02-24 04:55:54 PST
Created attachment 83636 [details]
A page to repro

To see the problem, type some characters in the textarea. Note that the problem could happen on Chromium and will not happen on Safari.
Comment 2 Kenichi Ishibashi 2011-02-24 17:39:09 PST
Created attachment 83754 [details]
workaround patch for http://crbug.com/66848
Comment 3 Kenichi Ishibashi 2011-02-24 17:49:41 PST
(In reply to comment #2)
> Created an attachment (id=83754) [details]
> workaround patch for http://crbug.com/66848

This is workaround patch to fix http://crbug.com/66848 without removing PLATFORM(MAC) macro. spellcheckAttributeState() is called from typingAddedToOpenCommand() and hasAttribute() and getAttribute() eventually call updateStyleAttribute(), which causes calling updateStyleIfNeeded(). We can avoid this using fastHasAttribute()/fastGetAttribute() because they don't call updateStyleAttribute(). If removing PLATFORM(MAC) is not good for fixing the problem, I'd like to land this patch.