Bug #55098 [Opn->Ver]: SimpleXML iteration produces infinite loop
| From: | cmb@php.net | Date: | Fri, 04 Sep 2015 14:46:10 +0000 |
| Subject: | Bug #55098 [Opn->Ver]: SimpleXML iteration produces infinite loop | ||
| References: | 1 | Groups: | php.bugs |
| Request: | Send a blank email to php-bugs+get-195767@lists.php.net to get a copy of this message | ||
Edit report at https://bugs.php.net/bug.php?id=55098&edit=1
ID: 55098
Updated by: cmb@php.net
Reported by: karl dot raab at elements dot at
Summary: SimpleXML iteration produces infinite loop
-Status: Open
+Status: Verified
Type: Bug
Package: SimpleXML related
Operating System: Linux
PHP Version: 5.3.6
Block user comment: N
Private report: N
New Comment:
Even simpler reproduce script:
<?php
$xml =
simplexml_load_string('<root><a>1</a><a>2</a></root>');
$as = $xml->a;
foreach ($as as $a) {
var_dump($as);
}
?>
Generally, when iterating over SimpleXMLElement, you must not
access this object inside the loop. That may may work in some
cases, but usually accessing a SimpleXMLElement calls
php_sxe_get_first_node()[1], which calls php_sxe_reset_iterator()[2],
when the element is currently iterated over. Obviously, this leads
to an infinite loop.
[1] <http://lxr.php.net/xref/PHP_5_6/ext/simplexml/simplexml.c#php_sxe_get_first_node>
[2] <http://lxr.php.net/xref/PHP_5_6/ext/simplexml/simplexml.c#php_sxe_reset_iterator>
Previous Comments:
------------------------------------------------------------------------
[2015-09-04 14:32:04] cmb@php.net
Related To: Bug #64917
------------------------------------------------------------------------
[2011-07-01 05:16:58] karl dot raab at elements dot at
already noticed an orphan comment in the test script.
just ignore the line "//iteration_breaker($nodes);"
cheers, karl
------------------------------------------------------------------------
[2011-07-01 04:23:29] karl dot raab at elements dot at
Description:
------------
see the test script.
inside the foreach-loop the call of e.g. $nodes->asXml() will reset the iteration
to the beginning and therefore the loop will forever remain on the second element.
this may be related to bug #50670 and #51846
greets, karl
Test script:
---------------
$xmlString =
"<root><a><b>1</b><b>2</b><b>3</b></a></root>";
$xml = simplexml_load_string($xmlString);
$nodes = $xml->a->b;
foreach ($nodes as $nodeData) {
echo "nodeData: " . $nodeData . "\n";
//the following code will break the iteration on the second element and resets the pointer
//happens by any of these methods
$xml = $nodes->asXml();
//$nodes->getName();
//$nodes->attributes();
//$nodes->children();
//$nodes->getNamespaces();
//iteration_breaker($nodes);
}
Expected result:
----------------
nodeData: 1
nodeData: 2
nodeData: 3
Actual result:
--------------
nodeData: 1
nodeData: 2
nodeData: 2
nodeData: 2
nodeData: 2
nodeData: 2
nodeData: 2
nodeData: 2
nodeData: 2
nodeData: 2
and so on...
------------------------------------------------------------------------
--
Edit this bug report at https://bugs.php.net/bug.php?id=55098&edit=1