@@ -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 ;
0 commit comments