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)