Skip to content

Commit d65c395

Browse files
committed
Fix instable array during in-place modification in uksort
The array isn't just observable if the array has RCn, but also if it is inside a reference that is RCn. By-ref parameters are always RCn and as such always observable. Fixes GH-13279 Closes GH-13285
1 parent 1a349ab commit d65c395

File tree

3 files changed

+23
-10
lines changed

3 files changed

+23
-10
lines changed

NEWS

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,9 @@ PHP NEWS
22
|||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
33
?? ??? ????, PHP 8.3.4
44

5+
- Standard:
6+
. Fixed bug GH-13279 (Instable array during in-place modification in uksort).
7+
(ilutov)
58

69
15 Feb 2024, PHP 8.3.3
710

ext/standard/array.c

Lines changed: 2 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -901,19 +901,11 @@ static void php_usort(INTERNAL_FUNCTION_PARAMETERS, bucket_compare_func_t compar
901901
RETURN_TRUE;
902902
}
903903

904-
/* Copy array, so the in-place modifications will not be visible to the callback function.
905-
* Unless there are no other references since we know for sure it won't be visible. */
906-
bool in_place = zend_may_modify_arg_in_place(array);
907-
if (!in_place) {
908-
arr = zend_array_dup(arr);
909-
}
904+
/* Copy array, so the in-place modifications will not be visible to the callback function */
905+
arr = zend_array_dup(arr);
910906

911907
zend_hash_sort(arr, compare_func, renumber);
912908

913-
if (in_place) {
914-
GC_ADDREF(arr);
915-
}
916-
917909
zval garbage;
918910
ZVAL_COPY_VALUE(&garbage, array);
919911
ZVAL_ARR(array, arr);

ext/standard/tests/gh13279.phpt

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
--TEST--
2+
GH-13279: Instable array during in-place modification in uksort
3+
--FILE--
4+
<?php
5+
6+
// Make sure the array is not const
7+
$array = [];
8+
$array['a'] = 1;
9+
$array['b'] = 2;
10+
11+
uksort($array, function ($a, $b) use (&$array) {
12+
return $array[$a] - $array[$b];
13+
});
14+
15+
?>
16+
===DONE===
17+
--EXPECT--
18+
===DONE===

0 commit comments

Comments
 (0)