From eaff91f5c617b7546cd93f6a5af7f3c9231e4228 Mon Sep 17 00:00:00 2001 From: "Christoph M. Becker" Date: Mon, 14 Jun 2021 18:11:10 +0200 Subject: [PATCH] Fix #54176: locale_compose accepts more than 3 extlang `locale_compose()` accepts at most 15 'variant' and 'private' subtags each, and at most 3 'extlang' subtags. This is currently only enforced if the subtags are given as specific key (e.g. 'variant0'); for consistency we enforce this for generic keys (e.g. 'variant'), too. --- ext/intl/locale/locale_methods.c | 15 +++++++++++++++ ext/intl/tests/locale/bug54176.phpt | 29 +++++++++++++++++++++++++++++ 2 files changed, 44 insertions(+) create mode 100644 ext/intl/tests/locale/bug54176.phpt diff --git a/ext/intl/locale/locale_methods.c b/ext/intl/locale/locale_methods.c index 50838de7ed8f..fbda97d0b989 100644 --- a/ext/intl/locale/locale_methods.c +++ b/ext/intl/locale/locale_methods.c @@ -830,6 +830,18 @@ static int append_multiple_key_values(smart_str* loc_name, HashTable* hash_arr, } else if(Z_TYPE_P(ele_value) == IS_ARRAY ) { HashTable *arr = Z_ARRVAL_P(ele_value); zval *data; + int max_value = 0; + + /* Decide the max_value: the max. no. of elements allowed */ + if( strcmp(key_name , LOC_VARIANT_TAG) ==0 ){ + max_value = MAX_NO_VARIANT; + } + if( strcmp(key_name , LOC_EXTLANG_TAG) ==0 ){ + max_value = MAX_NO_EXTLANG; + } + if( strcmp(key_name , LOC_PRIVATE_TAG) ==0 ){ + max_value = MAX_NO_PRIVATE; + } ZEND_HASH_FOREACH_VAL(arr, data) { if(Z_TYPE_P(data) != IS_STRING) { @@ -840,6 +852,9 @@ static int append_multiple_key_values(smart_str* loc_name, HashTable* hash_arr, } smart_str_appendl(loc_name, SEPARATOR , sizeof(SEPARATOR)-1); smart_str_appendl(loc_name, Z_STRVAL_P(data) , Z_STRLEN_P(data)); + if (max_value > 0 && isFirstSubtag >= max_value) { + break; + } } ZEND_HASH_FOREACH_END(); return SUCCESS; } else { diff --git a/ext/intl/tests/locale/bug54176.phpt b/ext/intl/tests/locale/bug54176.phpt new file mode 100644 index 000000000000..33815f6045aa --- /dev/null +++ b/ext/intl/tests/locale/bug54176.phpt @@ -0,0 +1,29 @@ +--TEST-- +Bug #54176 (locale_compose accepts more than 3 extlang) +--SKIPIF-- + +--FILE-- +'en', + 'script' =>'Hans', + 'region' =>'CN', + 'extlang' => ['a','b','c','d','e','f'], +]; +var_dump(locale_compose($arr)); +$arr = [ + 'language'=>'en', + 'script' =>'Hans', + 'region' =>'CN', + 'extlang0' => 'a', + 'extlang1' => 'b', + 'extlang2' => 'c', + 'extlang3' => 'd', +]; +var_dump(locale_compose($arr)); +?> +--EXPECT-- +string(16) "en_a_b_c_Hans_CN" +string(16) "en_a_b_c_Hans_CN"