diff --git a/ext/date/php_date.c b/ext/date/php_date.c index d6f66b700e8..841f280323e 100644 --- a/ext/date/php_date.c +++ b/ext/date/php_date.c @@ -24,6 +24,7 @@ #include "ext/standard/php_math.h" #include "php_date.h" #include "zend_interfaces.h" +#include "zend_exceptions.h" #include "lib/timelib.h" #include "lib/timelib_private.h" #ifndef PHP_WIN32 @@ -4117,13 +4118,11 @@ PHP_METHOD(DatePeriod, __construct) timelib_time *clone; zend_error_handling error_handling; - zend_replace_error_handling(EH_THROW, NULL, &error_handling); if (zend_parse_parameters_ex(ZEND_PARSE_PARAMS_QUIET, ZEND_NUM_ARGS(), "OOl|l", &start, date_ce_interface, &interval, date_ce_interval, &recurrences, &options) == FAILURE) { if (zend_parse_parameters_ex(ZEND_PARSE_PARAMS_QUIET, ZEND_NUM_ARGS(), "OOO|l", &start, date_ce_interface, &interval, date_ce_interval, &end, date_ce_interface, &options) == FAILURE) { if (zend_parse_parameters_ex(ZEND_PARSE_PARAMS_QUIET, ZEND_NUM_ARGS(), "s|l", &isostr, &isostr_len, &options) == FAILURE) { - php_error_docref(NULL, E_WARNING, "This constructor accepts either (DateTimeInterface, DateInterval, int) OR (DateTimeInterface, DateInterval, DateTime) OR (string) as arguments."); - zend_restore_error_handling(&error_handling); - return; + zend_type_error("DatePeriod::__construct() accepts (DateTimeInterface, DateInterval, int [, int]), or (DateTimeInterface, DateInterval, DateTime [, int]), or (string [, int]) as arguments"); + RETURN_THROWS(); } } } @@ -4132,15 +4131,30 @@ PHP_METHOD(DatePeriod, __construct) dpobj->current = NULL; if (isostr) { + zend_replace_error_handling(EH_THROW, NULL, &error_handling); date_period_initialize(&(dpobj->start), &(dpobj->end), &(dpobj->interval), &recurrences, isostr, isostr_len); + zend_restore_error_handling(&error_handling); + if (EG(exception)) { + RETURN_THROWS(); + } + if (dpobj->start == NULL) { - php_error_docref(NULL, E_WARNING, "The ISO interval '%s' did not contain a start date.", isostr); + zend_string *func = get_active_function_or_method_name(); + zend_throw_error(zend_ce_exception, "%s(): ISO interval must contain a start date, \"%s\" given", ZSTR_VAL(func), isostr); + zend_string_release(func); + RETURN_THROWS(); } if (dpobj->interval == NULL) { - php_error_docref(NULL, E_WARNING, "The ISO interval '%s' did not contain an interval.", isostr); + zend_string *func = get_active_function_or_method_name(); + zend_throw_error(zend_ce_exception, "%s(): ISO interval must contain an interval, \"%s\" given", ZSTR_VAL(func), isostr); + zend_string_release(func); + RETURN_THROWS(); } if (dpobj->end == NULL && recurrences == 0) { - php_error_docref(NULL, E_WARNING, "The ISO interval '%s' did not contain an end date or a recurrence count.", isostr); + zend_string *func = get_active_function_or_method_name(); + zend_throw_error(zend_ce_exception, "%s(): ISO interval must contain an end date or a recurrence count, \"%s\" given", ZSTR_VAL(func), isostr); + zend_string_release(func); + RETURN_THROWS(); } if (dpobj->start) { @@ -4179,7 +4193,10 @@ PHP_METHOD(DatePeriod, __construct) } if (dpobj->end == NULL && recurrences < 1) { - php_error_docref(NULL, E_WARNING, "The recurrence count '%d' is invalid. Needs to be > 0", (int) recurrences); + zend_string *func = get_active_function_or_method_name(); + zend_throw_error(zend_ce_exception, "%s(): Recurrence count must be greater than 0", ZSTR_VAL(func)); + zend_string_release(func); + RETURN_THROWS(); } /* options */ @@ -4189,8 +4206,6 @@ PHP_METHOD(DatePeriod, __construct) dpobj->recurrences = recurrences + dpobj->include_start_date; dpobj->initialized = 1; - - zend_restore_error_handling(&error_handling); } /* }}} */ diff --git a/ext/date/tests/DatePeriod_wrong_constructor.phpt b/ext/date/tests/DatePeriod_wrong_constructor.phpt index 8acdc5d3860..45f99bdb727 100644 --- a/ext/date/tests/DatePeriod_wrong_constructor.phpt +++ b/ext/date/tests/DatePeriod_wrong_constructor.phpt @@ -7,11 +7,12 @@ Havard Eide date.timezone=UTC --FILE-- getMessage() . "\n"; +} ?> ---EXPECTF-- -Fatal error: Uncaught Exception: DatePeriod::__construct(): This constructor accepts either (DateTimeInterface, DateInterval, int) OR (DateTimeInterface, DateInterval, DateTime) OR (string) as arguments. in %s:%d -Stack trace: -#0 %s(%d): DatePeriod->__construct() -#1 {main} - thrown in %s on line %d +--EXPECT-- +DatePeriod::__construct() accepts (DateTimeInterface, DateInterval, int [, int]), or (DateTimeInterface, DateInterval, DateTime [, int]), or (string [, int]) as arguments diff --git a/ext/date/tests/DatePeriod_wrong_recurrence_on_constructor.phpt b/ext/date/tests/DatePeriod_wrong_recurrence_on_constructor.phpt index f96753b019a..f2e121db389 100644 --- a/ext/date/tests/DatePeriod_wrong_recurrence_on_constructor.phpt +++ b/ext/date/tests/DatePeriod_wrong_recurrence_on_constructor.phpt @@ -9,11 +9,12 @@ try { } try { - new DatePeriod(new DateTime('yesterday'), new DateInterval('P1D'),-1); + new DatePeriod(new DateTime('yesterday'), new DateInterval('P1D'), -1); } catch (Exception $exception) { echo $exception->getMessage(), "\n"; } + ?> --EXPECT-- -DatePeriod::__construct(): The recurrence count '0' is invalid. Needs to be > 0 -DatePeriod::__construct(): The recurrence count '-1' is invalid. Needs to be > 0 +DatePeriod::__construct(): Recurrence count must be greater than 0 +DatePeriod::__construct(): Recurrence count must be greater than 0 diff --git a/ext/date/tests/bug44562.phpt b/ext/date/tests/bug44562.phpt index b4b721168f3..5e2a1e55014 100644 --- a/ext/date/tests/bug44562.phpt +++ b/ext/date/tests/bug44562.phpt @@ -4,12 +4,9 @@ Bug #44562 (Creating instance of DatePeriod crashes) getMessage(), "\n"; } diff --git a/ext/date/tests/date_interval_bad_format_leak.phpt b/ext/date/tests/date_interval_bad_format_leak.phpt index da6982c9bed..55cb5b341f1 100644 --- a/ext/date/tests/date_interval_bad_format_leak.phpt +++ b/ext/date/tests/date_interval_bad_format_leak.phpt @@ -4,13 +4,13 @@ DateInterval with bad format should not leak period getMessage(), "\n"; } try { - $perid = new DatePeriod('P3"D'); + new DatePeriod('P3"D'); } catch (Exception $e) { echo $e->getMessage(), "\n"; } diff --git a/ext/date/tests/date_period_bad_iso_format.phpt b/ext/date/tests/date_period_bad_iso_format.phpt new file mode 100644 index 00000000000..fecc4fa23ce --- /dev/null +++ b/ext/date/tests/date_period_bad_iso_format.phpt @@ -0,0 +1,29 @@ +--TEST-- +Test bad ISO date formats passed to DatePeriod constructor +--FILE-- +getMessage(), "\n"; +} + +try { + new DatePeriod("R4/2012-07-01T00:00:00Z"); +} catch (Exception $e) { + echo $e->getMessage(), "\n"; +} + + +try { + new DatePeriod("2012-07-01T00:00:00Z/P7D"); +} catch (Exception $e) { + echo $e->getMessage(), "\n"; +} + +?> +--EXPECT-- +DatePeriod::__construct(): ISO interval must contain a start date, "R4" given +DatePeriod::__construct(): ISO interval must contain an interval, "R4/2012-07-01T00:00:00Z" given +DatePeriod::__construct(): ISO interval must contain an end date or a recurrence count, "2012-07-01T00:00:00Z/P7D" given