[php-src] Issue #11154: Negative indices on empty array don't affect next chosen index

From: Date: Fri, 28 Apr 2023 10:06:54 +0000
Subject: [php-src] Issue #11154: Negative indices on empty array don't affect next chosen index
Groups: php.bugs 
Request: Send a blank email to php-bugs+get-244298@lists.php.net to get a copy of this message
Issue: https://github.com/php/php-src/issues/11154 Author: ColinHDev ### Description I was browsing through php's source code to look at how arrays work and noticed the following: This code: ```php <?php $a = array(); $a[-5] = "-5"; $a[] = "after -5"; ``` behaves differently than this code: ```php <?php $b = array( -5 => "-5" ); $b[] = "after -5"; ``` Resulted in this output: ``` array(2) { [-5]=> string(2) "-5" [0]=> string(8) "after -5" } array(2) { [-5]=> string(2) "-5" [-4]=> string(8) "after -5" } ``` But I expected this output instead: ``` array(2) { [-5]=> string(2) "-5" [-4]=> string(8) "after -5" } array(2) { [-5]=> string(2) "-5" [-4]=> string(8) "after -5" } ``` https://3v4l.org/MjbOm I am not sure, if this is a bug or intended, so I wanted to create an issue regarding that. The PR #3772 changed that appending to arrays would also work if the previous element has a negative index without defaulting to 0 in that case. It did so by setting the default value for nNextFreeElement from 0 to ZEND_LONG_MIN, while also adding the following "guard clause" to the _zend_hash_index_add_or_update_i( ) function, which makes sure that the chosen index defaults to 0 if it's still at ZEND_LONG_MIN and the element should be put at the next index. https://github.com/php/php-src/blob/master/Zend/zend_hash.c#L1027-L1029. But it did not change that for the _zend_empty_array constant: https://github.com/php/php-src/blob/master/Zend/zend_hash.c#L258. Because of that, the following if statement is always false for empty arrays since (any_negative_key >= 0) == false: https://github.com/php/php-src/blob/master/Zend/zend_hash.c#L1110-L1112. My question is, is this intended? Because it looks like a bug to me, especially since that "guard clause" would ensure that running $a[] = "" on an empty array, would still use index 0. But I am not familiar with the PHP internals, so I might have completely missed something. So if there is a reason for this behaviour or why _zend_empty_array's nNextFreeElement can't start at ZEND_LONG_MIN, I would be happy to know why! ### PHP Version PHP 8.2.3 ### Operating System _No response_

« previous php.bugs (#244298) next »