From 2fa84f1683d4c1d9fabab2e8c76c735da15f084d Mon Sep 17 00:00:00 2001 From: Tete17 Date: Fri, 8 Aug 2025 02:25:57 +0200 Subject: [PATCH] LibWeb: Properly propagate errors for Node set_text_content This function was supposed to throw errors even before the TrustedTypes spec thanks to the CharacterData replaceData call but had a MUST. This changes this to ensure this function can throw an error --- Libraries/LibWeb/DOM/DocumentLoading.cpp | 4 ++-- Libraries/LibWeb/DOM/Node.cpp | 10 +++++----- Libraries/LibWeb/DOM/Node.h | 2 +- Libraries/LibWeb/HTML/HTMLDetailsElement.cpp | 4 ++-- Libraries/LibWeb/HTML/HTMLInputElement.cpp | 10 +++++----- Libraries/LibWeb/HTML/HTMLSelectElement.cpp | 2 +- Libraries/LibWeb/HTML/HTMLTextAreaElement.cpp | 6 +++--- 7 files changed, 19 insertions(+), 19 deletions(-) diff --git a/Libraries/LibWeb/DOM/DocumentLoading.cpp b/Libraries/LibWeb/DOM/DocumentLoading.cpp index c548b321130..d92a6db0aaf 100644 --- a/Libraries/LibWeb/DOM/DocumentLoading.cpp +++ b/Libraries/LibWeb/DOM/DocumentLoading.cpp @@ -296,7 +296,7 @@ static WebIDL::ExceptionOr> load_media_document(HTML::Nav }; auto style_element = TRY(DOM::create_element(document, HTML::TagNames::style, Namespace::HTML)); - style_element->set_text_content(R"~~~( + MUST(style_element->set_text_content(R"~~~( :root { background-color: #222; } @@ -310,7 +310,7 @@ static WebIDL::ExceptionOr> load_media_document(HTML::Nav img { background-color: #fff; } - )~~~"_utf16); + )~~~"_utf16)); TRY(document->head()->append_child(style_element)); auto url_string = document->url_string(); diff --git a/Libraries/LibWeb/DOM/Node.cpp b/Libraries/LibWeb/DOM/Node.cpp index a63e429d6ab..5bc5837f517 100644 --- a/Libraries/LibWeb/DOM/Node.cpp +++ b/Libraries/LibWeb/DOM/Node.cpp @@ -199,7 +199,7 @@ Optional Node::text_content() const } // https://dom.spec.whatwg.org/#ref-for-dom-node-textcontent%E2%91%A0 -void Node::set_text_content(Optional const& maybe_content) +WebIDL::ExceptionOr Node::set_text_content(Optional const& maybe_content) { // The textContent setter steps are to, if the given value is null, act as if it was the empty string instead, // and then do as described below, switching on the interface this implements: @@ -209,20 +209,19 @@ void Node::set_text_content(Optional const& maybe_content) if (is(this) || is(this)) { // OPTIMIZATION: Replacing nothing with nothing is a no-op. Avoid all invalidation in this case. if (!first_child() && content.is_empty()) { - return; + return {}; } string_replace_all(content); } // If CharacterData, replace data with node this, offset 0, count this’s length, and data the given value. else if (auto* character_data = as_if(*this)) { - MUST(character_data->replace_data(0, character_data->length_in_utf16_code_units(), content)); + TRY(character_data->replace_data(0, character_data->length_in_utf16_code_units(), content)); } // If Attr, set an existing attribute value with this and the given value. else if (auto* attribute = as_if(*this)) { - // FIXME: This should propagate - MUST(attribute->set_value(content.to_utf8_but_should_be_ported_to_utf16())); + TRY(attribute->set_value(content.to_utf8_but_should_be_ported_to_utf16())); } // Otherwise, do nothing. @@ -233,6 +232,7 @@ void Node::set_text_content(Optional const& maybe_content) } document().bump_dom_tree_version(); + return {}; } // https://dom.spec.whatwg.org/#dom-node-normalize diff --git a/Libraries/LibWeb/DOM/Node.h b/Libraries/LibWeb/DOM/Node.h index 7c883f39368..1d3b402dc15 100644 --- a/Libraries/LibWeb/DOM/Node.h +++ b/Libraries/LibWeb/DOM/Node.h @@ -280,7 +280,7 @@ public: Utf16String descendant_text_content() const; Optional text_content() const; - void set_text_content(Optional const&); + WebIDL::ExceptionOr set_text_content(Optional const&); WebIDL::ExceptionOr normalize(); diff --git a/Libraries/LibWeb/HTML/HTMLDetailsElement.cpp b/Libraries/LibWeb/HTML/HTMLDetailsElement.cpp index a8a88b347ef..655d4ba8903 100644 --- a/Libraries/LibWeb/HTML/HTMLDetailsElement.cpp +++ b/Libraries/LibWeb/HTML/HTMLDetailsElement.cpp @@ -243,7 +243,7 @@ WebIDL::ExceptionOr HTMLDetailsElement::create_shadow_tree_if_needed() // The third child element is either a link or style element with the following styles for the default summary: auto style = TRY(DOM::create_element(document(), HTML::TagNames::style, Namespace::HTML)); - style->set_text_content(R"~~~( + MUST(style->set_text_content(R"~~~( :host summary { display: list-item; counter-increment: list-item 0; @@ -252,7 +252,7 @@ WebIDL::ExceptionOr HTMLDetailsElement::create_shadow_tree_if_needed() :host([open]) summary { list-style-type: disclosure-open; } - )~~~"_utf16); + )~~~"_utf16)); MUST(shadow_root->append_child(style)); m_summary_slot = static_cast(*summary_slot); diff --git a/Libraries/LibWeb/HTML/HTMLInputElement.cpp b/Libraries/LibWeb/HTML/HTMLInputElement.cpp index c0735f5d83e..5b89dc65c1d 100644 --- a/Libraries/LibWeb/HTML/HTMLInputElement.cpp +++ b/Libraries/LibWeb/HTML/HTMLInputElement.cpp @@ -1082,7 +1082,7 @@ void HTMLInputElement::create_text_input_shadow_tree() m_text_node = realm().create(document(), Utf16String {}); if (type_state() == TypeAttributeState::Password) m_text_node->set_is_password_input({}, true); - m_text_node->set_text_content(m_value); + MUST(m_text_node->set_text_content(m_value)); handle_maxlength_attribute(); MUST(m_inner_text_element->append_child(*m_text_node)); @@ -1225,15 +1225,15 @@ void HTMLInputElement::update_file_input_shadow_tree() return; auto files_label = has_attribute(HTML::AttributeNames::multiple) ? "files"sv : "file"sv; - m_file_button->set_text_content(Utf16String::formatted("Select {}...", files_label)); + MUST(m_file_button->set_text_content(Utf16String::formatted("Select {}...", files_label))); if (m_selected_files && m_selected_files->length() > 0) { if (m_selected_files->length() == 1) - m_file_label->set_text_content(Utf16String::from_utf8(m_selected_files->item(0)->name())); + MUST(m_file_label->set_text_content(Utf16String::from_utf8(m_selected_files->item(0)->name()))); else - m_file_label->set_text_content(Utf16String::formatted("{} files selected.", m_selected_files->length())); + MUST(m_file_label->set_text_content(Utf16String::formatted("{} files selected.", m_selected_files->length()))); } else { - m_file_label->set_text_content(Utf16String::formatted("No {} selected.", files_label)); + MUST(m_file_label->set_text_content(Utf16String::formatted("No {} selected.", files_label))); } } diff --git a/Libraries/LibWeb/HTML/HTMLSelectElement.cpp b/Libraries/LibWeb/HTML/HTMLSelectElement.cpp index 8f3768b4a6e..5de6a60fc42 100644 --- a/Libraries/LibWeb/HTML/HTMLSelectElement.cpp +++ b/Libraries/LibWeb/HTML/HTMLSelectElement.cpp @@ -633,7 +633,7 @@ void HTMLSelectElement::update_inner_text_element() // Update inner text element to the label of the selected option for (auto const& option_element : m_cached_list_of_options) { if (option_element->selected()) { - m_inner_text_element->set_text_content(Infra::strip_and_collapse_whitespace(Utf16String::from_utf8(option_element->label()))); + MUST(m_inner_text_element->set_text_content(Infra::strip_and_collapse_whitespace(Utf16String::from_utf8(option_element->label())))); return; } } diff --git a/Libraries/LibWeb/HTML/HTMLTextAreaElement.cpp b/Libraries/LibWeb/HTML/HTMLTextAreaElement.cpp index dda2ba70a1b..7100542c3c2 100644 --- a/Libraries/LibWeb/HTML/HTMLTextAreaElement.cpp +++ b/Libraries/LibWeb/HTML/HTMLTextAreaElement.cpp @@ -117,7 +117,7 @@ void HTMLTextAreaElement::reset_algorithm() set_raw_value(child_text_content()); if (m_text_node) { - m_text_node->set_text_content(m_raw_value); + MUST(m_text_node->set_text_content(m_raw_value)); update_placeholder_visibility(); } } @@ -350,7 +350,7 @@ void HTMLTextAreaElement::create_shadow_tree_if_needed() m_text_node = realm().create(document(), Utf16String {}); // NOTE: If `children_changed()` was called before now, `m_raw_value` will hold the text content. // Otherwise, it will get filled in whenever that does get called. - m_text_node->set_text_content(m_raw_value); + MUST(m_text_node->set_text_content(m_raw_value)); handle_maxlength_attribute(); MUST(m_inner_text_element->append_child(*m_text_node)); @@ -403,7 +403,7 @@ void HTMLTextAreaElement::children_changed(ChildrenChangedMetadata const* metada if (!m_dirty_value) { set_raw_value(child_text_content()); if (m_text_node) - m_text_node->set_text_content(m_raw_value); + MUST(m_text_node->set_text_content(m_raw_value)); update_placeholder_visibility(); } }