diff options
author | Stanislav Malyshev <stas@php.net> | 2016-05-22 17:49:02 -0700 |
---|---|---|
committer | Stanislav Malyshev <stas@php.net> | 2016-05-22 17:49:02 -0700 |
commit | 97eff7eb57fc2320c267a949cffd622c38712484 (patch) | |
tree | f3eb06fd5cb2974fbd2082a6500e7b739be72eaa /ext/intl/locale | |
parent | 0da8b8b801f9276359262f1ef8274c7812d3dfda (diff) | |
download | php-git-97eff7eb57fc2320c267a949cffd622c38712484.tar.gz |
Fix bug #72241: get_icu_value_internal out-of-bounds read
Diffstat (limited to 'ext/intl/locale')
-rw-r--r-- | ext/intl/locale/locale_methods.c | 235 |
1 files changed, 118 insertions, 117 deletions
diff --git a/ext/intl/locale/locale_methods.c b/ext/intl/locale/locale_methods.c index c8159bcd5a..31f60b39a4 100644 --- a/ext/intl/locale/locale_methods.c +++ b/ext/intl/locale/locale_methods.c @@ -65,26 +65,26 @@ ZEND_EXTERN_MODULE_GLOBALS( intl ) */ static const char * const LOC_GRANDFATHERED[] = { "art-lojban", "i-klingon", "i-lux", "i-navajo", "no-bok", "no-nyn", - "cel-gaulish", "en-GB-oed", "i-ami", - "i-bnn", "i-default", "i-enochian", - "i-mingo", "i-pwn", "i-tao", + "cel-gaulish", "en-GB-oed", "i-ami", + "i-bnn", "i-default", "i-enochian", + "i-mingo", "i-pwn", "i-tao", "i-tay", "i-tsu", "sgn-BE-fr", "sgn-BE-nl", "sgn-CH-de", "zh-cmn", "zh-cmn-Hans", "zh-cmn-Hant", "zh-gan" , "zh-guoyu", "zh-hakka", "zh-min", - "zh-min-nan", "zh-wuu", "zh-xiang", + "zh-min-nan", "zh-wuu", "zh-xiang", "zh-yue", NULL }; /* Based on IANA registry at the time of writing this code * This array lists the preferred values for the grandfathered tags if applicable -* This is in sync with the array LOC_GRANDFATHERED +* This is in sync with the array LOC_GRANDFATHERED * e.g. the offsets of the grandfathered tags match the offset of the preferred value */ static const int LOC_PREFERRED_GRANDFATHERED_LEN = 6; static const char * const LOC_PREFERRED_GRANDFATHERED[] = { "jbo", "tlh", "lb", - "nv", "nb", "nn", + "nv", "nb", "nn", NULL }; @@ -122,7 +122,7 @@ static int16_t findOffset(const char* const* list, const char* key) /*}}}*/ static char* getPreferredTag(const char* gf_tag) -{ +{ char* result = NULL; int grOffset = 0; @@ -141,15 +141,15 @@ static char* getPreferredTag(const char* gf_tag) } /* {{{ -* returns the position of next token for lookup +* returns the position of next token for lookup * or -1 if no token -* strtokr equivalent search for token in reverse direction +* strtokr equivalent search for token in reverse direction */ static int getStrrtokenPos(char* str, int savedPos) { int result =-1; int i; - + for(i=savedPos-1; i>=0; i--) { if(isIDSeparator(*(str+i)) ){ /* delimiter found; check for singleton */ @@ -171,7 +171,7 @@ static int getStrrtokenPos(char* str, int savedPos) /* }}} */ /* {{{ -* returns the position of a singleton if present +* returns the position of a singleton if present * returns -1 if no singleton * strtok equivalent search for singleton */ @@ -180,7 +180,7 @@ static int getSingletonPos(const char* str) int result =-1; int i=0; int len = 0; - + if( str && ((len=strlen(str))>0) ){ for( i=0; i<len ; i++){ if( isIDSeparator(*(str+i)) ){ @@ -198,7 +198,7 @@ static int getSingletonPos(const char* str) } } }/* end of for */ - + } return result; } @@ -224,7 +224,7 @@ PHP_NAMED_FUNCTION(zif_locale_get_default) PHP_NAMED_FUNCTION(zif_locale_set_default) { char* locale_name = NULL; - int len=0; + int len=0; if(zend_parse_parameters( ZEND_NUM_ARGS() TSRMLS_CC, "s", &locale_name ,&len ) == FAILURE) @@ -240,14 +240,14 @@ PHP_NAMED_FUNCTION(zif_locale_set_default) len = strlen(locale_name); } - zend_alter_ini_entry(LOCALE_INI_NAME, sizeof(LOCALE_INI_NAME), locale_name, len, PHP_INI_USER, PHP_INI_STAGE_RUNTIME); + zend_alter_ini_entry(LOCALE_INI_NAME, sizeof(LOCALE_INI_NAME), locale_name, len, PHP_INI_USER, PHP_INI_STAGE_RUNTIME); RETURN_TRUE; } /* }}} */ /* {{{ -* Gets the value from ICU +* Gets the value from ICU * common code shared by get_primary_language,get_script or get_region or get_variant * result = 0 if error, 1 if successful , -1 if no value */ @@ -284,7 +284,7 @@ static char* get_icu_value_internal( const char* loc_name , char* tag_name, int* } } - singletonPos = getSingletonPos( loc_name ); + singletonPos = getSingletonPos( loc_name ); if( singletonPos == 0){ /* singleton at start of script, region , variant etc. * or invalid singleton at start of language */ @@ -299,7 +299,7 @@ static char* get_icu_value_internal( const char* loc_name , char* tag_name, int* } /* end of if != LOC_CANONICAL_TAG */ if( mod_loc_name == NULL){ - mod_loc_name = estrdup(loc_name ); + mod_loc_name = estrdup(loc_name ); } /* Proceed to ICU */ @@ -326,6 +326,7 @@ static char* get_icu_value_internal( const char* loc_name , char* tag_name, int* if( U_FAILURE( status ) ) { if( status == U_BUFFER_OVERFLOW_ERROR ) { status = U_ZERO_ERROR; + buflen++; /* add space for \0 */ continue; } @@ -366,7 +367,7 @@ static char* get_icu_value_internal( const char* loc_name , char* tag_name, int* * Gets the value from ICU , called when PHP userspace function is called * common code shared by get_primary_language,get_script or get_region or get_variant */ -static void get_icu_value_src_php( char* tag_name, INTERNAL_FUNCTION_PARAMETERS) +static void get_icu_value_src_php( char* tag_name, INTERNAL_FUNCTION_PARAMETERS) { const char* loc_name = NULL; @@ -422,37 +423,37 @@ static void get_icu_value_src_php( char* tag_name, INTERNAL_FUNCTION_PARAMETERS) } /* }}} */ -/* {{{ proto static string Locale::getScript($locale) - * gets the script for the $locale +/* {{{ proto static string Locale::getScript($locale) + * gets the script for the $locale }}} */ -/* {{{ proto static string locale_get_script($locale) - * gets the script for the $locale +/* {{{ proto static string locale_get_script($locale) + * gets the script for the $locale */ -PHP_FUNCTION( locale_get_script ) +PHP_FUNCTION( locale_get_script ) { get_icu_value_src_php( LOC_SCRIPT_TAG , INTERNAL_FUNCTION_PARAM_PASSTHRU ); } /* }}} */ -/* {{{ proto static string Locale::getRegion($locale) - * gets the region for the $locale +/* {{{ proto static string Locale::getRegion($locale) + * gets the region for the $locale }}} */ -/* {{{ proto static string locale_get_region($locale) - * gets the region for the $locale +/* {{{ proto static string locale_get_region($locale) + * gets the region for the $locale */ -PHP_FUNCTION( locale_get_region ) +PHP_FUNCTION( locale_get_region ) { get_icu_value_src_php( LOC_REGION_TAG , INTERNAL_FUNCTION_PARAM_PASSTHRU ); } /* }}} */ -/* {{{ proto static string Locale::getPrimaryLanguage($locale) - * gets the primary language for the $locale +/* {{{ proto static string Locale::getPrimaryLanguage($locale) + * gets the primary language for the $locale }}} */ -/* {{{ proto static string locale_get_primary_language($locale) - * gets the primary language for the $locale +/* {{{ proto static string locale_get_primary_language($locale) + * gets the primary language for the $locale */ -PHP_FUNCTION(locale_get_primary_language ) +PHP_FUNCTION(locale_get_primary_language ) { get_icu_value_src_php( LOC_LANG_TAG , INTERNAL_FUNCTION_PARAM_PASSTHRU ); } @@ -460,9 +461,9 @@ PHP_FUNCTION(locale_get_primary_language ) /* {{{ - * common code shared by display_xyz functions to get the value from ICU + * common code shared by display_xyz functions to get the value from ICU }}} */ -static void get_icu_disp_value_src_php( char* tag_name, INTERNAL_FUNCTION_PARAMETERS) +static void get_icu_disp_value_src_php( char* tag_name, INTERNAL_FUNCTION_PARAMETERS) { const char* loc_name = NULL; int loc_name_len = 0; @@ -488,7 +489,7 @@ static void get_icu_disp_value_src_php( char* tag_name, INTERNAL_FUNCTION_PARAME intl_error_reset( NULL TSRMLS_CC ); if(zend_parse_parameters( ZEND_NUM_ARGS() TSRMLS_CC, "s|s", - &loc_name, &loc_name_len , + &loc_name, &loc_name_len , &disp_loc_name ,&disp_loc_name_len ) == FAILURE) { spprintf(&msg , 0, "locale_get_display_%s : unable to parse input params", tag_name ); @@ -525,7 +526,7 @@ static void get_icu_disp_value_src_php( char* tag_name, INTERNAL_FUNCTION_PARAME if( mod_loc_name==NULL ){ mod_loc_name = estrdup( loc_name ); } - + /* Check if disp_loc_name passed , if not use default locale */ if( !disp_loc_name){ disp_loc_name = estrdup(intl_locale_get_default(TSRMLS_C)); @@ -604,7 +605,7 @@ static void get_icu_disp_value_src_php( char* tag_name, INTERNAL_FUNCTION_PARAME /* {{{ proto static string get_display_name($locale[, $in_locale = null]) * gets the name for the $locale in $in_locale or default_locale */ -PHP_FUNCTION(locale_get_display_name) +PHP_FUNCTION(locale_get_display_name) { get_icu_disp_value_src_php( DISP_NAME , INTERNAL_FUNCTION_PARAM_PASSTHRU ); } @@ -616,7 +617,7 @@ PHP_FUNCTION(locale_get_display_name) /* {{{ proto static string get_display_language($locale[, $in_locale = null]) * gets the language for the $locale in $in_locale or default_locale */ -PHP_FUNCTION(locale_get_display_language) +PHP_FUNCTION(locale_get_display_language) { get_icu_disp_value_src_php( LOC_LANG_TAG , INTERNAL_FUNCTION_PARAM_PASSTHRU ); } @@ -628,7 +629,7 @@ PHP_FUNCTION(locale_get_display_language) /* {{{ proto static string get_display_script($locale, $in_locale = null) * gets the script for the $locale in $in_locale or default_locale */ -PHP_FUNCTION(locale_get_display_script) +PHP_FUNCTION(locale_get_display_script) { get_icu_disp_value_src_php( LOC_SCRIPT_TAG , INTERNAL_FUNCTION_PARAM_PASSTHRU ); } @@ -640,7 +641,7 @@ PHP_FUNCTION(locale_get_display_script) /* {{{ proto static string get_display_region($locale, $in_locale = null) * gets the region for the $locale in $in_locale or default_locale */ -PHP_FUNCTION(locale_get_display_region) +PHP_FUNCTION(locale_get_display_region) { get_icu_disp_value_src_php( LOC_REGION_TAG , INTERNAL_FUNCTION_PARAM_PASSTHRU ); } @@ -654,7 +655,7 @@ PHP_FUNCTION(locale_get_display_region) * proto static string get_display_variant($locale, $in_locale = null) * gets the variant for the $locale in $in_locale or default_locale */ -PHP_FUNCTION(locale_get_display_variant) +PHP_FUNCTION(locale_get_display_variant) { get_icu_disp_value_src_php( LOC_VARIANT_TAG , INTERNAL_FUNCTION_PARAM_PASSTHRU ); } @@ -667,7 +668,7 @@ PHP_FUNCTION(locale_get_display_variant) /* {{{ proto static array locale_get_keywords(string $locale) { * return an associative array containing keyword-value * pairs for this locale. The keys are keys to the array (doh!) - */ + */ PHP_FUNCTION( locale_get_keywords ) { UEnumeration* e = NULL; @@ -679,10 +680,10 @@ PHP_FUNCTION( locale_get_keywords ) const char* loc_name = NULL; int loc_name_len = 0; -/* - ICU expects the buffer to be allocated before calling the function - and so the buffer size has been explicitly specified - ICU uloc.h #define ULOC_KEYWORD_AND_VALUES_CAPACITY 100 +/* + ICU expects the buffer to be allocated before calling the function + and so the buffer size has been explicitly specified + ICU uloc.h #define ULOC_KEYWORD_AND_VALUES_CAPACITY 100 hence the kw_value buffer size is 100 */ char* kw_value = NULL; @@ -721,7 +722,7 @@ PHP_FUNCTION( locale_get_keywords ) kw_value_len=uloc_getKeywordValue( loc_name,kw_key, kw_value, kw_value_len+1 , &status ); } else if(!U_FAILURE(status)) { kw_value = erealloc( kw_value , kw_value_len+1); - } + } if (U_FAILURE(status)) { intl_error_set( NULL, U_ILLEGAL_ARGUMENT_ERROR, "locale_get_keywords: Error encountered while getting the keyword value for the keyword", 0 TSRMLS_CC ); if( kw_value){ @@ -740,10 +741,10 @@ PHP_FUNCTION( locale_get_keywords ) } /* }}} */ - /* {{{ proto static string Locale::canonicalize($locale) - * @return string the canonicalized locale + /* {{{ proto static string Locale::canonicalize($locale) + * @return string the canonicalized locale * }}} */ - /* {{{ proto static string locale_canonicalize(Locale $loc, string $locale) + /* {{{ proto static string locale_canonicalize(Locale $loc, string $locale) * @param string $locale The locale string to canonicalize */ PHP_FUNCTION(locale_canonicalize) @@ -752,10 +753,10 @@ PHP_FUNCTION(locale_canonicalize) } /* }}} */ -/* {{{ append_key_value +/* {{{ append_key_value * Internal function which is called from locale_compose * gets the value for the key_name and appends to the loc_name -* returns 1 if successful , -1 if not found , +* returns 1 if successful , -1 if not found , * 0 if array element is not a string , -2 if buffer-overflow */ static int append_key_value(smart_str* loc_name, HashTable* hash_arr, char* key_name) @@ -767,7 +768,7 @@ static int append_key_value(smart_str* loc_name, HashTable* hash_arr, char* key_ /* element value is not a string */ return FAILURE; } - if(strcmp(key_name, LOC_LANG_TAG) != 0 && + if(strcmp(key_name, LOC_LANG_TAG) != 0 && strcmp(key_name, LOC_GRANDFATHERED_LANG_TAG)!=0 ) { /* not lang or grandfathered tag */ smart_str_appendl(loc_name, SEPARATOR , sizeof(SEPARATOR)-1); @@ -792,11 +793,11 @@ static void add_prefix(smart_str* loc_name, char* key_name) } /* }}} */ -/* {{{ append_multiple_key_values +/* {{{ append_multiple_key_values * Internal function which is called from locale_compose * gets the multiple values for the key_name and appends to the loc_name -* used for 'variant','extlang','private' -* returns 1 if successful , -1 if not found , +* used for 'variant','extlang','private' +* returns 1 if successful , -1 if not found , * 0 if array element is not a string , -2 if buffer-overflow */ static int append_multiple_key_values(smart_str* loc_name, HashTable* hash_arr, char* key_name TSRMLS_DC) @@ -850,8 +851,8 @@ static int append_multiple_key_values(smart_str* loc_name, HashTable* hash_arr, /* Multiple variant values as variant0, variant1 ,variant2 */ isFirstSubtag = 0; - for( i=0 ; i< max_value; i++ ){ - snprintf( cur_key_name , 30, "%s%d", key_name , i); + for( i=0 ; i< max_value; i++ ){ + snprintf( cur_key_name , 30, "%s%d", key_name , i); if( zend_hash_find( hash_arr , cur_key_name , strlen(cur_key_name) + 1,(void **)&ele_value ) == SUCCESS ){ if( Z_TYPE_PP(ele_value)!= IS_STRING ){ /* variant is not a string */ @@ -873,7 +874,7 @@ static int append_multiple_key_values(smart_str* loc_name, HashTable* hash_arr, /*{{{ * If applicable sets error message and aborts locale_compose gracefully -* returns 0 if locale_compose needs to be aborted +* returns 0 if locale_compose needs to be aborted * otherwise returns 1 */ static int handleAppendResult( int result, smart_str* loc_name TSRMLS_DC) @@ -890,11 +891,11 @@ static int handleAppendResult( int result, smart_str* loc_name TSRMLS_DC) /* }}} */ #define RETURN_SMART_STR(s) smart_str_0((s)); RETURN_STRINGL((s)->c, (s)->len, 0) -/* {{{ proto static string Locale::composeLocale($array) -* Creates a locale by combining the parts of locale-ID passed +/* {{{ proto static string Locale::composeLocale($array) +* Creates a locale by combining the parts of locale-ID passed * }}} */ -/* {{{ proto static string compose_locale($array) -* Creates a locale by combining the parts of locale-ID passed +/* {{{ proto static string compose_locale($array) +* Creates a locale by combining the parts of locale-ID passed * }}} */ PHP_FUNCTION(locale_compose) { @@ -920,7 +921,7 @@ PHP_FUNCTION(locale_compose) RETURN_FALSE; /* Check for grandfathered first */ - result = append_key_value(loc_name, hash_arr, LOC_GRANDFATHERED_LANG_TAG); + result = append_key_value(loc_name, hash_arr, LOC_GRANDFATHERED_LANG_TAG); if( result == SUCCESS){ RETURN_SMART_STR(loc_name); } @@ -929,7 +930,7 @@ PHP_FUNCTION(locale_compose) } /* Not grandfathered */ - result = append_key_value(loc_name, hash_arr , LOC_LANG_TAG); + result = append_key_value(loc_name, hash_arr , LOC_LANG_TAG); if( result == LOC_NOT_FOUND ){ intl_error_set( NULL, U_ILLEGAL_ARGUMENT_ERROR, "locale_compose: parameter array does not contain 'language' tag.", 0 TSRMLS_CC ); @@ -947,11 +948,11 @@ PHP_FUNCTION(locale_compose) } /* Script */ - result = append_key_value(loc_name, hash_arr , LOC_SCRIPT_TAG); + result = append_key_value(loc_name, hash_arr , LOC_SCRIPT_TAG); if( !handleAppendResult( result, loc_name TSRMLS_CC)){ RETURN_FALSE; } - + /* Region */ result = append_key_value( loc_name, hash_arr , LOC_REGION_TAG); if( !handleAppendResult( result, loc_name TSRMLS_CC)){ @@ -959,7 +960,7 @@ PHP_FUNCTION(locale_compose) } /* Variant */ - result = append_multiple_key_values( loc_name, hash_arr , LOC_VARIANT_TAG TSRMLS_CC); + result = append_multiple_key_values( loc_name, hash_arr , LOC_VARIANT_TAG TSRMLS_CC); if( !handleAppendResult( result, loc_name TSRMLS_CC)){ RETURN_FALSE; } @@ -985,16 +986,16 @@ static char* get_private_subtags(const char* loc_name) { char* result =NULL; int singletonPos = 0; - int len =0; + int len =0; const char* mod_loc_name =NULL; if( loc_name && (len = strlen(loc_name)>0 ) ){ - mod_loc_name = loc_name ; + mod_loc_name = loc_name ; len = strlen(mod_loc_name); while( (singletonPos = getSingletonPos(mod_loc_name))!= -1){ - if( singletonPos!=-1){ - if( (*(mod_loc_name+singletonPos)=='x') || (*(mod_loc_name+singletonPos)=='X') ){ + if( singletonPos!=-1){ + if( (*(mod_loc_name+singletonPos)=='x') || (*(mod_loc_name+singletonPos)=='X') ){ /* private subtag start found */ if( singletonPos + 2 == len){ /* loc_name ends with '-x-' ; return NULL */ @@ -1019,7 +1020,7 @@ static char* get_private_subtags(const char* loc_name) } /* end of while */ } - + return result; } /* }}} */ @@ -1044,20 +1045,20 @@ static int add_array_entry(const char* loc_name, zval* hash_arr, char* key_name } else { key_value = get_icu_value_internal( loc_name , key_name , &result,1 ); } - if( (strcmp(key_name , LOC_PRIVATE_TAG)==0) || + if( (strcmp(key_name , LOC_PRIVATE_TAG)==0) || ( strcmp(key_name , LOC_VARIANT_TAG)==0) ){ if( result > 0 && key_value){ /* Tokenize on the "_" or "-" */ - token = php_strtok_r( key_value , DELIMITER ,&last_ptr); + token = php_strtok_r( key_value , DELIMITER ,&last_ptr); if( cur_key_name ){ efree( cur_key_name); } cur_key_name = (char*)ecalloc( 25, 25); - sprintf( cur_key_name , "%s%d", key_name , cnt++); + sprintf( cur_key_name , "%s%d", key_name , cnt++); add_assoc_string( hash_arr, cur_key_name , token ,TRUE ); /* tokenize on the "_" or "-" and stop at singleton if any */ while( (token = php_strtok_r(NULL , DELIMITER , &last_ptr)) && (strlen(token)>1) ){ - sprintf( cur_key_name , "%s%d", key_name , cnt++); + sprintf( cur_key_name , "%s%d", key_name , cnt++); add_assoc_string( hash_arr, cur_key_name , token , TRUE ); } /* @@ -1077,16 +1078,16 @@ static int add_array_entry(const char* loc_name, zval* hash_arr, char* key_name } /*if( key_name != LOC_PRIVATE_TAG && key_value){*/ if( key_value){ - efree(key_value); + efree(key_value); } return cur_result; } /* }}} */ -/* {{{ proto static array Locale::parseLocale($locale) +/* {{{ proto static array Locale::parseLocale($locale) * parses a locale-id into an array the different parts of it }}} */ -/* {{{ proto static array parse_locale($locale) +/* {{{ proto static array parse_locale($locale) * parses a locale-id into an array the different parts of it */ PHP_FUNCTION(locale_parse) @@ -1144,7 +1145,7 @@ PHP_FUNCTION(locale_get_all_variants) char* saved_ptr = NULL; intl_error_reset( NULL TSRMLS_CC ); - + if(zend_parse_parameters( ZEND_NUM_ARGS() TSRMLS_CC, "s", &loc_name, &loc_name_len ) == FAILURE) { @@ -1162,15 +1163,15 @@ PHP_FUNCTION(locale_get_all_variants) array_init( return_value ); /* If the locale is grandfathered, stop, no variants */ - if( findOffset( LOC_GRANDFATHERED , loc_name ) >= 0 ){ + if( findOffset( LOC_GRANDFATHERED , loc_name ) >= 0 ){ /* ("Grandfathered Tag. No variants."); */ } - else { + else { /* Call ICU variant */ variant = get_icu_value_internal( loc_name , LOC_VARIANT_TAG , &result ,0); if( result > 0 && variant){ /* Tokenize on the "_" or "-" */ - token = php_strtok_r( variant , DELIMITER , &saved_ptr); + token = php_strtok_r( variant , DELIMITER , &saved_ptr); add_next_index_stringl( return_value, token , strlen(token) ,TRUE ); /* tokenize on the "_" or "-" and stop at singleton if any */ while( (token = php_strtok_r(NULL , DELIMITER, &saved_ptr)) && (strlen(token)>1) ){ @@ -1181,7 +1182,7 @@ PHP_FUNCTION(locale_get_all_variants) efree( variant ); } } - + } /* }}} */ @@ -1220,11 +1221,11 @@ static int strToMatch(const char* str ,char *retstr) /* }}} */ /* {{{ proto static boolean Locale::filterMatches(string $langtag, string $locale[, bool $canonicalize]) -* Checks if a $langtag filter matches with $locale according to RFC 4647's basic filtering algorithm +* Checks if a $langtag filter matches with $locale according to RFC 4647's basic filtering algorithm */ /* }}} */ /* {{{ proto boolean locale_filter_matches(string $langtag, string $locale[, bool $canonicalize]) -* Checks if a $langtag filter matches with $locale according to RFC 4647's basic filtering algorithm +* Checks if a $langtag filter matches with $locale according to RFC 4647's basic filtering algorithm */ PHP_FUNCTION(locale_filter_matches) { @@ -1243,13 +1244,13 @@ PHP_FUNCTION(locale_filter_matches) char* cur_lang_tag = NULL; char* cur_loc_range = NULL; - zend_bool boolCanonical = 0; + zend_bool boolCanonical = 0; UErrorCode status = U_ZERO_ERROR; intl_error_reset( NULL TSRMLS_CC ); - + if(zend_parse_parameters( ZEND_NUM_ARGS() TSRMLS_CC, "ss|b", - &lang_tag, &lang_tag_len , &loc_range , &loc_range_len , + &lang_tag, &lang_tag_len , &loc_range , &loc_range_len , &boolCanonical) == FAILURE) { intl_error_set( NULL, U_ILLEGAL_ARGUMENT_ERROR, @@ -1270,7 +1271,7 @@ PHP_FUNCTION(locale_filter_matches) /* canonicalize loc_range */ can_loc_range=get_icu_value_internal( loc_range , LOC_CANONICALIZE_TAG , &result , 0); if( result ==0) { - intl_error_set( NULL, status, + intl_error_set( NULL, status, "locale_filter_matches : unable to canonicalize loc_range" , 0 TSRMLS_CC ); RETURN_FALSE; } @@ -1278,7 +1279,7 @@ PHP_FUNCTION(locale_filter_matches) /* canonicalize lang_tag */ can_lang_tag = get_icu_value_internal( lang_tag , LOC_CANONICALIZE_TAG , &result , 0); if( result ==0) { - intl_error_set( NULL, status, + intl_error_set( NULL, status, "locale_filter_matches : unable to canonicalize lang_tag" , 0 TSRMLS_CC ); RETURN_FALSE; } @@ -1306,11 +1307,11 @@ PHP_FUNCTION(locale_filter_matches) /* check if prefix */ token = strstr( cur_lang_tag , cur_loc_range ); - + if( token && (token==cur_lang_tag) ){ /* check if the char. after match is SEPARATOR */ chrcheck = token + (strlen(cur_loc_range)); - if( isIDSeparator(*chrcheck) || isEndOfTag(*chrcheck) ){ + if( isIDSeparator(*chrcheck) || isEndOfTag(*chrcheck) ){ if( cur_lang_tag){ efree( cur_lang_tag ); } @@ -1346,7 +1347,7 @@ PHP_FUNCTION(locale_filter_matches) else{ /* Convert to lower case for case-insensitive comparison */ cur_lang_tag = ecalloc( 1, strlen(lang_tag ) + 1); - + result = strToMatch( lang_tag , cur_lang_tag); if( result == 0) { efree( cur_lang_tag ); @@ -1362,11 +1363,11 @@ PHP_FUNCTION(locale_filter_matches) /* check if prefix */ token = strstr( cur_lang_tag , cur_loc_range ); - + if( token && (token==cur_lang_tag) ){ /* check if the char. after match is SEPARATOR */ chrcheck = token + (strlen(cur_loc_range)); - if( isIDSeparator(*chrcheck) || isEndOfTag(*chrcheck) ){ + if( isIDSeparator(*chrcheck) || isEndOfTag(*chrcheck) ){ if( cur_lang_tag){ efree( cur_lang_tag ); } @@ -1393,7 +1394,7 @@ PHP_FUNCTION(locale_filter_matches) static void array_cleanup( char* arr[] , int arr_size) { int i=0; - for( i=0; i< arr_size; i++ ){ + for( i=0; i< arr_size; i++ ){ if( arr[i*2] ){ efree( arr[i*2]); } @@ -1403,7 +1404,7 @@ static void array_cleanup( char* arr[] , int arr_size) #define LOOKUP_CLEAN_RETURN(value) array_cleanup(cur_arr, cur_arr_len); return (value) /* {{{ -* returns the lookup result to lookup_loc_range_src_php +* returns the lookup result to lookup_loc_range_src_php * internal function */ static char* lookup_loc_range(const char* loc_range, HashTable* hash_arr, int canonicalize TSRMLS_DC) @@ -1427,7 +1428,7 @@ static char* lookup_loc_range(const char* loc_range, HashTable* hash_arr, int ca for(zend_hash_internal_pointer_reset(hash_arr); zend_hash_has_more_elements(hash_arr) == SUCCESS; zend_hash_move_forward(hash_arr)) { - + if (zend_hash_get_current_data(hash_arr, (void**)&ele_value) == FAILURE) { /* Should never actually fail since the key is known to exist.*/ continue; @@ -1436,7 +1437,7 @@ static char* lookup_loc_range(const char* loc_range, HashTable* hash_arr, int ca /* element value is not a string */ intl_error_set(NULL, U_ILLEGAL_ARGUMENT_ERROR, "lookup_loc_range: locale array element is not a string", 0 TSRMLS_CC); LOOKUP_CLEAN_RETURN(NULL); - } + } cur_arr[cur_arr_len*2] = estrndup(Z_STRVAL_PP(ele_value), Z_STRLEN_PP(ele_value)); result = strToMatch(Z_STRVAL_PP(ele_value), cur_arr[cur_arr_len*2]); if(result == 0) { @@ -1444,12 +1445,12 @@ static char* lookup_loc_range(const char* loc_range, HashTable* hash_arr, int ca LOOKUP_CLEAN_RETURN(NULL); } cur_arr[cur_arr_len*2+1] = Z_STRVAL_PP(ele_value); - cur_arr_len++ ; + cur_arr_len++ ; } /* end of for */ /* Canonicalize array elements */ if(canonicalize) { - for(i=0; i<cur_arr_len; i++) { + for(i=0; i<cur_arr_len; i++) { lang_tag = get_icu_value_internal(cur_arr[i*2], LOC_CANONICALIZE_TAG, &result, 0); if(result != 1 || lang_tag == NULL || !lang_tag[0]) { if(lang_tag) { @@ -1459,7 +1460,7 @@ static char* lookup_loc_range(const char* loc_range, HashTable* hash_arr, int ca LOOKUP_CLEAN_RETURN(NULL); } cur_arr[i*2] = erealloc(cur_arr[i*2], strlen(lang_tag)+1); - result = strToMatch(lang_tag, cur_arr[i*2]); + result = strToMatch(lang_tag, cur_arr[i*2]); efree(lang_tag); if(result == 0) { intl_error_set(NULL, U_ILLEGAL_ARGUMENT_ERROR, "lookup_loc_range: unable to canonicalize lang_tag" , 0 TSRMLS_CC); @@ -1482,11 +1483,11 @@ static char* lookup_loc_range(const char* loc_range, HashTable* hash_arr, int ca } else { loc_range = can_loc_range; } - } + } cur_loc_range = ecalloc(1, strlen(loc_range)+1); /* convert to lower and replace hyphens */ - result = strToMatch(loc_range, cur_loc_range); + result = strToMatch(loc_range, cur_loc_range); if(can_loc_range) { efree(can_loc_range); } @@ -1498,8 +1499,8 @@ static char* lookup_loc_range(const char* loc_range, HashTable* hash_arr, int ca /* Lookup for the lang_tag match */ saved_pos = strlen(cur_loc_range); while(saved_pos > 0) { - for(i=0; i< cur_arr_len; i++){ - if(cur_arr[i*2] != NULL && strlen(cur_arr[i*2]) == saved_pos && strncmp(cur_loc_range, cur_arr[i*2], saved_pos) == 0) { + for(i=0; i< cur_arr_len; i++){ + if(cur_arr[i*2] != NULL && strlen(cur_arr[i*2]) == saved_pos && strncmp(cur_loc_range, cur_arr[i*2], saved_pos) == 0) { /* Match found */ return_value = estrdup(canonicalize?cur_arr[i*2]:cur_arr[i*2+1]); efree(cur_loc_range); @@ -1515,14 +1516,14 @@ static char* lookup_loc_range(const char* loc_range, HashTable* hash_arr, int ca } /* }}} */ -/* {{{ proto string Locale::lookup(array $langtag, string $locale[, bool $canonicalize[, string $default = null]]) +/* {{{ proto string Locale::lookup(array $langtag, string $locale[, bool $canonicalize[, string $default = null]]) * Searchs the items in $langtag for the best match to the language -* range +* range */ /* }}} */ /* {{{ proto string locale_lookup(array $langtag, string $locale[, bool $canonicalize[, string $default = null]]) * Searchs the items in $langtag for the best match to the language -* range +* range */ PHP_FUNCTION(locale_lookup) { @@ -1552,8 +1553,8 @@ PHP_FUNCTION(locale_lookup) if( !hash_arr || zend_hash_num_elements( hash_arr ) == 0 ) { RETURN_EMPTY_STRING(); - } - + } + result = lookup_loc_range(loc_range, hash_arr, boolCanonical TSRMLS_CC); if(result == NULL || result[0] == '\0') { if( fallback_loc ) { @@ -1590,10 +1591,10 @@ PHP_FUNCTION(locale_accept_from_http) "locale_accept_from_http: unable to parse input parameters", 0 TSRMLS_CC ); RETURN_FALSE; } - + available = ures_openAvailableLocales(NULL, &status); INTL_CHECK_STATUS(status, "locale_accept_from_http: failed to retrieve locale list"); - len = uloc_acceptLanguageFromHTTP(resultLocale, INTL_MAX_LOCALE_LEN, + len = uloc_acceptLanguageFromHTTP(resultLocale, INTL_MAX_LOCALE_LEN, &outResult, http_accept, available, &status); uenum_close(available); INTL_CHECK_STATUS(status, "locale_accept_from_http: failed to find acceptable locale"); |