[php-src] PR #24404: ext/standard: Fix array_merge() with an empty array argument

From: Date: Sun, 18 Oct 2026 10:21:22 +0000
Subject: [php-src] PR #24404: ext/standard: Fix array_merge() with an empty array argument
Groups: php.git-pulls 
Request: Send a blank email to git-pulls+get-39545@lists.php.net to get a copy of this message
Pull Request: https://github.com/php/php-src/pull/24404 Author: GromNaN array_merge() returns the non-empty argument as is when the other argument is empty. The returned array is the argument itself, shared through copy-on-write, so it also kept two pieces of internal state that array_merge() is expected to reset: the next free index, reset because integer keys are renumbered from 0, and the internal pointer, rewound to the first element. Both were observable: ```php $a = [1, 2, 3]; unset($a[2]); $r = array_merge($a, []); $r[] = 4; // key 3 instead of 2 $c = [10, 20, 30]; next($c); next($c); current(array_merge([], $c)); // 30 instead of 10 ``` The shortcut now applies only when the argument already behaves like the result of the general path: a packed array without holes, or an array with string keys only, whose next free index is the element count (or unset) and whose internal pointer is on the first element. Everything else goes through the general path. Clean arrays are still returned as is, so the copy is still avoided. array_merge_recursive() shares the code path and gets the same fix. A regression test is added. Output before and after the change: ```diff array(3) { [0]=> int(1) [1]=> int(2) - [3]=> + [2]=> int(4) } array(2) { ["a"]=> int(1) - [1]=> + [0]=> int(3) } -int(30) +int(10) ```

« previous php.git-pulls (#39545) next »