Skip to content

Commit 74c42b3

Browse files
committed
Convert some internal IntlCalendar warnigns to Errors
1 parent 7e86c1d commit 74c42b3

11 files changed

+272
-289
lines changed

ext/intl/calendar/calendar_methods.cpp

Lines changed: 48 additions & 81 deletions
Original file line numberDiff line numberDiff line change
@@ -43,6 +43,27 @@ extern "C" {
4343

4444
using icu::Locale;
4545

46+
#define ZEND_VALUE_ERROR_INVALID_FIELD(argument, zpp_arg_position) \
47+
if (argument < 0 || argument >= UCAL_FIELD_COUNT) { \
48+
zend_argument_value_error(getThis() ? ((zpp_arg_position)-1) : zpp_arg_position, \
49+
"must be a valid field"); \
50+
RETURN_THROWS(); \
51+
}
52+
53+
#define ZEND_VALUE_ERROR_OUT_OF_BOUND_VALUE(argument, zpp_arg_position) \
54+
if (argument < INT32_MIN || argument > INT32_MAX) { \
55+
zend_argument_value_error(getThis() ? ((zpp_arg_position)-1) : zpp_arg_position, \
56+
"must be between %d and %d", INT32_MIN, INT32_MAX); \
57+
RETURN_THROWS(); \
58+
}
59+
60+
#define ZEND_VALUE_ERROR_INVALID_DAY_OF_WEEK(argument, zpp_arg_position) \
61+
if (argument < UCAL_SUNDAY || argument > UCAL_SATURDAY) { \
62+
zend_argument_value_error(getThis() ? ((zpp_arg_position)-1) : zpp_arg_position, \
63+
"must be a valid day of the week"); \
64+
RETURN_THROWS(); \
65+
}
66+
4667
U_CFUNC PHP_METHOD(IntlCalendar, __construct)
4768
{
4869
zend_throw_exception( NULL,
@@ -209,24 +230,17 @@ U_CFUNC PHP_FUNCTION(intlcal_get_available_locales)
209230

210231
static void _php_intlcal_field_uec_ret_in32t_method(
211232
int32_t (Calendar::*func)(UCalendarDateFields, UErrorCode&) const,
212-
const char *method_name,
213233
INTERNAL_FUNCTION_PARAMETERS)
214234
{
215235
zend_long field;
216-
char *message;
217236
CALENDAR_METHOD_INIT_VARS;
218237

219238
if (zend_parse_method_parameters(ZEND_NUM_ARGS(), getThis(),
220239
"Ol", &object, Calendar_ce_ptr, &field) == FAILURE) {
221240
RETURN_THROWS();
222241
}
223242

224-
if (field < 0 || field >= UCAL_FIELD_COUNT) {
225-
spprintf(&message, 0, "%s: invalid field", method_name);
226-
intl_error_set(NULL, U_ILLEGAL_ARGUMENT_ERROR, message, 1);
227-
efree(message);
228-
RETURN_FALSE;
229-
}
243+
ZEND_VALUE_ERROR_INVALID_FIELD(field, 2);
230244

231245
CALENDAR_METHOD_FETCH_OBJECT;
232246

@@ -240,7 +254,7 @@ static void _php_intlcal_field_uec_ret_in32t_method(
240254
U_CFUNC PHP_FUNCTION(intlcal_get)
241255
{
242256
_php_intlcal_field_uec_ret_in32t_method(&Calendar::get,
243-
"intlcal_get", INTERNAL_FUNCTION_PARAM_PASSTHRU);
257+
INTERNAL_FUNCTION_PARAM_PASSTHRU);
244258
}
245259

246260
U_CFUNC PHP_FUNCTION(intlcal_get_time)
@@ -290,16 +304,8 @@ U_CFUNC PHP_FUNCTION(intlcal_add)
290304
RETURN_THROWS();
291305
}
292306

293-
if (field < 0 || field >= UCAL_FIELD_COUNT) {
294-
intl_error_set(NULL, U_ILLEGAL_ARGUMENT_ERROR,
295-
"intlcal_add: invalid field", 0);
296-
RETURN_FALSE;
297-
}
298-
if (amount < INT32_MIN || amount > INT32_MAX) {
299-
intl_error_set(NULL, U_ILLEGAL_ARGUMENT_ERROR,
300-
"intlcal_add: amount out of bounds", 0);
301-
RETURN_FALSE;
302-
}
307+
ZEND_VALUE_ERROR_INVALID_FIELD(field, 2);
308+
ZEND_VALUE_ERROR_OUT_OF_BOUND_VALUE(amount, 3);
303309

304310
CALENDAR_METHOD_FETCH_OBJECT;
305311

@@ -355,6 +361,7 @@ static void _php_intlcal_before_after(
355361
CALENDAR_METHOD_FETCH_OBJECT;
356362

357363
when_co = Z_INTL_CALENDAR_P(when_object);
364+
/* Can this ever happen ? */
358365
if (when_co->ucal == NULL) {
359366
intl_errors_set(&co->err, U_ILLEGAL_ARGUMENT_ERROR,
360367
"intlcal_before/after: Other IntlCalendar was unconstructed", 0);
@@ -395,11 +402,7 @@ U_CFUNC PHP_FUNCTION(intlcal_set)
395402
}
396403

397404
for (int i = 0; i < arg_num; i++) {
398-
if (args[i] < INT32_MIN || args[i] > INT32_MAX) {
399-
intl_error_set(NULL, U_ILLEGAL_ARGUMENT_ERROR,
400-
"intlcal_set: at least one of the arguments has an absolute value that is too large", 0);
401-
RETURN_FALSE;
402-
}
405+
ZEND_VALUE_ERROR_OUT_OF_BOUND_VALUE(args[i], i);
403406
}
404407

405408
CALENDAR_METHOD_FETCH_OBJECT;
@@ -436,20 +439,13 @@ U_CFUNC PHP_FUNCTION(intlcal_roll)
436439

437440
CALENDAR_METHOD_FETCH_OBJECT;
438441

439-
if (field < 0 || field >= UCAL_FIELD_COUNT) {
440-
intl_error_set(NULL, U_ILLEGAL_ARGUMENT_ERROR, "intlcal_roll: invalid field", 0);
441-
RETURN_FALSE;
442-
}
442+
ZEND_VALUE_ERROR_INVALID_FIELD(field, 2);
443443

444444
if (Z_TYPE_P(zvalue) == IS_FALSE || Z_TYPE_P(zvalue) == IS_TRUE) {
445445
value = Z_TYPE_P(zvalue) == IS_TRUE ? 1 : -1;
446446
} else {
447447
value = zval_get_long(zvalue);
448-
449-
if (value < INT32_MIN || value > INT32_MAX) {
450-
intl_error_set(NULL, U_ILLEGAL_ARGUMENT_ERROR, "intlcal_roll: value out of bounds", 0);
451-
RETURN_FALSE;
452-
}
448+
ZEND_VALUE_ERROR_OUT_OF_BOUND_VALUE(value, 3);
453449
}
454450

455451
co->ucal->roll((UCalendarDateFields)field, (int32_t)value, CALENDAR_ERROR_CODE(co));
@@ -475,11 +471,7 @@ U_CFUNC PHP_FUNCTION(intlcal_clear)
475471
if (field_is_null) {
476472
co->ucal->clear();
477473
} else {
478-
if (field < 0 || field >= UCAL_FIELD_COUNT) {
479-
intl_error_set(NULL, U_ILLEGAL_ARGUMENT_ERROR,
480-
"intlcal_clear: invalid field", 0);
481-
RETURN_FALSE;
482-
}
474+
ZEND_VALUE_ERROR_INVALID_FIELD(field, 2);
483475

484476
co->ucal->clear((UCalendarDateFields)field);
485477
}
@@ -498,11 +490,7 @@ U_CFUNC PHP_FUNCTION(intlcal_field_difference)
498490
RETURN_THROWS();
499491
}
500492

501-
if (field < 0 || field >= UCAL_FIELD_COUNT) {
502-
intl_error_set(NULL, U_ILLEGAL_ARGUMENT_ERROR,
503-
"intlcal_field_difference: invalid field", 0);
504-
RETURN_FALSE;
505-
}
493+
ZEND_VALUE_ERROR_INVALID_FIELD(field, 3);
506494

507495
CALENDAR_METHOD_FETCH_OBJECT;
508496

@@ -517,13 +505,13 @@ U_CFUNC PHP_FUNCTION(intlcal_field_difference)
517505
U_CFUNC PHP_FUNCTION(intlcal_get_actual_maximum)
518506
{
519507
_php_intlcal_field_uec_ret_in32t_method(&Calendar::getActualMaximum,
520-
"intlcal_get_actual_maximum", INTERNAL_FUNCTION_PARAM_PASSTHRU);
508+
INTERNAL_FUNCTION_PARAM_PASSTHRU);
521509
}
522510

523511
U_CFUNC PHP_FUNCTION(intlcal_get_actual_minimum)
524512
{
525513
_php_intlcal_field_uec_ret_in32t_method(&Calendar::getActualMinimum,
526-
"intlcal_get_actual_minimum", INTERNAL_FUNCTION_PARAM_PASSTHRU);
514+
INTERNAL_FUNCTION_PARAM_PASSTHRU);
527515
}
528516

529517
U_CFUNC PHP_FUNCTION(intlcal_get_day_of_week_type)
@@ -536,11 +524,7 @@ U_CFUNC PHP_FUNCTION(intlcal_get_day_of_week_type)
536524
RETURN_THROWS();
537525
}
538526

539-
if (dow < UCAL_SUNDAY || dow > UCAL_SATURDAY) {
540-
intl_error_set(NULL, U_ILLEGAL_ARGUMENT_ERROR,
541-
"intlcal_get_day_of_week_type: invalid day of week", 0);
542-
RETURN_FALSE;
543-
}
527+
ZEND_VALUE_ERROR_INVALID_DAY_OF_WEEK(dow, 2);
544528

545529
CALENDAR_METHOD_FETCH_OBJECT;
546530

@@ -572,24 +556,17 @@ U_CFUNC PHP_FUNCTION(intlcal_get_first_day_of_week)
572556

573557
static void _php_intlcal_field_ret_in32t_method(
574558
int32_t (Calendar::*func)(UCalendarDateFields) const,
575-
const char *method_name,
576559
INTERNAL_FUNCTION_PARAMETERS)
577560
{
578561
zend_long field;
579-
char *message;
580562
CALENDAR_METHOD_INIT_VARS;
581563

582564
if (zend_parse_method_parameters(ZEND_NUM_ARGS(), getThis(),
583565
"Ol", &object, Calendar_ce_ptr, &field) == FAILURE) {
584566
RETURN_THROWS();
585567
}
586568

587-
if (field < 0 || field >= UCAL_FIELD_COUNT) {
588-
spprintf(&message, 0, "%s: invalid field", method_name);
589-
intl_error_set(NULL, U_ILLEGAL_ARGUMENT_ERROR, message, 1);
590-
efree(message);
591-
RETURN_FALSE;
592-
}
569+
ZEND_VALUE_ERROR_INVALID_FIELD(field, 2);
593570

594571
CALENDAR_METHOD_FETCH_OBJECT;
595572

@@ -602,13 +579,13 @@ static void _php_intlcal_field_ret_in32t_method(
602579
U_CFUNC PHP_FUNCTION(intlcal_get_greatest_minimum)
603580
{
604581
_php_intlcal_field_ret_in32t_method(&Calendar::getGreatestMinimum,
605-
"intlcal_get_greatest_minimum", INTERNAL_FUNCTION_PARAM_PASSTHRU);
582+
INTERNAL_FUNCTION_PARAM_PASSTHRU);
606583
}
607584

608585
U_CFUNC PHP_FUNCTION(intlcal_get_least_maximum)
609586
{
610587
_php_intlcal_field_ret_in32t_method(&Calendar::getLeastMaximum,
611-
"intlcal_get_least_maximum", INTERNAL_FUNCTION_PARAM_PASSTHRU);
588+
INTERNAL_FUNCTION_PARAM_PASSTHRU);
612589
}
613590

614591
U_CFUNC PHP_FUNCTION(intlcal_get_locale)
@@ -621,6 +598,7 @@ U_CFUNC PHP_FUNCTION(intlcal_get_locale)
621598
RETURN_THROWS();
622599
}
623600

601+
// Promote to ValueError?
624602
if (locale_type != ULOC_ACTUAL_LOCALE && locale_type != ULOC_VALID_LOCALE) {
625603
intl_error_set(NULL, U_ILLEGAL_ARGUMENT_ERROR,
626604
"intlcal_get_locale: invalid locale type", 0);
@@ -640,7 +618,7 @@ U_CFUNC PHP_FUNCTION(intlcal_get_locale)
640618
U_CFUNC PHP_FUNCTION(intlcal_get_maximum)
641619
{
642620
_php_intlcal_field_ret_in32t_method(&Calendar::getMaximum,
643-
"intlcal_get_maximum", INTERNAL_FUNCTION_PARAM_PASSTHRU);
621+
INTERNAL_FUNCTION_PARAM_PASSTHRU);
644622
}
645623

646624
U_CFUNC PHP_FUNCTION(intlcal_get_minimal_days_in_first_week)
@@ -664,7 +642,7 @@ U_CFUNC PHP_FUNCTION(intlcal_get_minimal_days_in_first_week)
664642
U_CFUNC PHP_FUNCTION(intlcal_get_minimum)
665643
{
666644
_php_intlcal_field_ret_in32t_method(&Calendar::getMinimum,
667-
"intlcal_get_minimum", INTERNAL_FUNCTION_PARAM_PASSTHRU);
645+
INTERNAL_FUNCTION_PARAM_PASSTHRU);
668646
}
669647

670648
U_CFUNC PHP_FUNCTION(intlcal_get_time_zone)
@@ -712,11 +690,7 @@ U_CFUNC PHP_FUNCTION(intlcal_get_weekend_transition)
712690
RETURN_THROWS();
713691
}
714692

715-
if (dow < UCAL_SUNDAY || dow > UCAL_SATURDAY) {
716-
intl_error_set(NULL, U_ILLEGAL_ARGUMENT_ERROR,
717-
"intlcal_get_weekend_transition: invalid day of week", 0);
718-
RETURN_FALSE;
719-
}
693+
ZEND_VALUE_ERROR_INVALID_DAY_OF_WEEK(dow, 2);
720694

721695
CALENDAR_METHOD_FETCH_OBJECT;
722696

@@ -759,6 +733,7 @@ U_CFUNC PHP_FUNCTION(intlcal_is_equivalent_to)
759733
}
760734

761735
other_co = Z_INTL_CALENDAR_P(other_object);
736+
// Can this happen?
762737
if (other_co->ucal == NULL) {
763738
intl_error_set(NULL, U_ILLEGAL_ARGUMENT_ERROR, "intlcal_is_equivalent_to:"
764739
" Other IntlCalendar is unconstructed", 0);
@@ -794,11 +769,7 @@ U_CFUNC PHP_FUNCTION(intlcal_is_set)
794769
RETURN_THROWS();
795770
}
796771

797-
if (field < 0 || field >= UCAL_FIELD_COUNT) {
798-
intl_error_set(NULL, U_ILLEGAL_ARGUMENT_ERROR,
799-
"intlcal_is_set: invalid field", 0);
800-
RETURN_FALSE;
801-
}
772+
ZEND_VALUE_ERROR_INVALID_FIELD(field, 2);
802773

803774
CALENDAR_METHOD_FETCH_OBJECT;
804775

@@ -839,11 +810,7 @@ U_CFUNC PHP_FUNCTION(intlcal_set_first_day_of_week)
839810
RETURN_THROWS();
840811
}
841812

842-
if (dow < UCAL_SUNDAY || dow > UCAL_SATURDAY) {
843-
intl_error_set(NULL, U_ILLEGAL_ARGUMENT_ERROR,
844-
"intlcal_set_first_day_of_week: invalid day of week", 0);
845-
RETURN_FALSE;
846-
}
813+
ZEND_VALUE_ERROR_INVALID_DAY_OF_WEEK(dow, 2);
847814

848815
CALENDAR_METHOD_FETCH_OBJECT;
849816

@@ -880,10 +847,8 @@ U_CFUNC PHP_FUNCTION(intlcal_set_minimal_days_in_first_week)
880847
}
881848

882849
if (num_days < 1 || num_days > 7) {
883-
intl_error_set(NULL, U_ILLEGAL_ARGUMENT_ERROR,
884-
"intlcal_set_minimal_days_in_first_week: invalid number of days; "
885-
"must be between 1 and 7", 0);
886-
RETURN_FALSE;
850+
zend_argument_value_error(getThis() ? 1:2, "must be between 1 and 7");
851+
RETURN_THROWS();
887852
}
888853

889854
CALENDAR_METHOD_FETCH_OBJECT;
@@ -907,6 +872,7 @@ U_CFUNC PHP_FUNCTION(intlcal_equals)
907872

908873
CALENDAR_METHOD_FETCH_OBJECT;
909874
other_co = Z_INTL_CALENDAR_P(other_object);
875+
// Can this happen?
910876
if (other_co->ucal == NULL) {
911877
intl_errors_set(&co->err, U_ILLEGAL_ARGUMENT_ERROR,
912878
"intlcal_equals: The second IntlCalendar is unconstructed", 0);
@@ -1147,6 +1113,7 @@ U_CFUNC PHP_FUNCTION(intlcal_to_date_time)
11471113
zval_ptr_dtor(&ts_zval);
11481114

11491115
/* due to bug #40743, we have to set the time zone again */
1116+
// TODO Check this still applies
11501117
zend_call_method_with_1_params(Z_OBJ_P(return_value), NULL, NULL, "settimezone",
11511118
&retval, timezone_zval);
11521119
if (Z_ISUNDEF(retval) || Z_TYPE(retval) == IS_FALSE) {

ext/intl/tests/calendar_clear_error.phpt

Lines changed: 19 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -8,23 +8,26 @@ if (!extension_loaded('intl'))
88
die('skip intl extension not enabled');
99
--FILE--
1010
<?php
11-
ini_set("intl.error_level", E_WARNING);
1211

1312
$c = new IntlGregorianCalendar(NULL, 'pt_PT');
1413

15-
var_dump($c->clear(-1));
14+
try {
15+
var_dump($c->clear(-1));
16+
} catch (\ValueError $e) {
17+
echo $e->getMessage() . \PHP_EOL;
18+
}
19+
try {
20+
var_dump(intlcal_clear($c, -1));
21+
} catch (\ValueError $e) {
22+
echo $e->getMessage() . \PHP_EOL;
23+
}
1624

17-
var_dump(intlcal_clear($c, -1));
18-
var_dump(intlcal_clear(1, 2));
19-
--EXPECTF--
20-
Warning: IntlCalendar::clear(): intlcal_clear: invalid field in %s on line %d
21-
bool(false)
22-
23-
Warning: intlcal_clear(): intlcal_clear: invalid field in %s on line %d
24-
bool(false)
25-
26-
Fatal error: Uncaught TypeError: intlcal_clear(): Argument #1 ($calendar) must be of type IntlCalendar, int given in %s:%d
27-
Stack trace:
28-
#0 %s(%d): intlcal_clear(1, 2)
29-
#1 {main}
30-
thrown in %s on line %d
25+
try {
26+
var_dump(intlcal_clear(1, 2));
27+
} catch (\TypeError $e) {
28+
echo $e->getMessage() . \PHP_EOL;
29+
}
30+
--EXPECT--
31+
IntlCalendar::clear(): Argument #1 ($field) must be a valid field
32+
intlcal_clear(): Argument #2 ($field) must be a valid field
33+
intlcal_clear(): Argument #1 ($calendar) must be of type IntlCalendar, int given

0 commit comments

Comments
 (0)