]> granicus.if.org Git - php/commitdiff
Bug #73218: add mitigation for ICU int overflow
authorStanislav Malyshev <stas@php.net>
Wed, 5 Oct 2016 05:40:09 +0000 (22:40 -0700)
committerStanislav Malyshev <stas@php.net>
Wed, 5 Oct 2016 05:40:43 +0000 (22:40 -0700)
ext/intl/resourcebundle/resourcebundle_class.c

index dc1212431a9a4ed33ed4466c000619fe05599ae8..90aebd4a76479bc9cb292d6c48083a69f96ee76c 100644 (file)
@@ -77,7 +77,7 @@ static zend_object_value ResourceBundle_object_create( zend_class_entry *ce TSRM
 /* }}} */
 
 /* {{{ ResourceBundle_ctor */
-static void resourcebundle_ctor(INTERNAL_FUNCTION_PARAMETERS) 
+static void resourcebundle_ctor(INTERNAL_FUNCTION_PARAMETERS)
 {
        const char      *bundlename;
        int                     bundlename_len = 0;
@@ -90,7 +90,7 @@ static void resourcebundle_ctor(INTERNAL_FUNCTION_PARAMETERS)
 
        intl_error_reset( NULL TSRMLS_CC );
 
-       if( zend_parse_parameters( ZEND_NUM_ARGS() TSRMLS_CC, "s!s!|b", 
+       if( zend_parse_parameters( ZEND_NUM_ARGS() TSRMLS_CC, "s!s!|b",
                &locale, &locale_len, &bundlename, &bundlename_len, &fallback ) == FAILURE )
        {
                intl_error_set( NULL, U_ILLEGAL_ARGUMENT_ERROR,
@@ -100,11 +100,18 @@ static void resourcebundle_ctor(INTERNAL_FUNCTION_PARAMETERS)
        }
 
        INTL_CHECK_LOCALE_LEN_OBJ(locale_len, return_value);
-       
+
        if (locale == NULL) {
                locale = intl_locale_get_default(TSRMLS_C);
        }
 
+       if (bundlename_len >= MAXPATHLEN) {
+               intl_error_set( NULL, U_ILLEGAL_ARGUMENT_ERROR, "Bundle name too long", 0 TSRMLS_CC );
+               zval_dtor(return_value);
+               ZVAL_NULL(return_value);
+               RETURN_NULL();
+       }
+
        if (fallback) {
                rb->me = ures_open(bundlename, locale, &INTL_DATA_ERROR_CODE(rb));
        } else {
@@ -151,7 +158,7 @@ PHP_METHOD( ResourceBundle, __construct )
 /* {{{ proto ResourceBundle ResourceBundle::create( string $locale [, string $bundlename [, bool $fallback = true ]] )
 proto ResourceBundle resourcebundle_create( string $locale [, string $bundlename [, bool $fallback = true ]] )
 */
-PHP_FUNCTION( resourcebundle_create ) 
+PHP_FUNCTION( resourcebundle_create )
 {
        object_init_ex( return_value, ResourceBundle_ce_ptr );
        resourcebundle_ctor(INTERNAL_FUNCTION_PARAM_PASSTHRU);
@@ -159,7 +166,7 @@ PHP_FUNCTION( resourcebundle_create )
 /* }}} */
 
 /* {{{ resourcebundle_array_fetch */
-static void resourcebundle_array_fetch(zval *object, zval *offset, zval *return_value, int fallback TSRMLS_DC) 
+static void resourcebundle_array_fetch(zval *object, zval *offset, zval *return_value, int fallback TSRMLS_DC)
 {
        int32_t     meindex = 0;
        char *      mekey = NULL;
@@ -167,7 +174,7 @@ static void resourcebundle_array_fetch(zval *object, zval *offset, zval *return_
        char         *pbuf;
        ResourceBundle_object *rb;
 
-       intl_error_reset( NULL TSRMLS_CC );     
+       intl_error_reset( NULL TSRMLS_CC );
        RESOURCEBUNDLE_METHOD_FETCH_OBJECT;
 
        if(Z_TYPE_P(offset) == IS_LONG) {
@@ -178,12 +185,12 @@ static void resourcebundle_array_fetch(zval *object, zval *offset, zval *return_
                mekey = Z_STRVAL_P(offset);
                rb->child = ures_getByKey(rb->me, mekey, rb->child, &INTL_DATA_ERROR_CODE(rb) );
        } else {
-               intl_errors_set(INTL_DATA_ERROR_P(rb), U_ILLEGAL_ARGUMENT_ERROR,        
+               intl_errors_set(INTL_DATA_ERROR_P(rb), U_ILLEGAL_ARGUMENT_ERROR,
                        "resourcebundle_get: index should be integer or string", 0 TSRMLS_CC);
                RETURN_NULL();
        }
 
-       intl_error_set_code( NULL, INTL_DATA_ERROR_CODE(rb) TSRMLS_CC );        
+       intl_error_set_code( NULL, INTL_DATA_ERROR_CODE(rb) TSRMLS_CC );
        if (U_FAILURE(INTL_DATA_ERROR_CODE(rb))) {
                if (is_numeric) {
                        spprintf( &pbuf, 0, "Cannot load resource element %d", meindex );
@@ -213,7 +220,7 @@ static void resourcebundle_array_fetch(zval *object, zval *offset, zval *return_
 /* }}} */
 
 /* {{{ resourcebundle_array_get */
-zval *resourcebundle_array_get(zval *object, zval *offset, int type TSRMLS_DC) 
+zval *resourcebundle_array_get(zval *object, zval *offset, int type TSRMLS_DC)
 {
        zval *retval;
 
@@ -246,7 +253,7 @@ PHP_FUNCTION( resourcebundle_get )
        zval *      object;
 
        if (zend_parse_method_parameters(ZEND_NUM_ARGS() TSRMLS_CC, getThis(), "Oz|b",  &object, ResourceBundle_ce_ptr, &offset, &fallback ) == FAILURE) {
-               intl_error_set(NULL, U_ILLEGAL_ARGUMENT_ERROR,  
+               intl_error_set(NULL, U_ILLEGAL_ARGUMENT_ERROR,
                        "resourcebundle_get: unable to parse input params", 0 TSRMLS_CC);
                RETURN_FALSE;
        }
@@ -256,7 +263,7 @@ PHP_FUNCTION( resourcebundle_get )
 /* }}} */
 
 /* {{{ resourcebundle_array_count */
-int resourcebundle_array_count(zval *object, long *count TSRMLS_DC) 
+int resourcebundle_array_count(zval *object, long *count TSRMLS_DC)
 {
        ResourceBundle_object *rb;
        RESOURCEBUNDLE_METHOD_FETCH_OBJECT_NO_CHECK;
@@ -288,7 +295,7 @@ PHP_FUNCTION( resourcebundle_count )
        RESOURCEBUNDLE_METHOD_INIT_VARS;
 
        if( zend_parse_method_parameters( ZEND_NUM_ARGS() TSRMLS_CC, getThis(), "O", &object, ResourceBundle_ce_ptr ) == FAILURE ) {
-               intl_error_set(NULL, U_ILLEGAL_ARGUMENT_ERROR,  
+               intl_error_set(NULL, U_ILLEGAL_ARGUMENT_ERROR,
                        "resourcebundle_count: unable to parse input params", 0 TSRMLS_CC);
                RETURN_FALSE;
        }
@@ -322,21 +329,26 @@ PHP_FUNCTION( resourcebundle_locales )
 
        if( zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "s", &bundlename, &bundlename_len ) == FAILURE )
        {
-               intl_error_set(NULL, U_ILLEGAL_ARGUMENT_ERROR,  
+               intl_error_set(NULL, U_ILLEGAL_ARGUMENT_ERROR,
                        "resourcebundle_locales: unable to parse input params", 0 TSRMLS_CC);
                RETURN_FALSE;
        }
 
+       if (bundlename_len >= MAXPATHLEN) {
+               intl_error_set( NULL, U_ILLEGAL_ARGUMENT_ERROR, "resourcebundle_locales: bundle name too long", 0 TSRMLS_CC );
+               RETURN_FALSE;
+       }
+
        if(bundlename_len == 0) {
                // fetch default locales list
                bundlename = NULL;
        }
 
        icuenum = ures_openAvailableLocales( bundlename, &icuerror );
-       INTL_CHECK_STATUS(icuerror, "Cannot fetch locales list");               
+       INTL_CHECK_STATUS(icuerror, "Cannot fetch locales list");
 
        uenum_reset( icuenum, &icuerror );
-       INTL_CHECK_STATUS(icuerror, "Cannot iterate locales list");             
+       INTL_CHECK_STATUS(icuerror, "Cannot iterate locales list");
 
        array_init( return_value );
        while ((entry = uenum_next( icuenum, &entry_len, &icuerror ))) {