Skip to content

Commit 6aa02f5

Browse files
committed
Protected hapless internal functions against extra named params
1 parent 584949d commit 6aa02f5

File tree

3 files changed

+51
-2
lines changed

3 files changed

+51
-2
lines changed

Zend/tests/named_params/internal_variadics.phpt

Lines changed: 13 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3,8 +3,19 @@ Named params on internal functions: Variadic functions
33
--FILE--
44
<?php
55

6-
array_merge([1, 2], a: [3, 4]);
6+
try {
7+
array_merge([1, 2], a: [3, 4]);
8+
} catch (ArgumentCountError $e) {
9+
echo $e->getMessage(), "\n";
10+
}
11+
12+
try {
13+
array_diff_key([1, 2], [3, 4], a: [5, 6]);
14+
} catch (ArgumentCountError $e) {
15+
echo $e->getMessage(), "\n";
16+
}
717

818
?>
919
--EXPECT--
10-
20+
array_merge() does not accept unknown named parameters
21+
array_diff_key() does not accept unknown named parameters

Zend/zend_API.c

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -263,6 +263,14 @@ ZEND_API ZEND_COLD void ZEND_FASTCALL zend_wrong_callback_error(int num, char *e
263263
}
264264
/* }}} */
265265

266+
ZEND_API ZEND_COLD void ZEND_FASTCALL zend_unexpected_extra_named_error(void)
267+
{
268+
const char *space;
269+
const char *class_name = get_active_class_name(&space);
270+
zend_argument_count_error("%s%s%s() does not accept unknown named parameters",
271+
class_name, space, get_active_function_name());
272+
}
273+
266274
static ZEND_COLD void ZEND_FASTCALL zend_argument_error_variadic(zend_class_entry *error_ce, uint32_t arg_num, const char *format, va_list va) /* {{{ */
267275
{
268276
const char *space;
@@ -907,6 +915,11 @@ static int zend_parse_va_args(uint32_t num_args, const char *type_spec, va_list
907915
}
908916
/* mark the beginning of varargs */
909917
post_varargs = max_num_args;
918+
919+
if (ZEND_CALL_INFO(EG(current_execute_data)) & ZEND_CALL_HAS_EXTRA_NAMED_PARAMS) {
920+
zend_unexpected_extra_named_error();
921+
return FAILURE;
922+
}
910923
break;
911924

912925
default:

Zend/zend_API.h

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1236,6 +1236,8 @@ ZEND_API ZEND_COLD void ZEND_FASTCALL zend_wrong_parameter_type_error(int num, z
12361236
ZEND_API ZEND_COLD void ZEND_FASTCALL zend_wrong_parameter_class_error(int num, const char *name, zval *arg);
12371237
ZEND_API ZEND_COLD void ZEND_FASTCALL zend_wrong_parameter_class_or_null_error(int num, const char *name, zval *arg);
12381238
ZEND_API ZEND_COLD void ZEND_FASTCALL zend_wrong_callback_error(int num, char *error);
1239+
ZEND_API ZEND_COLD void ZEND_FASTCALL zend_unexpected_extra_named_error(void);
1240+
12391241
ZEND_API ZEND_COLD void ZEND_FASTCALL zend_argument_error(zend_class_entry *error_ce, uint32_t arg_num, const char *format, ...);
12401242
ZEND_API ZEND_COLD void ZEND_FASTCALL zend_argument_type_error(uint32_t arg_num, const char *format, ...);
12411243
ZEND_API ZEND_COLD void ZEND_FASTCALL zend_argument_value_error(uint32_t arg_num, const char *format, ...);
@@ -1247,6 +1249,7 @@ ZEND_API ZEND_COLD void ZEND_FASTCALL zend_argument_value_error(uint32_t arg_num
12471249
#define ZPP_ERROR_WRONG_CLASS_OR_NULL 4
12481250
#define ZPP_ERROR_WRONG_ARG 5
12491251
#define ZPP_ERROR_WRONG_COUNT 6
1252+
#define ZPP_ERROR_UNEXPECTED_EXTRA_NAMED 7
12501253

12511254
#define ZEND_PARSE_PARAMETERS_START_EX(flags, min_num_args, max_num_args) do { \
12521255
const int _flags = (flags); \
@@ -1301,6 +1304,8 @@ ZEND_API ZEND_COLD void ZEND_FASTCALL zend_argument_value_error(uint32_t arg_num
13011304
zend_wrong_parameter_class_or_null_error(_i, _error, _arg); \
13021305
} else if (_error_code == ZPP_ERROR_WRONG_ARG) { \
13031306
zend_wrong_parameter_type_error(_i, _expected_type, _arg); \
1307+
} else if (_error_code == ZPP_ERROR_UNEXPECTED_EXTRA_NAMED) { \
1308+
zend_unexpected_extra_named_error(); \
13041309
} \
13051310
} \
13061311
failure; \
@@ -1663,11 +1668,31 @@ ZEND_API ZEND_COLD void ZEND_FASTCALL zend_argument_value_error(uint32_t arg_num
16631668
dest = NULL; \
16641669
dest_num = 0; \
16651670
} \
1671+
if (UNEXPECTED(ZEND_CALL_INFO(execute_data) & ZEND_CALL_HAS_EXTRA_NAMED_PARAMS)) { \
1672+
_error_code = ZPP_ERROR_UNEXPECTED_EXTRA_NAMED; \
1673+
break; \
1674+
} \
16661675
} while (0);
16671676

16681677
#define Z_PARAM_VARIADIC(spec, dest, dest_num) \
16691678
Z_PARAM_VARIADIC_EX(spec, dest, dest_num, 0)
16701679

1680+
#define Z_PARAM_VARIADIC_WITH_NAMED(spec, dest, dest_num, dest_named) do { \
1681+
int _num_varargs = _num_args - _i; \
1682+
if (EXPECTED(_num_varargs > 0)) { \
1683+
dest = _real_arg + 1; \
1684+
dest_num = _num_varargs; \
1685+
} else { \
1686+
dest = NULL; \
1687+
dest_num = 0; \
1688+
} \
1689+
if (ZEND_CALL_INFO(execute_data) & ZEND_CALL_HAS_EXTRA_NAMED_PARAMS) { \
1690+
dest_named = execute_data->extra_named_params; \
1691+
} else { \
1692+
dest_named = NULL; \
1693+
} \
1694+
} while (0);
1695+
16711696
#define Z_PARAM_STR_OR_ARRAY_HT_EX(dest_str, dest_ht, allow_null) \
16721697
Z_PARAM_PROLOGUE(0, 0); \
16731698
if (UNEXPECTED(!zend_parse_arg_str_or_array_ht(_arg, &dest_str, &dest_ht, allow_null))) { \

0 commit comments

Comments
 (0)