php.net |  support |  documentation |  report a bug |  advanced search |  search howto |  statistics |  random bug |  login
Bug #55098 SimpleXML iteration produces infinite loop
Submitted: 2011-07-01 04:23 UTC Modified: 2015-09-04 14:46 UTC
Votes:21
Avg. Score:4.4 ± 0.7
Reproduced:19 of 19 (100.0%)
Same Version:9 (47.4%)
Same OS:10 (52.6%)
From: karl dot raab at elements dot at Assigned:
Status: Closed Package: SimpleXML related
PHP Version: 5.3.6 OS: Linux
Private report: No CVE-ID: None
Welcome back! If you're the original bug submitter, here's where you can edit the bug or add additional notes.
If you forgot your password, you can retrieve your password here.
Password:
Status:
Package:
Bug Type:
Summary:
From: karl dot raab at elements dot at
New email:
PHP Version: OS:

 

 [2011-07-01 04:23 UTC] 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...

Patches

Pull Requests

History

AllCommentsChangesGit/SVN commitsRelated reports
 [2011-07-01 05:16 UTC] 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
 [2015-09-04 14:46 UTC] cmb@php.net
-Status: Open +Status: Verified
 [2015-09-04 14:46 UTC] cmb@php.net
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>
 [2023-09-20 19:05 UTC] git@php.net
Automatic comment on behalf of nielsdos
Revision: https://github.com/php/php-src/commit/1a4e401bf03855b7b61895baf14cc0b5389e2b1a
Log: Fix bug #55098: SimpleXML iteration produces infinite loop
 [2023-09-20 19:05 UTC] git@php.net
-Status: Verified +Status: Closed
 
PHP Copyright © 2001-2024 The PHP Group
All rights reserved.
Last updated: Thu Nov 21 11:01:29 2024 UTC