Pārlūkot izejas kodu

LibWeb: Do not use HTMLFormElement::elements to get submittable elements

HTMLFormElement::elements is not the correct filter for submittable
elements. It includes non-submittable elements (HTMLObjectElement) and
also excludes submittable elements (HTMLInputElements in the "image"
type state, "for historical reasons").
Timothy Flynn 1 gadu atpakaļ
vecāks
revīzija
986811d2aa

+ 1 - 3
Userland/Libraries/LibWeb/HTML/FormControlInfrastructure.cpp

@@ -51,8 +51,6 @@ WebIDL::ExceptionOr<XHR::FormDataEntry> create_entry(JS::Realm& realm, String co
 // https://html.spec.whatwg.org/multipage/form-control-infrastructure.html#constructing-the-form-data-set
 WebIDL::ExceptionOr<Optional<Vector<XHR::FormDataEntry>>> construct_entry_list(JS::Realm& realm, HTMLFormElement& form, JS::GCPtr<HTMLElement> submitter, Optional<String> encoding)
 {
-    auto& vm = realm.vm();
-
     // 1. If form's constructing entry list is true, then return null.
     if (form.constructing_entry_list())
         return Optional<Vector<XHR::FormDataEntry>> {};
@@ -61,7 +59,7 @@ WebIDL::ExceptionOr<Optional<Vector<XHR::FormDataEntry>>> construct_entry_list(J
     form.set_constructing_entry_list(true);
 
     // 3. Let controls be a list of all the submittable elements whose form owner is form, in tree order.
-    auto controls = TRY_OR_THROW_OOM(vm, form.get_submittable_elements());
+    auto controls = form.get_submittable_elements();
 
     // 4. Let entry list be a new empty entry list.
     Vector<XHR::FormDataEntry> entry_list;

+ 10 - 19
Userland/Libraries/LibWeb/HTML/HTMLFormElement.cpp

@@ -538,29 +538,20 @@ WebIDL::ExceptionOr<bool> HTMLFormElement::report_validity()
 }
 
 // https://html.spec.whatwg.org/multipage/forms.html#category-submit
-ErrorOr<Vector<JS::NonnullGCPtr<DOM::Element>>> HTMLFormElement::get_submittable_elements()
+Vector<JS::NonnullGCPtr<DOM::Element>> HTMLFormElement::get_submittable_elements()
 {
-    Vector<JS::NonnullGCPtr<DOM::Element>> submittable_elements = {};
-    for (size_t i = 0; i < elements()->length(); i++) {
-        auto* element = elements()->item(i);
-        TRY(populate_vector_with_submittable_elements_in_tree_order(*element, submittable_elements));
-    }
-    return submittable_elements;
-}
+    Vector<JS::NonnullGCPtr<DOM::Element>> submittable_elements;
 
-ErrorOr<void> HTMLFormElement::populate_vector_with_submittable_elements_in_tree_order(JS::NonnullGCPtr<DOM::Element> element, Vector<JS::NonnullGCPtr<DOM::Element>>& elements)
-{
-    if (auto* form_associated_element = dynamic_cast<HTML::FormAssociatedElement*>(element.ptr())) {
-        if (form_associated_element->is_submittable())
-            TRY(elements.try_append(element));
-    }
+    root().for_each_in_subtree([&](auto& node) {
+        if (auto* form_associated_element = dynamic_cast<FormAssociatedElement*>(&node)) {
+            if (form_associated_element->is_submittable() && form_associated_element->form() == this)
+                submittable_elements.append(form_associated_element->form_associated_element_to_html_element());
+        }
 
-    for (size_t i = 0; i < element->children()->length(); i++) {
-        auto* child = element->children()->item(i);
-        TRY(populate_vector_with_submittable_elements_in_tree_order(*child, elements));
-    }
+        return IterationDecision::Continue;
+    });
 
-    return {};
+    return submittable_elements;
 }
 
 // https://html.spec.whatwg.org/multipage/form-control-infrastructure.html#dom-fs-method

+ 1 - 3
Userland/Libraries/LibWeb/HTML/HTMLFormElement.h

@@ -74,7 +74,7 @@ public:
     void add_associated_element(Badge<FormAssociatedElement>, HTMLElement&);
     void remove_associated_element(Badge<FormAssociatedElement>, HTMLElement&);
 
-    ErrorOr<Vector<JS::NonnullGCPtr<DOM::Element>>> get_submittable_elements();
+    Vector<JS::NonnullGCPtr<DOM::Element>> get_submittable_elements();
 
     JS::NonnullGCPtr<DOM::HTMLFormControlsCollection> elements() const;
     unsigned length() const;
@@ -109,8 +109,6 @@ private:
     virtual Vector<FlyString> supported_property_names() const override;
     virtual bool is_supported_property_index(u32) const override;
 
-    ErrorOr<void> populate_vector_with_submittable_elements_in_tree_order(JS::NonnullGCPtr<DOM::Element> element, Vector<JS::NonnullGCPtr<DOM::Element>>& elements);
-
     ErrorOr<String> pick_an_encoding() const;
 
     ErrorOr<void> mutate_action_url(AK::URL parsed_action, Vector<XHR::FormDataEntry> entry_list, String encoding, JS::NonnullGCPtr<Navigable> target_navigable, Bindings::NavigationHistoryBehavior history_handling, UserNavigationInvolvement user_involvement);