[php-src] PHP-8.5: Merge branch 'PHP-8.4' into 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:33:30-04:00

Commit: https://github.com/php/php-src/commit/38a666f4c121b7a7a09ba2a19b7d1d8757b93116
Raw diff: https://github.com/php/php-src/commit/38a666f4c121b7a7a09ba2a19b7d1d8757b93116.diff

Merge branch 'PHP-8.4' into PHP-8.5

* PHP-8.4:
  [DOM] Fix getNamedItemNS() with empty URI not matching null namespace

# Conflicts:
#	ext/dom/namednodemap.c

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 75355cb5130a..ec85f966ed38 100644
--- a/NEWS
+++ b/NEWS
@@ -9,6 +9,8 @@ PHP                                                                        NEWS
     middle generator delegates again). (Lazizbek Ergashev)
 
 - 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)
   . Fixed a use-after-free when cloning a DOMNameSpaceNode after
diff --git a/ext/dom/namednodemap.c b/ext/dom/namednodemap.c
index 4964f836407c..5e0818e4a960 100644
--- a/ext/dom/namednodemap.c
+++ b/ext/dom/namednodemap.c
@@ -108,6 +108,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 800dadbfb422..88d7075be531 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"
lmpx.com only provides a reader for public news (NNTP) servers. It is not affiliated with the servers or forums shown here and is not responsible for the content of articles, which is written by their respective authors.