php.net |  support |  documentation |  report a bug |  advanced search |  search howto |  statistics |  random bug |  login
Bug #62477 Problem LimitIterator , argument Offset only Integers
Submitted: 2012-07-04 04:41 UTC Modified: 2017-10-24 09:40 UTC
Votes:13
Avg. Score:5.0 ± 0.0
Reproduced:13 of 13 (100.0%)
Same Version:5 (38.5%)
Same OS:4 (30.8%)
From: tuadmin at gmail dot com Assigned: ab (profile)
Status: Closed Package: SPL related
PHP Version: 5.6.24 OS: Any x86
Private report: No CVE-ID: None
 [2012-07-04 04:41 UTC] tuadmin at gmail dot com
Description:
------------
---
From manual page: http://www.php.net/class.limititerator
---
The LimitIterator error is given by the offset argument as INTEGER and not only allows FLOATS
--spanish--
El error de limitIterator es dado por el argumento de OFFSET ya que solo permite ENTEROS y no FLOATS

Test script:
---------------
/**
 * @author  tuadmin
 * @version  1.0.0
 */
class combinator implements SeekableIterator 
{
	private $_n = 0;//float val
	public function next(){$this->_n++;}
	public function rewind(){$this->_n = 0;}
	public function current(){	return $this->_n;}
	public function key(){}
	public function valid(){return $this->_n < 10000000000000000000;}
	public function seek($pos){$this->_n = $pos;}
}
$comb = new combinator();$float = 10000000000;
echo "-------------incorrect limit Iterator float seek----------\n";
foreach(new limitIterator($comb,$float,3) as $current){	echo $current."\n";}
echo "-------------correct----------\n";
for($comb->seek($float) ; $comb->current() < $float+3 && $comb->valid();$comb->next()){	echo $comb->current()."\n";}

Expected result:
----------------
-------------incorrect limit Iterator float seek----------
10000000000
10000000001
10000000002
-------------correct----------
10000000000
10000000001
10000000002

Actual result:
--------------
-------------incorrect limit Iterator float seek----------
1410065408
1410065409
1410065410
-------------correct----------
10000000000
10000000001
10000000002

Patches

Add a Patch

Pull Requests

Add a Pull Request

History

AllCommentsChangesGit/SVN commitsRelated reports
 [2012-07-11 17:24 UTC] ab@php.net
If you look at this signature 
http://lxr.php.net/xref/PHP_5_4/ext/spl/spl_iterators.c#2433 - the pos is of 
type long. Of course passing a value from the double range here causes 
overflows. But the thing is even worse if you look here 
http://lxr.php.net/xref/PHP_5_4/ext/spl/spl_iterators.h#126 as ->current.pos 
element is of type int. So for one there is an overflow with double/int, and for 
another - an overflow long/int. I think therefore you'll be getting strange 
effects also if you push enough elements into an iterator. 

All this might need a more complex solution, for now it might be at least 
catched checking the index range and throwing an exception.
 [2012-07-11 17:25 UTC] ab@php.net
-Status: Open +Status: Analyzed
 [2012-07-11 19:05 UTC] ab@php.net
-Assigned To: +Assigned To: ab
 [2012-07-11 20:39 UTC] ab@php.net
Automatic comment on behalf of ab
Revision: http://git.php.net/?p=php-src.git;a=commit;h=b383ddf1e5175abf1d000e887961fdcebae646a0
Log: Fixed bug #62477 LimitIterator int overflow
 [2012-07-11 20:41 UTC] ab@php.net
This bug has been fixed in SVN.

Snapshots of the sources are packaged every three hours; this change
will be in the next snapshot. You can grab the snapshot at
http://snaps.php.net/.

 For Windows:

http://windows.php.net/snapshots/
 
Thank you for the report, and for helping us make PHP better.


 [2012-07-11 20:41 UTC] ab@php.net
-Status: Analyzed +Status: Closed
 [2012-07-12 10:48 UTC] ab@php.net
-Status: Closed +Status: Re-Opened
 [2012-07-12 10:48 UTC] ab@php.net
the fix was reverted
 [2012-08-17 08:09 UTC] ab@php.net
-Status: Re-Opened +Status: Wont fix
 [2014-10-07 23:23 UTC] stas@php.net
Automatic comment on behalf of ab
Revision: http://git.php.net/?p=php-src-security.git;a=commit;h=b383ddf1e5175abf1d000e887961fdcebae646a0
Log: Fixed bug #62477 LimitIterator int overflow
 [2014-10-07 23:23 UTC] stas@php.net
-Status: Wont fix +Status: Closed
 [2014-10-07 23:34 UTC] stas@php.net
Automatic comment on behalf of ab
Revision: http://git.php.net/?p=php-src-security.git;a=commit;h=b383ddf1e5175abf1d000e887961fdcebae646a0
Log: Fixed bug #62477 LimitIterator int overflow
 [2016-08-02 01:06 UTC] tuadmin at gmail dot com
-Operating System: windows XP SP3 +Operating System: windows 10 -PHP Version: 5.3.14 +PHP Version: 5.5
 [2016-08-02 01:06 UTC] tuadmin at gmail dot com
Not Fixed
 [2016-08-02 01:09 UTC] tuadmin at gmail dot com
-Status: Closed +Status: Assigned -Operating System: windows 10 +Operating System: windows 7 -PHP Version: 5.5 +PHP Version: 5.4.9
 [2016-08-02 01:09 UTC] tuadmin at gmail dot com
bug not resolved
 [2016-08-02 02:24 UTC] requinix@php.net
-Status: Assigned +Status: Re-Opened -Operating System: windows 7 +Operating System: Any x86 -PHP Version: 5.4.9 +PHP Version: 5.6.24
 [2016-08-02 02:24 UTC] requinix@php.net
32-bit PHP 5.6 on Windows has the same problem as originally reported, however I don't think that's a bug: as implied in the first comment, LimitIterator accepts "int" so the 10e9 float will overflow (twice) to 1410065408. Changing to use floats/doubles could be a request but it doesn't sound like a good one.

Testing with 3v4l did show something odd: 64-bit 5.6 has a problem applying the $count=3 condition. <https://3v4l.org/mCQBW#v560> PHP 7 has current.pos, limit.offset, and limit.count as all zend_longs but 5.6.24 still has them as int,long,long respectively. Promoting current.pos to long should fix it but that commit (b383ddf) was reverted (ad7eeba)?

https://github.com/php/php-src/commit/b383ddf1e5175abf1d000e887961fdcebae646a0
https://github.com/php/php-src/commit/ad7eeba3c1a4c77f439afc936fbf50b811a46a6b
 [2016-08-02 09:56 UTC] nikic@php.net
@requinix: I'd assume it was reverted because it's an ABI break. spl_iterators.h is an exported header. We cannot change the structure in 5.6.

As far as I understand, PHP 7 fixes both a) use of int in LimitIterator, instead using zend_long and allowing 63-bit ranges on reasonable systems and b) no longer silently accepts truncating float to integer overflows during parameter parsing.

As such, I'd consider this issue resolved, as we cannot apply these changes in 5.6.
 [2017-10-24 05:46 UTC] kalle@php.net
-Status: Re-Opened +Status: Assigned
 [2017-10-24 09:40 UTC] nikic@php.net
-Status: Assigned +Status: Closed
 [2017-10-24 09:40 UTC] nikic@php.net
Closing this per my previous comment. The issue is fixed to the degree it can be fixed in PHP 7.
 
PHP Copyright © 2001-2024 The PHP Group
All rights reserved.
Last updated: Tue Mar 19 09:01:30 2024 UTC