From 0154bb515cc1b8fc1980e574249f28763c58e76d Mon Sep 17 00:00:00 2001 From: Niels Dossche <7771979+nielsdos@users.noreply.github.com> Date: Sun, 16 Mar 2025 13:40:54 +0100 Subject: [PATCH] Fix GH-18090: DOM: Svg attributes and tag names are being lowercased --- ext/dom/html5_parser.c | 12 ++++++++++-- ext/dom/tests/modern/html/parser/gh18090.phpt | 18 ++++++++++++++++++ .../html/parser/predefined_namespaces.phpt | 6 +++--- 3 files changed, 31 insertions(+), 5 deletions(-) create mode 100644 ext/dom/tests/modern/html/parser/gh18090.phpt diff --git a/ext/dom/html5_parser.c b/ext/dom/html5_parser.c index 0d7d2b9e7249d..f1dc2db53b25b 100644 --- a/ext/dom/html5_parser.c +++ b/ext/dom/html5_parser.c @@ -138,7 +138,9 @@ static lexbor_libxml2_bridge_status lexbor_libxml2_bridge_convert( * If a prefix:name format is used, then the local name will be "prefix:name" and the prefix will be empty. * There is however still somewhat of a concept of namespaces. There are three: HTML (the default), SVG, and MATHML. */ lxb_dom_element_t *element = lxb_dom_interface_element(node); - const lxb_char_t *name = lxb_dom_element_local_name(element, NULL); + const lxb_char_t *name = lxb_dom_element_qualified_name(element, NULL); + ZEND_ASSERT(!element->node.prefix); + xmlNodePtr lxml_element = xmlNewDocNode(lxml_doc, NULL, name, NULL); if (UNEXPECTED(lxml_element == NULL)) { retval = LEXBOR_LIBXML2_BRIDGE_STATUS_OOM; @@ -203,7 +205,13 @@ static lexbor_libxml2_bridge_status lexbor_libxml2_bridge_convert( for (lxb_dom_attr_t *attr = element->first_attr; attr != NULL; attr = attr->next) { /* Same namespace remark as for elements */ size_t local_name_length, value_length; - const lxb_char_t *local_name = lxb_dom_attr_local_name(attr, &local_name_length); + const lxb_char_t *local_name = lxb_dom_attr_qualified_name(attr, &local_name_length); + if (attr->node.prefix) { + const char *pos = strchr((const char *) local_name, ':'); + if (EXPECTED(pos)) { + local_name = (const lxb_char_t *) pos + 1; + } + } const lxb_char_t *value = lxb_dom_attr_value(attr, &value_length); if (UNEXPECTED(local_name_length >= INT_MAX || value_length >= INT_MAX)) { diff --git a/ext/dom/tests/modern/html/parser/gh18090.phpt b/ext/dom/tests/modern/html/parser/gh18090.phpt new file mode 100644 index 0000000000000..c32f5ddb51336 --- /dev/null +++ b/ext/dom/tests/modern/html/parser/gh18090.phpt @@ -0,0 +1,18 @@ +--TEST-- +GH-18090 (Svg attributes and tag names are being lowercased) +--EXTENSIONS-- +dom +--FILE-- +
', LIBXML_NOERROR)->saveHTML(), "\n"; + +echo \Dom\HTMLDocument::createFromString('', LIBXML_NOERROR)->saveHTML(), "\n"; + +echo \Dom\HTMLDocument::createFromString('', LIBXML_NOERROR)->querySelector('svg')->attributes[0]->name, "\n"; +?> +--EXPECT-- + + +viewBox diff --git a/ext/dom/tests/modern/html/parser/predefined_namespaces.phpt b/ext/dom/tests/modern/html/parser/predefined_namespaces.phpt index 7e78460454e60..b4c07c6fb3bb8 100644 --- a/ext/dom/tests/modern/html/parser/predefined_namespaces.phpt +++ b/ext/dom/tests/modern/html/parser/predefined_namespaces.phpt @@ -47,7 +47,7 @@ echo $dom->saveXml(); svg http://www.w3.org/2000/svg Attribute: width (NONE) Attribute: height (NONE) - Attribute: viewbox (NONE) + Attribute: viewBox (NONE) rect http://www.w3.org/2000/svg Attribute: id (NONE) Attribute: x (NONE) @@ -65,7 +65,7 @@ svg http://www.w3.org/1998/Math/MathML