Skip to content

Commit d69fa21

Browse files
committed
Refactor Zend parameter parsing API
1 parent 3b62e8b commit d69fa21

File tree

2 files changed

+27
-26
lines changed

2 files changed

+27
-26
lines changed

Zend/zend_API.c

Lines changed: 22 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -525,7 +525,7 @@ ZEND_API int ZEND_FASTCALL zend_parse_arg_str_or_long_slow(zval *arg, zend_strin
525525
}
526526
/* }}} */
527527

528-
static const char *zend_parse_arg_impl(int arg_num, zval *arg, va_list *va, const char **spec, char **error) /* {{{ */
528+
static const char *zend_parse_arg_impl(zval *arg, va_list *va, const char **spec, char **error) /* {{{ */
529529
{
530530
const char *spec_walk = *spec;
531531
char c = *spec_walk++;
@@ -794,12 +794,12 @@ static const char *zend_parse_arg_impl(int arg_num, zval *arg, va_list *va, cons
794794
}
795795
/* }}} */
796796

797-
static int zend_parse_arg(int arg_num, zval *arg, va_list *va, const char **spec, int flags) /* {{{ */
797+
static int zend_parse_arg(uint32_t arg_num, zval *arg, va_list *va, const char **spec, int flags) /* {{{ */
798798
{
799799
const char *expected_type = NULL;
800800
char *error = NULL;
801801

802-
expected_type = zend_parse_arg_impl(arg_num, arg, va, spec, &error);
802+
expected_type = zend_parse_arg_impl(arg, va, spec, &error);
803803
if (expected_type) {
804804
if (EG(exception)) {
805805
return FAILURE;
@@ -822,7 +822,7 @@ static int zend_parse_arg(int arg_num, zval *arg, va_list *va, const char **spec
822822
}
823823
/* }}} */
824824

825-
ZEND_API int zend_parse_parameter(int flags, int arg_num, zval *arg, const char *spec, ...)
825+
ZEND_API int zend_parse_parameter(int flags, uint32_t arg_num, zval *arg, const char *spec, ...)
826826
{
827827
va_list va;
828828
int ret;
@@ -843,16 +843,17 @@ static ZEND_COLD void zend_parse_parameters_debug_error(const char *msg) {
843843
ZSTR_VAL(active_function->common.function_name), msg);
844844
}
845845

846-
static int zend_parse_va_args(int num_args, const char *type_spec, va_list *va, int flags) /* {{{ */
846+
static int zend_parse_va_args(uint32_t num_args, const char *type_spec, va_list *va, int flags) /* {{{ */
847847
{
848848
const char *spec_walk;
849-
int c, i;
850-
int min_num_args = -1;
851-
int max_num_args = 0;
852-
int post_varargs = 0;
849+
char c;
850+
uint32_t i;
851+
uint32_t min_num_args = 0;
852+
uint32_t max_num_args = 0;
853+
uint32_t post_varargs = 0;
853854
zval *arg;
854-
int arg_count;
855855
zend_bool have_varargs = 0;
856+
zend_bool have_optional_args = 0;
856857
zval **varargs = NULL;
857858
int *n_varargs = NULL;
858859

@@ -874,6 +875,7 @@ static int zend_parse_va_args(int num_args, const char *type_spec, va_list *va,
874875

875876
case '|':
876877
min_num_args = max_num_args;
878+
have_optional_args = 1;
877879
break;
878880

879881
case '/':
@@ -903,35 +905,34 @@ static int zend_parse_va_args(int num_args, const char *type_spec, va_list *va,
903905
}
904906
}
905907

906-
if (min_num_args < 0) {
908+
/* with no optional arguments the minimum number of arguments must be the same as the maximum */
909+
if (!have_optional_args) {
907910
min_num_args = max_num_args;
908911
}
909912

910913
if (have_varargs) {
911914
/* calculate how many required args are at the end of the specifier list */
912915
post_varargs = max_num_args - post_varargs;
913-
max_num_args = -1;
914916
}
915917

916-
if (num_args < min_num_args || (num_args > max_num_args && max_num_args >= 0)) {
918+
if (num_args < min_num_args || (num_args > max_num_args && !have_varargs)) {
917919
if (!(flags & ZEND_PARSE_PARAMS_QUIET)) {
918920
zend_function *active_function = EG(current_execute_data)->func;
919921
const char *class_name = active_function->common.scope ? ZSTR_VAL(active_function->common.scope->name) : "";
920922
zend_argument_count_error("%s%s%s() expects %s %d parameter%s, %d given",
921923
class_name,
922924
class_name[0] ? "::" : "",
923925
ZSTR_VAL(active_function->common.function_name),
924-
min_num_args == max_num_args ? "exactly" : num_args < min_num_args ? "at least" : "at most",
926+
(min_num_args == max_num_args && !have_varargs) ? "exactly" :
927+
num_args < min_num_args ? "at least" : "at most",
925928
num_args < min_num_args ? min_num_args : max_num_args,
926929
(num_args < min_num_args ? min_num_args : max_num_args) == 1 ? "" : "s",
927930
num_args);
928931
}
929932
return FAILURE;
930933
}
931934

932-
arg_count = ZEND_CALL_NUM_ARGS(EG(current_execute_data));
933-
934-
if (num_args > arg_count) {
935+
if (num_args > ZEND_CALL_NUM_ARGS(EG(current_execute_data))) {
935936
zend_parse_parameters_debug_error("could not obtain parameters for parsing");
936937
return FAILURE;
937938
}
@@ -979,7 +980,7 @@ static int zend_parse_va_args(int num_args, const char *type_spec, va_list *va,
979980
}
980981
/* }}} */
981982

982-
ZEND_API int zend_parse_parameters_ex(int flags, int num_args, const char *type_spec, ...) /* {{{ */
983+
ZEND_API int zend_parse_parameters_ex(int flags, uint32_t num_args, const char *type_spec, ...) /* {{{ */
983984
{
984985
va_list va;
985986
int retval;
@@ -992,7 +993,7 @@ ZEND_API int zend_parse_parameters_ex(int flags, int num_args, const char *type_
992993
}
993994
/* }}} */
994995

995-
ZEND_API int zend_parse_parameters(int num_args, const char *type_spec, ...) /* {{{ */
996+
ZEND_API int zend_parse_parameters(uint32_t num_args, const char *type_spec, ...) /* {{{ */
996997
{
997998
va_list va;
998999
int retval;
@@ -1006,7 +1007,7 @@ ZEND_API int zend_parse_parameters(int num_args, const char *type_spec, ...) /*
10061007
}
10071008
/* }}} */
10081009

1009-
ZEND_API int zend_parse_method_parameters(int num_args, zval *this_ptr, const char *type_spec, ...) /* {{{ */
1010+
ZEND_API int zend_parse_method_parameters(uint32_t num_args, zval *this_ptr, const char *type_spec, ...) /* {{{ */
10101011
{
10111012
va_list va;
10121013
int retval;
@@ -1046,7 +1047,7 @@ ZEND_API int zend_parse_method_parameters(int num_args, zval *this_ptr, const ch
10461047
}
10471048
/* }}} */
10481049

1049-
ZEND_API int zend_parse_method_parameters_ex(int flags, int num_args, zval *this_ptr, const char *type_spec, ...) /* {{{ */
1050+
ZEND_API int zend_parse_method_parameters_ex(int flags, uint32_t num_args, zval *this_ptr, const char *type_spec, ...) /* {{{ */
10501051
{
10511052
va_list va;
10521053
int retval;

Zend/zend_API.h

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -295,18 +295,18 @@ ZEND_API int zend_copy_parameters_array(int param_count, zval *argument_array);
295295

296296
#define ZEND_PARSE_PARAMS_THROW 0 /* No longer used, zpp always uses exceptions */
297297
#define ZEND_PARSE_PARAMS_QUIET (1<<1)
298-
ZEND_API int zend_parse_parameters(int num_args, const char *type_spec, ...);
299-
ZEND_API int zend_parse_parameters_ex(int flags, int num_args, const char *type_spec, ...);
298+
ZEND_API int zend_parse_parameters(uint32_t num_args, const char *type_spec, ...);
299+
ZEND_API int zend_parse_parameters_ex(int flags, uint32_t num_args, const char *type_spec, ...);
300300
/* NOTE: This must have at least one value in __VA_ARGS__ for the expression to be valid */
301301
#define zend_parse_parameters_throw(num_args, ...) \
302302
zend_parse_parameters(num_args, __VA_ARGS__)
303303
ZEND_API const char *zend_zval_type_name(const zval *arg);
304304
ZEND_API zend_string *zend_zval_get_legacy_type(const zval *arg);
305305

306-
ZEND_API int zend_parse_method_parameters(int num_args, zval *this_ptr, const char *type_spec, ...);
307-
ZEND_API int zend_parse_method_parameters_ex(int flags, int num_args, zval *this_ptr, const char *type_spec, ...);
306+
ZEND_API int zend_parse_method_parameters(uint32_t num_args, zval *this_ptr, const char *type_spec, ...);
307+
ZEND_API int zend_parse_method_parameters_ex(int flags, uint32_t num_args, zval *this_ptr, const char *type_spec, ...);
308308

309-
ZEND_API int zend_parse_parameter(int flags, int arg_num, zval *arg, const char *spec, ...);
309+
ZEND_API int zend_parse_parameter(int flags, uint32_t arg_num, zval *arg, const char *spec, ...);
310310

311311
/* End of parameter parsing API -- andrei */
312312

0 commit comments

Comments
 (0)