Changeset 94274 in webkit
- Timestamp:
- Aug 31, 2011 11:11:07 PM (13 years ago)
- Location:
- trunk
- Files:
-
- 4 added
- 10 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/LayoutTests/ChangeLog
r94272 r94274 1 2011-08-31 Ryosuke Niwa <rniwa@webkit.org> 2 3 Crash when inserting text with a trailing newline into a textarea via JS 4 https://bugs.webkit.org/show_bug.cgi?id=66241 5 6 Reviewed by Darin Adler and Kent Tamura. 7 8 Add regressions tests to ensure WebKit doesn't crash even when style recalc happens 9 in the midst of editing commands. 10 11 * fast/forms/update-from-element-during-editing-crash-1-expected.txt: Added. 12 * fast/forms/update-from-element-during-editing-crash-1.html: Added. 13 * fast/forms/update-from-element-during-editing-crash-2-expected.txt: Added. 14 * fast/forms/update-from-element-during-editing-crash-2.html: Added. 15 1 16 2011-08-31 David Levin <levin@chromium.org> 2 17 -
trunk/Source/WebCore/ChangeLog
r94273 r94274 1 2011-08-31 Ryosuke Niwa <rniwa@webkit.org> 2 3 Crash when inserting text with a trailing newline into a textarea via JS 4 https://bugs.webkit.org/show_bug.cgi?id=66241 5 6 Reviewed by Darin Adler and Kent Tamura. 7 8 The crash was caused by updateFromElement biting on the editing code. 9 10 When there is a style rule that applies on text nodes inside the shadow DOM, DOM modifications made 11 by the editing code may trigger style recalculation on input or textarea elements in the midst of editing 12 commands. In response to this style recalculation, HTMLInputElement::updateFromElement and 13 HTMLTextAreaElement::updateFromElement call setInnerTextValue to re-create the text nodes in the 14 shadow DOM. The editing code blows up because setInnerTextValue detaches old text nodes referenced by 15 Positions and VisiblePositions held by the editing commands in progress. 16 17 Fixed the crash by stop calling setInnerTextValue in updateFromElement. Instead, WebKit now creates 18 the text nodes when attributes, descendent nodes, etc... of input or textarea element changes. 19 20 Tests: fast/forms/update-from-element-during-editing-crash-1.html 21 fast/forms/update-from-element-during-editing-crash-2.html 22 23 * html/HTMLInputElement.cpp: 24 (WebCore::HTMLInputElement::updateType): Force calling setInnerTextValue when input type changes. 25 (WebCore::HTMLInputElement::updateInnerTextValue): Extracted from RenderTextControlSingleLine's 26 updateElement. 27 (WebCore::HTMLInputElement::parseMappedAttribute): Calls updateInnerTextValue; force calling 28 setInnerTextValue when -webkit-speech attribute changes. In the theory, we should be able to call it less 29 frequently but there are too many cases to consider at the moment. 30 (WebCore::HTMLInputElement::setValue): Calls updateInnerTextValue when the value actually changed. 31 Note we need to call it before we set or restore selection. 32 * html/HTMLInputElement.h: 33 * html/HTMLTextAreaElement.cpp: 34 (WebCore::HTMLTextAreaElement::childrenChanged): Calls updateInnerTextValue when textarea's descendants 35 nodes are changed by parser or scripts. 36 (WebCore::HTMLTextAreaElement::setValueCommon): Calls updateInnerTextValue when the value changes. 37 * html/HTMLTextFormControlElement.h: 38 * html/NumberInputType.cpp: 39 (WebCore::NumberInputType::willBlur): Calls updateInnerTextValue because input[type=number] forces 40 the value to be valid on blur. 41 * rendering/RenderTextControlMultiLine.cpp: Removed RenderTextControlMultiLine::updateFromElement. 42 * rendering/RenderTextControlMultiLine.h: Ditto. 43 * rendering/RenderTextControlSingleLine.cpp: 44 (WebCore::RenderTextControlSingleLine::updateFromElement): 45 1 46 2011-08-31 Tom Zakrajsek <tomz@codeaurora.org> 2 47 -
trunk/Source/WebCore/html/HTMLInputElement.cpp
r94252 r94274 50 50 #include "RenderTextControlSingleLine.h" 51 51 #include "RenderTheme.h" 52 #include "RuntimeEnabledFeatures.h"53 52 #include "SearchInputType.h" 54 53 #include "ScriptEventListener.h" … … 60 59 #include "ColorChooser.h" 61 60 #include "ColorInputType.h" 61 #endif 62 63 #if ENABLE(INPUT_SPEECH) 64 #include "RuntimeEnabledFeatures.h" 62 65 #endif 63 66 … … 584 587 else 585 588 updateValueIfNeeded(); 589 590 setFormControlValueMatchesRenderer(false); 591 updateInnerTextValue(); 592 586 593 m_wasModifiedByUser = false; 587 594 … … 614 621 setNeedsValidityCheck(); 615 622 notifyFormStateChanged(); 623 } 624 625 void HTMLInputElement::updateInnerTextValue() 626 { 627 if (!isTextField()) 628 return; 629 630 if (!suggestedValue().isNull()) 631 setInnerTextValue(suggestedValue()); 632 else if (!formControlValueMatchesRenderer()) { 633 // Update the renderer value if the formControlValueMatchesRenderer() flag is false. 634 // It protects an unacceptable renderer value from being overwritten with the DOM value. 635 setInnerTextValue(visibleValue()); 636 } 616 637 } 617 638 … … 823 844 m_inputType->createShadowSubtree(); 824 845 } 846 setFormControlValueMatchesRenderer(false); 825 847 setNeedsStyleRecalc(); 826 848 } else if (attr->name() == onwebkitspeechchangeAttr) … … 829 851 else 830 852 HTMLTextFormControlElement::parseMappedAttribute(attr); 853 updateInnerTextValue(); 831 854 } 832 855 … … 1077 1100 1078 1101 setNeedsValidityCheck(); 1102 1103 if (valueChanged) 1104 updateInnerTextValue(); 1079 1105 1080 1106 if (isTextField()) { -
trunk/Source/WebCore/html/HTMLInputElement.h
r94158 r94274 146 146 String sanitizeValue(const String&) const; 147 147 148 void updateInnerTextValue(); 149 148 150 // The value which is drawn by a renderer. 149 151 String visibleValue() const; -
trunk/Source/WebCore/html/HTMLTextAreaElement.cpp
r94252 r94274 37 37 #include "Frame.h" 38 38 #include "HTMLNames.h" 39 #include "RenderStyle.h"40 39 #include "RenderTextControlMultiLine.h" 41 40 #include "ShadowRoot.h" … … 102 101 if (!m_isDirty) 103 102 setNonDirtyValue(defaultValue()); 103 setInnerTextValue(value()); 104 104 HTMLElement::childrenChanged(changedByParser, beforeChange, afterChange, childCountDelta); 105 105 } … … 330 330 331 331 m_value = normalizedValue; 332 setInnerTextValue(m_value); 332 333 setLastChangeWasNotUserEdit(); 333 334 updatePlaceholderVisibility(false); -
trunk/Source/WebCore/html/HTMLTextFormControlElement.h
r94252 r94274 104 104 105 105 String valueWithHardLineBreaks() const; 106 106 107 private: 107 108 int computeSelectionStart() const; -
trunk/Source/WebCore/html/NumberInputType.cpp
r94252 r94274 281 281 // We need to reset the renderer value explicitly because an unacceptable 282 282 // renderer value should be purged before style calculation. 283 if (element()->renderer()) 284 element()->renderer()->updateFromElement(); 283 element()->updateInnerTextValue(); 285 284 } 286 285 -
trunk/Source/WebCore/rendering/RenderTextControlMultiLine.cpp
r94047 r94274 81 81 } 82 82 83 void RenderTextControlMultiLine::updateFromElement()84 {85 RenderTextControl::updateFromElement();86 87 textFormControlElement()->setInnerTextValue(static_cast<HTMLTextAreaElement*>(node())->value());88 }89 90 83 PassRefPtr<RenderStyle> RenderTextControlMultiLine::createInnerTextStyle(const RenderStyle* startStyle) const 91 84 { -
trunk/Source/WebCore/rendering/RenderTextControlMultiLine.h
r93334 r94274 42 42 virtual LayoutUnit baselinePosition(FontBaseline, bool firstLine, LineDirectionMode, LinePositionMode = PositionOnContainingLine) const; 43 43 44 virtual void updateFromElement();45 46 44 virtual RenderStyle* textBaseStyle() const; 47 45 virtual PassRefPtr<RenderStyle> createInnerTextStyle(const RenderStyle* startStyle) const; -
trunk/Source/WebCore/rendering/RenderTextControlSingleLine.cpp
r94149 r94274 477 477 updateCancelButtonVisibility(); 478 478 479 if (!inputElement()->suggestedValue().isNull())480 textFormControlElement()->setInnerTextValue(inputElement()->suggestedValue());481 else {482 if (node()->hasTagName(inputTag)) {483 // For HTMLInputElement, update the renderer value if the formControlValueMatchesRenderer()484 // flag is false. It protects an unacceptable renderer value from485 // being overwritten with the DOM value.486 if (!inputElement()->formControlValueMatchesRenderer())487 textFormControlElement()->setInnerTextValue(inputElement()->visibleValue());488 }489 }490 491 479 if (m_searchPopupIsVisible) 492 480 m_searchPopup->popupMenu()->updateFromElement();
Note: See TracChangeset
for help on using the changeset viewer.