Commit:    46629e35ffadae77114088c59faf301328159d83
Author:    Gustavo André dos Santos Lopes <cataphr...@php.net>         Mon, 2 
Jul 2012 00:26:38 +0200
Parents:   2416719fb184f84fcd521be2c8a5feabf65270e9
Branches:  master

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

Log:
Refactored internal_get_timestamp()

Added bounds checking for 32-bit ints.

Do not fetch array elements that ::parse() generates but that
::format() does not actually care about.y

Changed paths:
  M  ext/intl/dateformat/dateformat_format.c


Diff:
diff --git a/ext/intl/dateformat/dateformat_format.c 
b/ext/intl/dateformat/dateformat_format.c
index 65fe68e..468a3d7 100755
--- a/ext/intl/dateformat/dateformat_format.c
+++ b/ext/intl/dateformat/dateformat_format.c
@@ -59,20 +59,38 @@ static void internal_format(IntlDateFormatter_object *dfo, 
UDate timestamp, zval
 /* {{{ 
  * Internal function which fetches an element from the passed array for the 
key_name passed 
 */
-static double internal_get_arr_ele(IntlDateFormatter_object *dfo, HashTable* 
hash_arr, char* key_name TSRMLS_DC)
+static int32_t internal_get_arr_ele(IntlDateFormatter_object *dfo,
+               HashTable* hash_arr, char* key_name, intl_error *err TSRMLS_DC)
 {
-       zval**  ele_value       = NULL;
-       UDate result = -1;
-
-        if( zend_hash_find( hash_arr, key_name, strlen(key_name) + 1, (void 
**)&ele_value ) == SUCCESS ){
-                if( Z_TYPE_PP(ele_value)!= IS_LONG ){
-                       intl_error_set( NULL, U_ILLEGAL_ARGUMENT_ERROR,
-                               "datefmt_format: parameter array does not 
contain a long element.", 0 TSRMLS_CC );
-                }else{
-                       result =  Z_LVAL_PP(ele_value);
+       zval    **ele_value     = NULL;
+       int32_t result          = 0;
+       char    *message;
+
+       if (U_FAILURE(err->code)) {
+               return result;
+       }
+
+       if (zend_hash_find(hash_arr, key_name, strlen(key_name) + 1,
+                       (void **)&ele_value) == SUCCESS) {
+               if(Z_TYPE_PP(ele_value) != IS_LONG) {
+                       spprintf(&message, 0, "datefmt_format: parameter array 
contains "
+                                       "a non-integer element for key '%s'", 
key_name);
+                       intl_errors_set(err, U_ILLEGAL_ARGUMENT_ERROR, message, 
1 TSRMLS_CC);
+                       efree(message);
+               } else {
+                       if (Z_LVAL_PP(ele_value) > INT32_MAX ||
+                                       Z_LVAL_PP(ele_value) < INT32_MIN) {
+                               spprintf(&message, 0, "datefmt_format: value 
%ld is out of "
+                                               "bounds for a 32-bit integer in 
key '%s'",
+                                               Z_LVAL_PP(ele_value), key_name);
+                               intl_errors_set(err, U_ILLEGAL_ARGUMENT_ERROR, 
message, 1 TSRMLS_CC);
+                               efree(message);
+                       } else {
+                               result = Z_LVAL_PP(ele_value);
+                       }
                }
        }
-       /* printf("\n Inside internal_get_arr_ele key_name= %s, result = %g 
\n", key_name, result); */
+
        return result;
 }
 /* }}} */
@@ -80,41 +98,49 @@ static double internal_get_arr_ele(IntlDateFormatter_object 
*dfo, HashTable* has
 /* {{{ 
  * Internal function which sets UCalendar  from the passed array and retrieves 
timestamp
 */
-static UDate internal_get_timestamp(IntlDateFormatter_object *dfo, HashTable* 
hash_arr  TSRMLS_DC)
+static UDate internal_get_timestamp(IntlDateFormatter_object *dfo,
+               HashTable *hash_arr TSRMLS_DC)
 {
-       long year =0;
-       long month =0;
-       long hour =0;
-       long minute =0;
-       long second =0;
-       long wday =0;
-       long yday =0;
-       long mday =0;
-       UBool isInDST = FALSE;
-       const UCalendar *pcal;
+       int32_t         year,
+                               month,
+                               hour,
+                               minute,
+                               second,
+                               mday;
+       UCalendar       *pcal;
+       intl_error      *err = &dfo->datef_data.error;
+
+#define INTL_GET_ELEM(elem) \
+       internal_get_arr_ele(dfo, hash_arr, (elem), err TSRMLS_CC)
 
        /* Fetch  values from the incoming array */
-       year = internal_get_arr_ele( dfo, hash_arr, CALENDAR_YEAR TSRMLS_CC) + 
1900; /* tm_year is years since 1900 */
+       year    = INTL_GET_ELEM(CALENDAR_YEAR) + 1900; /* tm_year is years 
since 1900 */
        /* Month in ICU and PHP starts from January =0 */
-       month = internal_get_arr_ele( dfo, hash_arr, CALENDAR_MON TSRMLS_CC);
-       hour = internal_get_arr_ele( dfo, hash_arr, CALENDAR_HOUR TSRMLS_CC);
-       minute = internal_get_arr_ele( dfo, hash_arr, CALENDAR_MIN TSRMLS_CC);
-       second = internal_get_arr_ele( dfo, hash_arr, CALENDAR_SEC TSRMLS_CC);
-       wday = internal_get_arr_ele( dfo, hash_arr, CALENDAR_WDAY TSRMLS_CC);
-       yday = internal_get_arr_ele( dfo, hash_arr, CALENDAR_YDAY TSRMLS_CC);
-       isInDST = internal_get_arr_ele( dfo, hash_arr, CALENDAR_ISDST 
TSRMLS_CC);
+       month   = INTL_GET_ELEM(CALENDAR_MON);
+       hour    = INTL_GET_ELEM(CALENDAR_HOUR);
+       minute  = INTL_GET_ELEM(CALENDAR_MIN);
+       second  = INTL_GET_ELEM(CALENDAR_SEC);
        /* For the ucal_setDateTime() function, this is the 'date'  value */
-       mday = internal_get_arr_ele( dfo, hash_arr, CALENDAR_MDAY TSRMLS_CC);
+       mday    = INTL_GET_ELEM(CALENDAR_MDAY);
 
-       pcal = udat_getCalendar(DATE_FORMAT_OBJECT(dfo));
-       /* set the incoming values for the calendar */
-       ucal_setDateTime( pcal, year, month, mday, hour, minute, second, 
&INTL_DATA_ERROR_CODE(dfo));
-       if( INTL_DATA_ERROR_CODE(dfo) != U_ZERO_ERROR){
+#undef INTL_GET_ELEM
+
+       pcal = ucal_clone(udat_getCalendar(DATE_FORMAT_OBJECT(dfo)),
+                       &INTL_DATA_ERROR_CODE(dfo));
+
+       if (INTL_DATA_ERROR_CODE(dfo) != U_ZERO_ERROR) {
+               intl_errors_set(err, INTL_DATA_ERROR_CODE(dfo), 
"datefmt_format: "
+                               "error cloning calendar", 0 TSRMLS_CC);
                return 0;
        }
+
+       /* set the incoming values for the calendar */
+       ucal_setDateTime(pcal, year, month, mday, hour, minute, second, 
&INTL_DATA_ERROR_CODE(dfo));
+       /* actually, ucal_setDateTime cannot fail */
        
        /* Fetch the timestamp from the UCalendar */
-       return ucal_getMillis(pcal, &INTL_DATA_ERROR_CODE(dfo) );
+       return ucal_getMillis(pcal, &INTL_DATA_ERROR_CODE(dfo));
+       udat_close(pcal);
 }


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

Reply via email to