From f32da8029eaba2c95c9feabf0f087d3801c57c92 Mon Sep 17 00:00:00 2001 From: Niels Dossche <7771979+nielsdos@users.noreply.github.com> Date: Sat, 15 Feb 2025 13:46:25 +0100 Subject: [PATCH 1/2] Fix GH-17802: \Dom\HTMLDocument querySelector attribute name is case sensitive in HTML According to https://html.spec.whatwg.org/#case-sensitivity-of-selectors, the CSS selector attribute name must be converted to lowercase in HTML elements, and then compared case-sensitive to the attribute name in the element. We implement this not by doing the explicit conversion, but by a manual loop using a function that first converts the rhs characters to lowercase and keeps the lhs characters the same, achieving the same effect. --- .../lexbor/selectors-adapted/selectors.c | 16 ++++++- .../tests/modern/css_selectors/gh17802.phpt | 47 +++++++++++++++++++ 2 files changed, 62 insertions(+), 1 deletion(-) create mode 100644 ext/dom/tests/modern/css_selectors/gh17802.phpt diff --git a/ext/dom/lexbor/lexbor/selectors-adapted/selectors.c b/ext/dom/lexbor/lexbor/selectors-adapted/selectors.c index 8bd996a3910fe..7d99ee8e0bc3b 100644 --- a/ext/dom/lexbor/lexbor/selectors-adapted/selectors.c +++ b/ext/dom/lexbor/lexbor/selectors-adapted/selectors.c @@ -65,7 +65,21 @@ static zend_always_inline bool lxb_selectors_adapted_cmp_local_name_id(const xml static zend_always_inline const xmlAttr *lxb_selectors_adapted_attr(const xmlNode *node, const lxb_char_t *name) { - const xmlAttr *attr = xmlHasProp(node, (const xmlChar *) name); + const xmlAttr *attr = NULL; + ZEND_ASSERT(node->doc != NULL); + if (php_dom_ns_is_html_and_document_is_html(node)) { + /* No need to handle DTD entities as we're in HTML. */ + size_t name_bound = strlen((const char *) name) + 1; + for (const xmlAttr *cur = node->properties; cur != NULL; cur = cur->next) { + if (lexbor_str_data_nlocmp_right(cur->name, name, name_bound)) { + attr = cur; + break; + } + } + } else { + attr = xmlHasProp(node, (const xmlChar *) name); + } + if (attr != NULL && attr->ns != NULL) { return NULL; } diff --git a/ext/dom/tests/modern/css_selectors/gh17802.phpt b/ext/dom/tests/modern/css_selectors/gh17802.phpt new file mode 100644 index 0000000000000..4797b7fb1c9e8 --- /dev/null +++ b/ext/dom/tests/modern/css_selectors/gh17802.phpt @@ -0,0 +1,47 @@ +--TEST-- +GH-17802 (\Dom\HTMLDocument querySelector attribute name is case sensitive in HTML) +--EXTENSIONS-- +dom +--FILE-- + +
+ + + + +