[php-src] master: Merge branch 'PHP-8.5'
Ilia Alshanetsky <[email protected]>
| Newsgroups | gmane.comp.php.cvs.general |
|---|---|
| Message-ID | <[email protected]> |
Author: Ilia Alshanetsky (iliaal)
Date: 2026-08-30T12:34:09-04:00
Commit: https://github.com/php/php-src/commit/f142b815884597f398b8bb52d9558cc313397075
Raw diff: https://github.com/php/php-src/commit/f142b815884597f398b8bb52d9558cc313397075.diff
Merge branch 'PHP-8.5'
* PHP-8.5:
[DOM] Fix getNamedItemNS() with empty URI not matching null namespace
Changed paths:
A ext/dom/tests/modern/spec/NamedNodeMap_getNamedItemNS.phpt
A ext/dom/tests/modern/spec/NamedNodeMap_getNamedItemNS_dtd_default.phpt
M NEWS
M ext/dom/namednodemap.c
M ext/dom/obj_map.c
Diff:
diff --git a/NEWS b/NEWS
index 89a8dd8dc939..653bcff9e05a 100644
--- a/NEWS
+++ b/NEWS
@@ -7,6 +7,8 @@ PHP NEWS
100-continue flow control). (Sjoerd Langkemper)
- DOM:
+ . Fixed NamedNodeMap::getNamedItemNS() with an empty URI not matching
+ the null namespace in spec-following mode. (Ilia Alshanetsky)
. Fixed stale getElementsByClassName() and other node list caches after
className/classList writes and attribute removals. (Ilia Alshanetsky)
diff --git a/ext/dom/namednodemap.c b/ext/dom/namednodemap.c
index c6d8157881a3..d665bbbaebdc 100644
--- a/ext/dom/namednodemap.c
+++ b/ext/dom/namednodemap.c
@@ -106,6 +106,9 @@ PHP_METHOD(DOMNamedNodeMap, getNamedItemNS)
objmap = (dom_nnodemap_object *)intern->ptr;
if (objmap != NULL) {
+ if (urilen == 0 && objmap->baseobj != NULL && php_dom_follow_spec_intern(objmap->baseobj)) {
+ uri = NULL;
+ }
php_dom_obj_map_get_ns_named_item_into_zval(objmap, named, uri, return_value);
}
}
diff --git a/ext/dom/obj_map.c b/ext/dom/obj_map.c
index 4d6479e003f9..14521f333263 100644
--- a/ext/dom/obj_map.c
+++ b/ext/dom/obj_map.c
@@ -514,7 +514,11 @@ static xmlNodePtr dom_map_get_ns_named_item_prop(dom_nnodemap_object *map, const
xmlNodePtr nodep = dom_object_get_node(map->baseobj);
if (nodep) {
if (ns) {
- return (xmlNodePtr) xmlHasNsProp(nodep, BAD_CAST ZSTR_VAL(named), BAD_CAST ns);
+ xmlNodePtr itemnode = (xmlNodePtr) xmlHasNsProp(nodep, BAD_CAST ZSTR_VAL(named), BAD_CAST ns);
+ if (itemnode != NULL && itemnode->type == XML_ATTRIBUTE_DECL) {
+ return NULL;
+ }
+ return itemnode;
} else {
if (php_dom_follow_spec_intern(map->baseobj)) {
return (xmlNodePtr) php_dom_get_attribute_node(nodep, BAD_CAST ZSTR_VAL(named), ZSTR_LEN(named));
diff --git a/ext/dom/tests/modern/spec/NamedNodeMap_getNamedItemNS.phpt b/ext/dom/tests/modern/spec/NamedNodeMap_getNamedItemNS.phpt
new file mode 100644
index 000000000000..17d0659678e6
--- /dev/null
+++ b/ext/dom/tests/modern/spec/NamedNodeMap_getNamedItemNS.phpt
@@ -0,0 +1,25 @@
+--TEST--
+getNamedItemNS() with an empty URI must look up the null namespace
+--EXTENSIONS--
+dom
+--FILE--
+<?php
+$d = new DOMDocument();
+$d->loadXML('<root xmlns:q="urn:q" bar="no-ns" q:bar="ns"/>');
+$a = $d->documentElement->attributes->getNamedItemNS('', 'bar');
+var_dump($a === null ? null : $a->nodeValue);
+$b = $d->documentElement->attributes->getNamedItemNS('urn:q', 'bar');
+var_dump($b === null ? null : $b->nodeValue);
+$d2 = Dom\XMLDocument::createFromString('<root xmlns:q="urn:q" bar="no-ns" q:bar="ns"/>');
+$a2 = $d2->documentElement->attributes->getNamedItemNS('', 'bar');
+var_dump($a2 === null ? null : $a2->nodeValue);
+var_dump($d2->documentElement->hasAttributeNS('', 'bar'));
+$c = $d2->documentElement->attributes->getNamedItemNS('urn:q', 'bar');
+var_dump($c === null ? null : $c->nodeValue);
+?>
+--EXPECT--
+NULL
+string(2) "ns"
+string(5) "no-ns"
+bool(true)
+string(2) "ns"
diff --git a/ext/dom/tests/modern/spec/NamedNodeMap_getNamedItemNS_dtd_default.phpt b/ext/dom/tests/modern/spec/NamedNodeMap_getNamedItemNS_dtd_default.phpt
new file mode 100644
index 000000000000..c661af974c77
--- /dev/null
+++ b/ext/dom/tests/modern/spec/NamedNodeMap_getNamedItemNS_dtd_default.phpt
@@ -0,0 +1,24 @@
+--TEST--
+getNamedItemNS() with empty URI must not throw on DTD default attributes
+--EXTENSIONS--
+dom
+--FILE--
+<?php
+$xml = <<<XML
+<?xml version="1.0"?>
+<!DOCTYPE root [
+<!ELEMENT root EMPTY>
+<!ATTLIST root defaulted CDATA "from-dtd">
+]>
+<root real="present"/>
+XML;
+
+$el = Dom\XMLDocument::createFromString($xml)->documentElement;
+$defaulted = $el->attributes->getNamedItemNS('', 'defaulted');
+var_dump($defaulted === null ? null : $defaulted->nodeValue);
+$real = $el->attributes->getNamedItemNS('', 'real');
+var_dump($real === null ? null : $real->nodeValue);
+?>
+--EXPECT--
+NULL
+string(7) "present"