Skip to content

Commit e340dcc

Browse files
committed
Merge branch 'PHP-8.5' into PHP-8.6
* PHP-8.5: Fix GH-25268: clone of Dom\Notation NULL dereference
2 parents 2399bf6 + 3139a42 commit e340dcc

3 files changed

Lines changed: 36 additions & 3 deletions

File tree

‎ext/dom/node.c‎

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1533,6 +1533,10 @@ PHP_METHOD(DOMNode, cloneNode)
15331533
if (clone_document && private_data != NULL) {
15341534
php_dom_private_data_destroy(private_data);
15351535
}
1536+
if (instanceof_function(intern->std.ce, dom_modern_node_class_entry)) {
1537+
php_dom_throw_error(INVALID_STATE_ERR, /* strict */ true);
1538+
RETURN_THROWS();
1539+
}
15361540
RETURN_FALSE;
15371541
}
15381542

‎ext/dom/php_dom.c‎

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -660,9 +660,11 @@ static zend_object *dom_objects_store_clone_obj(zend_object *zobject) /* {{{ */
660660
xmlNodePtr cloned_node = dom_clone_node(php_dom_ns_mapper_from_private(private_data), node, node->doc, true);
661661
if (cloned_node != NULL) {
662662
dom_update_refcount_after_clone(intern, node, clone, cloned_node);
663-
}
664-
if (private_data != NULL) {
665-
clone->document->private_data = php_dom_libxml_private_data_header(private_data);
663+
if (private_data != NULL) {
664+
clone->document->private_data = php_dom_libxml_private_data_header(private_data);
665+
}
666+
} else if (private_data != NULL && (node->type == XML_DOCUMENT_NODE || node->type == XML_HTML_DOCUMENT_NODE)) {
667+
php_dom_private_data_destroy(private_data);
666668
}
667669
}
668670
}
Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
--TEST--
2+
GH-25268 (NULL php_libxml_ref_obj dereference in dom_objects_store_clone_obj when cloning DTD declarations)
3+
--EXTENSIONS--
4+
dom
5+
--FILE--
6+
<?php
7+
$dom = Dom\XMLDocument::createFromString('<!DOCTYPE root [<!ELEMENT root EMPTY><!ENTITY e "x">]><root/>');
8+
9+
foreach ([$dom->doctype->entities->getNamedItem("e"), $dom->doctype->childNodes[0]] as $decl) {
10+
$clone = clone $decl;
11+
try {
12+
var_dump($clone->nodeName);
13+
} catch (DOMException $e) {
14+
echo $e::class, ': ', $e->getMessage(), PHP_EOL;
15+
}
16+
try {
17+
var_dump($decl->cloneNode());
18+
} catch (DOMException $e) {
19+
echo $e::class, ': ', $e->getMessage(), PHP_EOL;
20+
}
21+
}
22+
?>
23+
--EXPECT--
24+
DOMException: Invalid State Error
25+
DOMException: Invalid State Error
26+
DOMException: Invalid State Error
27+
DOMException: Invalid State Error

0 commit comments

Comments
 (0)