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.
This commit is contained in:
Gustavo André dos Santos Lopes 2012-05-24 10:44:44 +02:00
parent e08566c613
commit 2da2de46a8
2 changed files with 58 additions and 4 deletions

View File

@ -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);

View File

@ -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==