Commit:    e08566c6139461db9dbf0f6c2e870d67923ee587
Author:    Gustavo André dos Santos Lopes <cataphr...@php.net>         Wed, 23 
May 2012 15:48:50 +0200
Parents:   c449bf144373bb8ba1453f8c44801d2738c09d15
Branches:  PHP-5.3 PHP-5.4 master

Link:       
http://git.php.net/?p=php-src.git;a=commitdiff;h=e08566c6139461db9dbf0f6c2e870d67923ee587

Log:
Fixed bug #62017

IntlDateFormatter constructor would release some resources
under certain error conditions.

Bugs:
https://bugs.php.net/62017

Changed paths:
  M  NEWS
  M  ext/intl/dateformat/dateformat.c
  A  ext/intl/tests/bug62017.phpt


Diff:
diff --git a/NEWS b/NEWS
index 900dd5c..35f0d6b 100644
--- a/NEWS
+++ b/NEWS
@@ -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). 
diff --git a/ext/intl/dateformat/dateformat.c b/ext/intl/dateformat/dateformat.c
index 05ba19e..6c0c522 100755
--- a/ext/intl/dateformat/dateformat.c
+++ b/ext/intl/dateformat/dateformat.c
@@ -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,24 +143,24 @@ 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);
-       }
-       if(timezone_utf16)
-       {
-               efree(timezone_utf16);
+    } else {
+               intl_error_set(NULL, INTL_DATA_ERROR_CODE(dfo), 
"datefmt_create: date "
+                               "formatter creation failed", 0 TSRMLS_CC);
+               goto error;
        }
 
-       INTL_CTOR_CHECK_STATUS(dfo, "datefmt_create: date formatter creation 
failed");
-
        /* Set the class variables */
        dfo->date_type = date_type;
        dfo->time_type = time_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();
+       }
 }
 /* }}} */
 
diff --git a/ext/intl/tests/bug62017.phpt b/ext/intl/tests/bug62017.phpt
new file mode 100644
index 0000000..13c4fe5
--- /dev/null
+++ b/ext/intl/tests/bug62017.phpt
@@ -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
+


--
PHP CVS Mailing List (http://www.php.net/)
To unsubscribe, visit: http://www.php.net/unsub.php

Reply via email to