php.net |  support |  documentation |  report a bug |  advanced search |  search howto |  statistics |  random bug |  login
Bug #48646 SimpleXML Element write causes infinity loop in Foreach
Submitted: 2009-06-22 15:00 UTC Modified: 2009-08-06 01:00 UTC
Votes:2
Avg. Score:2.5 ± 1.5
Reproduced:2 of 2 (100.0%)
Same Version:0 (0.0%)
Same OS:0 (0.0%)
From: php at mrfoo dot de Assigned: jani (profile)
Status: No Feedback Package: SimpleXML related
PHP Version: 5.*, 6CVS (2009-06-24) OS: *
Private report: No CVE-ID: None
 [2009-06-22 15:00 UTC] php at mrfoo dot de
Description:
------------
Tested with: 5.2.6(win), 5.2.9(win) and 5.2.9-0.dotdeb.2 (lin).

Writing a value of a SimpleXML-Element in a foreach loop, causes PHP to never leave the foreach loop, if you access that element via an extra index.


Reproduce code:
---------------
error_reporting(E_ALL);
$xmlData = '<root><child><name>A child</name><info><version>1</version></info></child><child><name>B child</name><info><version>2</version></info></child><child><name>C child</name><info><version>2</version></info></child><child><name>D child</name><info><version>3</version></info></child></root>';
$xml = simplexml_load_string($xmlData);
$i = -1;
foreach ($xml as $xi => $child) {
    ++$i;
    $xml->child[$i]->info->version = rand(1,9);
    echo 'I: '.$i.' Xi: '.$xi.' Count : '.count($xml).' '.$xml->child[$i]->name.' => '.$child->name.' v:'.$child->info->version."\n";
    if($i > 10) {
        echo "Too many iterations";
        break;
    }
}
// Code below works as expected
$xml = simplexml_load_string($xmlData);
for($i = 0, $size = count($xml); $i < $size; ++$i) {
    echo 'I: '.$i.' Count : '.count($xml).' '.$xml->child[$i]->name."\n";
    $xml->child[$i]->info->version = rand(1,9);
}

Expected result:
----------------
Something like that:

I: 0 Xi: child Count : 4 A child => A child v:1
I: 1 Xi: child Count : 4 B child => B child v:3
I: 2 Xi: child Count : 4 C child => C child v:3
I: 3 Xi: child Count : 4 D child => D child v:7
I: 0 Count : 4 A child
I: 1 Count : 4 B child
I: 2 Count : 4 C child
I: 3 Count : 4 D child


Actual result:
--------------
I: 1 Xi: child Count : 4 B child => B child v:6
I: 2 Xi: child Count : 4 C child => B child v:6
I: 3 Xi: child Count : 4 D child => B child v:6
I: 4 Xi: child Count : 5  => B child v:6
I: 5 Xi: child Count : 6  => B child v:6
I: 6 Xi: child Count : 7  => B child v:6
I: 7 Xi: child Count : 8  => B child v:6
I: 8 Xi: child Count : 9  => B child v:6
I: 9 Xi: child Count : 10  => B child v:6
I: 10 Xi: child Count : 11  => B child v:6
I: 11 Xi: child Count : 12  => B child v:6
Too many iterations
I: 0 Count : 4 A child
I: 1 Count : 4 B child
I: 2 Count : 4 C child
I: 3 Count : 4 D child


Patches

Pull Requests

History

AllCommentsChangesGit/SVN commitsRelated reports
 [2009-06-22 15:13 UTC] php at mrfoo dot de
I forget to say: Tested with 5.2.10(win) too.
 [2009-06-22 22:23 UTC] phpwnd at gmail dot com
I have investigated this bug a little bit (on 5.2.9), and it seems that some pointer gets reset to the first node of the list whenever the value of any node from the list is modified, which makes the next iteration apply to the second node of the list, where it gets stuck forever. In my case, modifying a descendant of those nodes (as opposed to the nodes themselves) did NOT reset the pointer, but I assume it's the same bug.

Here's a reduced test case, which gets stuck on <c>1</c>:


$xml = simplexml_load_string('<root><c>0</c><c>1</c><c>2</c></root>');

$i = -1;
foreach ($xml as $child)
{
	if (++$i > 3)
	{
		die('Too many iterations');
	}

	echo 'Current node: ', $child->asXML(), "\n\nBefore: ", $xml->asXML(), "\n";
	$xml->c[2] = "changed: $i";
	echo 'After: ', $xml->asXML(), "\n\n";
}
 [2009-06-23 00:35 UTC] phpwnd at gmail dot com
Verified on 5.3CVS-2009-06-23 too.
 [2009-07-24 09:42 UTC] jani@php.net
I can not reproduce this with current SVN checkouts of either PHP_5_2 or 
PHP_5_3 branches. What libxml version is your PHP linked with? (check 
from phpinfo() output!)
 [2009-08-06 01:00 UTC] php-bugs at lists dot php dot net
No feedback was provided for this bug for over a week, so it is
being suspended automatically. If you are able to provide the
information that was originally requested, please do so and change
the status of the bug back to "Open".
 
PHP Copyright © 2001-2024 The PHP Group
All rights reserved.
Last updated: Sun Dec 22 06:01:30 2024 UTC