Fix GH-12223: Entity reference produces infinite loop in var_dump/print_r

Closes GH-12223.
This commit is contained in:
Niels Dossche 2023-09-16 14:18:33 +02:00
parent 4d888cf53f
commit 39a9e561f9
3 changed files with 75 additions and 0 deletions

2
NEWS
View File

@ -13,6 +13,8 @@ PHP NEWS
. Fixed bug GH-12170 (Can't use xpath with comments in SimpleXML). (nielsdos) . Fixed bug GH-12170 (Can't use xpath with comments in SimpleXML). (nielsdos)
. Fixed bug GH-12192 (SimpleXML infinite loop when getName() is called . Fixed bug GH-12192 (SimpleXML infinite loop when getName() is called
within foreach). (nielsdos) within foreach). (nielsdos)
. Fixed bug GH-12223 (Entity reference produces infinite loop in
var_dump/print_r). (nielsdos)
28 Sep 2023, PHP 8.1.24 28 Sep 2023, PHP 8.1.24

View File

@ -1197,6 +1197,12 @@ static HashTable *sxe_get_prop_hash(zend_object *object, int is_debug) /* {{{ */
sxe_properties_add(rv, name, namelen, &value); sxe_properties_add(rv, name, namelen, &value);
} }
next_iter: next_iter:
if (UNEXPECTED(node->type == XML_ENTITY_DECL)) {
/* Entity decls are linked together via the next pointer.
* The only way to get to an entity decl is via an entity reference in the document.
* If we then continue iterating, we'll end up in the DTD. Even worse, if the entities reference each other we'll infinite loop. */
break;
}
if (use_iter) { if (use_iter) {
node = php_sxe_iterator_fetch(sxe, node->next, 0); node = php_sxe_iterator_fetch(sxe, node->next, 0);
} else { } else {

View File

@ -0,0 +1,67 @@
--TEST--
GH-12223: Entity reference produces infinite loop in var_dump/print_r
--EXTENSIONS--
simplexml
--FILE--
<?php
$xml = <<<XML
<?xml version="1.0"?>
<!DOCTYPE somedoc [
<!ENTITY a "something">
<!ENTITY b "&a;">
<!ENTITY c "&b;">
]>
<somedoc>&c;</somedoc>
XML;
$sxe = simplexml_load_string($xml);
var_dump($sxe);
print_r($sxe);
?>
--EXPECT--
object(SimpleXMLElement)#1 (1) {
["c"]=>
object(SimpleXMLElement)#2 (1) {
["c"]=>
object(SimpleXMLElement)#3 (1) {
["b"]=>
object(SimpleXMLElement)#4 (1) {
["b"]=>
object(SimpleXMLElement)#5 (1) {
["a"]=>
object(SimpleXMLElement)#6 (1) {
["a"]=>
string(9) "something"
}
}
}
}
}
}
SimpleXMLElement Object
(
[c] => SimpleXMLElement Object
(
[c] => SimpleXMLElement Object
(
[b] => SimpleXMLElement Object
(
[b] => SimpleXMLElement Object
(
[a] => SimpleXMLElement Object
(
[a] => something
)
)
)
)
)
)