Diff
Modified: trunk/Source/WebCore/ChangeLog (88215 => 88216)
--- trunk/Source/WebCore/ChangeLog 2011-06-07 04:42:45 UTC (rev 88215)
+++ trunk/Source/WebCore/ChangeLog 2011-06-07 04:52:14 UTC (rev 88216)
@@ -1,3 +1,33 @@
+2011-06-06 Kent Tamura <[email protected]>
+
+ Unreviewed, a crash fix by a roll out.
+
+ REGRESSION(r87980): Null pointer dereference in RenderTextControl::setInnerText()
+ https://bugs.webkit.org/show_bug.cgi?id=62116
+
+ Roll out the WebCore part of r87980.
+
+ * html/SearchInputType.cpp:
+ (WebCore::SearchInputType::SearchInputType):
+ (WebCore::SearchInputType::createShadowSubtree):
+ (WebCore::SearchInputType::destroyShadowSubtree):
+ * html/SearchInputType.h:
+ (WebCore::SearchInputType::innerBlockElement):
+ (WebCore::SearchInputType::resultsButtonElement):
+ (WebCore::SearchInputType::cancelButtonElement):
+ * html/TextFieldInputType.cpp:
+ (WebCore::TextFieldInputType::TextFieldInputType):
+ (WebCore::TextFieldInputType::createShadowSubtree):
+ (WebCore::TextFieldInputType::destroyShadowSubtree):
+ * html/TextFieldInputType.h:
+ (WebCore::TextFieldInputType::innerTextElement):
+ (WebCore::TextFieldInputType::innerSpinButtonElement):
+ (WebCore::TextFieldInputType::speechButtonElement):
+ (WebCore::TextFieldInputType::setInnerTextElement):
+ (WebCore::TextFieldInputType::setSpeechButtonElement):
+ * html/shadow/TextControlInnerElements.cpp:
+ * html/shadow/TextControlInnerElements.h:
+
2011-06-06 No'am Rosenthal <[email protected]>
Reviewed by Simon Fraser.
Modified: trunk/Source/WebCore/html/SearchInputType.cpp (88215 => 88216)
--- trunk/Source/WebCore/html/SearchInputType.cpp 2011-06-07 04:42:45 UTC (rev 88215)
+++ trunk/Source/WebCore/html/SearchInputType.cpp 2011-06-07 04:52:14 UTC (rev 88216)
@@ -40,6 +40,9 @@
inline SearchInputType::SearchInputType(HTMLInputElement* element)
: BaseTextInputType(element)
+ , m_innerBlock(0)
+ , m_resultsButton(0)
+ , m_cancelButton(0)
{
}
@@ -63,54 +66,47 @@
return true;
}
-static const AtomicString& innerBlockId()
-{
- DEFINE_STATIC_LOCAL(AtomicString, id, ("innerBlock"));
- return id;
-}
-
-static const AtomicString& resultButtonId()
-{
- DEFINE_STATIC_LOCAL(AtomicString, id, ("resultButton"));
- return id;
-}
-
-static const AtomicString& cancelButtonId()
-{
- DEFINE_STATIC_LOCAL(AtomicString, id, ("cancelButton"));
- return id;
-}
-
void SearchInputType::createShadowSubtree()
{
+ ASSERT(!m_innerBlock);
+ ASSERT(!innerTextElement());
+ ASSERT(!m_resultsButton);
+ ASSERT(!m_cancelButton);
+
+ ExceptionCode ec = 0;
Document* document = element()->document();
RefPtr<HTMLElement> inner = TextControlInnerElement::create(document);
- HTMLElement* innerBlock = inner.get();
- appendChildAndSetId(element()->ensureShadowRoot(), inner.release(), innerBlockId());
+ m_innerBlock = inner.get();
+ element()->ensureShadowRoot()->appendChild(inner.release(), ec);
#if ENABLE(INPUT_SPEECH)
- if (element()->isSpeechEnabled())
- appendChildAndSetId(element()->ensureShadowRoot(), InputFieldSpeechButtonElement::create(document), speechButtonId());
+ if (element()->isSpeechEnabled()) {
+ RefPtr<HTMLElement> speech = InputFieldSpeechButtonElement::create(document);
+ setSpeechButtonElement(speech.get());
+ element()->ensureShadowRoot()->appendChild(speech.release(), ec);
+ }
#endif
- appendChildAndSetId(innerBlock, SearchFieldResultsButtonElement::create(document), resultButtonId());
- appendChildAndSetId(innerBlock, TextControlInnerTextElement::create(document), innerTextId());
- appendChildAndSetId(innerBlock, SearchFieldCancelButtonElement::create(document), cancelButtonId());
-}
+ RefPtr<HTMLElement> results = SearchFieldResultsButtonElement::create(document);
+ m_resultsButton = results.get();
+ m_innerBlock->appendChild(results.release(), ec);
-HTMLElement* SearchInputType::innerBlockElement() const
-{
- return getShadowElementById(innerBlockId());
-}
+ RefPtr<HTMLElement> innerText = TextControlInnerTextElement::create(document);
+ setInnerTextElement(innerText.get());
+ m_innerBlock->appendChild(innerText.release(), ec);
-HTMLElement* SearchInputType::resultsButtonElement() const
-{
- return getShadowElementById(resultButtonId());
+ RefPtr<HTMLElement> cancel = SearchFieldCancelButtonElement::create(element()->document());
+ m_cancelButton = cancel.get();
+ m_innerBlock->appendChild(cancel.release(), ec);
}
-HTMLElement* SearchInputType::cancelButtonElement() const
+void SearchInputType::destroyShadowSubtree()
{
- return getShadowElementById(cancelButtonId());
+ TextFieldInputType::destroyShadowSubtree();
+ m_innerBlock = 0;
+ m_resultsButton = 0;
+ m_cancelButton = 0;
}
+
} // namespace WebCore
Modified: trunk/Source/WebCore/html/SearchInputType.h (88215 => 88216)
--- trunk/Source/WebCore/html/SearchInputType.h 2011-06-07 04:42:45 UTC (rev 88215)
+++ trunk/Source/WebCore/html/SearchInputType.h 2011-06-07 04:52:14 UTC (rev 88216)
@@ -35,19 +35,29 @@
namespace WebCore {
+class SearchFieldCancelButtonElement;
+class SearchFieldResultsButtonElement;
+
class SearchInputType : public BaseTextInputType {
public:
static PassOwnPtr<InputType> create(HTMLInputElement*);
+protected:
+ virtual void createShadowSubtree();
+ virtual void destroyShadowSubtree();
+
private:
SearchInputType(HTMLInputElement*);
virtual const AtomicString& formControlType() const;
virtual bool shouldRespectSpeechAttribute();
virtual bool isSearchField() const;
- virtual void createShadowSubtree();
- virtual HTMLElement* innerBlockElement() const;
- virtual HTMLElement* resultsButtonElement() const;
- virtual HTMLElement* cancelButtonElement() const;
+ virtual HTMLElement* innerBlockElement() const { return m_innerBlock; }
+ virtual HTMLElement* resultsButtonElement() const { return m_resultsButton; }
+ virtual HTMLElement* cancelButtonElement() const { return m_cancelButton; }
+
+ HTMLElement* m_innerBlock;
+ HTMLElement* m_resultsButton;
+ HTMLElement* m_cancelButton;
};
} // namespace WebCore
Modified: trunk/Source/WebCore/html/TextFieldInputType.cpp (88215 => 88216)
--- trunk/Source/WebCore/html/TextFieldInputType.cpp 2011-06-07 04:42:45 UTC (rev 88215)
+++ trunk/Source/WebCore/html/TextFieldInputType.cpp 2011-06-07 04:52:14 UTC (rev 88216)
@@ -35,7 +35,6 @@
#include "BeforeTextInsertedEvent.h"
#include "Frame.h"
#include "HTMLInputElement.h"
-#include "HTMLNames.h"
#include "KeyboardEvent.h"
#include "RenderTextControlSingleLine.h"
#include "RenderTheme.h"
@@ -48,10 +47,13 @@
namespace WebCore {
-using namespace HTMLNames;
-
TextFieldInputType::TextFieldInputType(HTMLInputElement* element)
: InputType(element)
+ , m_innerText(0)
+ , m_innerSpinButton(0)
+#if ENABLE(INPUT_SPEECH)
+ , m_speechButton(0)
+#endif
{
}
@@ -127,81 +129,51 @@
return new (arena) RenderTextControlSingleLine(element(), element()->placeholderShouldBeVisible());
}
-const AtomicString& TextFieldInputType::innerTextId() const
-{
- DEFINE_STATIC_LOCAL(AtomicString, id, ("innerText"));
- return id;
-}
-
-static const AtomicString& spinButtonId()
-{
- DEFINE_STATIC_LOCAL(AtomicString, id, ("spinButton"));
- return id;
-}
-
-#if ENABLE(INPUT_SPEECH)
-const AtomicString& TextFieldInputType::speechButtonId() const
-{
- DEFINE_STATIC_LOCAL(AtomicString, id, ("speechButton"));
- return id;
-}
-#endif
-
-void TextFieldInputType::appendChildAndSetId(ContainerNode* parent, PassRefPtr<HTMLElement> child, const AtomicString& id)
-{
- ExceptionCode ec = 0;
- child->setAttribute(idAttr, id);
- parent->appendChild(child, ec);
-}
-
void TextFieldInputType::createShadowSubtree()
{
- Document* document = element()->document();
- bool shouldHaveSpinButton = RenderTheme::themeForPage(document->page())->shouldHaveSpinButton(element());
+ ASSERT(!m_innerText);
+ ASSERT(!m_innerSpinButton);
+
+ bool shouldHaveSpinButton = RenderTheme::themeForPage(element()->document()->page())->shouldHaveSpinButton(element());
bool hasDecorations = shouldHaveSpinButton;
#if ENABLE(INPUT_SPEECH)
if (element()->isSpeechEnabled())
hasDecorations = true;
#endif
- ShadowRoot* shadowRoot = element()->ensureShadowRoot();
- appendChildAndSetId(shadowRoot, TextControlInnerTextElement::create(document), innerTextId());
+ ExceptionCode ec = 0;
+ Document* document = element()->document();
+ RefPtr<HTMLElement> innerText = TextControlInnerTextElement::create(document);
+ m_innerText = innerText.get();
+ element()->ensureShadowRoot()->appendChild(innerText.release(), ec);
if (!hasDecorations)
return;
#if ENABLE(INPUT_SPEECH)
- if (element()->isSpeechEnabled())
- appendChildAndSetId(shadowRoot, InputFieldSpeechButtonElement::create(document), speechButtonId());
+ ASSERT(!m_speechButton);
+ if (element()->isSpeechEnabled()) {
+ RefPtr<HTMLElement> speech = InputFieldSpeechButtonElement::create(document);
+ m_speechButton = speech.get();
+ element()->ensureShadowRoot()->appendChild(speech.release(), ec);
+ }
#endif
- if (shouldHaveSpinButton)
- appendChildAndSetId(shadowRoot, SpinButtonElement::create(document), spinButtonId());
+ if (shouldHaveSpinButton) {
+ RefPtr<HTMLElement> inner = SpinButtonElement::create(document);
+ m_innerSpinButton = inner.get();
+ element()->ensureShadowRoot()->appendChild(inner.release(), ec);
+ }
}
-HTMLElement* TextFieldInputType::getShadowElementById(const AtomicString& id) const
+void TextFieldInputType::destroyShadowSubtree()
{
- if (!element()->shadowRoot())
- return 0;
- Element* shadow = element()->shadowRoot()->getElementById(id);
- return shadow ? static_cast<HTMLElement*>(shadow) : 0;
-}
-
-HTMLElement* TextFieldInputType::innerTextElement() const
-{
- return getShadowElementById(innerTextId());
-}
-
-HTMLElement* TextFieldInputType::innerSpinButtonElement() const
-{
- return getShadowElementById(spinButtonId());
-}
-
+ InputType::destroyShadowSubtree();
+ m_innerText = 0;
#if ENABLE(INPUT_SPEECH)
-HTMLElement* TextFieldInputType::speechButtonElement() const
-{
- return getShadowElementById(speechButtonId());
-}
+ m_speechButton = 0;
#endif
+ m_innerSpinButton = 0;
+}
bool TextFieldInputType::shouldUseInputMethod() const
{
Modified: trunk/Source/WebCore/html/TextFieldInputType.h (88215 => 88216)
--- trunk/Source/WebCore/html/TextFieldInputType.h 2011-06-07 04:42:45 UTC (rev 88215)
+++ trunk/Source/WebCore/html/TextFieldInputType.h 2011-06-07 04:52:14 UTC (rev 88216)
@@ -35,8 +35,6 @@
namespace WebCore {
-class ContainerNode;
-
// The class represents types of which UI contain text fields.
// It supports not only the types for BaseTextInputType but also type=number.
class TextFieldInputType : public InputType {
@@ -47,20 +45,19 @@
void handleKeydownEventForSpinButton(KeyboardEvent*);
void handleWheelEventForSpinButton(WheelEvent*);
- virtual HTMLElement* innerTextElement() const;
- virtual HTMLElement* innerSpinButtonElement() const;
+ virtual HTMLElement* innerTextElement() const { return m_innerText; }
+ virtual HTMLElement* innerSpinButtonElement() const { return m_innerSpinButton; }
#if ENABLE(INPUT_SPEECH)
- virtual HTMLElement* speechButtonElement() const;
+ virtual HTMLElement* speechButtonElement() const { return m_speechButton; }
#endif
protected:
- const AtomicString& innerTextId() const;
+ virtual void createShadowSubtree();
+ virtual void destroyShadowSubtree();
+ void setInnerTextElement(HTMLElement* element) { m_innerText = element; }
#if ENABLE(INPUT_SPEECH)
- const AtomicString& speechButtonId() const;
+ void setSpeechButtonElement(HTMLElement* element) { m_speechButton = element; }
#endif
- static void appendChildAndSetId(ContainerNode*, PassRefPtr<HTMLElement>, const AtomicString&);
- virtual void createShadowSubtree();
- HTMLElement* getShadowElementById(const AtomicString&) const;
private:
virtual bool isTextField() const;
@@ -72,6 +69,12 @@
virtual bool shouldUseInputMethod() const;
virtual String sanitizeValue(const String&);
virtual bool shouldRespectListAttribute();
+
+ HTMLElement* m_innerText;
+ HTMLElement* m_innerSpinButton;
+#if ENABLE(INPUT_SPEECH)
+ HTMLElement* m_speechButton;
+#endif
};
} // namespace WebCore
Modified: trunk/Source/WebCore/html/shadow/TextControlInnerElements.cpp (88215 => 88216)
--- trunk/Source/WebCore/html/shadow/TextControlInnerElements.cpp 2011-06-07 04:42:45 UTC (rev 88215)
+++ trunk/Source/WebCore/html/shadow/TextControlInnerElements.cpp 2011-06-07 04:52:14 UTC (rev 88216)
@@ -63,11 +63,6 @@
return parentRenderer->createInnerBlockStyle(parentRenderer->style());
}
-PassRefPtr<Element> TextControlInnerElement::cloneElementWithoutAttributesAndChildren() const
-{
- return create(document());
-}
-
// ----------------------------
inline TextControlInnerTextElement::TextControlInnerTextElement(Document* document)
@@ -114,11 +109,6 @@
return parentRenderer->createInnerTextStyle(parentRenderer->style());
}
-PassRefPtr<Element> TextControlInnerTextElement::cloneElementWithoutAttributesAndChildren() const
-{
- return create(document());
-}
-
// ----------------------------
inline SearchFieldResultsButtonElement::SearchFieldResultsButtonElement(Document* document)
@@ -168,11 +158,6 @@
HTMLDivElement::defaultEventHandler(event);
}
-PassRefPtr<Element> SearchFieldResultsButtonElement::cloneElementWithoutAttributesAndChildren() const
-{
- return create(document());
-}
-
// ----------------------------
inline SearchFieldCancelButtonElement::SearchFieldCancelButtonElement(Document* document)
@@ -236,11 +221,6 @@
HTMLDivElement::defaultEventHandler(event);
}
-PassRefPtr<Element> SearchFieldCancelButtonElement::cloneElementWithoutAttributesAndChildren() const
-{
- return create(document());
-}
-
// ----------------------------
inline SpinButtonElement::SpinButtonElement(Document* document)
@@ -377,10 +357,6 @@
HTMLDivElement::setHovered(flag);
}
-PassRefPtr<Element> SpinButtonElement::cloneElementWithoutAttributesAndChildren() const
-{
- return create(document());
-}
// ----------------------------
@@ -549,11 +525,6 @@
return pseudoId;
}
-PassRefPtr<Element> InputFieldSpeechButtonElement::cloneElementWithoutAttributesAndChildren() const
-{
- return create(document());
-}
-
#endif // ENABLE(INPUT_SPEECH)
}
Modified: trunk/Source/WebCore/html/shadow/TextControlInnerElements.h (88215 => 88216)
--- trunk/Source/WebCore/html/shadow/TextControlInnerElements.h 2011-06-07 04:42:45 UTC (rev 88215)
+++ trunk/Source/WebCore/html/shadow/TextControlInnerElements.h 2011-06-07 04:52:14 UTC (rev 88216)
@@ -46,7 +46,6 @@
private:
virtual bool isMouseFocusable() const { return false; }
- virtual PassRefPtr<Element> cloneElementWithoutAttributesAndChildren() const;
};
class TextControlInnerTextElement : public HTMLDivElement {
@@ -60,7 +59,6 @@
virtual RenderObject* createRenderer(RenderArena*, RenderStyle*);
virtual PassRefPtr<RenderStyle> styleForRenderer();
virtual bool isMouseFocusable() const { return false; }
- virtual PassRefPtr<Element> cloneElementWithoutAttributesAndChildren() const;
};
class SearchFieldResultsButtonElement : public HTMLDivElement {
@@ -73,7 +71,6 @@
SearchFieldResultsButtonElement(Document*);
virtual const AtomicString& shadowPseudoId() const;
virtual bool isMouseFocusable() const { return false; }
- virtual PassRefPtr<Element> cloneElementWithoutAttributesAndChildren() const;
};
class SearchFieldCancelButtonElement : public HTMLDivElement {
@@ -87,7 +84,6 @@
virtual const AtomicString& shadowPseudoId() const;
virtual void detach();
virtual bool isMouseFocusable() const { return false; }
- virtual PassRefPtr<Element> cloneElementWithoutAttributesAndChildren() const;
bool m_capturing;
};
@@ -117,7 +113,6 @@
void repeatingTimerFired(Timer<SpinButtonElement>*);
virtual void setHovered(bool = true);
virtual bool isMouseFocusable() const { return false; }
- virtual PassRefPtr<Element> cloneElementWithoutAttributesAndChildren() const;
bool m_capturing;
UpDownState m_upDownState;
@@ -157,7 +152,6 @@
virtual const AtomicString& shadowPseudoId() const;
virtual bool isMouseFocusable() const { return false; }
virtual void attach();
- virtual PassRefPtr<Element> cloneElementWithoutAttributesAndChildren() const;
bool m_capturing;
SpeechInputState m_state;