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).
|
. Fixed OSS Fuzz #433303828 (Leak in failed unserialize() with opcache).
|
||||||
(ilutov)
|
(ilutov)
|
||||||
. Fix theoretical issues with hrtime() not being available. (nielsdos)
|
. Fix theoretical issues with hrtime() not being available. (nielsdos)
|
||||||
|
. Fixed bug GH-19300 (Nested array_multisort invocation with error breaks).
|
||||||
|
(nielsdos)
|
||||||
|
|
||||||
- Windows:
|
- Windows:
|
||||||
. Free opened_path when opened_path_len >= MAXPATHLEN. (dixyes)
|
. Free opened_path when opened_path_len >= MAXPATHLEN. (dixyes)
|
||||||
|
|
|
@ -6038,7 +6038,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
|
||||||
|
@ -6054,7 +6054,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;
|
||||||
}
|
}
|
||||||
|
@ -6106,8 +6106,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]));
|
||||||
|
@ -6125,6 +6123,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
|
||||||
|
@ -6201,6 +6204,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) {
|
||||||
|
}
|
||||||
|
}
|
Loading…
Add table
Add a link
Reference in a new issue