diff options
author | Christoph M. Becker <cmbecker69@gmx.de> | 2015-08-17 15:58:37 +0200 |
---|---|---|
committer | Christoph M. Becker <cmbecker69@gmx.de> | 2015-08-17 15:58:37 +0200 |
commit | bb057498f7457e8b2eba98332a3bad434de4cf12 (patch) | |
tree | 494738e534b21f89a330b678b50c3a70d046a0e4 | |
parent | b010a9d84617930b5ae412c41e994ca00d489471 (diff) | |
download | php-git-bb057498f7457e8b2eba98332a3bad434de4cf12.tar.gz |
Fix #70277: new DateTimeZone($foo) is ignoring text after null byte
The DateTimeZone constructors are not binary safe. They're parsing the timezone
as string, but discard the length when calling timezone_initialize(). This
patch adds a tz_len parameter and a respective check to timezone_initialize().
-rw-r--r-- | ext/date/php_date.c | 13 | ||||
-rw-r--r-- | ext/date/tests/bug70277.phpt | 17 |
2 files changed, 26 insertions, 4 deletions
diff --git a/ext/date/php_date.c b/ext/date/php_date.c index 4ed439c4f5..4eca65bb11 100644 --- a/ext/date/php_date.c +++ b/ext/date/php_date.c @@ -3682,12 +3682,17 @@ PHP_FUNCTION(date_diff) } /* }}} */ -static int timezone_initialize(php_timezone_obj *tzobj, /*const*/ char *tz TSRMLS_DC) +static int timezone_initialize(php_timezone_obj *tzobj, /*const*/ char *tz, size_t tz_len TSRMLS_DC) { timelib_time *dummy_t = ecalloc(1, sizeof(timelib_time)); int dst, not_found; char *orig_tz = tz; + if (strlen(tz) != tz_len) { + php_error_docref(NULL TSRMLS_CC, E_WARNING, "Timezone must not contain null bytes"); + return FAILURE; + } + dummy_t->z = timelib_parse_zone(&tz, &dst, dummy_t, ¬_found, DATE_TIMEZONEDB, php_date_parse_tzfile_wrapper); if (not_found) { php_error_docref(NULL TSRMLS_CC, E_WARNING, "Unknown or bad timezone (%s)", orig_tz); @@ -3714,7 +3719,7 @@ PHP_FUNCTION(timezone_open) RETURN_FALSE; } tzobj = zend_object_store_get_object(php_date_instantiate(date_ce_timezone, return_value TSRMLS_CC) TSRMLS_CC); - if (SUCCESS != timezone_initialize(tzobj, tz TSRMLS_CC)) { + if (SUCCESS != timezone_initialize(tzobj, tz, tz_len TSRMLS_CC)) { RETURN_FALSE; } } @@ -3733,7 +3738,7 @@ PHP_METHOD(DateTimeZone, __construct) zend_replace_error_handling(EH_THROW, NULL, &error_handling TSRMLS_CC); if (SUCCESS == zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "s", &tz, &tz_len)) { tzobj = zend_object_store_get_object(getThis() TSRMLS_CC); - if (FAILURE == timezone_initialize(tzobj, tz TSRMLS_CC)) { + if (FAILURE == timezone_initialize(tzobj, tz, tz_len TSRMLS_CC)) { ZVAL_NULL(getThis()); } } @@ -3748,7 +3753,7 @@ static int php_date_timezone_initialize_from_hash(zval **return_value, php_timez if (zend_hash_find(myht, "timezone_type", 14, (void**) &z_timezone_type) == SUCCESS && Z_TYPE_PP(z_timezone_type) == IS_LONG) { if (zend_hash_find(myht, "timezone", 9, (void**) &z_timezone) == SUCCESS && Z_TYPE_PP(z_timezone) == IS_STRING) { - if (SUCCESS == timezone_initialize(*tzobj, Z_STRVAL_PP(z_timezone) TSRMLS_CC)) { + if (SUCCESS == timezone_initialize(*tzobj, Z_STRVAL_PP(z_timezone), Z_STRLEN_PP(z_timezone) TSRMLS_CC)) { return SUCCESS; } } diff --git a/ext/date/tests/bug70277.phpt b/ext/date/tests/bug70277.phpt new file mode 100644 index 0000000000..b6522dff1a --- /dev/null +++ b/ext/date/tests/bug70277.phpt @@ -0,0 +1,17 @@ +--TEST-- +Bug #70277 (new DateTimeZone($foo) is ignoring text after null byte) +--FILE-- +<?php +$timezone = "Europe/Zurich\0Foo"; +var_dump(timezone_open($timezone)); +var_dump(new DateTimeZone($timezone)); +?> +--EXPECTF-- +Warning: timezone_open(): Timezone must not contain null bytes in %sbug70277.php on line %d +bool(false) + +Fatal error: Uncaught exception 'Exception' with message 'DateTimeZone::__construct(): Timezone must not contain null bytes' in %sbug70277.php:%d +Stack trace: +#0 %sbug70277.php(%d): DateTimeZone->__construct('Europe/Zurich\x00F...') +#1 {main} + thrown in %sbug70277.php on line %d |