-
Notifications
You must be signed in to change notification settings - Fork 8.1k
Add Locale::getDisplayKeyword() and Locale::getDisplayKeywordValue() #22264
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from 6 commits
cb244e3
2b0d787
a3097f1
9a9348e
37d515e
053f749
1ab6deb
247501e
0340d9c
28f8b6b
6053116
793bc58
70383dc
dcc5543
42e5f8c
4632f47
df63024
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -44,6 +44,8 @@ ZEND_EXTERN_MODULE_GLOBALS( intl ) | |
| #define EXTLANG_PREFIX "a" | ||
| #define PRIVATE_PREFIX "x" | ||
| #define DISP_NAME "name" | ||
| #define DISP_KEYWORD "keyword" | ||
| #define DISP_KEYWORD_VALUE "keyword_value" | ||
|
|
||
| #define MAX_NO_VARIANT 15 | ||
| #define MAX_NO_EXTLANG 3 | ||
|
|
@@ -671,6 +673,107 @@ static void get_icu_disp_value_src_php( const char* tag_name, INTERNAL_FUNCTION_ | |
| } | ||
| /* }}} */ | ||
|
|
||
| /* {{{ | ||
| * common code shared by display keyword functions to get the value from ICU | ||
| }}} */ | ||
| static void get_icu_disp_keyword_value_src_php(const char* tag_name, INTERNAL_FUNCTION_PARAMETERS) | ||
| { | ||
| char* loc_name = NULL; | ||
| size_t loc_name_len = 0; | ||
| char* keyword_name = NULL; | ||
| size_t keyword_name_len = 0; | ||
| char* disp_loc_name = NULL; | ||
| size_t disp_loc_name_len = 0; | ||
| int free_loc_name = 0; | ||
|
|
||
| UChar* disp_name = NULL; | ||
| int32_t disp_name_len = 0; | ||
| int32_t buflen = 512; | ||
| UErrorCode status = U_ZERO_ERROR; | ||
|
|
||
| zend_string* u8str; | ||
| char* msg = NULL; | ||
|
|
||
| intl_error_reset( NULL ); | ||
|
|
||
| if (strcmp(tag_name, DISP_KEYWORD) == 0) { | ||
| ZEND_PARSE_PARAMETERS_START(1, 2) | ||
| Z_PARAM_PATH(keyword_name, keyword_name_len) | ||
| Z_PARAM_OPTIONAL | ||
| Z_PARAM_PATH_OR_NULL(disp_loc_name, disp_loc_name_len) | ||
| ZEND_PARSE_PARAMETERS_END(); | ||
| } else { | ||
| ZEND_PARSE_PARAMETERS_START(2, 3) | ||
| Z_PARAM_PATH(loc_name, loc_name_len) | ||
| Z_PARAM_PATH(keyword_name, keyword_name_len) | ||
| Z_PARAM_OPTIONAL | ||
| Z_PARAM_PATH_OR_NULL(disp_loc_name, disp_loc_name_len) | ||
| ZEND_PARSE_PARAMETERS_END(); | ||
|
|
||
| if (loc_name_len > ULOC_FULLNAME_CAPACITY) { | ||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Nit: |
||
| intl_error_set( NULL, U_ILLEGAL_ARGUMENT_ERROR, "name too long"); | ||
| RETURN_FALSE; | ||
| } | ||
|
|
||
| if (loc_name_len == 0) { | ||
| loc_name = (char *)intl_locale_get_default(); | ||
| } | ||
| } | ||
|
|
||
| if (!disp_loc_name) { | ||
| disp_loc_name = estrdup(intl_locale_get_default()); | ||
| free_loc_name = 1; | ||
| } | ||
|
|
||
| do { | ||
| disp_name = reinterpret_cast<UChar *>(erealloc(disp_name, buflen * sizeof(UChar))); | ||
| disp_name_len = buflen; | ||
|
|
||
| if (strcmp(tag_name, DISP_KEYWORD) == 0) { | ||
| buflen = uloc_getDisplayKeyword(keyword_name, disp_loc_name, disp_name, disp_name_len, &status); | ||
| } else { | ||
| buflen = uloc_getDisplayKeywordValue(loc_name, keyword_name, disp_loc_name, disp_name, disp_name_len, &status); | ||
| } | ||
|
|
||
| /* U_STRING_NOT_TERMINATED_WARNING is admissible here; don't look for it */ | ||
| if (U_FAILURE(status)) { | ||
| if (status == U_BUFFER_OVERFLOW_ERROR) { | ||
| status = U_ZERO_ERROR; | ||
| continue; | ||
| } | ||
|
|
||
| spprintf(&msg, 0, "unable to get locale %s", tag_name); | ||
| intl_error_set( NULL, status, msg); | ||
| efree(msg); | ||
| if (disp_name) { | ||
| efree(disp_name); | ||
| } | ||
| if (free_loc_name) { | ||
| efree((void *)disp_loc_name); | ||
| disp_loc_name = NULL; | ||
| } | ||
| RETURN_FALSE; | ||
| } | ||
| } while (buflen > disp_name_len); | ||
|
|
||
| if (free_loc_name) { | ||
| efree((void *)disp_loc_name); | ||
| disp_loc_name = NULL; | ||
| } | ||
|
|
||
| u8str = intl_convert_utf16_to_utf8(disp_name, buflen, &status); | ||
| efree(disp_name); | ||
| if (!u8str) { | ||
| spprintf(&msg, 0, "error converting display name for %s to UTF-8", tag_name); | ||
| intl_error_set( NULL, status, msg); | ||
| efree(msg); | ||
| RETURN_FALSE; | ||
| } | ||
|
|
||
| RETVAL_NEW_STR(u8str); | ||
| } | ||
| /* }}} */ | ||
|
|
||
| /* {{{ gets the name for the $locale in $in_locale or default_locale */ | ||
| U_CFUNC PHP_FUNCTION(locale_get_display_name) | ||
| { | ||
|
|
@@ -711,6 +814,20 @@ U_CFUNC PHP_FUNCTION(locale_get_display_variant) | |
| { | ||
| get_icu_disp_value_src_php( LOC_VARIANT_TAG , INTERNAL_FUNCTION_PARAM_PASSTHRU ); | ||
| } | ||
| /* }}} */ | ||
|
|
||
| /* {{{ gets the keyword display label in $in_locale or default_locale */ | ||
| U_CFUNC PHP_FUNCTION(locale_get_display_keyword) | ||
| { | ||
| get_icu_disp_keyword_value_src_php(DISP_KEYWORD, INTERNAL_FUNCTION_PARAM_PASSTHRU); | ||
| } | ||
| /* }}} */ | ||
|
|
||
| /* {{{ gets the keyword value display label in $in_locale or default_locale */ | ||
| U_CFUNC PHP_FUNCTION(locale_get_display_keyword_value) | ||
| { | ||
| get_icu_disp_keyword_value_src_php(DISP_KEYWORD_VALUE, INTERNAL_FUNCTION_PARAM_PASSTHRU); | ||
| } | ||
| /* }}} */ | ||
|
|
||
| /* {{{ return an associative array containing keyword-value | ||
|
|
||
Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,35 @@ | ||
| --TEST-- | ||
| locale_get_display_keyword() basic | ||
| --EXTENSIONS-- | ||
| intl | ||
| --FILE-- | ||
| <?php | ||
|
|
||
| function ut_main() | ||
| { | ||
| $default = ut_loc_get_default(); | ||
| ut_loc_set_default('en'); | ||
|
|
||
| var_dump(ut_loc_get_display_keyword('calendar', 'en')); | ||
| var_dump(ut_loc_get_display_keyword('calendar', null)); | ||
| var_dump(ut_loc_get_display_keyword_value('de_DE@calendar=gregorian', 'calendar', 'en')); | ||
| var_dump(ut_loc_get_display_keyword_value('de_DE@calendar=gregorian', 'calendar', null)); | ||
| var_dump(ut_loc_get_display_keyword_value('de_DE@collation=phonebook', 'collation', 'en')); | ||
|
|
||
| ut_loc_set_default($default); | ||
| } | ||
|
|
||
| include_once 'ut_common.inc'; | ||
| ut_run(); | ||
| ?> | ||
| --EXPECT-- | ||
| string(8) "Calendar" | ||
| string(8) "Calendar" | ||
| string(18) "Gregorian Calendar" | ||
| string(18) "Gregorian Calendar" | ||
| string(20) "Phonebook Sort Order" | ||
| string(8) "Calendar" | ||
| string(8) "Calendar" | ||
| string(18) "Gregorian Calendar" | ||
| string(18) "Gregorian Calendar" | ||
| string(20) "Phonebook Sort Order" | ||
|
LamentXU123 marked this conversation as resolved.
Outdated
|
||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,40 @@ | ||
| --TEST-- | ||
| locale_get_display_keyword() throwing null bytes exceptions. | ||
| --EXTENSIONS-- | ||
| intl | ||
| --FILE-- | ||
| <?php | ||
|
|
||
| function ut_main() | ||
| { | ||
| $calls = [ | ||
| fn() => ut_loc_get_display_keyword("cur\0rency", "fr"), | ||
| fn() => ut_loc_get_display_keyword("currency", "f\0r"), | ||
| fn() => ut_loc_get_display_keyword_value("de_DE@calendar=gregorian\0", "calendar", "en"), | ||
| fn() => ut_loc_get_display_keyword_value("de_DE@calendar=gregorian", "cal\0endar", "en"), | ||
| fn() => ut_loc_get_display_keyword_value("de_DE@calendar=gregorian", "calendar", "e\0n"), | ||
| ]; | ||
|
|
||
| foreach ($calls as $call) { | ||
| try { | ||
| $call(); | ||
| } catch (\ValueError $e) { | ||
| echo $e->getMessage(), PHP_EOL; | ||
| } | ||
| } | ||
| } | ||
|
|
||
| include_once 'ut_common.inc'; | ||
| ut_run(); | ||
| ?> | ||
| --EXPECT-- | ||
| Locale::getDisplayKeyword(): Argument #1 ($keyword) must not contain any null bytes | ||
| Locale::getDisplayKeyword(): Argument #2 ($displayLocale) must not contain any null bytes | ||
| Locale::getDisplayKeywordValue(): Argument #1 ($locale) must not contain any null bytes | ||
| Locale::getDisplayKeywordValue(): Argument #2 ($keyword) must not contain any null bytes | ||
| Locale::getDisplayKeywordValue(): Argument #3 ($displayLocale) must not contain any null bytes | ||
| locale_get_display_keyword(): Argument #1 ($keyword) must not contain any null bytes | ||
| locale_get_display_keyword(): Argument #2 ($displayLocale) must not contain any null bytes | ||
| locale_get_display_keyword_value(): Argument #1 ($locale) must not contain any null bytes | ||
| locale_get_display_keyword_value(): Argument #2 ($keyword) must not contain any null bytes | ||
| locale_get_display_keyword_value(): Argument #3 ($displayLocale) must not contain any null bytes |
Uh oh!
There was an error while loading. Please reload this page.