Bug #75433 [Ana->Csd]: Possible array indicies regression in array_values
Edit report at https://bugs.php.net/bug.php?id=75433&edit=1
ID: 75433
Updated by: cmb@php.net
Reported by: bourigaultfabien at gmail dot com
Summary: Possible array indicies regression in array_values
-Status: Analyzed
+Status: Closed
Type: Bug
Package: Arrays related
Operating System: Linux
PHP Version: 7.2.0RC4
Assigned To: pollita
Block user comment: N
Private report: N
New Comment:
Issue is fixed as of PHP 7.2.2.
Previous Comments:
------------------------------------------------------------------------
[2017-12-11 10:46:02] geompse at gmail dot com
As domen at jollydeck dot com pointed out, the issue is not solved for empty arrays. My test case is
so close to his it seems copy-and-paste'd : https://3v4l.org/5rncA
------------------------------------------------------------------------
[2017-12-08 13:55:48] requinix@php.net
Related To: Bug #75653
------------------------------------------------------------------------
[2017-12-05 22:47:46] domen at jollydeck dot com
It looks like this regression still affects array_values on empty arrays (arrays which previously
had values but values are all unseted before using array_values):
https://3v4l.org/U4qRd
------------------------------------------------------------------------
[2017-10-27 17:09:39] pollita@php.net
https://github.com/php/php-src/commit/cc96166f743011c037d9915681b28c363c189e0a
should address this (thanks for the catch during pre-release!)
Going to keep this open for a bit as array_slice() is impacted by a similar root cause (in 7.3 only)
and this is as good a place to track it as any.
------------------------------------------------------------------------
[2017-10-25 02:42:02] requinix@php.net
> It looks like calling unset() on one array element and then appending an item to this array
> produce a different
> result in PHP 7.2+.
Close. PHP won't reuse the removed key in any version, even if it was at the end of the array.
The problem here is in array_values: https://3v4l.org/vlTD7
> $old = ['one', 'two', 'three', 'four'];
> unset($old[3]);
Before and after, $old is a particular form of array where it has consecutive integer keys starting
from 0 in ascending order ("packed without holes"). In other words,
array_keys($old) === range(0, count($old) - 1)
https://github.com/php/php-src/blob/php-7.2.0RC4/ext/standard/array.c#L4016
In PHP 7.2 array_values() gained an optimization: for packed no-hole arrays it returns the array
as-is because the reindexing would not have changed anything, however it would have reset the value
for the next array key by virtue of creating a new array. So it looks like there should be a check
added for that as well. (Or maybe it gets bundled into HT_IS_WITHOUT_HOLES?)
------------------------------------------------------------------------
The remainder of the comments for this report are too long. To view
the rest of the comments, please view the bug report online at
https://bugs.php.net/bug.php?id=75433
--
Edit this bug report at https://bugs.php.net/bug.php?id=75433&edit=1
Thread (6 messages)