From 486276f0f9880dc585ddd64f543391c6f006d31c Mon Sep 17 00:00:00 2001 From: Niels Dossche <7771979+nielsdos@users.noreply.github.com> Date: Sun, 17 Sep 2023 13:39:19 +0200 Subject: [PATCH] Fix GH-12208: SimpleXML infinite loop when a cast is used inside a foreach Closes GH-12229. --- NEWS | 2 ++ ext/simplexml/simplexml.c | 4 ++-- ext/simplexml/tests/gh12208.phpt | 26 ++++++++++++++++++++++++++ 3 files changed, 30 insertions(+), 2 deletions(-) create mode 100644 ext/simplexml/tests/gh12208.phpt diff --git a/NEWS b/NEWS index 2691caec352..5b999380c14 100644 --- a/NEWS +++ b/NEWS @@ -15,6 +15,8 @@ PHP NEWS within foreach). (nielsdos) . Fixed bug GH-12223 (Entity reference produces infinite loop in var_dump/print_r). (nielsdos) + . Fixed bug GH-12208 (SimpleXML infinite loop when a cast is used inside a + foreach). (nielsdos) 28 Sep 2023, PHP 8.1.24 diff --git a/ext/simplexml/simplexml.c b/ext/simplexml/simplexml.c index 2853c0272ec..a90cbec2fd4 100644 --- a/ext/simplexml/simplexml.c +++ b/ext/simplexml/simplexml.c @@ -1860,7 +1860,7 @@ static int sxe_object_cast_ex(zend_object *readobj, zval *writeobj, int type) sxe = php_sxe_fetch_object(readobj); if (type == _IS_BOOL) { - node = php_sxe_get_first_node(sxe, NULL); + node = php_sxe_get_first_node_non_destructive(sxe, NULL); if (node) { ZVAL_TRUE(writeobj); } else { @@ -1870,7 +1870,7 @@ static int sxe_object_cast_ex(zend_object *readobj, zval *writeobj, int type) } if (sxe->iter.type != SXE_ITER_NONE) { - node = php_sxe_get_first_node(sxe, NULL); + node = php_sxe_get_first_node_non_destructive(sxe, NULL); if (node) { contents = xmlNodeListGetString((xmlDocPtr) sxe->document->ptr, node->children, 1); } diff --git a/ext/simplexml/tests/gh12208.phpt b/ext/simplexml/tests/gh12208.phpt new file mode 100644 index 00000000000..da3a997a504 --- /dev/null +++ b/ext/simplexml/tests/gh12208.phpt @@ -0,0 +1,26 @@ +--TEST-- +GH-12208 (SimpleXML infinite loop when a cast is used inside a foreach) +--EXTENSIONS-- +simplexml +--FILE-- +12"; +$xml = simplexml_load_string($xml); + +$a = $xml->a; + +foreach ($a as $test) { + var_dump((string) $a->current()); + var_dump((string) $a); + var_dump((bool) $a); +} + +?> +--EXPECT-- +string(1) "1" +string(1) "1" +bool(true) +string(1) "2" +string(1) "1" +bool(true)