From 4840ded1f61e6d97afc83c8e4a428058656cdb08 Mon Sep 17 00:00:00 2001 From: ldm0 Date: Wed, 15 Jul 2026 03:29:19 +0800 Subject: [PATCH] fix(forms): sanitize multiple and IDN email values --- .../wpt-cross-current/failed-cases.txt | 2 -- .../wpt-cross-current/passed-cases.txt | 2 ++ moli-dom/src/native/element/control_state.rs | 10 +++++--- moli-dom/src/native/element/mod.rs | 25 ++++++++----------- moli-dom/src/native/element/rare_data.rs | 6 ++--- moli-dom/src/native/element/tests.rs | 1 + 6 files changed, 24 insertions(+), 22 deletions(-) diff --git a/moli-benchmark/wpt-cross-current/failed-cases.txt b/moli-benchmark/wpt-cross-current/failed-cases.txt index c18018880d..fc0a904d48 100644 --- a/moli-benchmark/wpt-cross-current/failed-cases.txt +++ b/moli-benchmark/wpt-cross-current/failed-cases.txt @@ -3085,8 +3085,6 @@ html/semantics/forms/form-submission-target/rel-form-target.html html/semantics/forms/form-submission-target/rel-input-target.html html/semantics/forms/textfieldselection/selection.html html/semantics/forms/the-button-element/button-click-submits-with-commandfor.html -html/semantics/forms/the-input-element/email-value-idn.html -html/semantics/forms/the-input-element/email.html html/semantics/forms/the-input-element/input-type-button.html html/semantics/forms/the-input-element/range-2.html html/semantics/forms/the-input-element/range.html diff --git a/moli-benchmark/wpt-cross-current/passed-cases.txt b/moli-benchmark/wpt-cross-current/passed-cases.txt index ae3a5c2396..a1b4530c52 100644 --- a/moli-benchmark/wpt-cross-current/passed-cases.txt +++ b/moli-benchmark/wpt-cross-current/passed-cases.txt @@ -6359,6 +6359,8 @@ html/semantics/forms/the-input-element/datetime-local-valueasdate.html html/semantics/forms/the-input-element/datetime-local.html html/semantics/forms/the-input-element/datetime-weekmonth.html html/semantics/forms/the-input-element/datetime.html +html/semantics/forms/the-input-element/email-value-idn.html +html/semantics/forms/the-input-element/email.html html/semantics/forms/the-input-element/files.html html/semantics/forms/the-input-element/focus-dynamic-type-change-on-blur.html html/semantics/forms/the-input-element/focus-dynamic-type-change.html diff --git a/moli-dom/src/native/element/control_state.rs b/moli-dom/src/native/element/control_state.rs index 4814e35f19..4620c323b3 100644 --- a/moli-dom/src/native/element/control_state.rs +++ b/moli-dom/src/native/element/control_state.rs @@ -875,8 +875,8 @@ impl ElementControlState { namespace: &str, local_name: &str, input_type: InputType, - input_multiple: bool, input_value_attribute: Option<&str>, + input_multiple: bool, attribute_name: &str, attribute_value: Option<&str>, ) { @@ -924,10 +924,14 @@ impl ElementControlState { } } ("input", "multiple") if input_type == InputType::Email => { - let current = self.input_value.as_deref().unwrap_or_default(); + let source = if self.input_value_dirty { + self.input_value.as_deref().unwrap_or_default() + } else { + input_value_attribute.unwrap_or_default() + }; self.input_value = Some(sanitize_input_value_for_type_with_multiple( input_type, - current, + source, input_multiple, )); self.input_bad_input = false; diff --git a/moli-dom/src/native/element/mod.rs b/moli-dom/src/native/element/mod.rs index 06e1213745..06688a747e 100644 --- a/moli-dom/src/native/element/mod.rs +++ b/moli-dom/src/native/element/mod.rs @@ -1163,29 +1163,26 @@ impl Element { attribute_name: &str, attribute_value: Option<&str>, ) { - let input_value_attribute = if self.namespace() == "http://www.w3.org/1999/xhtml" - && self.local_name() == "input" - && attribute_name == "type" - { - self.attribute("value").map(str::to_owned) - } else { - None - }; - let input_type = if self.namespace() == "http://www.w3.org/1999/xhtml" - && self.local_name() == "input" - && attribute_name == "type" - { + let is_html_input = + self.namespace() == "http://www.w3.org/1999/xhtml" && self.local_name() == "input"; + let input_value_attribute = + if is_html_input && matches!(attribute_name, "type" | "multiple") { + self.attribute("value").map(str::to_owned) + } else { + None + }; + let input_type = if is_html_input && attribute_name == "type" { InputType::from_attribute_value(attribute_value) } else { self.input_type() }; - let input_multiple = self.is_html_input() && self.has_attribute("multiple"); + let input_multiple = is_html_input && self.has_attribute("multiple"); self.rare_data.sync_control_state_from_attribute( self.namespace.as_ref(), self.local_name.as_ref(), input_type, - input_multiple, input_value_attribute.as_deref(), + input_multiple, attribute_name, attribute_value, ); diff --git a/moli-dom/src/native/element/rare_data.rs b/moli-dom/src/native/element/rare_data.rs index c411186608..6ce7223ec5 100644 --- a/moli-dom/src/native/element/rare_data.rs +++ b/moli-dom/src/native/element/rare_data.rs @@ -215,8 +215,8 @@ impl ElementRareData { namespace: &str, local_name: &str, input_type: InputType, - input_multiple: bool, input_value_attribute: Option<&str>, + input_multiple: bool, attribute_name: &str, attribute_value: Option<&str>, ) { @@ -229,8 +229,8 @@ impl ElementRareData { namespace, local_name, input_type, - input_multiple, input_value_attribute, + input_multiple, attribute_name, attribute_value, ); @@ -250,8 +250,8 @@ impl ElementRareData { namespace, local_name, input_type, - input_multiple, input_value_attribute, + input_multiple, attribute_name, attribute_value, ); diff --git a/moli-dom/src/native/element/tests.rs b/moli-dom/src/native/element/tests.rs index 8360870088..d19b66f149 100644 --- a/moli-dom/src/native/element/tests.rs +++ b/moli-dom/src/native/element/tests.rs @@ -366,6 +366,7 @@ fn input_type_change_sanitizes_without_dirtying_default_value() { assert!(input.input_value_dirty()); } + #[test] fn script_element_state_distinguishes_dynamic_and_parser_created_scripts() { let dynamic = Element::new_html("script");