Bug #75433 [Com]: Possible array indicies regression in array_values
| From: | domen at jollydeck dot com | Date: | Tue, 05 Dec 2017 22:47:47 +0000 |
| Subject: | Bug #75433 [Com]: Possible array indicies regression in array_values | ||
| References: | 1 | Groups: | php.bugs |
| Request: | Send a blank email to php-bugs+get-212953@lists.php.net to get a copy of this message | ||
Edit report at https://bugs.php.net/bug.php?id=75433&edit=1
ID: 75433
Comment by: domen at jollydeck dot com
Reported by: bourigaultfabien at gmail dot com
Summary: Possible array indicies regression in array_values
Status: Analyzed
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:
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
Previous Comments:
------------------------------------------------------------------------
[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?)
------------------------------------------------------------------------
[2017-10-24 20:43:34] bourigaultfabien at gmail dot com
Description:
------------
It looks like there are some weird behavior with array indices. If you look at https://3v4l.org/IOvBR the output is is different for PHP 7.2+
(and also for HHVM 3.21+). After looking deeper at what may be wrong I ended to write https://3v4l.org/gG7BG which gives the same output for any PHP
version. 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+.
------------------------------------------------------------------------
--
Edit this bug report at https://bugs.php.net/bug.php?id=75433&edit=1