Modified: trunk/Source/WebCore/ChangeLog (116641 => 116642)
--- trunk/Source/WebCore/ChangeLog 2012-05-10 14:05:32 UTC (rev 116641)
+++ trunk/Source/WebCore/ChangeLog 2012-05-10 14:11:37 UTC (rev 116642)
@@ -1,3 +1,27 @@
+2012-05-10 Keishi Hattori <[email protected]>
+
+ Crash in HTMLFormControlElement::m_fieldSetAncestor
+ https://bugs.webkit.org/show_bug.cgi?id=86070
+
+ Reviewed by Kent Tamura.
+
+ No new tests.
+
+ The previous patch r115990 didn't completely resolve the crash (Bug 85453)
+ We don't have a reproducible test case, so we are reverting to the old code for setting m_fieldSetAncestor.
+
+ * html/HTMLFormControlElement.cpp:
+ (WebCore::HTMLFormControlElement::HTMLFormControlElement):
+ (WebCore::HTMLFormControlElement::updateFieldSetAndLegendAncestor):
+ (WebCore::HTMLFormControlElement::insertedInto): Set m_dataListAncestorState to Unknown because ancestor has changed. Call setNeedsWillValidateCheck because style might need to be updated.
+ (WebCore::HTMLFormControlElement::removedFrom):
+ (WebCore::HTMLFormControlElement::disabled):
+ (WebCore::HTMLFormControlElement::recalcWillValidate):
+ (WebCore::HTMLFormControlElement::willValidate):
+ (WebCore::HTMLFormControlElement::setNeedsWillValidateCheck):
+ * html/HTMLFormControlElement.h:
+ (HTMLFormControlElement): Added m_dataListAncestorState.
+
2012-05-10 Sam D <[email protected]>
Web Inspector: rename InspectorBackendStub.js to InspectorBackendCommands.js
Modified: trunk/Source/WebCore/html/HTMLFormControlElement.cpp (116641 => 116642)
--- trunk/Source/WebCore/html/HTMLFormControlElement.cpp 2012-05-10 14:05:32 UTC (rev 116641)
+++ trunk/Source/WebCore/html/HTMLFormControlElement.cpp 2012-05-10 14:11:37 UTC (rev 116642)
@@ -50,17 +50,17 @@
: LabelableElement(tagName, document)
, m_fieldSetAncestor(0)
, m_legendAncestor(0)
- , m_ancestorsValid(false)
+ , m_fieldSetAncestorValid(false)
, m_disabled(false)
, m_readOnly(false)
, m_required(false)
, m_valueMatchesRenderer(false)
+ , m_dataListAncestorState(Unknown)
, m_willValidateInitialized(false)
, m_willValidate(true)
, m_isValid(true)
, m_wasChangedSinceLastFormControlChangeEvent(false)
, m_hasAutofocused(false)
- , m_hasDataListAncestor(false)
{
setForm(form ? form : findFormAncestor());
setHasCustomWillOrDidRecalcStyle();
@@ -101,22 +101,19 @@
return fastHasAttribute(formnovalidateAttr);
}
-void HTMLFormControlElement::updateAncestors() const
+void HTMLFormControlElement::updateFieldSetAndLegendAncestor() const
{
m_fieldSetAncestor = 0;
m_legendAncestor = 0;
- m_hasDataListAncestor = false;
for (ContainerNode* ancestor = parentNode(); ancestor; ancestor = ancestor->parentNode()) {
if (!m_legendAncestor && ancestor->hasTagName(legendTag))
m_legendAncestor = static_cast<HTMLLegendElement*>(ancestor);
- if (!m_fieldSetAncestor && ancestor->hasTagName(fieldsetTag))
+ if (ancestor->hasTagName(fieldsetTag)) {
m_fieldSetAncestor = static_cast<HTMLFieldSetElement*>(ancestor);
- if (!m_hasDataListAncestor && ancestor->hasTagName(datalistTag))
- m_hasDataListAncestor = true;
- if (m_hasDataListAncestor && m_fieldSetAncestor)
break;
+ }
}
- m_ancestorsValid = true;
+ m_fieldSetAncestorValid = true;
}
void HTMLFormControlElement::parseAttribute(Attribute* attr)
@@ -227,18 +224,19 @@
Node::InsertionNotificationRequest HTMLFormControlElement::insertedInto(Node* insertionPoint)
{
+ m_dataListAncestorState = Unknown;
+ setNeedsWillValidateCheck();
HTMLElement::insertedInto(insertionPoint);
FormAssociatedElement::insertedInto(insertionPoint);
- m_ancestorsValid = false;
- setNeedsWillValidateCheck();
return InsertionDone;
}
void HTMLFormControlElement::removedFrom(Node* insertionPoint)
{
+ m_fieldSetAncestorValid = false;
+ m_dataListAncestorState = Unknown;
HTMLElement::removedFrom(insertionPoint);
FormAssociatedElement::removedFrom(insertionPoint);
- m_ancestorsValid = false;
}
const AtomicString& HTMLFormControlElement::formControlName() const
@@ -279,8 +277,8 @@
if (m_disabled)
return true;
- if (!m_ancestorsValid)
- updateAncestors();
+ if (!m_fieldSetAncestorValid)
+ updateFieldSetAndLegendAncestor();
// Form controls in the first legend element inside a fieldset are not affected by fieldset.disabled.
if (m_fieldSetAncestor && m_fieldSetAncestor->disabled())
@@ -359,15 +357,22 @@
bool HTMLFormControlElement::recalcWillValidate() const
{
- return !m_hasDataListAncestor && !m_disabled && !m_readOnly;
+ if (m_dataListAncestorState == Unknown) {
+ for (ContainerNode* ancestor = parentNode(); ancestor; ancestor = ancestor->parentNode()) {
+ if (!m_legendAncestor && ancestor->hasTagName(datalistTag)) {
+ m_dataListAncestorState = InsideDataList;
+ break;
+ }
+ }
+ if (m_dataListAncestorState == Unknown)
+ m_dataListAncestorState = NotInsideDataList;
+ }
+ return m_dataListAncestorState == NotInsideDataList && !m_disabled && !m_readOnly;
}
bool HTMLFormControlElement::willValidate() const
{
- if (!m_willValidateInitialized || !m_ancestorsValid) {
- if (!m_ancestorsValid)
- updateAncestors();
-
+ if (!m_willValidateInitialized || m_dataListAncestorState == Unknown) {
m_willValidateInitialized = true;
m_willValidate = recalcWillValidate();
} else {
@@ -381,9 +386,6 @@
void HTMLFormControlElement::setNeedsWillValidateCheck()
{
- if (!m_ancestorsValid)
- updateAncestors();
-
// We need to recalculate willValidate immediately because willValidate change can causes style change.
bool newWillValidate = recalcWillValidate();
if (m_willValidateInitialized && m_willValidate == newWillValidate)
Modified: trunk/Source/WebCore/html/HTMLFormControlElement.h (116641 => 116642)
--- trunk/Source/WebCore/html/HTMLFormControlElement.h 2012-05-10 14:05:32 UTC (rev 116641)
+++ trunk/Source/WebCore/html/HTMLFormControlElement.h 2012-05-10 14:11:37 UTC (rev 116642)
@@ -51,7 +51,7 @@
void setFormMethod(const String&);
bool formNoValidate() const;
- void updateAncestors() const;
+ void updateFieldSetAndLegendAncestor() const;
virtual void reset() { }
@@ -153,12 +153,15 @@
mutable HTMLFieldSetElement* m_fieldSetAncestor;
mutable HTMLLegendElement* m_legendAncestor;
OwnPtr<ValidationMessage> m_validationMessage;
- mutable bool m_ancestorsValid : 1;
+ mutable bool m_fieldSetAncestorValid : 1;
bool m_disabled : 1;
bool m_readOnly : 1;
bool m_required : 1;
bool m_valueMatchesRenderer : 1;
+ enum DataListAncestorState { Unknown, InsideDataList, NotInsideDataList };
+ mutable enum DataListAncestorState m_dataListAncestorState;
+
// The initial value of m_willValidate depends on the derived class. We can't
// initialize it with a virtual function in the constructor. m_willValidate
// is not deterministic as long as m_willValidateInitialized is false.
@@ -172,7 +175,6 @@
bool m_wasChangedSinceLastFormControlChangeEvent : 1;
bool m_hasAutofocused : 1;
- mutable bool m_hasDataListAncestor : 1;
};
} // namespace