diff options
author | Jeff Davis <jdavis@postgresql.org> | 2023-05-17 13:43:41 -0700 |
---|---|---|
committer | Jeff Davis <jdavis@postgresql.org> | 2023-05-17 14:18:45 -0700 |
commit | 1c634f6647c28354258d114041252475325aea32 (patch) | |
tree | 70dd674a1b46de4925248933f4b8ceec661e991e /src/bin/initdb/initdb.c | |
parent | 6de31ce446e59a1f947c7ebe4e4bbe7ca2b842bc (diff) | |
download | postgresql-master.tar.gz |
Fixes memory error in cases where the length of the language name
returned by uloc_getLanguage() is exactly ULOC_LANG_CAPACITY, in which
case the status is set to U_STRING_NOT_TERMINATED_WARNING.
Also check in call sites for other ICU functions that are expected to
return a C string to be safe (no bug is known at these other call
sites).
Reported-by: Alexander Lakhin
Discussion: https://postgr.es/m/2098874d-c111-41e4-9063-30bcf135226b@gmail.com
Diffstat (limited to 'src/bin/initdb/initdb.c')
-rw-r--r-- | src/bin/initdb/initdb.c | 15 |
1 files changed, 4 insertions, 11 deletions
diff --git a/src/bin/initdb/initdb.c b/src/bin/initdb/initdb.c index e03d498b1e..30b576932f 100644 --- a/src/bin/initdb/initdb.c +++ b/src/bin/initdb/initdb.c @@ -2252,7 +2252,7 @@ icu_language_tag(const char *loc_str) status = U_ZERO_ERROR; uloc_getLanguage(loc_str, lang, ULOC_LANG_CAPACITY, &status); - if (U_FAILURE(status)) + if (U_FAILURE(status) || status == U_STRING_NOT_TERMINATED_WARNING) { pg_fatal("could not get language from locale \"%s\": %s", loc_str, u_errorName(status)); @@ -2272,19 +2272,12 @@ icu_language_tag(const char *loc_str) langtag = pg_malloc(buflen); while (true) { - int32_t len; - status = U_ZERO_ERROR; - len = uloc_toLanguageTag(loc_str, langtag, buflen, strict, &status); + uloc_toLanguageTag(loc_str, langtag, buflen, strict, &status); - /* - * If the result fits in the buffer exactly (len == buflen), - * uloc_toLanguageTag() will return success without nul-terminating - * the result. Check for either U_BUFFER_OVERFLOW_ERROR or len >= - * buflen and try again. - */ + /* try again if the buffer is not large enough */ if (status == U_BUFFER_OVERFLOW_ERROR || - (U_SUCCESS(status) && len >= buflen)) + status == U_STRING_NOT_TERMINATED_WARNING) { buflen = buflen * 2; langtag = pg_realloc(langtag, buflen); |