diff --git a/NEWS b/NEWS
index f4be6b28c69..14d1cfb1b82 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.2.11
diff --git a/ext/simplexml/simplexml.c b/ext/simplexml/simplexml.c
index ecad6054dff..03dff330f50 100644
--- a/ext/simplexml/simplexml.c
+++ b/ext/simplexml/simplexml.c
@@ -1860,7 +1860,7 @@ static zend_result sxe_object_cast_ex(zend_object *readobj, zval *writeobj, int
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 zend_result sxe_object_cast_ex(zend_object *readobj, zval *writeobj, int
}
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)