Typecasting in ArrayObject::offsetGet and ArrayObject::offsetSet

From: Date: Tue, 31 May 2011 15:59:09 +0000
Subject: Typecasting in ArrayObject::offsetGet and ArrayObject::offsetSet
Groups: php.internals 
Request: Send a blank email to internals+get-52565@lists.php.net to get a copy of this message
Hello. Typecasting on the index passed to ArrayObject::offsetGet and ArrayObject::offsetSet seems to be the reason of ArrayObject's confusing behavior on x86 systems. According to http://php.net/manual/en/language.types.integer.php#language.types.integer.overflow, > If PHP encounters a number beyond the bounds of the integer type, it will be interpreted as a > float instead. Also, an operation which results in a number beyond the bounds of the integer type > will return a float instead. So, integer is casted to float, then it's passed to ArrayObject::offsetSet and is casted back to integer, probably due to the following lines (ext/spl/spl_array.c:348): if (offset->type == IS_DOUBLE) { index = (long)Z_DVAL_P(offset); } else { index = Z_LVAL_P(offset); } As a result of calling ArrayObject::offsetSet(index, value) on x86 with a float index exceeds 'long', value appears under a non-obvious index and is replaced on every other call with greater than 'long' index. Tests are attached. test_array.phpt is passed on both x86 and x86_64, test_array_object.phpt fails to pass on x86 (but is passed on x86_64). This difference in array's and ArrayObject's behavior made me to consider this a bug. array_object_error.php on x86 just makes pretty clear the reason of fail (see notices PHP throws).

--TEST-- test 1 --FILE-- <?php //$array = new ArrayObject; $array = array(); $key1 = 1e9; $key2 = $key1 * 10; $key3 = $key2 + 1; $array[$key1] = "a"; $array[$key2] = "b"; $array[$key3] = "c"; echo $array[$key1],$array[$key2],$array[$key3]; --EXPECT-- abc --TEST-- test 1 --FILE-- <?php $array = new ArrayObject; //$array = array(); $key1 = 1e9; $key2 = $key1 * 10; $key3 = $key2 + 1; $array[$key1] = "a"; $array[$key2] = "b"; $array[$key3] = "c"; echo $array[$key1],$array[$key2],$array[$key3]; --EXPECT-- abc Attachment: [application/x-httpd-php] array_object_error.php
« previous php.internals (#52565) next »