From 1c634f6647c28354258d114041252475325aea32 Mon Sep 17 00:00:00 2001 From: Jeff Davis Date: Wed, 17 May 2023 13:43:41 -0700 Subject: ICU: check for U_STRING_NOT_TERMINATED_WARNING. 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 --- src/bin/initdb/initdb.c | 15 ++++----------- 1 file changed, 4 insertions(+), 11 deletions(-) (limited to 'src/bin/initdb/initdb.c') 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); -- cgit v1.2.1