From 1a249f9d852408fba6978725170ba272844c5642 Mon Sep 17 00:00:00 2001 From: Tim Ledbetter Date: Sun, 18 Feb 2024 14:27:25 +0000 Subject: [PATCH] LibWeb: Add ad-hoc method for serializing CDATASection nodes to string Previously, CDATASection nodes were being serialized as if they were text, which meant they were missing their start and end delimiters. Occurrences of the '&', '<' and '>' characters were also being replaced with their entity names. --- .../LibWeb/DOMParsing/XMLSerializer.cpp | 23 ++++++++++++++++++- 1 file changed, 22 insertions(+), 1 deletion(-) diff --git a/Userland/Libraries/LibWeb/DOMParsing/XMLSerializer.cpp b/Userland/Libraries/LibWeb/DOMParsing/XMLSerializer.cpp index c2d20365191..ea076a78487 100644 --- a/Userland/Libraries/LibWeb/DOMParsing/XMLSerializer.cpp +++ b/Userland/Libraries/LibWeb/DOMParsing/XMLSerializer.cpp @@ -161,6 +161,7 @@ static WebIDL::ExceptionOr serialize_text(DOM::Text const& text, Require static WebIDL::ExceptionOr serialize_document_fragment(DOM::DocumentFragment const& document_fragment, Optional& namespace_, HashMap>>& namespace_prefix_map, u64& prefix_index, RequireWellFormed require_well_formed); static WebIDL::ExceptionOr serialize_document_type(DOM::DocumentType const& document_type, RequireWellFormed require_well_formed); static WebIDL::ExceptionOr serialize_processing_instruction(DOM::ProcessingInstruction const& processing_instruction, RequireWellFormed require_well_formed); +static WebIDL::ExceptionOr serialize_cdata_section(DOM::CDATASection const& cdata_section, RequireWellFormed require_well_formed); // https://w3c.github.io/DOM-Parsing/#dfn-xml-serialization-algorithm WebIDL::ExceptionOr serialize_node_to_xml_string_impl(JS::NonnullGCPtr root, Optional& namespace_, HashMap>>& namespace_prefix_map, u64& prefix_index, RequireWellFormed require_well_formed) @@ -194,7 +195,7 @@ WebIDL::ExceptionOr serialize_node_to_xml_string_impl(JS::NonnullGCPtr(*root), require_well_formed); } - if (is(*root) || is(*root)) { + if (is(*root)) { // -> Text // Run the algorithm for XML serializing a Text node node. return serialize_text(static_cast(*root), require_well_formed); @@ -218,6 +219,12 @@ WebIDL::ExceptionOr serialize_node_to_xml_string_impl(JS::NonnullGCPtr(*root), require_well_formed); } + if (is(*root)) { + // Note: Serialization of CDATASection nodes is not mentioned in the specification, but treating CDATASection nodes as + // text leads to incorrect serialization. + return serialize_cdata_section(static_cast(*root), require_well_formed); + } + if (is(*root)) { // -> An Attr object // Return an empty string. @@ -898,4 +905,18 @@ static WebIDL::ExceptionOr serialize_processing_instruction(DOM::Process return MUST(markup.to_string()); } +// FIXME: This is ad-hoc +static WebIDL::ExceptionOr serialize_cdata_section(DOM::CDATASection const& cdata_section, RequireWellFormed require_well_formed) +{ + if (require_well_formed == RequireWellFormed::Yes && cdata_section.data().contains("]]>"sv)) + return WebIDL::InvalidStateError::create(cdata_section.realm(), "CDATA section data contains a CDATA section end delimiter"_fly_string); + + StringBuilder markup; + markup.append(""sv); + + return MUST(markup.to_string()); +} + }