diff options
author | Gustavo André dos Santos Lopes <cataphract@php.net> | 2012-05-24 10:44:44 +0200 |
---|---|---|
committer | Gustavo André dos Santos Lopes <cataphract@php.net> | 2012-05-24 11:06:21 +0200 |
commit | 2da2de46a8dc9d44b624c40adb0d6bf698567167 (patch) | |
tree | d05be33e6507ed15e0d85c7facca6acfd3714c0b /ext/intl | |
parent | e08566c6139461db9dbf0f6c2e870d67923ee587 (diff) | |
download | php-git-2da2de46a8dc9d44b624c40adb0d6bf698567167.tar.gz |
Fixed bug #60785
Memory leak in IntlDateFormatter constructor.
udat_setCalendar() clones the calendar before it adopts it,
so we were leaking the original calendar.
Also we now validate the calendar type.
Diffstat (limited to 'ext/intl')
-rwxr-xr-x | ext/intl/dateformat/dateformat.c | 17 | ||||
-rw-r--r-- | ext/intl/tests/dateformat_calendars.phpt | 45 |
2 files changed, 58 insertions, 4 deletions
diff --git a/ext/intl/dateformat/dateformat.c b/ext/intl/dateformat/dateformat.c index 6c0c52257b..b399a39fcb 100755 --- a/ext/intl/dateformat/dateformat.c +++ b/ext/intl/dateformat/dateformat.c @@ -99,6 +99,15 @@ static void datefmt_ctor(INTERNAL_FUNCTION_PARAMETERS) } INTL_CHECK_LOCALE_LEN_OBJ(locale_len, return_value); + + if (calendar != UCAL_TRADITIONAL && calendar != UCAL_GREGORIAN) { + intl_error_set(NULL, U_ILLEGAL_ARGUMENT_ERROR, "datefmt_create: " + "invalid value for calendar type; it must be one of " + "IntlDateFormatter::TRADITIONAL (locale's default calendar) " + "or IntlDateFormatter::GREGORIAN", 0 TSRMLS_CC); + goto error; + } + DATE_FORMAT_METHOD_FETCH_OBJECT; if (DATE_FORMAT_OBJECT(dfo) != NULL) { @@ -142,13 +151,13 @@ static void datefmt_ctor(INTERNAL_FUNCTION_PARAMETERS) DATE_FORMAT_OBJECT(dfo) = udat_open(time_type, date_type, locale, timezone_utf16, timezone_utf16_len, svalue, slength, &INTL_DATA_ERROR_CODE(dfo)); } - /* Set the calendar if passed */ - if(!U_FAILURE(INTL_DATA_ERROR_CODE(dfo))) { - if (calendar) { + if (!U_FAILURE(INTL_DATA_ERROR_CODE(dfo))) { + if (calendar != UCAL_TRADITIONAL) { ucal_obj = ucal_open(timezone_utf16, timezone_utf16_len, locale, calendar, &INTL_DATA_ERROR_CODE(dfo)); if (!U_FAILURE(INTL_DATA_ERROR_CODE(dfo))) { - udat_setCalendar( DATE_FORMAT_OBJECT(dfo), ucal_obj ); + udat_setCalendar(DATE_FORMAT_OBJECT(dfo), ucal_obj); + ucal_close(ucal_obj); } else { intl_error_set(NULL, INTL_DATA_ERROR_CODE(dfo), "datefmt_create" ": error opening calendar", 0 TSRMLS_CC); diff --git a/ext/intl/tests/dateformat_calendars.phpt b/ext/intl/tests/dateformat_calendars.phpt new file mode 100644 index 0000000000..27f380c718 --- /dev/null +++ b/ext/intl/tests/dateformat_calendars.phpt @@ -0,0 +1,45 @@ +--TEST-- +IntlDateFormatter, calendars and time zone +--INI-- +date.timezone=Atlantic/Azores +--SKIPIF-- +<?php +if (!extension_loaded('intl')) + die('skip intl extension not enabled'); +--FILE-- +<?php +ini_set("intl.error_level", E_WARNING); + +$fmt1 = new IntlDateFormatter('en_US', + IntlDateFormatter::FULL, + IntlDateFormatter::FULL, + 'GMT+05:12', + IntlDateFormatter::TRADITIONAL); +$fmt2 = new IntlDateFormatter('en_US', + IntlDateFormatter::FULL, + IntlDateFormatter::FULL, + 'GMT+05:12', + IntlDateFormatter::GREGORIAN); +$fmt3 = new IntlDateFormatter('en_US@calendar=hebrew', + IntlDateFormatter::FULL, + IntlDateFormatter::FULL, + 'GMT+05:12', + IntlDateFormatter::TRADITIONAL); +var_dump($fmt1->format(strtotime('2012-01-01 00:00:00 +0000'))); +var_dump($fmt2->format(strtotime('2012-01-01 00:00:00 +0000'))); +var_dump($fmt3->format(strtotime('2012-01-01 00:00:00 +0000'))); + +new IntlDateFormatter('en_US@calendar=hebrew', + IntlDateFormatter::FULL, + IntlDateFormatter::FULL, + 'GMT+05:12', + -1); +?> +==DONE== +--EXPECTF-- +string(44) "Sunday, January 1, 2012 5:12:00 AM GMT+05:12" +string(44) "Sunday, January 1, 2012 5:12:00 AM GMT+05:12" +string(42) "Sunday, Tevet 6, 5772 5:12:00 AM GMT+05:12" + +Warning: IntlDateFormatter::__construct(): datefmt_create: invalid value for calendar type; it must be one of IntlDateFormatter::TRADITIONAL (locale's default calendar) or IntlDateFormatter::GREGORIAN in %s on line %d +==DONE== |