php.net |  support |  documentation |  report a bug |  advanced search |  search howto |  statistics |  random bug |  login
Bug #40608 break within foreach causes strange behaviour
Submitted: 2007-02-23 16:49 UTC Modified: 2007-05-20 12:12 UTC
Votes:12
Avg. Score:4.1 ± 1.3
Reproduced:8 of 10 (80.0%)
Same Version:8 (100.0%)
Same OS:0 (0.0%)
From: eric dot broersma at phil dot uu dot nl Assigned:
Status: No Feedback Package: Arrays related
PHP Version: 5.2.1 OS: Sun Solaris
Private report: No CVE-ID: None
Have you experienced this issue?
Rate the importance of this bug to you:

 [2007-02-23 16:49 UTC] eric dot broersma at phil dot uu dot nl
Description:
------------
A break within a foreach construct may cause an infinite loop when the foreach construct is nested within another foreach construct, possibly as a result of the internal array pointer of the array being foreach'ed not being reset.

This problem did not occur in PHP 5.0.5, but did occur in PHP 5.2.1.

Reproduce code:
---------------
$w = array ( 0, 1 );

echo 'a';
foreach ( $w as $x ) {		
	echo 'b' . $x;
	foreach ( $w as $z ) {
		echo 'c' . $z;
		break 1;
	}		
	echo 'e' . $x;
}	
echo 'f';

Expected result:
----------------
ab0c0e0b1c0e1f


(Behaviour in PHP 5.0.5)

Actual result:
--------------
ab0c0e0b1c0e1b2c0e2b1c0e1b2c0e2b1c0e1b2c0e2b1c0e1b2c0e2b1c0e1b2c0e2b1c0e1b2c0e2b1c0e1b2c0e2b1c0e1b2c0e2b1c0e1b2c0e2b1c0e1b2c0e2b1c0e1b2c0e2b1c0e1b2c0e2b1c0e1b2c0e2b1c0e1b2c0e2b1c0e1b2c0e2b1c0e1b2c0e2b1c0e1b2c0e2b1c0e1b2c0e2b1c0e1b2c0e2b1c0e1b2c0e2b1c0e1b2c0e2b1c0e1b2c0e2b1c0e1b2c0e2b1c0e1b2c0e2b1c0e1b2c0e2b1c0e1b2c0e2b1c0e1b2c0e2b1c0e1b2c0e2b1c0e1b2c0e2b1c0e1b2c0e2b1c0e1b2c0e2b1c0e1b2c0e2b1c0e1b2c0e2b1c0e1b2c0e2b1c0e1b2c0e2b1c0e1b2c0e2b1c0e1b2c0e2b1c0e1b2c0e2b1c0e1b2c0e2b1c0e1b2c0e2b1c0e1b2c0e2b1c0e1b2c0e2b1c0e1b2c0e2b1c0e1b2c0e2b1c0e1b2c0e2b1c0e1b2c0e2b1c0e1b2c0e2b1c0e1b2c0e2b1c0e1b2c0e2b1c0e1b2c0e2b1c0e1b2c0e2b1c0e1b2c0e2b1c0e1b2c0e2b1c0e1b2c0e2b1c0e1b2c0e2b1c0e1b2c0e2b1c0e1b2c0e2b1c0e1b2c0e2b1c0e1b2c0e2b1c0e1b2c0e2b1c0e1b2c0e2b1c0e1b2c0e2b1c0e1b2c0e2b1c0e1b2c0e2b1c0e1b2c0e2b1c0e1b2c0e2b1c0e1b2c0e2b1c0e1b2c0e2b1c0e1b2c0e2b1c0e1b2c0e2b1c0e1b2c0e2b1c0e1b2c0e2b1c0e1b2c0e2b1c0e1b2c0e2b1c0e1b2c0e2b1c0e1b2c0e2b1c0e1b2c0e2b1c0e1b2c0e2b1c0e1b2c0e2b1c0e1b2c0e2b1c0e1b2c0e2b1c0e1b2c0e2b1c0e1b2c0e2b1c0e1b2c0e2b1c0e1b2c0e2b1c0e1b2c0e2b1c0e1b2c0e2b1c0e1b2c0e2b1c0e1b2c0e2b1c0e1b2c0e2b1c0e1b2c0e2b1c0e1b2c0e2b1c0e1b2c0e2b1c0e1b2c0e2b1c0e1b2c0e2b1c0e1b2c0e2b1c0e1b2c0e2b1c0e1b2c0e2b1c0e1b2c0e2b1c0e1b2c0e2b1c0e1b2c0e2b1c0e1b2c0e2b1c0e1b2c0e2b1c0e1b2c0e2b1c0e1b2c0e2b1c0e1b2c0e2b1c0e1b2c0e2b1c0e1b2c0e2b1c0e1b2c0e2b1c0e1b2c0e2b1c0e1b2c0e2b1c0e1b2c0e2b1c0e1b2c0e2b1c0e1b2c0e2b1c0e1b2c0e2b1c0e1b2c0e2b1c0e1b2c0e2b1c0e1b2c0e2b1c0e1b2c0e2b1c0e1b2c0e2b1c0e1b2c0e2b1c0e1b2c0e2b1c0e1b2c0e2b1c0e1b2c0e2b1c0e1b2c0e2b1c0e1b2c0e2b1c0e1b2c0e2b1c0e1b2c0e2b1c0e1b2c0e2b1c0e1b2c0e2b1c0e1b2c0e2b1c0e1b2c0e2b1c0e1b2c0e2b1c0e1b2c0e2b1c0e1b... (infinite loop)

(Behaviour in PHP 5.2.1)

Patches

Add a Patch

Pull Requests

Add a Pull Request

History

AllCommentsChangesGit/SVN commitsRelated reports
 [2007-02-23 20:56 UTC] tony2001@php.net
Cannot reproduce.
Make sure you don't have any zend_extension's like ionCube, Zend Optimizer, APC, eAccelerator etc.
 [2007-03-03 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".
 [2007-03-19 18:47 UTC] ashnazg@php.net
I am experiencing this problem using PHP v5.2.1, exactly as described, whereas it works as described in v5.2.0.

I am running a vanilla compilation of PHP 5.2.0 (./configure, make, make install) with no compiler options added.  I'm running it on WinXP via Cygwin.  I first encountered the issue while running PhpDocumentor v1.3.1 on PHP v5.2.0, where PhpDocumentor's code has a function containing an inner foreach (inside an outer foreach) that is returning explicitly to the caller.  This function is being called from inside a foreach in the main code.  The array that is being iterated through in the caller's foreach is being passed to the function, and in the function that same array is being iterated through by the inner foreach.  This also results in an infinite loop.  What I see happening is that the array counter in the innermost foreach is reaching the end and then inexplicably jumping back to "3".

During discussion on the bug file against PhpDocumentor (PEAR #10289), this particular PHP code change was discovered and considered a possible culprit:  http://cvs.php.net/viewvc.cgi/ZendEngine2/zend_compile.c?annotate=1.647.2.27.2.26#l3791 

It was considered suspect due to the explicit subtraction of "3", too much of a coincidence with the behavior seen in PhpDocumentor.

Just to help rule out PhpDocumentor code itself, please realize that the same PhpDoc code runs fine on all PHP versions prior to v5.2.1 that I tested it on (5.2.0, 5.1.6, 4.4.6, 4.4.5, 4.4.4, 4.4.2).

Since this was "closed" due to no feedback, rather than being a duplicate or actually fixed, I'm reopening it so the PHP developers can revisit it based on my additional info.
 [2007-03-19 18:51 UTC] ashnazg@php.net
That was supposed to read:

"I am running a vanilla compilation of PHP 5.2.1"

"I first encountered the issue while running PhpDocumentor
v1.3.1 on PHP v5.2.1"
 [2007-03-19 19:01 UTC] tony2001@php.net
We would gladly revisit it, but your reproduce code works perfectly fine on Linux i386, Linux x86, Linux PPC, Solaris/SPARC, AIX/PPC and MacOS.
 [2007-03-19 19:20 UTC] ashnazg@php.net
Do I need to open a separate bug to have this looked at on Windows?
 [2007-03-19 19:22 UTC] tony2001@php.net
No.
 [2007-03-19 19:34 UTC] ashnazg@php.net
It's not necessary to compile 5.2.1 from source to test this on Windows.  You can use the 5.2.1 zip file available at php.net.  That's what I had installed first, encountered this problem, then compiled from source to see if the problem remained.
 [2007-03-19 19:52 UTC] tony2001@php.net
I don't have a Windows machine handy at the moment (not mentioning MSVC and other tools required to get something useful on Windows).
 [2007-03-19 19:55 UTC] ashnazg@php.net
Tested this example against the 5.2 snapshot (php5.2-win32-200703191630.zip) from php.net, and it works properly.  So, looks like it has been fixed on the 5.2 branch after 5.2.1 was released.
 [2007-03-19 20:40 UTC] ashnazg@php.net
Please try using this CVS snapshot:

  http://snaps.php.net/php5.2-latest.tar.gz
 
For Windows:
 
  http://snaps.php.net/win32/php5.2-win32-latest.zip


 [2007-03-19 20:48 UTC] tony2001@php.net
Are you asking yourself to try fresh snapshot?
Or did you click wrong link?
 [2007-03-20 16:35 UTC] ashnazg@php.net
My bad... pretending to be a dev myself there, by selecting the "Quick Fix" option to "notify" the original bug submitter (and all readers) about the snapshot option.
 [2007-03-20 16:40 UTC] ashnazg@php.net
I wasn't feeling spunky enough to mark the bug "closed", though... figured I'd better leave that to the real PHP devs...
 [2007-03-23 07:53 UTC] cweiske@php.net
I cannot reproduce this on Gentoo with 5.2.1
 [2007-03-31 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".
 [2007-04-29 22:16 UTC] chris at dented-planet dot net
I can reproduce this with PHP-CLI 5.2.1 on Mac OS X 10.4.9 Intel.
 [2007-05-20 12:12 UTC] cipri@php.net
A quick fix that somehow forces PHP to work again, is to access the key in the second(inner) loop:


echo 'a';
foreach ( $w as $x ) {
        echo 'b' . $x;
        foreach ( $w as $z ) {
                key($w);
                echo 'c' . $z;
                break 1;
        }
        echo 'e' . $x;
}
echo 'f';


Outputs: ab0c0e0b1c0e1f
 
PHP Copyright © 2001-2024 The PHP Group
All rights reserved.
Last updated: Tue Apr 23 13:01:29 2024 UTC