mirror of
https://github.com/php/php-src.git
synced 2026-03-24 00:02:20 +01:00
Merge branch 'PHP-8.4'
* PHP-8.4: Fix GH-19300: Nested array_multisort invocation with error breaks
This commit is contained in:
@@ -6051,7 +6051,7 @@ PHP_FUNCTION(array_multisort)
|
|||||||
for (i = 0; i < MULTISORT_LAST; i++) {
|
for (i = 0; i < MULTISORT_LAST; i++) {
|
||||||
parse_state[i] = 0;
|
parse_state[i] = 0;
|
||||||
}
|
}
|
||||||
func = ARRAYG(multisort_func) = ecalloc(argc, sizeof(bucket_compare_func_t));
|
func = ecalloc(argc, sizeof(bucket_compare_func_t));
|
||||||
|
|
||||||
/* Here we go through the input arguments and parse them. Each one can
|
/* Here we go through the input arguments and parse them. Each one can
|
||||||
* be either an array or a sort flag which follows an array. If not
|
* be either an array or a sort flag which follows an array. If not
|
||||||
@@ -6067,7 +6067,7 @@ PHP_FUNCTION(array_multisort)
|
|||||||
/* We see the next array, so we update the sort flags of
|
/* We see the next array, so we update the sort flags of
|
||||||
* the previous array and reset the sort flags. */
|
* the previous array and reset the sort flags. */
|
||||||
if (i > 0) {
|
if (i > 0) {
|
||||||
ARRAYG(multisort_func)[num_arrays - 1] = php_get_data_compare_func_unstable(sort_type, sort_order != PHP_SORT_ASC);
|
func[num_arrays - 1] = php_get_data_compare_func_unstable(sort_type, sort_order != PHP_SORT_ASC);
|
||||||
sort_order = PHP_SORT_ASC;
|
sort_order = PHP_SORT_ASC;
|
||||||
sort_type = PHP_SORT_REGULAR;
|
sort_type = PHP_SORT_REGULAR;
|
||||||
}
|
}
|
||||||
@@ -6119,8 +6119,6 @@ PHP_FUNCTION(array_multisort)
|
|||||||
MULTISORT_ABORT;
|
MULTISORT_ABORT;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
/* Take care of the last array sort flags. */
|
|
||||||
ARRAYG(multisort_func)[num_arrays - 1] = php_get_data_compare_func_unstable(sort_type, sort_order != PHP_SORT_ASC);
|
|
||||||
|
|
||||||
/* Make sure the arrays are of the same size. */
|
/* Make sure the arrays are of the same size. */
|
||||||
array_size = zend_hash_num_elements(Z_ARRVAL_P(arrays[0]));
|
array_size = zend_hash_num_elements(Z_ARRVAL_P(arrays[0]));
|
||||||
@@ -6138,6 +6136,11 @@ PHP_FUNCTION(array_multisort)
|
|||||||
RETURN_TRUE;
|
RETURN_TRUE;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Take care of the last array sort flags. */
|
||||||
|
func[num_arrays - 1] = php_get_data_compare_func_unstable(sort_type, sort_order != PHP_SORT_ASC);
|
||||||
|
bucket_compare_func_t *old_multisort_func = ARRAYG(multisort_func);
|
||||||
|
ARRAYG(multisort_func) = func;
|
||||||
|
|
||||||
/* Create the indirection array. This array is of size MxN, where
|
/* Create the indirection array. This array is of size MxN, where
|
||||||
* M is the number of entries in each input array and N is the number
|
* M is the number of entries in each input array and N is the number
|
||||||
* of the input arrays + 1. The last column is UNDEF to indicate the end
|
* of the input arrays + 1. The last column is UNDEF to indicate the end
|
||||||
@@ -6214,6 +6217,7 @@ clean_up:
|
|||||||
efree(indirect);
|
efree(indirect);
|
||||||
efree(func);
|
efree(func);
|
||||||
efree(arrays);
|
efree(arrays);
|
||||||
|
ARRAYG(multisort_func) = old_multisort_func;
|
||||||
}
|
}
|
||||||
/* }}} */
|
/* }}} */
|
||||||
|
|
||||||
|
|||||||
40
ext/standard/tests/array/gh19300_1.phpt
Normal file
40
ext/standard/tests/array/gh19300_1.phpt
Normal file
@@ -0,0 +1,40 @@
|
|||||||
|
--TEST--
|
||||||
|
GH-19300 (Nested array_multisort invocation with error breaks) - correct invocation variation
|
||||||
|
--FILE--
|
||||||
|
<?php
|
||||||
|
class MyStringable {
|
||||||
|
public function __construct(private string $data) {}
|
||||||
|
public function __tostring() {
|
||||||
|
array_multisort([]); // Trigger update of array sort globals in happy path
|
||||||
|
return $this->data;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
$inputs = [
|
||||||
|
new MyStringable('3'),
|
||||||
|
new MyStringable('1'),
|
||||||
|
new MyStringable('2'),
|
||||||
|
];
|
||||||
|
|
||||||
|
var_dump(array_multisort($inputs, SORT_STRING));
|
||||||
|
var_dump($inputs);
|
||||||
|
?>
|
||||||
|
--EXPECT--
|
||||||
|
bool(true)
|
||||||
|
array(3) {
|
||||||
|
[0]=>
|
||||||
|
object(MyStringable)#2 (1) {
|
||||||
|
["data":"MyStringable":private]=>
|
||||||
|
string(1) "1"
|
||||||
|
}
|
||||||
|
[1]=>
|
||||||
|
object(MyStringable)#3 (1) {
|
||||||
|
["data":"MyStringable":private]=>
|
||||||
|
string(1) "2"
|
||||||
|
}
|
||||||
|
[2]=>
|
||||||
|
object(MyStringable)#1 (1) {
|
||||||
|
["data":"MyStringable":private]=>
|
||||||
|
string(1) "3"
|
||||||
|
}
|
||||||
|
}
|
||||||
40
ext/standard/tests/array/gh19300_2.phpt
Normal file
40
ext/standard/tests/array/gh19300_2.phpt
Normal file
@@ -0,0 +1,40 @@
|
|||||||
|
--TEST--
|
||||||
|
GH-19300 (Nested array_multisort invocation with error breaks) - error variation
|
||||||
|
--FILE--
|
||||||
|
<?php
|
||||||
|
|
||||||
|
function error_handle($level, $message, $file = '', $line = 0){
|
||||||
|
try {
|
||||||
|
array_multisort($a, SORT_ASC); // Trigger multisort abort
|
||||||
|
} catch (TypeError $e) {
|
||||||
|
echo $e->getMessage(), "\n";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
set_error_handler('error_handle');
|
||||||
|
|
||||||
|
$inputs = [
|
||||||
|
new stdClass,
|
||||||
|
new stdClass,
|
||||||
|
new stdClass,
|
||||||
|
];
|
||||||
|
|
||||||
|
var_dump(array_multisort($inputs, SORT_NUMERIC));
|
||||||
|
var_dump($inputs);
|
||||||
|
?>
|
||||||
|
--EXPECT--
|
||||||
|
array_multisort(): Argument #1 ($array) must be an array or a sort flag
|
||||||
|
array_multisort(): Argument #1 ($array) must be an array or a sort flag
|
||||||
|
array_multisort(): Argument #1 ($array) must be an array or a sort flag
|
||||||
|
array_multisort(): Argument #1 ($array) must be an array or a sort flag
|
||||||
|
bool(true)
|
||||||
|
array(3) {
|
||||||
|
[0]=>
|
||||||
|
object(stdClass)#1 (0) {
|
||||||
|
}
|
||||||
|
[1]=>
|
||||||
|
object(stdClass)#2 (0) {
|
||||||
|
}
|
||||||
|
[2]=>
|
||||||
|
object(stdClass)#3 (0) {
|
||||||
|
}
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user