From 2ee2335249d4bbeed27d60a59245a966d0580074 Mon Sep 17 00:00:00 2001 From: Derick Rethans Date: Fri, 4 Sep 2020 15:55:08 +0100 Subject: [PATCH] Fixed bug #80057 (DateTimeImmutable::createFromFormat() does not populate time) --- NEWS | 4 ++++ ext/date/php_date.c | 23 +++++++++++++++-------- ext/date/php_date.h | 5 ++++- ext/date/tests/bug80057.phpt | 13 +++++++++++++ 4 files changed, 36 insertions(+), 9 deletions(-) create mode 100644 ext/date/tests/bug80057.phpt diff --git a/NEWS b/NEWS index 34a8805503..ebf47b05a3 100644 --- a/NEWS +++ b/NEWS @@ -8,6 +8,10 @@ PHP NEWS . Fixed bug #80045 (memleak after two set_exception_handler calls with __call). (Nikita) +- Date: + . Fixed bug #80057 (DateTimeImmutable::createFromFormat() does not populate + time). (Derick) + 03 Sep 2020, PHP 8.0.0beta3 - Calendar: diff --git a/ext/date/php_date.c b/ext/date/php_date.c index c6ef4700ec..d6f66b700e 100644 --- a/ext/date/php_date.c +++ b/ext/date/php_date.c @@ -707,7 +707,7 @@ static zend_string *date_format(const char *format, size_t format_len, timelib_t /* timezone */ case 'I': length = slprintf(buffer, sizeof(buffer), "%d", localtime ? offset->is_dst : 0); break; - case 'p': + case 'p': if (!localtime || strcmp(offset->abbr, "UTC") == 0 || strcmp(offset->abbr, "Z") == 0) { length = slprintf(buffer, sizeof(buffer), "%s", "Z"); break; @@ -2179,7 +2179,7 @@ static void php_date_get_current_time_with_fraction(time_t *sec, suseconds_t *us #endif } -PHPAPI int php_date_initialize(php_date_obj *dateobj, const char *time_str, size_t time_str_len, const char *format, zval *timezone_object, int ctor) /* {{{ */ +PHPAPI int php_date_initialize(php_date_obj *dateobj, const char *time_str, size_t time_str_len, const char *format, zval *timezone_object, int flags) /* {{{ */ { timelib_time *now; timelib_tzinfo *tzi = NULL; @@ -2189,6 +2189,7 @@ PHPAPI int php_date_initialize(php_date_obj *dateobj, const char *time_str, size timelib_sll new_offset = 0; time_t sec; suseconds_t usec; + int options = 0; if (dateobj->time) { timelib_time_dtor(dateobj->time); @@ -2210,7 +2211,7 @@ PHPAPI int php_date_initialize(php_date_obj *dateobj, const char *time_str, size update_errors_warnings(err); - if (ctor && err && err->error_count) { + if ((flags & PHP_DATE_INIT_CTOR) && err && err->error_count) { /* 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, err->error_messages[0].position, err->error_messages[0].character, err->error_messages[0].message); @@ -2263,7 +2264,13 @@ PHPAPI int php_date_initialize(php_date_obj *dateobj, const char *time_str, size php_date_get_current_time_with_fraction(&sec, &usec); timelib_unixtime2local(now, (timelib_sll) sec); php_date_set_time_fraction(now, usec); - timelib_fill_holes(dateobj->time, now, TIMELIB_NO_CLONE); + + options = TIMELIB_NO_CLONE; + if (flags & PHP_DATE_INIT_FORMAT) { + options |= TIMELIB_OVERRIDE_TIME; + } + timelib_fill_holes(dateobj->time, now, options); + timelib_update_ts(dateobj->time, tzi); timelib_update_from_sse(dateobj->time); @@ -2331,7 +2338,7 @@ PHP_FUNCTION(date_create_from_format) ZEND_PARSE_PARAMETERS_END(); php_date_instantiate(execute_data->This.value.ce ? execute_data->This.value.ce : date_ce_date, return_value); - if (!php_date_initialize(Z_PHPDATE_P(return_value), time_str, time_str_len, format_str, timezone_object, 0)) { + if (!php_date_initialize(Z_PHPDATE_P(return_value), time_str, time_str_len, format_str, timezone_object, PHP_DATE_INIT_FORMAT)) { zval_ptr_dtor(return_value); RETURN_FALSE; } @@ -2353,7 +2360,7 @@ PHP_FUNCTION(date_create_immutable_from_format) ZEND_PARSE_PARAMETERS_END(); php_date_instantiate(execute_data->This.value.ce ? execute_data->This.value.ce : date_ce_immutable, return_value); - if (!php_date_initialize(Z_PHPDATE_P(return_value), time_str, time_str_len, format_str, timezone_object, 0)) { + if (!php_date_initialize(Z_PHPDATE_P(return_value), time_str, time_str_len, format_str, timezone_object, PHP_DATE_INIT_FORMAT)) { zval_ptr_dtor(return_value); RETURN_FALSE; } @@ -2375,7 +2382,7 @@ PHP_METHOD(DateTime, __construct) 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, 1); + 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); } /* }}} */ @@ -2395,7 +2402,7 @@ PHP_METHOD(DateTimeImmutable, __construct) 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, 1); + 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); } /* }}} */ diff --git a/ext/date/php_date.h b/ext/date/php_date.h index b89438e0c5..491f0b6c3e 100644 --- a/ext/date/php_date.h +++ b/ext/date/php_date.h @@ -130,8 +130,11 @@ PHPAPI zend_class_entry *php_date_get_interval_ce(void); PHPAPI zend_class_entry *php_date_get_period_ce(void); /* Functions for creating DateTime objects, and initializing them from a string */ +#define PHP_DATE_INIT_CTOR 0x01 +#define PHP_DATE_INIT_FORMAT 0x02 + PHPAPI zval *php_date_instantiate(zend_class_entry *pce, zval *object); -PHPAPI int php_date_initialize(php_date_obj *dateobj, const char *time_str, size_t time_str_len, const char *format, zval *timezone_object, int ctor); +PHPAPI int php_date_initialize(php_date_obj *dateobj, const char *time_str, size_t time_str_len, const char *format, zval *timezone_object, int flags); #endif /* PHP_DATE_H */ diff --git a/ext/date/tests/bug80057.phpt b/ext/date/tests/bug80057.phpt new file mode 100644 index 0000000000..30a3f8ccd7 --- /dev/null +++ b/ext/date/tests/bug80057.phpt @@ -0,0 +1,13 @@ +--TEST-- +Bug #80057 (DateTimeImmutable::createFromFormat() does not populate time) +--FILE-- +format("H:i"); +$parsedStr = $parsed->format("H:i"); + +var_dump($nowStr == $parsedStr); +?> +--EXPECT-- +bool(true) -- 2.50.1