[php-src] master: Merge branch 'PHP-8.5' into PHP-8.6
| From: | David Carlier | Date: | Tue, 06 Oct 2026 21:48:36 +0000 |
| Subject: | [php-src] master: Merge branch 'PHP-8.5' into PHP-8.6 | ||
| Groups: | php.cvs | ||
| Request: | Send a blank email to php-cvs+get-142051@lists.php.net to get a copy of this message | ||
Author: David Carlier (devnexen)
Date: 2026-10-06T22:46:58+01:00
Commit: https://github.com/php/php-src/commit/fac360cbc15887cc5aed08abc323d047371f870f
Raw diff: https://github.com/php/php-src/commit/fac360cbc15887cc5aed08abc323d047371f870f.diff
Merge branch 'PHP-8.5' into PHP-8.6
* PHP-8.5:
Fix GH-23352: DOMDocument::adoptNode() stale document references
Changed paths:
A ext/dom/tests/DOMDocument_adoptNode_sibling_subtree.phpt
A ext/dom/tests/gh23352.phpt
A ext/dom/tests/modern/spec/gh23352.phpt
M ext/dom/document.c
Diff:
diff --git a/ext/dom/document.c b/ext/dom/document.c
index bad0dd9feb1b..605c4dae782b 100644
--- a/ext/dom/document.c
+++ b/ext/dom/document.c
@@ -1085,6 +1085,9 @@ static void php_dom_transfer_document_ref_single_aux(xmlNodePtr node,
php_libxml
if (node->type == XML_ELEMENT_NODE) {
for (xmlAttrPtr attr = node->properties; attr != NULL; attr = attr->next) {
php_dom_transfer_document_ref_single_node((xmlNodePtr) attr, new_document);
+ for (xmlNodePtr child = attr->children; child; child = child->next) {
+ php_dom_transfer_document_ref_single_node((xmlNodePtr) child, new_document);
+ }
}
}
}
diff --git a/ext/dom/tests/DOMDocument_adoptNode_sibling_subtree.phpt
b/ext/dom/tests/DOMDocument_adoptNode_sibling_subtree.phpt
new file mode 100644
index 000000000000..d794324fc899
--- /dev/null
+++ b/ext/dom/tests/DOMDocument_adoptNode_sibling_subtree.phpt
@@ -0,0 +1,22 @@
+--TEST--
+DOMDocument::adoptNode() with a node retained under a later sibling
+--EXTENSIONS--
+dom
+--FILE--
+<?php
+
+$source = new DOMDocument();
+$root = $source->appendChild($source->createElement('root'));
+$root->appendChild($source->createElement('first'));
+$second = $root->appendChild($source->createElement('second'));
+$victim = $second->appendChild($source->createElement('grandchild'));
+
+$destination = new DOMDocument();
+$destination->appendChild($destination->adoptNode($root));
+unset($destination, $source, $root, $second);
+
+echo $victim->nodeName, PHP_EOL;
+
+?>
+--EXPECT--
+grandchild
diff --git a/ext/dom/tests/gh23352.phpt b/ext/dom/tests/gh23352.phpt
new file mode 100644
index 000000000000..67d6d4be2ffb
--- /dev/null
+++ b/ext/dom/tests/gh23352.phpt
@@ -0,0 +1,21 @@
+--TEST--
+GH-23352 (UAF reading an attribute value node retained across DOMDocument::adoptNode())
+--EXTENSIONS--
+dom
+--FILE--
+<?php
+
+$source = new DOMDocument();
+$element = $source->appendChild($source->createElement('element'));
+$element->setAttribute('attribute', 'victim');
+$victim = $element->getAttributeNode('attribute')->firstChild;
+
+$destination = new DOMDocument();
+$destination->appendChild($destination->adoptNode($element));
+unset($destination, $source, $element);
+
+echo $victim->data, PHP_EOL;
+
+?>
+--EXPECT--
+victim
diff --git a/ext/dom/tests/modern/spec/gh23352.phpt b/ext/dom/tests/modern/spec/gh23352.phpt
new file mode 100644
index 000000000000..f6d72dc9f182
--- /dev/null
+++ b/ext/dom/tests/modern/spec/gh23352.phpt
@@ -0,0 +1,21 @@
+--TEST--
+GH-23352 (UAF reading an attribute value node retained across Dom\Document::adoptNode())
+--EXTENSIONS--
+dom
+--FILE--
+<?php
+
+$source = Dom\XMLDocument::createFromString('<root/>');
+$element = $source->documentElement;
+$element->setAttribute('attribute', 'victim');
+$victim = $element->getAttributeNode('attribute')->firstChild;
+
+$destination = Dom\XMLDocument::createEmpty();
+$destination->appendChild($destination->adoptNode($element));
+unset($destination, $source, $element);
+
+echo $victim->data, PHP_EOL;
+
+?>
+--EXPECT--
+victim