diff --git a/ext/date/php_date.c b/ext/date/php_date.c index 1795d41b27ce..e8585f8ca162 100644 --- a/ext/date/php_date.c +++ b/ext/date/php_date.c @@ -530,8 +530,8 @@ static PHP_INI_MH(OnUpdate_date_timezone) if (new_value && !timelib_timezone_id_is_valid(ZSTR_VAL(new_value), DATE_TIMEZONEDB)) { php_error_docref( NULL, E_WARNING, - "Invalid date.timezone value '%s', using '%s' instead", - ZSTR_VAL(new_value), + "Invalid date.timezone value '%pS', using '%s' instead", + new_value, DATEG(default_timezone) ? DATEG(default_timezone) : "UTC" ); return FAILURE; @@ -2393,7 +2393,7 @@ static void php_date_get_current_time_with_fraction(time_t *sec, suseconds_t *us #endif } -PHPAPI bool php_date_initialize(php_date_obj *dateobj, const char *time_str, size_t time_str_len, const char *format, zval *timezone_object, int flags) /* {{{ */ +PHPAPI bool php_date_initialize(php_date_obj *dateobj, const zend_string *time_string, const char *format, zval *timezone_object, int flags) /* {{{ */ { timelib_time *now; timelib_tzinfo *tzi = NULL; @@ -2404,6 +2404,13 @@ PHPAPI bool php_date_initialize(php_date_obj *dateobj, const char *time_str, siz time_t sec; suseconds_t usec; int options = 0; + const char *time_str = ""; + size_t time_str_len = 0; + + if (time_string) { + time_str = ZSTR_VAL(time_string); + time_str_len = ZSTR_LEN(time_string); + } if (dateobj->time) { timelib_time_dtor(dateobj->time); @@ -2427,7 +2434,7 @@ PHPAPI bool php_date_initialize(php_date_obj *dateobj, const char *time_str, siz /* If called from a constructor throw an exception */ if ((flags & PHP_DATE_INIT_CTOR) && err && err->error_count) { /* spit out the first library error message, at least */ - zend_throw_exception_ex(date_ce_date_malformed_string_exception, 0, "Failed to parse time string (%s) at position %d (%c): %s", time_str, + zend_throw_exception_ex(date_ce_date_malformed_string_exception, 0, "Failed to parse time string (%pS) at position %d (%c): %s", time_string, err->error_messages[0].position, err->error_messages[0].character ? err->error_messages[0].character : ' ', err->error_messages[0].message); } if (err && err->error_count) { @@ -2571,17 +2578,16 @@ PHPAPI bool php_date_initialize_from_ts_double(php_date_obj *dateobj, double ts) PHP_FUNCTION(date_create) { zval *timezone_object = NULL; - char *time_str = NULL; - size_t time_str_len = 0; + zend_string *time_str = NULL; ZEND_PARSE_PARAMETERS_START(0, 2) Z_PARAM_OPTIONAL - Z_PARAM_STRING(time_str, time_str_len) + Z_PARAM_PATH_STR(time_str) Z_PARAM_OBJECT_OF_CLASS_OR_NULL(timezone_object, date_ce_timezone) ZEND_PARSE_PARAMETERS_END(); php_date_instantiate(date_ce_date, return_value); - if (!php_date_initialize(Z_PHPDATE_P(return_value), time_str, time_str_len, NULL, timezone_object, 0)) { + if (!php_date_initialize(Z_PHPDATE_P(return_value), time_str, NULL, timezone_object, 0)) { zval_ptr_dtor(return_value); RETURN_FALSE; } @@ -2592,17 +2598,16 @@ PHP_FUNCTION(date_create) PHP_FUNCTION(date_create_immutable) { zval *timezone_object = NULL; - char *time_str = NULL; - size_t time_str_len = 0; + zend_string *time_str = NULL; ZEND_PARSE_PARAMETERS_START(0, 2) Z_PARAM_OPTIONAL - Z_PARAM_STRING(time_str, time_str_len) + Z_PARAM_PATH_STR(time_str) Z_PARAM_OBJECT_OF_CLASS_OR_NULL(timezone_object, date_ce_timezone) ZEND_PARSE_PARAMETERS_END(); php_date_instantiate(date_ce_immutable, return_value); - if (!php_date_initialize(Z_PHPDATE_P(return_value), time_str, time_str_len, NULL, timezone_object, 0)) { + if (!php_date_initialize(Z_PHPDATE_P(return_value), time_str, NULL, timezone_object, 0)) { zval_ptr_dtor(return_value); RETURN_FALSE; } @@ -2613,12 +2618,13 @@ PHP_FUNCTION(date_create_immutable) PHP_FUNCTION(date_create_from_format) { zval *timezone_object = NULL; - char *time_str = NULL, *format_str = NULL; - size_t time_str_len = 0, format_str_len = 0; + zend_string *time_str = NULL; + char *format_str = NULL; + size_t format_str_len = 0; ZEND_PARSE_PARAMETERS_START(2, 3) Z_PARAM_STRING(format_str, format_str_len) - Z_PARAM_PATH(time_str, time_str_len) + Z_PARAM_PATH_STR(time_str) Z_PARAM_OPTIONAL Z_PARAM_OBJECT_OF_CLASS_OR_NULL(timezone_object, date_ce_timezone) ZEND_PARSE_PARAMETERS_END(); @@ -2626,7 +2632,7 @@ PHP_FUNCTION(date_create_from_format) if (object_init_ex(return_value, execute_data->This.value.ce ? execute_data->This.value.ce : date_ce_date) != SUCCESS) { RETURN_THROWS(); } - if (!php_date_initialize(Z_PHPDATE_P(return_value), time_str, time_str_len, format_str, timezone_object, PHP_DATE_INIT_FORMAT)) { + if (!php_date_initialize(Z_PHPDATE_P(return_value), time_str, format_str, timezone_object, PHP_DATE_INIT_FORMAT)) { zval_ptr_dtor(return_value); RETURN_FALSE; } @@ -2637,12 +2643,13 @@ PHP_FUNCTION(date_create_from_format) PHP_FUNCTION(date_create_immutable_from_format) { zval *timezone_object = NULL; - char *time_str = NULL, *format_str = NULL; - size_t time_str_len = 0, format_str_len = 0; + char *format_str = NULL; + zend_string *time_str = NULL; + size_t format_str_len = 0; ZEND_PARSE_PARAMETERS_START(2, 3) Z_PARAM_STRING(format_str, format_str_len) - Z_PARAM_PATH(time_str, time_str_len) + Z_PARAM_PATH_STR(time_str) Z_PARAM_OPTIONAL Z_PARAM_OBJECT_OF_CLASS_OR_NULL(timezone_object, date_ce_timezone) ZEND_PARSE_PARAMETERS_END(); @@ -2650,7 +2657,7 @@ PHP_FUNCTION(date_create_immutable_from_format) if (object_init_ex(return_value, execute_data->This.value.ce ? execute_data->This.value.ce : date_ce_immutable) != SUCCESS) { RETURN_THROWS(); } - if (!php_date_initialize(Z_PHPDATE_P(return_value), time_str, time_str_len, format_str, timezone_object, PHP_DATE_INIT_FORMAT)) { + if (!php_date_initialize(Z_PHPDATE_P(return_value), time_str, format_str, timezone_object, PHP_DATE_INIT_FORMAT)) { zval_ptr_dtor(return_value); RETURN_FALSE; } @@ -2661,16 +2668,15 @@ PHP_FUNCTION(date_create_immutable_from_format) PHP_METHOD(DateTime, __construct) { zval *timezone_object = NULL; - char *time_str = NULL; - size_t time_str_len = 0; + zend_string *time_str = NULL; ZEND_PARSE_PARAMETERS_START(0, 2) Z_PARAM_OPTIONAL - Z_PARAM_STRING(time_str, time_str_len) + Z_PARAM_PATH_STR(time_str) Z_PARAM_OBJECT_OF_CLASS_OR_NULL(timezone_object, date_ce_timezone) ZEND_PARSE_PARAMETERS_END(); - 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, NULL, timezone_object, PHP_DATE_INIT_CTOR); } /* }}} */ @@ -2678,16 +2684,15 @@ PHP_METHOD(DateTime, __construct) PHP_METHOD(DateTimeImmutable, __construct) { zval *timezone_object = NULL; - char *time_str = NULL; - size_t time_str_len = 0; + zend_string *time_str = NULL; ZEND_PARSE_PARAMETERS_START(0, 2) Z_PARAM_OPTIONAL - Z_PARAM_STRING(time_str, time_str_len) + Z_PARAM_PATH_STR(time_str) Z_PARAM_OBJECT_OF_CLASS_OR_NULL(timezone_object, date_ce_timezone) ZEND_PARSE_PARAMETERS_END(); - 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, NULL, timezone_object, PHP_DATE_INIT_CTOR); } /* }}} */ @@ -2882,7 +2887,7 @@ static bool php_date_initialize_from_hash(php_date_obj **dateobj, const HashTabl zend_string *tmp = zend_string_concat3( Z_STRVAL_P(z_date), Z_STRLEN_P(z_date), " ", 1, Z_STRVAL_P(z_timezone), Z_STRLEN_P(z_timezone)); - bool ret = php_date_initialize(*dateobj, ZSTR_VAL(tmp), ZSTR_LEN(tmp), NULL, NULL, 0); + bool ret = php_date_initialize(*dateobj, tmp, NULL, NULL, 0); zend_string_release(tmp); return ret; } @@ -2902,7 +2907,7 @@ static bool php_date_initialize_from_hash(php_date_obj **dateobj, const HashTabl tzobj->tzi.tz = tzi; tzobj->initialized = true; - ret = php_date_initialize(*dateobj, Z_STRVAL_P(z_date), Z_STRLEN_P(z_date), NULL, &tmp_obj, 0); + ret = php_date_initialize(*dateobj, Z_STR_P(z_date), NULL, &tmp_obj, 0); zval_ptr_dtor(&tmp_obj); return ret; } @@ -3262,7 +3267,7 @@ typedef enum { PHP_DATE_MODIFY_THROW } php_date_modify_error_mode; -static bool php_date_modify(zval *object, char *modify, size_t modify_len, const php_date_modify_error_mode error_mode) /* {{{ */ +static bool php_date_modify(zval *object, zend_string *modify, const php_date_modify_error_mode error_mode) /* {{{ */ { php_date_obj *dateobj; timelib_time *tmp_time; @@ -3275,7 +3280,7 @@ static bool php_date_modify(zval *object, char *modify, size_t modify_len, const return false; } - tmp_time = timelib_strtotime(modify, modify_len, &err, DATE_TIMEZONEDB, php_date_parse_tzfile_wrapper); + tmp_time = timelib_strtotime(ZSTR_VAL(modify), ZSTR_LEN(modify), &err, DATE_TIMEZONEDB, php_date_parse_tzfile_wrapper); /* update last errors and warnings */ update_errors_warnings(&err); @@ -3285,7 +3290,7 @@ static bool php_date_modify(zval *object, char *modify, size_t modify_len, const if (error_mode == PHP_DATE_MODIFY_THROW) { zend_string *func_name = get_active_function_or_method_name(); zend_throw_exception_ex(date_ce_date_malformed_string_exception, 0, - "%s(): Failed to parse time string (%s) at position %d (%c): %s", + "%s(): Failed to parse time string (%pS) at position %d (%c): %s", ZSTR_VAL(func_name), modify, err->error_messages[0].position, @@ -3293,7 +3298,7 @@ static bool php_date_modify(zval *object, char *modify, size_t modify_len, const err->error_messages[0].message); zend_string_release_ex(func_name, false); } else { - php_error_docref(NULL, E_WARNING, "Failed to parse time string (%s) at position %d (%c): %s", modify, + php_error_docref(NULL, E_WARNING, "Failed to parse time string (%s) at position %d (%c): %s", ZSTR_VAL(modify), err->error_messages[0].position, err->error_messages[0].character ? err->error_messages[0].character : ' ', err->error_messages[0].message); @@ -3359,14 +3364,13 @@ static bool php_date_modify(zval *object, char *modify, size_t modify_len, const PHP_FUNCTION(date_modify) { zval *object; - char *modify; - size_t modify_len; + zend_string *modify; - if (zend_parse_method_parameters(ZEND_NUM_ARGS(), getThis(), "Os", &object, date_ce_date, &modify, &modify_len) == FAILURE) { + if (zend_parse_method_parameters(ZEND_NUM_ARGS(), getThis(), "OS", &object, date_ce_date, &modify) == FAILURE) { RETURN_THROWS(); } - if (!php_date_modify(object, modify, modify_len, PHP_DATE_MODIFY_WARNING)) { + if (!php_date_modify(object, modify, PHP_DATE_MODIFY_WARNING)) { RETURN_FALSE; } @@ -3378,15 +3382,14 @@ PHP_FUNCTION(date_modify) PHP_METHOD(DateTime, modify) { zval *object; - char *modify; - size_t modify_len; + zend_string *modify; object = ZEND_THIS; ZEND_PARSE_PARAMETERS_START(1, 1) - Z_PARAM_STRING(modify, modify_len) + Z_PARAM_STR(modify) ZEND_PARSE_PARAMETERS_END(); - if (!php_date_modify(object, modify, modify_len, PHP_DATE_MODIFY_THROW)) { + if (!php_date_modify(object, modify, PHP_DATE_MODIFY_THROW)) { RETURN_THROWS(); } @@ -3398,17 +3401,16 @@ PHP_METHOD(DateTime, modify) PHP_METHOD(DateTimeImmutable, modify) { zval *object, new_object; - char *modify; - size_t modify_len; + zend_string *modify; object = ZEND_THIS; ZEND_PARSE_PARAMETERS_START(1, 1) - Z_PARAM_STRING(modify, modify_len) + Z_PARAM_STR(modify) ZEND_PARSE_PARAMETERS_END(); date_clone_immutable(object, &new_object); - if (!php_date_modify(&new_object, modify, modify_len, PHP_DATE_MODIFY_THROW)) { + if (!php_date_modify(&new_object, modify, PHP_DATE_MODIFY_THROW)) { zval_ptr_dtor(&new_object); RETURN_THROWS(); } @@ -4459,7 +4461,7 @@ PHP_FUNCTION(timezone_location_get) } /* }}} */ -static bool date_interval_initialize(timelib_rel_time **rt, const char *format, size_t format_length) /* {{{ */ +static bool date_interval_initialize(timelib_rel_time **rt, const zend_string *format) /* {{{ */ { timelib_time *b = NULL, *e = NULL; timelib_rel_time *p = NULL; @@ -4467,10 +4469,10 @@ static bool date_interval_initialize(timelib_rel_time **rt, const char *format, bool retval = false; timelib_error_container *errors; - timelib_strtointerval(format, format_length, &b, &e, &p, &r, &errors); + timelib_strtointerval(ZSTR_VAL(format), ZSTR_LEN(format), &b, &e, &p, &r, &errors); if (errors->error_count > 0) { - zend_throw_exception_ex(date_ce_date_malformed_interval_string_exception, 0, "Unknown or bad format (%s)", format); + zend_throw_exception_ex(date_ce_date_malformed_interval_string_exception, 0, "Unknown or bad format (%pS)", format); retval = false; if (p) { timelib_rel_time_dtor(p); @@ -4486,7 +4488,7 @@ static bool date_interval_initialize(timelib_rel_time **rt, const char *format, *rt = timelib_diff(b, e); retval = true; } else { - zend_throw_exception_ex(date_ce_date_malformed_interval_string_exception, 0, "Failed to parse interval (%s)", format); + zend_throw_exception_ex(date_ce_date_malformed_interval_string_exception, 0, "Failed to parse interval (%pS)", format); retval = false; } } @@ -4632,10 +4634,10 @@ PHP_METHOD(DateInterval, __construct) timelib_rel_time *reltime; ZEND_PARSE_PARAMETERS_START(1, 1) - Z_PARAM_STR(interval_string) + Z_PARAM_PATH_STR(interval_string) ZEND_PARSE_PARAMETERS_END(); - if (!date_interval_initialize(&reltime, ZSTR_VAL(interval_string), ZSTR_LEN(interval_string))) { + if (!date_interval_initialize(&reltime, interval_string)) { RETURN_THROWS(); } @@ -4657,9 +4659,15 @@ static void php_date_interval_initialize_from_hash(php_interval_obj *intobj, con time = timelib_strtotime(Z_STRVAL_P(date_str), Z_STRLEN_P(date_str), &err, DATE_TIMEZONEDB, php_date_parse_tzfile_wrapper); if (err->error_count > 0) { + const zend_string *date_string; + if (Z_TYPE_P(date_str) == IS_STRING) { + date_string = Z_STR_P(date_str); + } else { + date_string = ZSTR_EMPTY_ALLOC(); + } zend_throw_error(NULL, - "Unknown or bad format (%s) at position %d (%c) while unserializing: %s", - Z_STRVAL_P(date_str), + "Unknown or bad format (%pS) at position %d (%c) while unserializing: %s", + date_string, err->error_messages[0].position, err->error_messages[0].character ? err->error_messages[0].character : ' ', err->error_messages[0].message); timelib_time_dtor(time); @@ -4899,20 +4907,20 @@ PHP_FUNCTION(date_interval_create_from_date_string) timelib_error_container *err = NULL; ZEND_PARSE_PARAMETERS_START(1, 1) - Z_PARAM_STR(time_str) + Z_PARAM_PATH_STR(time_str) ZEND_PARSE_PARAMETERS_END(); time = timelib_strtotime(ZSTR_VAL(time_str), ZSTR_LEN(time_str), &err, DATE_TIMEZONEDB, php_date_parse_tzfile_wrapper); if (err->error_count > 0) { - php_error_docref(NULL, E_WARNING, "Unknown or bad format (%s) at position %d (%c): %s", ZSTR_VAL(time_str), + php_error_docref(NULL, E_WARNING, "Unknown or bad format (%pS) at position %d (%c): %s", time_str, err->error_messages[0].position, err->error_messages[0].character ? err->error_messages[0].character : ' ', err->error_messages[0].message); RETVAL_FALSE; goto cleanup; } if (time->have_date || time->have_time || time->have_zone) { - php_error_docref(NULL, E_WARNING, "String '%s' contains non-relative elements", ZSTR_VAL(time_str)); + php_error_docref(NULL, E_WARNING, "String '%pS' contains non-relative elements", time_str); RETVAL_FALSE; goto cleanup; } @@ -4933,13 +4941,13 @@ PHP_METHOD(DateInterval, createFromDateString) timelib_error_container *err = NULL; ZEND_PARSE_PARAMETERS_START(1, 1) - Z_PARAM_STR(time_str) + Z_PARAM_PATH_STR(time_str) ZEND_PARSE_PARAMETERS_END(); time = timelib_strtotime(ZSTR_VAL(time_str), ZSTR_LEN(time_str), &err, DATE_TIMEZONEDB, php_date_parse_tzfile_wrapper); if (err->error_count > 0) { - zend_throw_error(date_ce_date_malformed_interval_string_exception, "Unknown or bad format (%s) at position %d (%c): %s", ZSTR_VAL(time_str), + zend_throw_error(date_ce_date_malformed_interval_string_exception, "Unknown or bad format (%pS) at position %d (%c): %s", time_str, err->error_messages[0].position, err->error_messages[0].character ? err->error_messages[0].character : ' ', err->error_messages[0].message); goto cleanup; } @@ -5045,7 +5053,7 @@ PHP_FUNCTION(date_interval_format) } /* }}} */ -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) /* {{{ */ +static bool date_period_initialize(timelib_time **st, timelib_time **et, timelib_rel_time **d, zend_long *recurrences, const zend_string *format) /* {{{ */ { timelib_time *b = NULL, *e = NULL; timelib_rel_time *p = NULL; @@ -5053,11 +5061,11 @@ static bool date_period_initialize(timelib_time **st, timelib_time **et, timelib timelib_error_container *errors; bool retval = false; - timelib_strtointerval(format, format_length, &b, &e, &p, &r, &errors); + timelib_strtointerval(ZSTR_VAL(format), ZSTR_LEN(format), &b, &e, &p, &r, &errors); if (errors->error_count > 0) { retval = false; - zend_throw_exception_ex(date_ce_date_malformed_period_string_exception, 0, "Unknown or bad format (%s)", format); + zend_throw_exception_ex(date_ce_date_malformed_period_string_exception, 0, "Unknown or bad format (%pS)", format); if (b) { timelib_time_dtor(b); } @@ -5078,27 +5086,27 @@ static bool date_period_initialize(timelib_time **st, timelib_time **et, timelib return retval; } /* }}} */ -static bool date_period_init_iso8601_string(php_period_obj *dpobj, zend_class_entry* base_ce, const char *isostr, size_t isostr_len, zend_long *recurrences) +static bool date_period_init_iso8601_string(php_period_obj *dpobj, zend_class_entry* base_ce, const zend_string *isostr, zend_long *recurrences) { - if (!date_period_initialize(&(dpobj->start), &(dpobj->end), &(dpobj->interval), recurrences, isostr, isostr_len)) { + if (!date_period_initialize(&(dpobj->start), &(dpobj->end), &(dpobj->interval), recurrences, isostr)) { return false; } if (dpobj->start == NULL) { zend_string *func = get_active_function_or_method_name(); - zend_throw_exception_ex(date_ce_date_malformed_period_string_exception, 0, "%s(): ISO interval must contain a start date, \"%s\" given", ZSTR_VAL(func), isostr); + zend_throw_exception_ex(date_ce_date_malformed_period_string_exception, 0, "%s(): ISO interval must contain a start date, \"%pS\" given", ZSTR_VAL(func), isostr); zend_string_release(func); return false; } if (dpobj->interval == NULL) { zend_string *func = get_active_function_or_method_name(); - zend_throw_exception_ex(date_ce_date_malformed_period_string_exception, 0, "%s(): ISO interval must contain an interval, \"%s\" given", ZSTR_VAL(func), isostr); + zend_throw_exception_ex(date_ce_date_malformed_period_string_exception, 0, "%s(): ISO interval must contain an interval, \"%pS\" given", ZSTR_VAL(func), isostr); zend_string_release(func); return false; } if (dpobj->end == NULL && *recurrences == 0) { zend_string *func = get_active_function_or_method_name(); - zend_throw_exception_ex(date_ce_date_malformed_period_string_exception, 0, "%s(): ISO interval must contain an end date or a recurrence count, \"%s\" given", ZSTR_VAL(func), isostr); + zend_throw_exception_ex(date_ce_date_malformed_period_string_exception, 0, "%s(): ISO interval must contain an end date or a recurrence count, \"%pS\" given", ZSTR_VAL(func), isostr); zend_string_release(func); return false; } @@ -5150,11 +5158,10 @@ PHP_METHOD(DatePeriod, createFromISO8601String) { php_period_obj *dpobj; zend_long recurrences = 0, options = 0; - char *isostr = NULL; - size_t isostr_len = 0; + zend_string *isostr = NULL; ZEND_PARSE_PARAMETERS_START(1, 2) - Z_PARAM_STRING(isostr, isostr_len) + Z_PARAM_PATH_STR(isostr) Z_PARAM_OPTIONAL Z_PARAM_LONG(options) ZEND_PARSE_PARAMETERS_END(); @@ -5166,7 +5173,7 @@ PHP_METHOD(DatePeriod, createFromISO8601String) dpobj->current = NULL; - if (!date_period_init_iso8601_string(dpobj, date_ce_immutable, isostr, isostr_len, &recurrences)) { + if (!date_period_init_iso8601_string(dpobj, date_ce_immutable, isostr, &recurrences)) { RETURN_THROWS(); } @@ -5199,13 +5206,12 @@ PHP_METHOD(DatePeriod, __construct) php_date_obj *dateobj; zval *start, *end = NULL, *interval; zend_long recurrences = 0, options = 0; - char *isostr = NULL; - size_t isostr_len = 0; + zend_string *isostr = NULL; timelib_time *clone; 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) { + if (zend_parse_parameters_ex(ZEND_PARSE_PARAMS_QUIET, ZEND_NUM_ARGS(), "S|l", &isostr, &options) == FAILURE) { zend_type_error("DatePeriod::__construct() accepts (DateTimeInterface, DateInterval, int [, int]), or (DateTimeInterface, DateInterval, DateTime [, int]), or (string [, int]) as arguments"); RETURN_THROWS(); } @@ -5222,7 +5228,7 @@ PHP_METHOD(DatePeriod, __construct) RETURN_THROWS(); } - if (!date_period_init_iso8601_string(dpobj, date_ce_date, isostr, isostr_len, &recurrences)) { + if (!date_period_init_iso8601_string(dpobj, date_ce_date, isostr, &recurrences)) { RETURN_THROWS(); } } else { @@ -5466,22 +5472,21 @@ PHP_FUNCTION(timezone_abbreviations_list) /* {{{ Sets the default timezone used by all date/time functions in a script */ PHP_FUNCTION(date_default_timezone_set) { - char *zone; - size_t zone_len; + zend_string *zone; ZEND_PARSE_PARAMETERS_START(1, 1) - Z_PARAM_STRING(zone, zone_len) + Z_PARAM_PATH_STR(zone) ZEND_PARSE_PARAMETERS_END(); - if (!timelib_timezone_id_is_valid(zone, DATE_TIMEZONEDB)) { - php_error_docref(NULL, E_NOTICE, "Timezone ID '%s' is invalid", zone); + if (!timelib_timezone_id_is_valid(ZSTR_VAL(zone), DATE_TIMEZONEDB)) { + php_error_docref(NULL, E_NOTICE, "Timezone ID '%pS' is invalid", zone); RETURN_FALSE; } if (DATEG(timezone)) { efree(DATEG(timezone)); DATEG(timezone) = NULL; } - DATEG(timezone) = estrndup(zone, zone_len); + DATEG(timezone) = estrndup(ZSTR_VAL(zone), ZSTR_LEN(zone)); RETURN_TRUE; } /* }}} */ diff --git a/ext/date/php_date.h b/ext/date/php_date.h index 97a49974f1a4..d409d9e7ae18 100644 --- a/ext/date/php_date.h +++ b/ext/date/php_date.h @@ -152,7 +152,7 @@ PHPAPI zend_class_entry *php_date_get_period_ce(void); #define PHP_DATE_INIT_FORMAT 0x02 PHPAPI zval *php_date_instantiate(zend_class_entry *pce, zval *object); -PHPAPI bool php_date_initialize(php_date_obj *dateobj, const char *time_str, size_t time_str_len, const char *format, zval *timezone_object, int flags); +PHPAPI bool php_date_initialize(php_date_obj *dateobj, const zend_string *time_str, const char *format, zval *timezone_object, int flags); PHPAPI void php_date_initialize_from_ts_long(php_date_obj *dateobj, zend_long sec, int usec); PHPAPI bool php_date_initialize_from_ts_double(php_date_obj *dateobj, double ts); diff --git a/ext/date/tests/22993/dateInterval_create_null_byte.phpt b/ext/date/tests/22993/dateInterval_create_null_byte.phpt new file mode 100644 index 000000000000..61eaf014a44a --- /dev/null +++ b/ext/date/tests/22993/dateInterval_create_null_byte.phpt @@ -0,0 +1,14 @@ +--TEST-- +GH-22993: DateInterval::createFromDateString() rejects embedded NUL byte +--FILE-- + +--EXPECTF-- +Fatal error: Uncaught ValueError: DateInterval::createFromDateString(): Argument #1 ($datetime) must not contain any null bytes in %s:%d +Stack trace: +#0 %s(%d): DateInterval::createFromDateString('foo\x00bar') +#1 {main} + thrown in %s on line %d \ No newline at end of file diff --git a/ext/date/tests/22993/dateInterval_nul_byte.phpt b/ext/date/tests/22993/dateInterval_nul_byte.phpt new file mode 100644 index 000000000000..64e622eb4c5e --- /dev/null +++ b/ext/date/tests/22993/dateInterval_nul_byte.phpt @@ -0,0 +1,18 @@ +--TEST-- +GH-22993: DateInterval error message with embedded NUL byte +--FILE-- +getMessage(), PHP_EOL; +} + +?> +--EXPECTF-- +Fatal error: Uncaught ValueError: DateInterval::__construct(): Argument #1 ($duration) must not contain any null bytes in %s:%d +Stack trace: +#0 %s(%d): DateInterval->__construct('foo\x00bar') +#1 {main} + thrown in %s on line %d diff --git a/ext/date/tests/22993/dateInterval_unserialize_null_byte.phpt b/ext/date/tests/22993/dateInterval_unserialize_null_byte.phpt new file mode 100644 index 000000000000..c4bb09cd4e7f --- /dev/null +++ b/ext/date/tests/22993/dateInterval_unserialize_null_byte.phpt @@ -0,0 +1,14 @@ +--TEST-- +GH-22993: DateInterval unserialize() error message with embedded NUL byte +--FILE-- +getMessage(), PHP_EOL; +} + +?> +--EXPECTF-- +Unknown or bad format (foo%0bar) at position 0 (f) while unserializing: The timezone could not be found in the database diff --git a/ext/date/tests/22993/datePeriod_create_iso8601_null_byte.phpt b/ext/date/tests/22993/datePeriod_create_iso8601_null_byte.phpt new file mode 100644 index 000000000000..5c41a3f4e37d --- /dev/null +++ b/ext/date/tests/22993/datePeriod_create_iso8601_null_byte.phpt @@ -0,0 +1,14 @@ +--TEST-- +GH-22993: DatePeriod::createFromISO8601String() rejects embedded NUL byte +--FILE-- +getMessage(), PHP_EOL; +} + +?> +--EXPECT-- +DatePeriod::createFromISO8601String(): Argument #1 ($specification) must not contain any null bytes \ No newline at end of file diff --git a/ext/date/tests/22993/dateTime_modify_embedded_null.phpt b/ext/date/tests/22993/dateTime_modify_embedded_null.phpt new file mode 100644 index 000000000000..900fa4937ddc --- /dev/null +++ b/ext/date/tests/22993/dateTime_modify_embedded_null.phpt @@ -0,0 +1,16 @@ +--TEST-- +GH-22993: DateTime::modify() error message with embedded NUL byte +--FILE-- +modify("foo\0bar"); +} catch (DateMalformedStringException $e) { + echo $e->getMessage(), "\n"; +} + +?> +--EXPECTF-- +DateTime::modify(): Failed to parse time string (foo%0bar) at position %s diff --git a/ext/date/tests/22993/date_interval_null_byte.phpt b/ext/date/tests/22993/date_interval_null_byte.phpt new file mode 100644 index 000000000000..0d1e9f909a0e --- /dev/null +++ b/ext/date/tests/22993/date_interval_null_byte.phpt @@ -0,0 +1,14 @@ +--TEST-- +GH-22993: date_interval_create_from_date_string() rejects embedded NUL byte +--FILE-- + +--EXPECTF-- +Fatal error: Uncaught ValueError: date_interval_create_from_date_string(): Argument #1 ($datetime) must not contain any null bytes in %s:%d +Stack trace: +#0 %s(%d): date_interval_create_from_date_string('foo\x00bar') +#1 {main} + thrown in %s on line %d \ No newline at end of file diff --git a/ext/date/tests/22993/ini_date_timezone_null_byte.phpt b/ext/date/tests/22993/ini_date_timezone_null_byte.phpt new file mode 100644 index 000000000000..0d98638b190c --- /dev/null +++ b/ext/date/tests/22993/ini_date_timezone_null_byte.phpt @@ -0,0 +1,10 @@ +--TEST-- +GH-22993: ini_set() with embedded NUL byte in date.timezone +--FILE-- + +--EXPECTF-- +Warning: ini_set(): Invalid date.timezone value 'foo%0bar', using 'UTC' instead in %s on line %d diff --git a/ext/date/tests/22993/nul-byte-error-message.phpt b/ext/date/tests/22993/nul-byte-error-message.phpt new file mode 100644 index 000000000000..b7c178955cf8 --- /dev/null +++ b/ext/date/tests/22993/nul-byte-error-message.phpt @@ -0,0 +1,14 @@ +--TEST-- +GH-22993: DateTimeImmutable rejects embedded NUL byte +--FILE-- + +--EXPECTF-- +Fatal error: Uncaught ValueError: DateTimeImmutable::__construct(): Argument #1 ($datetime) must not contain any null bytes in %s:%d +Stack trace: +#0 %s(%d): DateTimeImmutable->__construct('foo\x00bar') +#1 {main} + thrown in %s on line %d \ No newline at end of file diff --git a/ext/date/tests/22993/timezone_set_null_byte.phpt b/ext/date/tests/22993/timezone_set_null_byte.phpt new file mode 100644 index 000000000000..41bd5dd620b0 --- /dev/null +++ b/ext/date/tests/22993/timezone_set_null_byte.phpt @@ -0,0 +1,14 @@ +--TEST-- +GH-22993: date_default_timezone_set() rejects embedded NUL byte +--FILE-- +getMessage(), PHP_EOL; +} + +?> +--EXPECT-- +date_default_timezone_set(): Argument #1 ($timezoneId) must not contain any null bytes \ No newline at end of file