php.net |  support |  documentation |  report a bug |  advanced search |  search howto |  statistics |  random bug |  login
Bug #71073 Foreach behaviour changes allow for infinite loops
Submitted: 2015-12-09 09:42 UTC Modified: 2015-12-09 10:12 UTC
From: ljsteadman at gmail dot com Assigned:
Status: Not a bug Package: Performance problem
PHP Version: 7.0.0 OS: Any
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 this is not your bug, you can add a comment by following this link.
If this is your bug, but you forgot your password, you can retrieve your password here.
Password:
Status:
Package:
Bug Type:
Summary:
From: ljsteadman at gmail dot com
New email:
PHP Version: OS:

 

 [2015-12-09 09:42 UTC] ljsteadman at gmail dot com
Description:
------------
The latest behaviour changes to foreach means that if an element is pushed onto the array during iteration with a unique key, it will infinite loop.


Test script:
---------------
https://3v4l.org/ATFK9

Expected result:
----------------
foreach shouldn't produce a infinite loop.

Actual result:
--------------
foreach continues to iterate until it runs out of memory, thus producing an infinite loop.

Patches

Add a Patch

Pull Requests

Add a Pull Request

History

AllCommentsChangesGit/SVN commitsRelated reports
 [2015-12-09 09:48 UTC] nikic@php.net
-Status: Open +Status: Not a bug
 [2015-12-09 09:48 UTC] nikic@php.net
Foreach could always produce infinite loops. Both through iterators (InfiniteIterator), but also for arrays. The modifications you had to do were only different previously.

If you don't want an infinite loop, don't grow your array infinitely...
 [2015-12-09 09:54 UTC] ljsteadman at gmail dot com
PHP 5.3 - PHP 5.6 would use a copy of the array, thus not producing an infinite loop. The change in behaviour is the concern here.
 [2015-12-09 10:06 UTC] nikic@php.net
PHP 5 would not create a copy for by-reference iteration. That's pretty much the point of iterating by-reference, that you're working on the original array, not a copy of it. The foreach implementation in PHP 5 was simply broken and didn't handle this particular case correctly. With a slight change to your sample code you'll get an infinite loop in PHP 5 as well: https://3v4l.org/FX3Ld (Two starting elements instead of one)

The foreach changes in PHP 7 are specified here: https://wiki.php.net/rfc/php7_foreach
 [2015-12-09 10:12 UTC] ljsteadman at gmail dot com
Thanks nikic. 

I didn't suggest PHP created a copy of the array for by-reference iteration. I suggested that there's a change in behaviour because foreach in PHP 7 defaults to by-reference iteration, not creating a copy of the array and iterating over said copy.

You've already pointed out this fixes a broken implementation.
 
PHP Copyright © 2001-2024 The PHP Group
All rights reserved.
Last updated: Fri Apr 19 19:01:28 2024 UTC