php.net |  support |  documentation |  report a bug |  advanced search |  search howto |  statistics |  random bug |  login
Bug #52899 Incorrect array key cast (string to integer) when key > PHP_INT_MAX
Submitted: 2010-09-21 11:50 UTC Modified: 2010-09-29 17:37 UTC
Votes:2
Avg. Score:3.0 ± 0.0
Reproduced:0 of 1 (0.0%)
From: thorn at slonik dot sk Assigned:
Status: Duplicate Package: Scripting Engine problem
PHP Version: 5.2.14 OS: Linux 32-bit
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 you forgot your password, you can retrieve your password here.
Password:
Status:
Package:
Bug Type:
Summary:
From: thorn at slonik dot sk
New email:
PHP Version: OS:

 

 [2010-09-21 11:50 UTC] thorn at slonik dot sk
Description:
------------
When using string as an array's key which looks like integer - the key is converted to integer. That is ok for integers not bigger than PHP_INT_MAX.

But when the key is: PHP_INT_MAX < key < 3000000000 (on 32-bit system)
the key is converted to incorrect integer (it overflows :)

The key should remain string and not be converted to incorrect int.

See test script, expected and actual results.

Doc:
http://www.php.net/manual/en/language.types.array.php
A key may be either an integer or a string. If a key is the standard representation of an integer, it will be interpreted as such (i.e. "8" will be interpreted as 8, while "08" will be interpreted as "08").

Related bugs:
#51430
#48254
#52025

Test script:
---------------
$array['2000000000'] = 1; // ok
$array['2147483647'] = 2; // ok
$array['2147483648'] = 3; // incorrect
$array['2999999999'] = 4; // incorrect
$array['3000000000'] = 5; // ok again
var_dump($array);



Expected result:
----------------
array(5) {
  [2000000000]=>
  int(1)
  [2147483647]=>
  int(2)
  ["2147483648"]=>
  int(3)
  ["2999999999"]=>
  int(4)
  ["3000000000"]=>
  int(5)
}


Actual result:
--------------
array(5) {
  [2000000000]=>
  int(1)
  [2147483647]=>
  int(2)
  [-2147483648]=> // int key overflow
  int(3)
  [-1294967297]=> // int key overflow
  int(4)
  ["3000000000"]=>
  int(5)
}


Patches

Pull Requests

History

AllCommentsChangesGit/SVN commitsRelated reports
 [2010-09-21 13:54 UTC] cataphract@php.net
Can you give more details about your system? Are you using distro binaries?

I can't reproduce this:

root@router:~# php
<?php
$array['2147483648'] = 3;
var_dump($array);
var_dump(PHP_INT_MAX);
array(1) {
  ["2147483648"]=>
  int(3)
}
int(2147483647)
root@router:~# php -v
PHP 5.2.14 (cli) (built: Aug 18 2010 17:16:15)
Copyright (c) 1997-2010 The PHP Group
Zend Engine v2.2.0, Copyright (c) 1998-2010 Zend Technologies
root@router:~# uname -a
Linux router 2.4.36 #340 Sun Jul 27 20:07:55 CEST 2008 mips unknown
 [2010-09-21 15:54 UTC] thorn at slonik dot sk
I'm using gentoo linux (no distro binaries)
$ php -v
PHP 5.2.14-pl0-gentoo (cli) (built: Sep 17 2010 12:47:23) 
Copyright (c) 1997-2010 The PHP Group
Zend Engine v2.2.0, Copyright (c) 1998-2010 Zend Technologies
$ uname -a
Linux gloriosa 2.6.35-tuxonice-r1 #1 SMP Wed Sep 1 08:59:13 CEST 2010 i686 Intel(R) Pentium(R) 4 CPU 2.80GHz GenuineIntel GNU/Linux
 [2010-09-21 17:41 UTC] cataphract@php.net
-Status: Open +Status: Feedback
 [2010-09-21 17:41 UTC] cataphract@php.net
Can you try with a vanilla version of PHP 5.2.14?

By inspection, I don't see how this can happen. Most likely it's due to a Gentoo patch.
 [2010-09-22 09:08 UTC] thorn at slonik dot sk
-Status: Feedback +Status: Open
 [2010-09-22 09:08 UTC] thorn at slonik dot sk
I opened a gentoo bug:
http://bugs.gentoo.org/show_bug.cgi?id=338280

I tried my test script on same machine with windows and it works correctly.

I'm compiling 5.3.3 now to see if it's any different.
Will post results later.
 [2010-09-22 13:28 UTC] thorn at slonik dot sk
I tried 5.3.3 but the results are same as with 5.2.14.
 [2010-09-24 09:09 UTC] thorn at slonik dot sk
-Status: Open +Status: Closed
 [2010-09-24 09:09 UTC] thorn at slonik dot sk
Since you cannot reproduce it and I don't have access to other 32-bit machine with linux & php I close this bug.

I'd conclude with: It seems to be gentoo specific bug.
Even though they could not help as of yet. :(
 [2010-09-29 17:37 UTC] cataphract@php.net
-Status: Closed +Status: Duplicate
 [2010-09-29 17:37 UTC] cataphract@php.net
The relevant code is here:

http://lxr.php.net/xref/PHP_TRUNK/Zend/zend_hash.h#ZEND_HANDLE_NUMERIC_EX

It's not the most beautiful thing and it actually relies on undefined behavior, namely that an integer overflow will result in a wrap-around (signed integer overflow has undefined behavior as per the C standard). It relies on getting a negative number to detect the overflow.

However, it explicitly tests for the sign of the result, so it would appear it could never allow a negative number without the string starting with "-". But apparently, that check is optimized away, depending on compiler flags.

Duplicate of bug #51008.

The Debian patch is probably the way to go.
 
PHP Copyright © 2001-2025 The PHP Group
All rights reserved.
Last updated: Tue Mar 11 19:01:31 2025 UTC