Bug #67693 [Opn->Ana]: incorrect push to the empty array
| From: | yohgaki@php.net | Date: | Mon, 28 Jul 2014 07:13:02 +0000 |
| Subject: | Bug #67693 [Opn->Ana]: incorrect push to the empty array | ||
| References: | 1 | Groups: | php.bugs |
| Request: | Send a blank email to php-bugs+get-186835@lists.php.net to get a copy of this message | ||
Edit report at https://bugs.php.net/bug.php?id=67693&edit=1
ID: 67693
Updated by: yohgaki@php.net
Reported by: dvlasov at parallels dot com
Summary: incorrect push to the empty array
-Status: Open
+Status: Analyzed
Type: Bug
-Package: Arrays related
+Package: Scripting Engine problem
Operating System: ubuntu 14.04 (32 bit)
PHP Version: 5.5.15
Block user comment: N
Private report: N
New Comment:
http://3v4l.org/MPaIr
It's the same in 64 bit architecture. Current behavior is debatable/erroneous.
I haven't read Zend hash code. It seems it's converting index to PHP_INT_MAX somewhere.
_phpi_pop() is the function.
http://lxr.php.net/xref/PHP_5_5/ext/standard/array.c#1934
ulong index; is used for numeric index and next free element is set as
Z_ARRVAL_P(stack)->nNextFreeElement = Z_ARRVAL_P(stack)->nNextFreeElement - 1;
Use of signed long for index would result in more intuitive behavior since PHP's int is always
signed. This is Zend Hash index signed/unsigned issue. For this reason, category is changed to
"Scripting Engine Problem" There might be similar issues elsewhere.
Another possible fix for this specific bug might be adding check against signed int max and set
nNextFreeElement to 0 when index is larger than signed long max. This could be in released versions.
It's ugly. Uniform use of signed/unsigned is much cleaner solution. IMO.
Previous Comments:
------------------------------------------------------------------------
[2014-07-28 05:29:03] dvlasov at parallels dot com
Description:
------------
When the initial one element array, starting with -1 index, is poped, and afterwards two values are
pushed into the obtained empty array, the second value index is becoming 2147483647, which is
obviously an error.
All other starting indexes (-2, 0, 1, 2,...) do not affect array in this way.
Also, when starting index is > 0, the index of the first element, pushed into the empty array is
kept from the previous key-value pair. Such behaviour may be also considered erroneous.
Test script:
---------------
<?php
$b=array(-1=>0);
$c=array_pop($b); assert($c == 0);
assert(array_push($b, 0), 1);
assert(array_push($b, 0), 2);
var_dump($b);
assert(array_push($b, 0), 3);
?>
Expected result:
----------------
array(2) {
[0]=>
int(0)
[1]=>
int(0)
}
Actual result:
--------------
array(2) {
[-1]=>
int(0)
[2147483647]=>
int(0)
}
PHP Warning: array_push(): Cannot add element to the array as the next element is already occupied
in /home/dmitri/workspace/cell/temp/array_push_pop_bug.php on line 8
------------------------------------------------------------------------
--
Edit this bug report at https://bugs.php.net/bug.php?id=67693&edit=1