Throw directly instead of replacing error handler in ext/date (#6954)

This commit is contained in:
George Peter Banyard 2021-05-07 11:10:39 +01:00 committed by GitHub
parent b9cfd288e5
commit 2f1d0f2bc3
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
8 changed files with 38 additions and 49 deletions

View file

@ -16,5 +16,5 @@ var_dump(error_get_last());
?> ?>
--EXPECT-- --EXPECT--
string(105) "DateTime::__construct(): Failed to parse time string (9999-11-33) at position 9 (3): Unexpected character" string(80) "Failed to parse time string (9999-11-33) at position 9 (3): Unexpected character"
NULL NULL

View file

@ -2215,10 +2215,10 @@ PHPAPI int php_date_initialize(php_date_obj *dateobj, const char *time_str, size
/* update last errors and warnings */ /* update last errors and warnings */
update_errors_warnings(err); update_errors_warnings(err);
/* If called from a constructor throw an exception */
if ((flags & PHP_DATE_INIT_CTOR) && err && err->error_count) { if ((flags & PHP_DATE_INIT_CTOR) && err && err->error_count) {
/* spit out the first library error message, at least */ /* spit out the first library error message, at least */
php_error_docref(NULL, E_WARNING, "Failed to parse time string (%s) at position %d (%c): %s", time_str, zend_throw_exception_ex(NULL, 0, "Failed to parse time string (%s) at position %d (%c): %s", time_str,
err->error_messages[0].position, err->error_messages[0].character, err->error_messages[0].message); err->error_messages[0].position, err->error_messages[0].character, err->error_messages[0].message);
} }
if (err && err->error_count) { if (err && err->error_count) {
@ -2386,7 +2386,6 @@ PHP_METHOD(DateTime, __construct)
zval *timezone_object = NULL; zval *timezone_object = NULL;
char *time_str = NULL; char *time_str = NULL;
size_t time_str_len = 0; size_t time_str_len = 0;
zend_error_handling error_handling;
ZEND_PARSE_PARAMETERS_START(0, 2) ZEND_PARSE_PARAMETERS_START(0, 2)
Z_PARAM_OPTIONAL Z_PARAM_OPTIONAL
@ -2394,9 +2393,7 @@ PHP_METHOD(DateTime, __construct)
Z_PARAM_OBJECT_OF_CLASS_OR_NULL(timezone_object, date_ce_timezone) Z_PARAM_OBJECT_OF_CLASS_OR_NULL(timezone_object, date_ce_timezone)
ZEND_PARSE_PARAMETERS_END(); ZEND_PARSE_PARAMETERS_END();
zend_replace_error_handling(EH_THROW, NULL, &error_handling);
php_date_initialize(Z_PHPDATE_P(ZEND_THIS), time_str, time_str_len, NULL, timezone_object, PHP_DATE_INIT_CTOR); php_date_initialize(Z_PHPDATE_P(ZEND_THIS), time_str, time_str_len, NULL, timezone_object, PHP_DATE_INIT_CTOR);
zend_restore_error_handling(&error_handling);
} }
/* }}} */ /* }}} */
@ -2406,7 +2403,6 @@ PHP_METHOD(DateTimeImmutable, __construct)
zval *timezone_object = NULL; zval *timezone_object = NULL;
char *time_str = NULL; char *time_str = NULL;
size_t time_str_len = 0; size_t time_str_len = 0;
zend_error_handling error_handling;
ZEND_PARSE_PARAMETERS_START(0, 2) ZEND_PARSE_PARAMETERS_START(0, 2)
Z_PARAM_OPTIONAL Z_PARAM_OPTIONAL
@ -2414,9 +2410,7 @@ PHP_METHOD(DateTimeImmutable, __construct)
Z_PARAM_OBJECT_OF_CLASS_OR_NULL(timezone_object, date_ce_timezone) Z_PARAM_OBJECT_OF_CLASS_OR_NULL(timezone_object, date_ce_timezone)
ZEND_PARSE_PARAMETERS_END(); ZEND_PARSE_PARAMETERS_END();
zend_replace_error_handling(EH_THROW, NULL, &error_handling);
php_date_initialize(Z_PHPDATE_P(ZEND_THIS), time_str, time_str_len, NULL, timezone_object, PHP_DATE_INIT_CTOR); php_date_initialize(Z_PHPDATE_P(ZEND_THIS), time_str, time_str_len, NULL, timezone_object, PHP_DATE_INIT_CTOR);
zend_restore_error_handling(&error_handling);
} }
/* }}} */ /* }}} */
@ -3686,35 +3680,35 @@ PHP_FUNCTION(timezone_location_get)
} }
/* }}} */ /* }}} */
static int date_interval_initialize(timelib_rel_time **rt, /*const*/ char *format, size_t format_length) /* {{{ */ static bool date_interval_initialize(timelib_rel_time **rt, /*const*/ char *format, size_t format_length) /* {{{ */
{ {
timelib_time *b = NULL, *e = NULL; timelib_time *b = NULL, *e = NULL;
timelib_rel_time *p = NULL; timelib_rel_time *p = NULL;
int r = 0; int r = 0;
int retval = 0; bool retval = false;
timelib_error_container *errors; timelib_error_container *errors;
timelib_strtointerval(format, format_length, &b, &e, &p, &r, &errors); timelib_strtointerval(format, format_length, &b, &e, &p, &r, &errors);
if (errors->error_count > 0) { if (errors->error_count > 0) {
php_error_docref(NULL, E_WARNING, "Unknown or bad format (%s)", format); zend_throw_exception_ex(NULL, 0, "Unknown or bad format (%s)", format);
retval = FAILURE; retval = false;
if (p) { if (p) {
timelib_rel_time_dtor(p); timelib_rel_time_dtor(p);
} }
} else { } else {
if(p) { if(p) {
*rt = p; *rt = p;
retval = SUCCESS; retval = true;
} else { } else {
if(b && e) { if(b && e) {
timelib_update_ts(b, NULL); timelib_update_ts(b, NULL);
timelib_update_ts(e, NULL); timelib_update_ts(e, NULL);
*rt = timelib_diff(b, e); *rt = timelib_diff(b, e);
retval = SUCCESS; retval = true;
} else { } else {
php_error_docref(NULL, E_WARNING, "Failed to parse interval (%s)", format); zend_throw_exception_ex(NULL, 0, "Failed to parse interval (%s)", format);
retval = FAILURE; retval = false;
} }
} }
} }
@ -3853,20 +3847,19 @@ PHP_METHOD(DateInterval, __construct)
{ {
zend_string *interval_string = NULL; zend_string *interval_string = NULL;
timelib_rel_time *reltime; timelib_rel_time *reltime;
zend_error_handling error_handling;
ZEND_PARSE_PARAMETERS_START(1, 1) ZEND_PARSE_PARAMETERS_START(1, 1)
Z_PARAM_STR(interval_string) Z_PARAM_STR(interval_string)
ZEND_PARSE_PARAMETERS_END(); ZEND_PARSE_PARAMETERS_END();
zend_replace_error_handling(EH_THROW, NULL, &error_handling); if (!date_interval_initialize(&reltime, ZSTR_VAL(interval_string), ZSTR_LEN(interval_string))) {
if (date_interval_initialize(&reltime, ZSTR_VAL(interval_string), ZSTR_LEN(interval_string)) == SUCCESS) { RETURN_THROWS();
php_interval_obj *diobj = Z_PHPINTERVAL_P(ZEND_THIS);
diobj->diff = reltime;
diobj->initialized = 1;
diobj->civil_or_wall = PHP_DATE_WALL;
} }
zend_restore_error_handling(&error_handling);
php_interval_obj *diobj = Z_PHPINTERVAL_P(ZEND_THIS);
diobj->diff = reltime;
diobj->initialized = 1;
diobj->civil_or_wall = PHP_DATE_WALL;
} }
/* }}} */ /* }}} */
@ -4117,19 +4110,19 @@ PHP_FUNCTION(date_interval_format)
} }
/* }}} */ /* }}} */
static int date_period_initialize(timelib_time **st, timelib_time **et, timelib_rel_time **d, zend_long *recurrences, /*const*/ char *format, size_t format_length) /* {{{ */ static bool date_period_initialize(timelib_time **st, timelib_time **et, timelib_rel_time **d, zend_long *recurrences, /*const*/ char *format, size_t format_length) /* {{{ */
{ {
timelib_time *b = NULL, *e = NULL; timelib_time *b = NULL, *e = NULL;
timelib_rel_time *p = NULL; timelib_rel_time *p = NULL;
int r = 0; int r = 0;
int retval = 0;
timelib_error_container *errors; timelib_error_container *errors;
bool retval = false;
timelib_strtointerval(format, format_length, &b, &e, &p, &r, &errors); timelib_strtointerval(format, format_length, &b, &e, &p, &r, &errors);
if (errors->error_count > 0) { if (errors->error_count > 0) {
php_error_docref(NULL, E_WARNING, "Unknown or bad format (%s)", format); retval = false;
retval = FAILURE; zend_throw_exception_ex(NULL, 0, "Unknown or bad format (%s)", format);
if (b) { if (b) {
timelib_time_dtor(b); timelib_time_dtor(b);
} }
@ -4144,7 +4137,7 @@ static int date_period_initialize(timelib_time **st, timelib_time **et, timelib_
*et = e; *et = e;
*d = p; *d = p;
*recurrences = r; *recurrences = r;
retval = SUCCESS; retval = true;
} }
timelib_error_container_dtor(errors); timelib_error_container_dtor(errors);
return retval; return retval;
@ -4160,7 +4153,6 @@ PHP_METHOD(DatePeriod, __construct)
char *isostr = NULL; char *isostr = NULL;
size_t isostr_len = 0; size_t isostr_len = 0;
timelib_time *clone; timelib_time *clone;
zend_error_handling 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(), "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(), "OOO|l", &start, date_ce_interface, &interval, date_ce_interval, &end, date_ce_interface, &options) == FAILURE) {
@ -4175,28 +4167,25 @@ PHP_METHOD(DatePeriod, __construct)
dpobj->current = NULL; dpobj->current = NULL;
if (isostr) { if (isostr) {
zend_replace_error_handling(EH_THROW, NULL, &error_handling); if (!date_period_initialize(&(dpobj->start), &(dpobj->end), &(dpobj->interval), &recurrences, isostr, isostr_len)) {
date_period_initialize(&(dpobj->start), &(dpobj->end), &(dpobj->interval), &recurrences, isostr, isostr_len);
zend_restore_error_handling(&error_handling);
if (EG(exception)) {
RETURN_THROWS(); RETURN_THROWS();
} }
if (dpobj->start == NULL) { if (dpobj->start == NULL) {
zend_string *func = get_active_function_or_method_name(); 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_throw_exception_ex(NULL, 0, "%s(): ISO interval must contain a start date, \"%s\" given", ZSTR_VAL(func), isostr);
zend_string_release(func); zend_string_release(func);
RETURN_THROWS(); RETURN_THROWS();
} }
if (dpobj->interval == NULL) { if (dpobj->interval == NULL) {
zend_string *func = get_active_function_or_method_name(); 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_throw_exception_ex(NULL, 0, "%s(): ISO interval must contain an interval, \"%s\" given", ZSTR_VAL(func), isostr);
zend_string_release(func); zend_string_release(func);
RETURN_THROWS(); RETURN_THROWS();
} }
if (dpobj->end == NULL && recurrences == 0) { if (dpobj->end == NULL && recurrences == 0) {
zend_string *func = get_active_function_or_method_name(); 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_throw_exception_ex(NULL, 0, "%s(): ISO interval must contain an end date or a recurrence count, \"%s\" given", ZSTR_VAL(func), isostr);
zend_string_release(func); zend_string_release(func);
RETURN_THROWS(); RETURN_THROWS();
} }
@ -4238,7 +4227,7 @@ PHP_METHOD(DatePeriod, __construct)
if (dpobj->end == NULL && recurrences < 1) { if (dpobj->end == NULL && recurrences < 1) {
zend_string *func = get_active_function_or_method_name(); 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_throw_exception_ex(NULL, 0, "%s(): Recurrence count must be greater than 0", ZSTR_VAL(func));
zend_string_release(func); zend_string_release(func);
RETURN_THROWS(); RETURN_THROWS();
} }

View file

@ -21,7 +21,7 @@ foreach ( $dp as $d )
?> ?>
--EXPECT-- --EXPECT--
DatePeriod::__construct(): Unknown or bad format (2D) Unknown or bad format (2D)
string(24) "2008-07-20T22:44:53+0200" string(24) "2008-07-20T22:44:53+0200"
string(24) "2008-07-21T22:44:53+0200" string(24) "2008-07-21T22:44:53+0200"
string(24) "2008-07-22T22:44:53+0200" string(24) "2008-07-22T22:44:53+0200"

View file

@ -127,7 +127,7 @@ object(DateInterval)#%d (16) {
["have_special_relative"]=> ["have_special_relative"]=>
int(0) int(0)
} }
DateInterval::__construct(): Failed to parse interval (2007-05-11T15:30:00Z/) Failed to parse interval (2007-05-11T15:30:00Z/)
DateInterval::__construct(): Failed to parse interval (2007-05-11T15:30:00Z) Failed to parse interval (2007-05-11T15:30:00Z)
DateInterval::__construct(): Unknown or bad format (2007-05-11T15:30:00Z/:00Z) Unknown or bad format (2007-05-11T15:30:00Z/:00Z)
==DONE== ==DONE==

View file

@ -12,4 +12,4 @@ try {
?> ?>
--EXPECTF-- --EXPECTF--
Deprecated: DatePeriod::__construct(): Passing null to parameter #1 ($start) of type string is deprecated in %s on line %d Deprecated: DatePeriod::__construct(): Passing null to parameter #1 ($start) of type string is deprecated in %s on line %d
string(51) "DatePeriod::__construct(): Unknown or bad format ()" string(24) "Unknown or bad format ()"

View file

@ -26,4 +26,4 @@ int(3)
Warning: Undefined property: Crasher::$2 in %s on line %d Warning: Undefined property: Crasher::$2 in %s on line %d
NULL NULL
string(%s) "DateInterval::__construct(): Unknown or bad format (blah)" string(28) "Unknown or bad format (blah)"

View file

@ -23,6 +23,6 @@ try {
?> ?>
--EXPECT-- --EXPECT--
DateInterval::__construct(): Unknown or bad format (P3"D) Unknown or bad format (P3"D)
DatePeriod::__construct(): Unknown or bad format (P3"D) Unknown or bad format (P3"D)
DatePeriod::__construct(): Unknown or bad format (2008-03-01T12:00:00Z1) Unknown or bad format (2008-03-01T12:00:00Z1)

View file

@ -65,7 +65,7 @@ echo "DONE\n";
--EXPECTF-- --EXPECTF--
string(19) "%d-%d-%d %d:%d:%d" string(19) "%d-%d-%d %d:%d:%d"
The DateTime object has not been correctly initialized by its constructor The DateTime object has not been correctly initialized by its constructor
DateTime::__construct(): Failed to parse time string (1am todax) at position 4 (t): The timezone could not be found in the database Failed to parse time string (1am todax) at position 4 (t): The timezone could not be found in the database
string(3) "UTC" string(3) "UTC"
The DateTimeZone object has not been correctly initialized by its constructor The DateTimeZone object has not been correctly initialized by its constructor
DateTimeZone::__construct(): Unknown or bad timezone (GottaFindThisOne) DateTimeZone::__construct(): Unknown or bad timezone (GottaFindThisOne)