IntlDateFormatter constructor would release some resources
under certain error conditions.
This commit is contained in:
Gustavo André dos Santos Lopes 2012-05-23 15:48:50 +02:00
parent c449bf1443
commit e08566c613
3 changed files with 69 additions and 19 deletions

2
NEWS
View File

@ -18,6 +18,8 @@ PHP NEWS
. Fixed bug #62081 (IntlDateFormatter constructor leaks memory when called
twice). (Gustavo)
. Fixed bug #62070 (Collator::getSortKey() returns garbage). (Gustavo)
. Fixed bug #62017 (datefmt_create with incorrectly encoded timezone leaks
pattern). (Gustavo)
- XML Writer:
. Fixed bug #62064 (memory leak in the XML Writer module).

View File

@ -109,14 +109,27 @@ static void datefmt_ctor(INTERNAL_FUNCTION_PARAMETERS)
/* Convert pattern (if specified) to UTF-16. */
if( pattern_str && pattern_str_len>0 ){
intl_convert_utf8_to_utf16(&svalue, &slength, pattern_str, pattern_str_len, &INTL_DATA_ERROR_CODE(dfo));
INTL_CTOR_CHECK_STATUS(dfo, "datefmt_create: error converting pattern to UTF-16");
intl_convert_utf8_to_utf16(&svalue, &slength,
pattern_str, pattern_str_len, &INTL_DATA_ERROR_CODE(dfo));
if (U_FAILURE(INTL_DATA_ERROR_CODE(dfo))) {
/* object construction -> only set global error */
intl_error_set(NULL, INTL_DATA_ERROR_CODE(dfo), "datefmt_create: "
"error converting pattern to UTF-16", 0 TSRMLS_CC);
goto error;
}
}
/* resources allocated from now on */
/* Convert pattern (if specified) to UTF-16. */
if( timezone_str && timezone_str_len >0 ){
intl_convert_utf8_to_utf16(&timezone_utf16, &timezone_utf16_len, timezone_str, timezone_str_len, &INTL_DATA_ERROR_CODE(dfo));
INTL_CTOR_CHECK_STATUS(dfo, "datefmt_create: error converting timezone_str to UTF-16" );
intl_convert_utf8_to_utf16(&timezone_utf16, &timezone_utf16_len,
timezone_str, timezone_str_len, &INTL_DATA_ERROR_CODE(dfo));
if (U_FAILURE(INTL_DATA_ERROR_CODE(dfo))) {
intl_error_set(NULL, INTL_DATA_ERROR_CODE(dfo), "datefmt_create: "
"error converting timezone_str to UTF-16", 0 TSRMLS_CC);
goto error;
}
}
if(locale_len == 0) {
@ -130,23 +143,23 @@ static void datefmt_ctor(INTERNAL_FUNCTION_PARAMETERS)
}
/* Set the calendar if passed */
if(!U_FAILURE(INTL_DATA_ERROR_CODE(dfo)) && calendar) {
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 );
if(!U_FAILURE(INTL_DATA_ERROR_CODE(dfo))) {
if (calendar) {
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 );
} else {
intl_error_set(NULL, INTL_DATA_ERROR_CODE(dfo), "datefmt_create"
": error opening calendar", 0 TSRMLS_CC);
goto error;
}
}
}
if(svalue)
{
efree(svalue);
} else {
intl_error_set(NULL, INTL_DATA_ERROR_CODE(dfo), "datefmt_create: date "
"formatter creation failed", 0 TSRMLS_CC);
goto error;
}
if(timezone_utf16)
{
efree(timezone_utf16);
}
INTL_CTOR_CHECK_STATUS(dfo, "datefmt_create: date formatter creation failed");
/* Set the class variables */
dfo->date_type = date_type;
@ -155,6 +168,19 @@ static void datefmt_ctor(INTERNAL_FUNCTION_PARAMETERS)
if( timezone_str && timezone_str_len > 0){
dfo->timezone_id = estrndup( timezone_str, timezone_str_len);
}
error:
if (svalue) {
efree(svalue);
}
if (timezone_utf16) {
efree(timezone_utf16);
}
if (U_FAILURE(intl_error_get_code(NULL TSRMLS_CC))) {
/* free_object handles partially constructed instances fine */
zval_dtor(return_value);
RETVAL_NULL();
}
}
/* }}} */

View File

@ -0,0 +1,22 @@
--TEST--
Bug #62017: datefmt_create with incorrectly encoded timezone leaks pattern
--SKIPIF--
<?php
if (!extension_loaded('intl'))
die('skip intl extension not enabled');
--FILE--
<?php
ini_set('intl.error_level', E_WARNING);
var_dump(
datefmt_create('', IntlDateFormatter::NONE, IntlDateFormatter::NONE, "\xFF",
IntlDateFormatter::GREGORIAN, 'a'));
var_dump(
new IntlDateFormatter('', IntlDateFormatter::NONE, IntlDateFormatter::NONE, "Europe/Lisbon",
IntlDateFormatter::GREGORIAN, "\x80"));
--EXPECTF--
Warning: datefmt_create(): datefmt_create: error converting timezone_str to UTF-16 in %s on line %d
NULL
Warning: IntlDateFormatter::__construct(): datefmt_create: error converting pattern to UTF-16 in %s on line %d
NULL