]> granicus.if.org Git - php/commitdiff
Fix ZPP of intl_cal_set()
authorMáté Kocsis <kocsismate@woohoolabs.com>
Thu, 21 Nov 2019 18:34:23 +0000 (19:34 +0100)
committerMáté Kocsis <kocsismate@woohoolabs.com>
Tue, 4 Feb 2020 13:47:11 +0000 (14:47 +0100)
ext/intl/calendar/calendar_methods.cpp
ext/intl/tests/calendar_set_error.phpt

index 55cb9536118fe76a2c73636e4882609081b87bce..57d4a825998a9f8f73d53c711fe4defc3b76baa8 100644 (file)
@@ -379,39 +379,23 @@ U_CFUNC PHP_FUNCTION(intlcal_before)
 
 U_CFUNC PHP_FUNCTION(intlcal_set)
 {
-       zend_long       arg1, arg2, arg3, arg4, arg5, arg6;
-       zval    args_a[7] = {0},
-                       *args = args_a;
-       int             i;
-       int             variant; /* number of args of the set() overload */
+       zend_long args[6];
+
        CALENDAR_METHOD_INIT_VARS;
 
        object = getThis();
 
-       /* must come before zpp because zpp would convert the args in the stack to 0 */
-       if (ZEND_NUM_ARGS() > (object ? 6 : 7) ||
-                               zend_get_parameters_array_ex(ZEND_NUM_ARGS(), args) == FAILURE) {
-               intl_error_set(NULL, U_ILLEGAL_ARGUMENT_ERROR,
-                       "intlcal_set: too many arguments", 0);
-               RETURN_FALSE;
-       }
-       if (!object) {
-               args++;
-       }
-       variant = ZEND_NUM_ARGS() - (object ? 0 : 1);
-       while (variant > 2 && Z_TYPE(args[variant - 1]) == IS_NULL) {
-               variant--;
-       }
+       int arg_num = ZEND_NUM_ARGS() - (object ? 0 : 1);
 
-       if (variant == 4 ||
-                       zend_parse_method_parameters(ZEND_NUM_ARGS(), object,
-                       "Oll|llll",     &object, Calendar_ce_ptr, &arg1, &arg2, &arg3, &arg4,
-                       &arg5, &arg6) == FAILURE) {
+       if (zend_parse_method_parameters(
+               ZEND_NUM_ARGS(), object, "Oll|llll",
+               &object, Calendar_ce_ptr, &args[0], &args[1], &args[2], &args[3], &args[4], &args[5]) == FAILURE
+       ) {
                RETURN_THROWS();
        }
 
-       for (i = 0; i < variant; i++) {
-               if (Z_LVAL(args[i]) < INT32_MIN || Z_LVAL(args[i]) > INT32_MAX) {
+       for (int i = 0; i < arg_num; i++) {
+               if (args[i] < INT32_MIN || args[i] > INT32_MAX) {
                        intl_error_set(NULL, U_ILLEGAL_ARGUMENT_ERROR,
                                "intlcal_set: at least one of the arguments has an absolute "
                                "value that is too large", 0);
@@ -419,22 +403,23 @@ U_CFUNC PHP_FUNCTION(intlcal_set)
                }
        }
 
-       if (variant == 2 && (arg1 < 0 || arg1 >= UCAL_FIELD_COUNT)) {
-               intl_error_set(NULL, U_ILLEGAL_ARGUMENT_ERROR,
-                       "intlcal_set: invalid field", 0);
-               RETURN_FALSE;
-       }
-
        CALENDAR_METHOD_FETCH_OBJECT;
 
-       if (variant == 2) {
-               co->ucal->set((UCalendarDateFields)arg1, (int32_t)arg2);
-       } else if (variant == 3) {
-               co->ucal->set((int32_t)arg1, (int32_t)arg2, (int32_t)arg3);
-       } else if (variant == 5) {
-               co->ucal->set((int32_t)arg1, (int32_t)arg2, (int32_t)arg3, (int32_t)arg4, (int32_t)arg5);
-       } else if (variant == 6) {
-               co->ucal->set((int32_t)arg1, (int32_t)arg2, (int32_t)arg3, (int32_t)arg4, (int32_t)arg5, (int32_t)arg6);
+       if (arg_num == 2) {
+               if (args[0] < 0 || args[0] >= UCAL_FIELD_COUNT) {
+                       intl_error_set(NULL, U_ILLEGAL_ARGUMENT_ERROR, "intlcal_set: invalid field", 0);
+                       RETURN_FALSE;
+               }
+               co->ucal->set((UCalendarDateFields)args[0], (int32_t)args[1]);
+       } else if (arg_num == 3) {
+               co->ucal->set((int32_t)args[0], (int32_t)args[1], (int32_t)args[2]);
+       } else if (arg_num == 4) {
+               zend_argument_count_error("No variant with 4 arguments");
+               return;
+       } else if (arg_num == 5) {
+               co->ucal->set((int32_t)args[0], (int32_t)args[1], (int32_t)args[2], (int32_t)args[3], (int32_t)args[4]);
+       } else {
+               co->ucal->set((int32_t)args[0], (int32_t)args[1], (int32_t)args[2], (int32_t)args[3], (int32_t)args[4], (int32_t)args[5]);
        }
 
        RETURN_TRUE;
index 8f48c0f975397a6beee1d7b345450f6fd970f83d..77623147f538348e40ea4dac0f972c62195af873 100644 (file)
@@ -12,14 +12,25 @@ ini_set("intl.error_level", E_WARNING);
 
 $c = new IntlGregorianCalendar(NULL, 'pt_PT');
 
-var_dump($c->set(1, 2, 3, 4, 5, 6, 7));
+try {
+    $c->set(1, 2, 3, 4, 5, 6, 7);
+} catch (ArgumentCountError $exception) {
+    echo $exception->getMessage() . "\n";
+}
+
+try {
+    $c->set(1, 2, 3, 4);
+} catch (ArgumentCountError $exception) {
+    echo $exception->getMessage() . "\n";
+}
+
 var_dump($c->set(-1, 2));
 
 var_dump(intlcal_set($c, -1, 2));
 var_dump(intlcal_set(1, 2, 3));
 --EXPECTF--
-Warning: IntlCalendar::set(): intlcal_set: too many arguments in %s on line %d
-bool(false)
+IntlCalendar::set() expects at most 6 parameters, 7 given
+No variant with 4 arguments
 
 Warning: IntlCalendar::set(): intlcal_set: invalid field in %s on line %d
 bool(false)