Skip to content

Commit 2236638

Browse files
committed
Fix ZPP of intl_cal_set()
1 parent daee985 commit 2236638

File tree

2 files changed

+38
-42
lines changed

2 files changed

+38
-42
lines changed

ext/intl/calendar/calendar_methods.cpp

Lines changed: 24 additions & 39 deletions
Original file line numberDiff line numberDiff line change
@@ -379,62 +379,47 @@ U_CFUNC PHP_FUNCTION(intlcal_before)
379379

380380
U_CFUNC PHP_FUNCTION(intlcal_set)
381381
{
382-
zend_long arg1, arg2, arg3, arg4, arg5, arg6;
383-
zval args_a[7] = {0},
384-
*args = args_a;
385-
int i;
386-
int variant; /* number of args of the set() overload */
382+
zend_long args[6];
383+
387384
CALENDAR_METHOD_INIT_VARS;
388385

389386
object = getThis();
390387

391-
/* must come before zpp because zpp would convert the args in the stack to 0 */
392-
if (ZEND_NUM_ARGS() > (object ? 6 : 7) ||
393-
zend_get_parameters_array_ex(ZEND_NUM_ARGS(), args) == FAILURE) {
394-
intl_error_set(NULL, U_ILLEGAL_ARGUMENT_ERROR,
395-
"intlcal_set: too many arguments", 0);
396-
RETURN_FALSE;
397-
}
398-
if (!object) {
399-
args++;
400-
}
401-
variant = ZEND_NUM_ARGS() - (object ? 0 : 1);
402-
while (variant > 2 && Z_TYPE(args[variant - 1]) == IS_NULL) {
403-
variant--;
404-
}
388+
int arg_num = ZEND_NUM_ARGS() - (object ? 0 : 1);
405389

406-
if (variant == 4 ||
407-
zend_parse_method_parameters(ZEND_NUM_ARGS(), object,
408-
"Oll|llll", &object, Calendar_ce_ptr, &arg1, &arg2, &arg3, &arg4,
409-
&arg5, &arg6) == FAILURE) {
390+
if (zend_parse_method_parameters(
391+
ZEND_NUM_ARGS(), object, "Oll|llll",
392+
&object, Calendar_ce_ptr, &args[0], &args[1], &args[2], &args[3], &args[4], &args[5]) == FAILURE
393+
) {
410394
RETURN_THROWS();
411395
}
412396

413-
for (i = 0; i < variant; i++) {
414-
if (Z_LVAL(args[i]) < INT32_MIN || Z_LVAL(args[i]) > INT32_MAX) {
397+
for (int i = 0; i < arg_num; i++) {
398+
if (args[i] < INT32_MIN || args[i] > INT32_MAX) {
415399
intl_error_set(NULL, U_ILLEGAL_ARGUMENT_ERROR,
416400
"intlcal_set: at least one of the arguments has an absolute "
417401
"value that is too large", 0);
418402
RETURN_FALSE;
419403
}
420404
}
421405

422-
if (variant == 2 && (arg1 < 0 || arg1 >= UCAL_FIELD_COUNT)) {
423-
intl_error_set(NULL, U_ILLEGAL_ARGUMENT_ERROR,
424-
"intlcal_set: invalid field", 0);
425-
RETURN_FALSE;
426-
}
427-
428406
CALENDAR_METHOD_FETCH_OBJECT;
429407

430-
if (variant == 2) {
431-
co->ucal->set((UCalendarDateFields)arg1, (int32_t)arg2);
432-
} else if (variant == 3) {
433-
co->ucal->set((int32_t)arg1, (int32_t)arg2, (int32_t)arg3);
434-
} else if (variant == 5) {
435-
co->ucal->set((int32_t)arg1, (int32_t)arg2, (int32_t)arg3, (int32_t)arg4, (int32_t)arg5);
436-
} else if (variant == 6) {
437-
co->ucal->set((int32_t)arg1, (int32_t)arg2, (int32_t)arg3, (int32_t)arg4, (int32_t)arg5, (int32_t)arg6);
408+
if (arg_num == 2) {
409+
if (args[0] < 0 || args[0] >= UCAL_FIELD_COUNT) {
410+
intl_error_set(NULL, U_ILLEGAL_ARGUMENT_ERROR, "intlcal_set: invalid field", 0);
411+
RETURN_FALSE;
412+
}
413+
co->ucal->set((UCalendarDateFields)args[0], (int32_t)args[1]);
414+
} else if (arg_num == 3) {
415+
co->ucal->set((int32_t)args[0], (int32_t)args[1], (int32_t)args[2]);
416+
} else if (arg_num == 4) {
417+
zend_argument_count_error("No variant with 4 arguments");
418+
return;
419+
} else if (arg_num == 5) {
420+
co->ucal->set((int32_t)args[0], (int32_t)args[1], (int32_t)args[2], (int32_t)args[3], (int32_t)args[4]);
421+
} else {
422+
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]);
438423
}
439424

440425
RETURN_TRUE;

ext/intl/tests/calendar_set_error.phpt

Lines changed: 14 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -12,14 +12,25 @@ ini_set("intl.error_level", E_WARNING);
1212

1313
$c = new IntlGregorianCalendar(NULL, 'pt_PT');
1414

15-
var_dump($c->set(1, 2, 3, 4, 5, 6, 7));
15+
try {
16+
$c->set(1, 2, 3, 4, 5, 6, 7);
17+
} catch (ArgumentCountError $exception) {
18+
echo $exception->getMessage() . "\n";
19+
}
20+
21+
try {
22+
$c->set(1, 2, 3, 4);
23+
} catch (ArgumentCountError $exception) {
24+
echo $exception->getMessage() . "\n";
25+
}
26+
1627
var_dump($c->set(-1, 2));
1728

1829
var_dump(intlcal_set($c, -1, 2));
1930
var_dump(intlcal_set(1, 2, 3));
2031
--EXPECTF--
21-
Warning: IntlCalendar::set(): intlcal_set: too many arguments in %s on line %d
22-
bool(false)
32+
IntlCalendar::set() expects at most 6 parameters, 7 given
33+
No variant with 4 arguments
2334

2435
Warning: IntlCalendar::set(): intlcal_set: invalid field in %s on line %d
2536
bool(false)

0 commit comments

Comments
 (0)