From 1bf49ee7d5186a0c68e23c562d59fc8c746393ad Mon Sep 17 00:00:00 2001 From: David Carlier Date: Wed, 12 Mar 2025 20:07:34 +0000 Subject: [PATCH] ext/intl: fix locale_compose/locale_lookup to be able to deal with references. --- NEWS | 4 +++ ext/intl/locale/locale_methods.c | 8 +++-- .../locale_compose_lookup_references.phpt | 29 +++++++++++++++++++ 3 files changed, 38 insertions(+), 3 deletions(-) create mode 100644 ext/intl/tests/locale_compose_lookup_references.phpt diff --git a/NEWS b/NEWS index e899b8ac86ce..39ee4c46becd 100644 --- a/NEWS +++ b/NEWS @@ -9,6 +9,10 @@ PHP NEWS . Fixed bug GH-17984 (calls with arguments as array with references). (David Carlier) +- Intl: + . Fix locale_compose and locale_lookup to work with their array argument + with values as references. (David Carlier) + - Embed: . Fixed bug GH-8533 (Unable to link dynamic libphp on Mac). (Kévin Dunglas) diff --git a/ext/intl/locale/locale_methods.c b/ext/intl/locale/locale_methods.c index d6053b6be56d..f810a61b6be1 100644 --- a/ext/intl/locale/locale_methods.c +++ b/ext/intl/locale/locale_methods.c @@ -814,7 +814,7 @@ static int append_key_value(smart_str* loc_name, HashTable* hash_arr, char* key_ { zval *ele_value; - if ((ele_value = zend_hash_str_find(hash_arr , key_name, strlen(key_name))) != NULL ) { + if ((ele_value = zend_hash_str_find_deref(hash_arr , key_name, strlen(key_name))) != NULL ) { if(Z_TYPE_P(ele_value)!= IS_STRING ){ /* element value is not a string */ return FAILURE; @@ -857,7 +857,7 @@ static int append_multiple_key_values(smart_str* loc_name, HashTable* hash_arr, int isFirstSubtag = 0; /* Variant/ Extlang/Private etc. */ - if ((ele_value = zend_hash_str_find( hash_arr , key_name , strlen(key_name))) != NULL) { + if ((ele_value = zend_hash_str_find_deref( hash_arr , key_name , strlen(key_name))) != NULL) { if( Z_TYPE_P(ele_value) == IS_STRING ){ add_prefix( loc_name , key_name); @@ -869,6 +869,7 @@ static int append_multiple_key_values(smart_str* loc_name, HashTable* hash_arr, zval *data; ZEND_HASH_FOREACH_VAL(arr, data) { + ZVAL_DEREF(data); if(Z_TYPE_P(data) != IS_STRING) { return FAILURE; } @@ -900,7 +901,7 @@ static int append_multiple_key_values(smart_str* loc_name, HashTable* hash_arr, isFirstSubtag = 0; for( i=0 ; i< max_value; i++ ){ snprintf( cur_key_name , 30, "%s%d", key_name , i); - if ((ele_value = zend_hash_str_find( hash_arr , cur_key_name , strlen(cur_key_name))) != NULL) { + if ((ele_value = zend_hash_str_find_deref( hash_arr , cur_key_name , strlen(cur_key_name))) != NULL) { if( Z_TYPE_P(ele_value)!= IS_STRING ){ /* variant is not a string */ return FAILURE; @@ -1437,6 +1438,7 @@ static zend_string* lookup_loc_range(const char* loc_range, HashTable* hash_arr, char **cur_arr = ecalloc(zend_hash_num_elements(hash_arr)*2, sizeof(char *)); ZEND_HASH_FOREACH_VAL(hash_arr, ele_value) { + ZVAL_DEREF(ele_value); /* convert the array to lowercase , also replace hyphens with the underscore and store it in cur_arr */ if(Z_TYPE_P(ele_value)!= IS_STRING) { /* element value is not a string */ diff --git a/ext/intl/tests/locale_compose_lookup_references.phpt b/ext/intl/tests/locale_compose_lookup_references.phpt new file mode 100644 index 000000000000..f6a202f7512f --- /dev/null +++ b/ext/intl/tests/locale_compose_lookup_references.phpt @@ -0,0 +1,29 @@ +--TEST-- +locale_compose()/locale_lookup() with values as references. +--EXTENSIONS-- +intl +--FILE-- + 'en', Locale::REGION_TAG => &$en]; + +var_dump(locale_compose($data)); + +$data = [ + 'language' => 'de', + 'script' => 'Hans', + 'region' => 'DE', + 'variant2' => 'fr', + 'variant1' => &$en, + 'private1' => 'private1', + 'private2' => 'private2', + ]; +var_dump(locale_compose($data)); +$data = ['de', &$en]; +var_dump(locale_lookup($data, "en", false, "en")); +?> +--EXPECT-- +string(5) "en_en" +string(36) "de_Hans_DE_en_fr_x_private1_private2" +string(2) "en"