diff --git a/ext/simplexml/simplexml.c b/ext/simplexml/simplexml.c
index 2853c0272ec78..a90cbec2fd4ca 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 0000000000000..da3a997a5046f
--- /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)