diff --git a/NEWS b/NEWS
index 96a584999bb..a18df44f7e5 100644
--- a/NEWS
+++ b/NEWS
@@ -17,6 +17,9 @@ PHP NEWS
. Fixed bug GH-12297 (PHP Startup: Invalid library (maybe not a PHP library)
'mysqlnd.so' in Unknown on line). (nielsdos)
+- SimpleXML:
+ . Apply iterator fixes only on master. (nielsdos)
+
- XSL:
. Fix type error on XSLTProcessor::transformToDoc return value with
SimpleXML. (nielsdos)
diff --git a/ext/simplexml/simplexml.c b/ext/simplexml/simplexml.c
index a2b883cedc4..3e2f1e68554 100644
--- a/ext/simplexml/simplexml.c
+++ b/ext/simplexml/simplexml.c
@@ -77,10 +77,10 @@ static void _node_as_zval(php_sxe_object *sxe, xmlNodePtr node, zval *value, SXE
}
/* }}} */
-static xmlNodePtr php_sxe_get_first_node_non_destructive(php_sxe_object *sxe, xmlNodePtr node)
+static xmlNodePtr php_sxe_get_first_node(php_sxe_object *sxe, xmlNodePtr node)
{
if (sxe && sxe->iter.type != SXE_ITER_NONE) {
- return php_sxe_reset_iterator_no_clear_iter_data(sxe, false);
+ return php_sxe_reset_iterator(sxe, 1);
} else {
return node;
}
@@ -163,7 +163,7 @@ static xmlNodePtr sxe_get_element_by_name(php_sxe_object *sxe, xmlNodePtr node,
if (sxe->iter.type == SXE_ITER_NONE) {
sxe->iter.type = SXE_ITER_CHILD;
}
- node = php_sxe_get_first_node_non_destructive(sxe, node);
+ node = php_sxe_get_first_node(sxe, node);
sxe->iter.type = orgtype;
}
@@ -238,11 +238,11 @@ long_dim:
if (sxe->iter.type == SXE_ITER_ATTRLIST) {
attribs = 1;
elements = 0;
- node = php_sxe_get_first_node_non_destructive(sxe, node);
+ node = php_sxe_get_first_node(sxe, node);
attr = (xmlAttrPtr)node;
test = sxe->iter.name != NULL;
} else if (sxe->iter.type != SXE_ITER_CHILD) {
- node = php_sxe_get_first_node_non_destructive(sxe, node);
+ node = php_sxe_get_first_node(sxe, node);
attr = node ? node->properties : NULL;
test = 0;
if (!member && node && node->parent &&
@@ -290,7 +290,7 @@ long_dim:
xmlNodePtr mynode = node;
if (sxe->iter.type == SXE_ITER_CHILD) {
- node = php_sxe_get_first_node_non_destructive(sxe, node);
+ node = php_sxe_get_first_node(sxe, node);
}
if (sxe->iter.type == SXE_ITER_NONE) {
if (member && Z_LVAL_P(member) > 0) {
@@ -426,12 +426,12 @@ long_dim:
if (sxe->iter.type == SXE_ITER_ATTRLIST) {
attribs = 1;
elements = 0;
- node = php_sxe_get_first_node_non_destructive(sxe, node);
+ node = php_sxe_get_first_node(sxe, node);
attr = (xmlAttrPtr)node;
test = sxe->iter.name != NULL;
} else if (sxe->iter.type != SXE_ITER_CHILD) {
mynode = node;
- node = php_sxe_get_first_node_non_destructive(sxe, node);
+ node = php_sxe_get_first_node(sxe, node);
attr = node ? node->properties : NULL;
test = 0;
if (!member && node && node->parent &&
@@ -677,7 +677,7 @@ static int sxe_prop_dim_exists(zend_object *object, zval *member, int check_empt
attribs = 0;
elements = 1;
if (sxe->iter.type == SXE_ITER_CHILD) {
- node = php_sxe_get_first_node_non_destructive(sxe, node);
+ node = php_sxe_get_first_node(sxe, node);
}
}
}
@@ -685,11 +685,11 @@ static int sxe_prop_dim_exists(zend_object *object, zval *member, int check_empt
if (sxe->iter.type == SXE_ITER_ATTRLIST) {
attribs = 1;
elements = 0;
- node = php_sxe_get_first_node_non_destructive(sxe, node);
+ node = php_sxe_get_first_node(sxe, node);
attr = (xmlAttrPtr)node;
test = sxe->iter.name != NULL;
} else if (sxe->iter.type != SXE_ITER_CHILD) {
- node = php_sxe_get_first_node_non_destructive(sxe, node);
+ node = php_sxe_get_first_node(sxe, node);
attr = node ? node->properties : NULL;
test = 0;
}
@@ -729,7 +729,7 @@ static int sxe_prop_dim_exists(zend_object *object, zval *member, int check_empt
if (elements) {
if (Z_TYPE_P(member) == IS_LONG) {
if (sxe->iter.type == SXE_ITER_CHILD) {
- node = php_sxe_get_first_node_non_destructive(sxe, node);
+ node = php_sxe_get_first_node(sxe, node);
}
node = sxe_get_element_by_offset(sxe, Z_LVAL_P(member), node, NULL);
} else {
@@ -801,7 +801,7 @@ static void sxe_prop_dim_delete(zend_object *object, zval *member, bool elements
attribs = 0;
elements = 1;
if (sxe->iter.type == SXE_ITER_CHILD) {
- node = php_sxe_get_first_node_non_destructive(sxe, node);
+ node = php_sxe_get_first_node(sxe, node);
}
}
}
@@ -809,11 +809,11 @@ static void sxe_prop_dim_delete(zend_object *object, zval *member, bool elements
if (sxe->iter.type == SXE_ITER_ATTRLIST) {
attribs = 1;
elements = 0;
- node = php_sxe_get_first_node_non_destructive(sxe, node);
+ node = php_sxe_get_first_node(sxe, node);
attr = (xmlAttrPtr)node;
test = sxe->iter.name != NULL;
} else if (sxe->iter.type != SXE_ITER_CHILD) {
- node = php_sxe_get_first_node_non_destructive(sxe, node);
+ node = php_sxe_get_first_node(sxe, node);
attr = node ? node->properties : NULL;
test = 0;
}
@@ -850,7 +850,7 @@ static void sxe_prop_dim_delete(zend_object *object, zval *member, bool elements
if (elements) {
if (Z_TYPE_P(member) == IS_LONG) {
if (sxe->iter.type == SXE_ITER_CHILD) {
- node = php_sxe_get_first_node_non_destructive(sxe, node);
+ node = php_sxe_get_first_node(sxe, node);
}
node = sxe_get_element_by_offset(sxe, Z_LVAL_P(member), node, NULL);
if (node) {
@@ -983,7 +983,7 @@ static int sxe_prop_is_empty(zend_object *object) /* {{{ */
}
if (sxe->iter.type == SXE_ITER_ELEMENT) {
- node = php_sxe_get_first_node_non_destructive(sxe, node);
+ node = php_sxe_get_first_node(sxe, node);
}
if (!node || node->type != XML_ENTITY_DECL) {
attr = node ? (xmlAttrPtr)node->properties : NULL;
@@ -997,7 +997,7 @@ static int sxe_prop_is_empty(zend_object *object) /* {{{ */
}
GET_NODE(sxe, node);
- node = php_sxe_get_first_node_non_destructive(sxe, node);
+ node = php_sxe_get_first_node(sxe, node);
is_empty = 1;
ZVAL_UNDEF(&iter_data);
if (node && sxe->iter.type != SXE_ITER_ATTRLIST) {
@@ -1092,7 +1092,7 @@ static HashTable *sxe_get_prop_hash(zend_object *object, int is_debug) /* {{{ */
}
if (is_debug || sxe->iter.type != SXE_ITER_CHILD) {
if (sxe->iter.type == SXE_ITER_ELEMENT) {
- node = php_sxe_get_first_node_non_destructive(sxe, node);
+ node = php_sxe_get_first_node(sxe, node);
}
if (!node || node->type != XML_ENTITY_DECL) {
attr = node ? (xmlAttrPtr)node->properties : NULL;
@@ -1114,7 +1114,7 @@ static HashTable *sxe_get_prop_hash(zend_object *object, int is_debug) /* {{{ */
}
GET_NODE(sxe, node);
- node = php_sxe_get_first_node_non_destructive(sxe, node);
+ node = php_sxe_get_first_node(sxe, node);
if (node && sxe->iter.type != SXE_ITER_ATTRLIST) {
if (node->type == XML_ATTRIBUTE_NODE) {
@@ -1273,7 +1273,7 @@ PHP_METHOD(SimpleXMLElement, xpath)
}
GET_NODE(sxe, nodeptr);
- nodeptr = php_sxe_get_first_node_non_destructive(sxe, nodeptr);
+ nodeptr = php_sxe_get_first_node(sxe, nodeptr);
if (!nodeptr) {
return;
}
@@ -1382,7 +1382,7 @@ PHP_METHOD(SimpleXMLElement, asXML)
sxe = Z_SXEOBJ_P(ZEND_THIS);
GET_NODE(sxe, node);
- node = php_sxe_get_first_node_non_destructive(sxe, node);
+ node = php_sxe_get_first_node(sxe, node);
if (!node) {
RETURN_FALSE;
@@ -1505,7 +1505,7 @@ PHP_METHOD(SimpleXMLElement, getNamespaces)
sxe = Z_SXEOBJ_P(ZEND_THIS);
GET_NODE(sxe, node);
- node = php_sxe_get_first_node_non_destructive(sxe, node);
+ node = php_sxe_get_first_node(sxe, node);
if (node) {
if (node->type == XML_ELEMENT_NODE) {
@@ -1590,7 +1590,7 @@ PHP_METHOD(SimpleXMLElement, children)
}
GET_NODE(sxe, node);
- node = php_sxe_get_first_node_non_destructive(sxe, node);
+ node = php_sxe_get_first_node(sxe, node);
if (!node) {
return;
}
@@ -1614,7 +1614,7 @@ PHP_METHOD(SimpleXMLElement, getName)
sxe = Z_SXEOBJ_P(ZEND_THIS);
GET_NODE(sxe, node);
- node = php_sxe_get_first_node_non_destructive(sxe, node);
+ node = php_sxe_get_first_node(sxe, node);
if (node) {
namelen = xmlStrlen(node->name);
RETURN_STRINGL((char*)node->name, namelen);
@@ -1639,7 +1639,7 @@ PHP_METHOD(SimpleXMLElement, attributes)
sxe = Z_SXEOBJ_P(ZEND_THIS);
GET_NODE(sxe, node);
- node = php_sxe_get_first_node_non_destructive(sxe, node);
+ node = php_sxe_get_first_node(sxe, node);
if (!node) {
return;
}
@@ -1682,7 +1682,7 @@ PHP_METHOD(SimpleXMLElement, addChild)
return;
}
- node = php_sxe_get_first_node_non_destructive(sxe, node);
+ node = php_sxe_get_first_node(sxe, node);
if (node == NULL) {
php_error_docref(NULL, E_WARNING, "Cannot add child. Parent is not a permanent member of the XML tree");
@@ -1742,7 +1742,7 @@ PHP_METHOD(SimpleXMLElement, addAttribute)
sxe = Z_SXEOBJ_P(ZEND_THIS);
GET_NODE(sxe, node);
- node = php_sxe_get_first_node_non_destructive(sxe, node);
+ node = php_sxe_get_first_node(sxe, node);
if (node && node->type != XML_ELEMENT_NODE) {
node = node->parent;
@@ -1835,7 +1835,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_non_destructive(sxe, NULL);
+ node = php_sxe_get_first_node(sxe, NULL);
if (node) {
ZVAL_TRUE(writeobj);
} else {
@@ -1845,7 +1845,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_non_destructive(sxe, NULL);
+ node = php_sxe_get_first_node(sxe, NULL);
if (node) {
contents = xmlNodeListGetString((xmlDocPtr) sxe->document->ptr, node->children, 1);
}
@@ -2593,7 +2593,7 @@ void *simplexml_export_node(zval *object) /* {{{ */
sxe = Z_SXEOBJ_P(object);
GET_NODE(sxe, node);
- return php_sxe_get_first_node_non_destructive(sxe, node);
+ return php_sxe_get_first_node(sxe, node);
}
/* }}} */
diff --git a/ext/simplexml/tests/bug55098.phpt b/ext/simplexml/tests/bug55098.phpt
deleted file mode 100644
index 71c8b424ecd..00000000000
--- a/ext/simplexml/tests/bug55098.phpt
+++ /dev/null
@@ -1,92 +0,0 @@
---TEST--
-Bug #55098 (SimpleXML iteration produces infinite loop)
---EXTENSIONS--
-simplexml
---FILE--
-123";
-$xml = simplexml_load_string($xmlString);
-
-$nodes = $xml->a->b;
-
-function test($nodes, $name, $callable) {
- echo "--- $name ---\n";
- foreach ($nodes as $nodeData) {
- echo "nodeData: " . $nodeData . "\n";
- $callable($nodes);
- }
-}
-
-test($nodes, "asXml", fn ($n) => $n->asXml());
-test($nodes, "attributes", fn ($n) => $n->attributes());
-test($nodes, "children", fn ($n) => $n->children());
-test($nodes, "getNamespaces", fn ($n) => $n->getNamespaces());
-test($nodes, "xpath", fn ($n) => $n->xpath("/root/a/b"));
-test($nodes, "var_dump", fn ($n) => var_dump($n));
-test($nodes, "manipulation combined with querying", function ($n) {
- $n->addAttribute("attr", "value");
- (bool) $n["attr"];
- $n->addChild("child", "value");
- $n->outer[]->inner = "foo";
- (bool) $n->outer;
- (bool) $n;
- isset($n->outer);
- isset($n["attr"]);
- unset($n->outer);
- unset($n["attr"]);
- unset($n->child);
-});
-?>
---EXPECT--
---- asXml ---
-nodeData: 1
-nodeData: 2
-nodeData: 3
---- attributes ---
-nodeData: 1
-nodeData: 2
-nodeData: 3
---- children ---
-nodeData: 1
-nodeData: 2
-nodeData: 3
---- getNamespaces ---
-nodeData: 1
-nodeData: 2
-nodeData: 3
---- xpath ---
-nodeData: 1
-nodeData: 2
-nodeData: 3
---- var_dump ---
-nodeData: 1
-object(SimpleXMLElement)#3 (3) {
- [0]=>
- string(1) "1"
- [1]=>
- string(1) "2"
- [2]=>
- string(1) "3"
-}
-nodeData: 2
-object(SimpleXMLElement)#3 (3) {
- [0]=>
- string(1) "1"
- [1]=>
- string(1) "2"
- [2]=>
- string(1) "3"
-}
-nodeData: 3
-object(SimpleXMLElement)#3 (3) {
- [0]=>
- string(1) "1"
- [1]=>
- string(1) "2"
- [2]=>
- string(1) "3"
-}
---- manipulation combined with querying ---
-nodeData: 1
-nodeData: 2
-nodeData: 3
diff --git a/ext/simplexml/tests/bug62639.phpt b/ext/simplexml/tests/bug62639.phpt
index 517162d84eb..286e6c5d8fd 100644
--- a/ext/simplexml/tests/bug62639.phpt
+++ b/ext/simplexml/tests/bug62639.phpt
@@ -41,7 +41,7 @@ foreach ($a2->b->c->children() as $key => $value) {
var_dump($value);
}?>
--EXPECT--
-object(A)#4 (2) {
+object(A)#2 (2) {
["@attributes"]=>
array(1) {
["attr"]=>
@@ -50,7 +50,7 @@ object(A)#4 (2) {
[0]=>
string(10) "Some Value"
}
-object(A)#6 (2) {
+object(A)#3 (2) {
["@attributes"]=>
array(1) {
["attr"]=>
diff --git a/ext/simplexml/tests/gh12192.phpt b/ext/simplexml/tests/gh12192.phpt
deleted file mode 100644
index 4d648495a10..00000000000
--- a/ext/simplexml/tests/gh12192.phpt
+++ /dev/null
@@ -1,37 +0,0 @@
---TEST--
-GH-12192 (SimpleXML infinite loop when getName() is called within foreach)
---EXTENSIONS--
-simplexml
---FILE--
-12";
-$xml = simplexml_load_string($xml);
-
-$a = $xml->a;
-
-foreach ($a as $test) {
- echo "Iteration\n";
- var_dump($a->key());
- var_dump($a->getName());
- var_dump((string) $test);
-}
-
-var_dump($a);
-
-?>
---EXPECT--
-Iteration
-string(1) "a"
-string(1) "a"
-string(1) "1"
-Iteration
-string(1) "a"
-string(1) "a"
-string(1) "2"
-object(SimpleXMLElement)#2 (2) {
- [0]=>
- string(1) "1"
- [1]=>
- string(1) "2"
-}
diff --git a/ext/simplexml/tests/gh12208.phpt b/ext/simplexml/tests/gh12208.phpt
deleted file mode 100644
index da3a997a504..00000000000
--- a/ext/simplexml/tests/gh12208.phpt
+++ /dev/null
@@ -1,26 +0,0 @@
---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)