php.net |  support |  documentation |  report a bug |  advanced search |  search howto |  statistics |  random bug |  login
Bug #41121 range() function produces an error for values 2147483646 & 2147483647 as low &
Submitted: 2007-04-17 14:14 UTC Modified: 2007-04-19 23:24 UTC
From: mahesh dot vemula at in dot ibm dot com Assigned:
Status: Closed Package: Scripting Engine problem
PHP Version: 5CVS-2007-04-17 (snap) OS: RHEL 4
Private report: No CVE-ID: None
 [2007-04-17 14:14 UTC] mahesh dot vemula at in dot ibm dot com
Description:
------------
range() function throws a fatal error message when low = 2147483646, high = 2147483647 & step is default (i.e 1). These values gives range of 1 step and the values are valid integers. 

Environment:
Operating System: RHEL 4
Linux Kernel : Linux 2.6.9
PHP Version: PHP 5.2 (Built on Apr 17, 2007 from snaps.php.net)
PHP Configure Setup: ./configure

I will be attaching a patch for this as soon as possible.


Reproduce code:
---------------
<?php
var_dump( range(2147483646, 2147483647) );
?>


Expected result:
----------------
array(2) {
  [0]=>
  int(2147483646)
  [1]=>
  int(2147483647)
}


Actual result:
--------------
Fatal error: Allowed memory size of 134217728 bytes exhausted (tried to allocate 34 bytes) in %s on line %d

Patches

Pull Requests

History

AllCommentsChangesGit/SVN commitsRelated reports
 [2007-04-17 14:18 UTC] iliaa@php.net
Thank you for taking the time to write to us, but this is not
a bug. Please double-check the documentation available at
http://www.php.net/manual/ and the instructions on how to report
a bug at http://bugs.php.net/how-to-report.php

The 2147483647 overflows resulting in a negative value directing PHP to 
create an array of an enourmous number of elements. To achieve the 
desired result you need to pass the parameters are doubles

Ex. var_dump( range(2147483646.0, 2147483647.0) );
 [2007-04-19 11:43 UTC] wharmby@php.net
HI Ilia,
        Again as with 41118 I reviewed this one prior to Mahesh
raising the defect and having reviewed your comments above I still believe this defect reports a valid issue in the PHP code.

As the value for low and high could be variables your suggestion that 
the request should be re-coded as range(2147483646.0, 2147483647.0)  
implies all user scripts would need to include range checks on calculated high and low values in order that the correct range()
request could be issued to avoid the bad behaviour reported by this defect, i.e script loops until storage is exhausted. This seems unnecessary and unacceptable to me. 

After reading the description of range() in the php manual I would 
expect 

	range(2147483646, 2147483647)

to create an array of int's with 2 entries as follows: 

array(2) {
   [0]=>
  int(2147483646)
  [1]=>
  int(2147483647)
}

I certainly would not expect an array with 2G entries. If the users
input causes overflow then that should be detected and reported.  

However, both the low and high values specified in the range() request
above are within the range which can be expressed as a 32 bit signed 
integer;  2147483647 is the MAX_INTEGER value. 

Further if I code something like range(2147483400, 2147483600, 100) 
where both high and low are clearly within range of valid int's I get 
the same bad behaviour, i.e  the PHP code loops creating a huge 
array because the logic in array.c does not detect overflow.

Please find here:
  
       http://www.pastebin.ca/447902

a patch to array.c based on latest PHP 52 branch from CVS which fixes 
the code to produce the output I would expect as per the description
in the PHP manual. 

The following testcase runs clean with the fix; without the fix a 
number of use cases cause bad/unexpected behaviour.

<?php
// posotive steps
var_dump(range(2147483400, 2147483600, 100));
var_dump( range(2147483646, 2147483648, 1 ) ); // OK
var_dump( range(2147483646, 2147483657, 1 ) ); // Loops without fix 
var_dump( range(2147483630, 2147483646, 5 ) ); // Loops without fix 
 
// negative steps  
var_dump( range(-2147483645, -2147483648, 1 ) ); // OK 
var_dump( range(-2147483645, -2147483649, 1 ) ); // OK 
var_dump( range(-2147483630, -2147483646, 5 ) ); // Loops without fix 

// low > high
var_dump(range(2147483647, 2147483645, 1 )); // Loops without fix 
var_dump(range(2147483648, 2147483645, 1 )); //OK 
 
?>

I am therefore re-opening the defect so that my propsed fix can be considered for inclusion.

Regards,
	Andy 


Andy Wharmby
IBM United Kingdom Limited
E-mail: andy_wharmby@uk.ibm.com

 [2007-04-19 23:24 UTC] iliaa@php.net
This bug has been fixed in CVS.

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/.
 
Thank you for the report, and for helping us make PHP better.


 
PHP Copyright © 2001-2024 The PHP Group
All rights reserved.
Last updated: Thu Nov 21 11:01:29 2024 UTC