mirror of
https://github.com/php/php-src.git
synced 2025-08-15 13:38:49 +02:00
Merge branch 'PHP-8.3' into PHP-8.4
* PHP-8.3: Fix GH-19300: Nested array_multisort invocation with error breaks
This commit is contained in:
commit
b82c8ba7fe
4 changed files with 90 additions and 4 deletions
2
NEWS
2
NEWS
|
@ -67,6 +67,8 @@ PHP NEWS
|
|||
. Fixed OSS Fuzz #433303828 (Leak in failed unserialize() with opcache).
|
||||
(ilutov)
|
||||
. Fix theoretical issues with hrtime() not being available. (nielsdos)
|
||||
. Fixed bug GH-19300 (Nested array_multisort invocation with error breaks).
|
||||
(nielsdos)
|
||||
|
||||
- Windows:
|
||||
. Free opened_path when opened_path_len >= MAXPATHLEN. (dixyes)
|
||||
|
|
|
@ -6038,7 +6038,7 @@ PHP_FUNCTION(array_multisort)
|
|||
for (i = 0; i < MULTISORT_LAST; i++) {
|
||||
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
|
||||
* be either an array or a sort flag which follows an array. If not
|
||||
|
@ -6054,7 +6054,7 @@ PHP_FUNCTION(array_multisort)
|
|||
/* We see the next array, so we update the sort flags of
|
||||
* the previous array and reset the sort flags. */
|
||||
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_type = PHP_SORT_REGULAR;
|
||||
}
|
||||
|
@ -6106,8 +6106,6 @@ PHP_FUNCTION(array_multisort)
|
|||
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. */
|
||||
array_size = zend_hash_num_elements(Z_ARRVAL_P(arrays[0]));
|
||||
|
@ -6125,6 +6123,11 @@ PHP_FUNCTION(array_multisort)
|
|||
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
|
||||
* 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
|
||||
|
@ -6201,6 +6204,7 @@ clean_up:
|
|||
efree(indirect);
|
||||
efree(func);
|
||||
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) {
|
||||
}
|
||||
}
|
Loading…
Add table
Add a link
Reference in a new issue