php.net |  support |  documentation |  report a bug |  advanced search |  search howto |  statistics |  random bug |  login
Bug #30315 big integers don't overflow
Submitted: 2004-10-03 21:35 UTC Modified: 2005-02-13 14:55 UTC
Votes:3
Avg. Score:4.7 ± 0.5
Reproduced:3 of 3 (100.0%)
Same Version:3 (100.0%)
Same OS:3 (100.0%)
From: tokul at users dot sourceforge dot net Assigned:
Status: Closed Package: Variables related
PHP Version: 5.0.2 OS: Linux
Private report: No CVE-ID: None
 [2004-10-03 21:35 UTC] tokul at users dot sourceforge dot net
Description:
------------
If big number (2500072158) is converted to integer, php 5.0.2 does not overflow and uses max integer value (2147483647).

OS details: Linux Debian Sarge

PHP compilation details (vanilla php-5.0.2.tar.bz2):
./configure --disable-debug --with-apxs=/somepath/apache/bin/apxs 
--prefix=/somepath/php 
--with-config-file-path=/somepath/ 
--with-pcre-regex --enable-mbstring --enable-session --disable-all --with-gettext=shared,/usr

php.ini details:
error_reporting=E_ALL
display_errors=on
register_globals=off
asp_tags=on
short_tags=off

Is this standard future php behaviour or just some error in my config?


Reproduce code:
---------------
echo (int)0xde120495;

Expected result:
----------------
-569244523


Actual result:
--------------
2147483647

Patches

Add a Patch

Pull Requests

Add a Pull Request

History

AllCommentsChangesGit/SVN commitsRelated reports
 [2004-10-04 08:39 UTC] derick@php.net
Sorry, but your problem does not imply a bug in PHP itself.  For a
list of more appropriate places to ask for help using PHP, please
visit http://www.php.net/support.php as this bug system is not the
appropriate forum for asking support questions. 

Thank you for your interest in PHP.

.
 [2004-10-04 08:58 UTC] tokul at users dot sourceforge dot net
Have you checked php behaviour in other php versions?

I have also tested 4.1.2, 4.3.9 and 5.0.1. This happens only on 5.0.2. I just need to know, if this is a bug or default behaviour in future php versions.
 [2004-10-04 10:03 UTC] derick@php.net
You didn't mention that before ;-) So no, then this is ofcourse a bug.
 [2004-10-05 14:43 UTC] jorton@php.net
PHP never guaranteed that integers larger than 2^31 wrap negative.  It has  never been true on a 64-bit platform, for example; there, your code will have always printed "3725722773".

I don't think this is a PHP bug.
 [2004-10-05 14:48 UTC] derick@php.net
But it's still breaking backward compatibility, and that is also important. IMO this should just work like it did before.
 [2004-10-05 15:11 UTC] jorton@php.net
I would argue that backwards compatibility is about making guarantees and not breaking them.  It's not about simply ensuring that all behaviour remains exactly the same forever, otherwise you can't change anything at all.  

But no guarantee was broken in this change.
 [2004-10-05 17:58 UTC] php at botimer dot net
According to my quick tests, there are a couple of issues at work here. They are:

1) The interpretation of hex constants
2) The conversion of numbers larger than 32-bits to 32-bit integers

I whipped together this test script to figure out exactly what's happening and ran it on PHP 4.1.2 and 5.0.2.  I haven't had a chance to run it on a 4.3.x, but I don't think it actually makes a difference unless it is yet another variant.

The first issue is that hex constants larger than 2^31 are truncated to 2^31.  I haven't thoroughly searched the documentation, but my Vim syntax highlighting suggests that 8 characters is the limit for understood hex constants.

The second issue is the actual sticky point.  PHP 4 exhibits the behavior I would expect.  When dealing with a number larger than a 32-bit integer can hold, casting to (int) returns the low byte of the value.  PHP5, however, ``makes up'' 2^31 as the value.  The last four lines of output are the most interesting.  On my 4.1.2 test, the values were 0, 2^31, 1, 2^31, while on 5.0.2, they were 2^31, 2^31, 2^31, 2^31.  Due to the behavior of the hex constant interpretation, I would expect the 2^31 in the second and fourth lines of that section, but I would not expect PHP to ``make up'' the other two.

I would classify this as a numeric bug.  If PHP5 were to truncate the values, it would return as does 4.1.2.  It is sensible that, because the quantity is positive, the ``rounding to the nearest positive 32-bit integer'' would yield 2^31, but I feel that it is likely undesired behavior.

====%<=====%<====
<?php

$big[] = 2147483647;
$big[] = 0x7FFFFFFF;

$big[] = 2147483648;
$big[] = 0x80000000;

$big[] = 4294967295;
$big[] = 0xFFFFFFFF;

$big[] = 4294967296;
$big[] = 0x100000000;

$big[] = 4294967297;
$big[] = 0x100000001;

foreach ($big as $bignum)
  var_dump($bignum);

echo "----\n";

echo (int) 4294967296  . "\n";
echo (int) 0x100000000 . "\n";

echo (int) 4294967297  . "\n";
echo (int) 0x100000001 . "\n";

?>
====%<=====%<====
PHP 4.1.2 results:
int(2147483647)
int(2147483647)
float(2147483648)
float(2147483648)
float(4294967295)
float(4294967295)
float(4294967296)
int(2147483647)
float(4294967297)
int(2147483647)
0
2147483647
1
2147483647
====%<====%<====
PHP 5.0.2 results:
int(2147483647)
int(2147483647)
float(2147483648)
float(2147483648)
float(4294967295)
float(4294967295)
float(4294967296)
int(2147483647)
float(4294967297)
int(2147483647)
----
2147483647
2147483647
2147483647
2147483647
 [2005-02-10 22:17 UTC] tony2001@php.net
Please try using this CVS snapshot:

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

Seems to be fixed, as I can't replicate it with latest snapshots (4.3/5.0/5.1).
 [2005-02-13 12:25 UTC] tokul at users dot sourceforge dot net
Unable to reproduce it in apache 1.3.33 and php 5.0.4cvs

-rw-r--r--  1 tomas tomas 5726524 Feb 11 17:40 php5-STABLE-latest.tar.gz

md5sum.
94fc7c5bbf2c41c9951c973a5debc90a  php5-STABLE-latest.tar.gz

PHP API  20031224  
PHP Extension  20041030  
Zend Extension  220040412

php configure:
./configure --prefix=/home/tomas/testbeds/test2/php \
 --with-config-file-path=/home/tomas/testbeds/config/ \
 --with-apxs=/home/tomas/testbeds/test2/apache/bin/apxs \
 --disable-all --enable-session  --with-pcre-regex \
 --enable-gettext=shared,/usr --enable-mbstring=all,shared

test script:

header('Content-Type: text/plain');
echo (int)0x950412de;
echo "\n";
echo (int)0xde120495;

code works same way in 4.3.10 (debian sarge package) and php 5.0.4cvs.

bigger than 0xffffffff hex numbers (from php at botimer dot net test script) cause php notice warnings, but they are not related to this bug report.
 [2005-02-13 14:55 UTC] tony2001@php.net
Ok, marking as closed then.
 
PHP Copyright © 2001-2024 The PHP Group
All rights reserved.
Last updated: Thu Mar 28 08:01:28 2024 UTC