Commit 5e6a440d authored by Kent Tamura's avatar Kent Tamura Committed by Commit Bot

Fix a DHCECK failure in DocumentState::ToStateVector()

https://chromium-review.googlesource.com/c/1417390 inserted a code
fragment to a wrong place, which was below an early-return. So
InvalidateStatefulFormControlList() was not called in some cases.

This CL fixes it, and adds a unit test.

Bug: 923691
Change-Id: I0aa630aeabd96d83609c0188d1fe57494b35f690
Reviewed-on: https://chromium-review.googlesource.com/c/1429321
Commit-Queue: Kent Tamura <tkent@chromium.org>
Reviewed-by: default avatarHayato Ito <hayato@chromium.org>
Cr-Commit-Position: refs/heads/master@{#625574}
parent 340ad0fc
......@@ -1926,6 +1926,7 @@ jumbo_source_set("unit_tests") {
"html/forms/email_input_type_test.cc",
"html/forms/external_popup_menu_test.cc",
"html/forms/file_input_type_test.cc",
"html/forms/form_controller_test.cc",
"html/forms/form_data_test.cc",
"html/forms/html_form_control_element_test.cc",
"html/forms/html_form_element_test.cc",
......
......@@ -24,6 +24,7 @@
#define THIRD_PARTY_BLINK_RENDERER_CORE_HTML_FORMS_FORM_CONTROLLER_H_
#include <memory>
#include "third_party/blink/renderer/core/core_export.h"
#include "third_party/blink/renderer/platform/heap/handle.h"
#include "third_party/blink/renderer/platform/wtf/allocator.h"
#include "third_party/blink/renderer/platform/wtf/forward.h"
......@@ -76,7 +77,8 @@ inline void FormControlState::Append(const String& value) {
using SavedFormStateMap =
HashMap<AtomicString, std::unique_ptr<SavedFormState>>;
class DocumentState final : public GarbageCollectedFinalized<DocumentState> {
class CORE_EXPORT DocumentState final
: public GarbageCollectedFinalized<DocumentState> {
public:
DocumentState(Document& document);
void Trace(Visitor*);
......@@ -92,7 +94,8 @@ class DocumentState final : public GarbageCollectedFinalized<DocumentState> {
bool form_controls_dirty_ = true;
};
class FormController final : public GarbageCollectedFinalized<FormController> {
class CORE_EXPORT FormController final
: public GarbageCollectedFinalized<FormController> {
public:
FormController(Document& document);
~FormController();
......
// Copyright 2019 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#include "third_party/blink/renderer/core/html/forms/form_controller.h"
#include "testing/gtest/include/gtest/gtest.h"
#include "third_party/blink/renderer/core/dom/document.h"
#include "third_party/blink/renderer/core/dom/element.h"
#include "third_party/blink/renderer/core/html_names.h"
namespace blink {
TEST(DocumentStateTest, ToStateVectorConnected) {
Document& doc = *Document::CreateForTest();
Element* html = doc.CreateRawElement(html_names::kHTMLTag);
doc.appendChild(html);
Node* body = html->appendChild(doc.CreateRawElement(html_names::kBodyTag));
ToElement(body)->SetInnerHTMLFromString("<select form='ff'></select>");
DocumentState* document_state = doc.GetFormController().FormElementsState();
Vector<String> state1 = document_state->ToStateVector();
// <signature>, <control-size>, <form-key>, <name>, <type>, <data-size(0)>
EXPECT_EQ(6u, state1.size());
Node* select = body->firstChild();
select->remove();
// Success if the following ToStateVector() doesn't fail with a DCHECK.
Vector<String> state2 = document_state->ToStateVector();
EXPECT_EQ(0u, state2.size());
}
} // namespace blink
......@@ -142,14 +142,14 @@ void ListedElement::RemovedFrom(ContainerNode& insertion_point) {
if (insertion_point.isConnected() && element->FastHasAttribute(kFormAttr)) {
SetFormAttributeTargetObserver(nullptr);
ResetFormOwner();
return;
} else {
// If the form and element are both in the same tree, preserve the
// connection to the form. Otherwise, null out our form and remove
// ourselves from the form's list of elements.
if (form_ && NodeTraversal::HighestAncestorOrSelf(*element) !=
NodeTraversal::HighestAncestorOrSelf(*form_.Get()))
ResetFormOwner();
}
// If the form and element are both in the same tree, preserve the connection
// to the form. Otherwise, null out our form and remove ourselves from the
// form's list of elements.
if (form_ && NodeTraversal::HighestAncestorOrSelf(*element) !=
NodeTraversal::HighestAncestorOrSelf(*form_.Get()))
ResetFormOwner();
DisabledStateMightBeChanged();
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment