Skip to content

Commit aa9694b

Browse files
authored
ext/date: null bytes in timezones can only happen via HT initialization (#19357)
Thus check this error condition early in the HT initialization code.
1 parent 7af4709 commit aa9694b

File tree

1 file changed

+12
-15
lines changed

1 file changed

+12
-15
lines changed

ext/date/php_date.c

Lines changed: 12 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -3968,24 +3968,18 @@ PHP_FUNCTION(date_diff)
39683968
}
39693969
/* }}} */
39703970

3971-
static bool timezone_initialize(php_timezone_obj *tzobj, const char *tz, size_t tz_len, char **warning_message) /* {{{ */
3971+
static bool timezone_initialize(php_timezone_obj *tzobj, const zend_string *tz_zstr, char **warning_message) /* {{{ */
39723972
{
39733973
timelib_time *dummy_t = ecalloc(1, sizeof(timelib_time));
39743974
int dst, not_found;
3975-
const char *orig_tz = tz;
3975+
const char *tz = ZSTR_VAL(tz_zstr);
39763976

3977-
if (strlen(tz) != tz_len) {
3978-
if (warning_message) {
3979-
spprintf(warning_message, 0, "Timezone must not contain null bytes");
3980-
}
3981-
efree(dummy_t);
3982-
return false;
3983-
}
3977+
ZEND_ASSERT(!zend_str_has_nul_byte(tz_zstr) && "timezone should have been checked to not have null bytes");
39843978

39853979
dummy_t->z = timelib_parse_zone(&tz, &dst, dummy_t, &not_found, DATE_TIMEZONEDB, php_date_parse_tzfile_wrapper);
39863980
if ((dummy_t->z >= (100 * 60 * 60)) || (dummy_t->z <= (-100 * 60 * 60))) {
39873981
if (warning_message) {
3988-
spprintf(warning_message, 0, "Timezone offset is out of range (%s)", orig_tz);
3982+
spprintf(warning_message, 0, "Timezone offset is out of range (%s)", ZSTR_VAL(tz_zstr));
39893983
}
39903984
timelib_free(dummy_t->tz_abbr);
39913985
efree(dummy_t);
@@ -3994,15 +3988,15 @@ static bool timezone_initialize(php_timezone_obj *tzobj, const char *tz, size_t
39943988
dummy_t->dst = dst;
39953989
if (!not_found && (*tz != '\0')) {
39963990
if (warning_message) {
3997-
spprintf(warning_message, 0, "Unknown or bad timezone (%s)", orig_tz);
3991+
spprintf(warning_message, 0, "Unknown or bad timezone (%s)", ZSTR_VAL(tz_zstr));
39983992
}
39993993
timelib_free(dummy_t->tz_abbr);
40003994
efree(dummy_t);
40013995
return false;
40023996
}
40033997
if (not_found) {
40043998
if (warning_message) {
4005-
spprintf(warning_message, 0, "Unknown or bad timezone (%s)", orig_tz);
3999+
spprintf(warning_message, 0, "Unknown or bad timezone (%s)", ZSTR_VAL(tz_zstr));
40064000
}
40074001
efree(dummy_t);
40084002
return false;
@@ -4026,7 +4020,7 @@ PHP_FUNCTION(timezone_open)
40264020
ZEND_PARSE_PARAMETERS_END();
40274021

40284022
tzobj = Z_PHPTIMEZONE_P(php_date_instantiate(date_ce_timezone, return_value));
4029-
if (!timezone_initialize(tzobj, ZSTR_VAL(tz), ZSTR_LEN(tz), &warning_message)) {
4023+
if (!timezone_initialize(tzobj, tz, &warning_message)) {
40304024
php_error_docref(NULL, E_WARNING, "%s", warning_message);
40314025
efree(warning_message);
40324026
zval_ptr_dtor(return_value);
@@ -4047,7 +4041,7 @@ PHP_METHOD(DateTimeZone, __construct)
40474041
ZEND_PARSE_PARAMETERS_END();
40484042

40494043
tzobj = Z_PHPTIMEZONE_P(ZEND_THIS);
4050-
if (!timezone_initialize(tzobj, ZSTR_VAL(tz), ZSTR_LEN(tz), &exception_message)) {
4044+
if (!timezone_initialize(tzobj, tz, &exception_message)) {
40514045
zend_throw_exception_ex(date_ce_date_invalid_timezone_exception, 0, "DateTimeZone::__construct(): %s", exception_message);
40524046
efree(exception_message);
40534047
RETURN_THROWS();
@@ -4078,7 +4072,10 @@ static bool php_date_timezone_initialize_from_hash(zval **return_value, php_time
40784072
if (Z_TYPE_P(z_timezone) != IS_STRING) {
40794073
return false;
40804074
}
4081-
return timezone_initialize(*tzobj, Z_STRVAL_P(z_timezone), Z_STRLEN_P(z_timezone), NULL);
4075+
if (UNEXPECTED(zend_str_has_nul_byte(Z_STR_P(z_timezone)))) {
4076+
return false;
4077+
}
4078+
return timezone_initialize(*tzobj, Z_STR_P(z_timezone), NULL);
40824079
} /* }}} */
40834080

40844081
/* {{{ */

0 commit comments

Comments
 (0)