summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorChristoph M. Becker <cmbecker69@gmx.de>2015-08-17 15:58:37 +0200
committerChristoph M. Becker <cmbecker69@gmx.de>2015-08-17 15:58:37 +0200
commitbb057498f7457e8b2eba98332a3bad434de4cf12 (patch)
tree494738e534b21f89a330b678b50c3a70d046a0e4
parentb010a9d84617930b5ae412c41e994ca00d489471 (diff)
downloadphp-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.c13
-rw-r--r--ext/date/tests/bug70277.phpt17
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, &not_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