summaryrefslogtreecommitdiff
path: root/src/bin/initdb/initdb.c
diff options
context:
space:
mode:
authorJeff Davis <jdavis@postgresql.org>2023-05-17 13:43:41 -0700
committerJeff Davis <jdavis@postgresql.org>2023-05-17 14:18:45 -0700
commit1c634f6647c28354258d114041252475325aea32 (patch)
tree70dd674a1b46de4925248933f4b8ceec661e991e /src/bin/initdb/initdb.c
parent6de31ce446e59a1f947c7ebe4e4bbe7ca2b842bc (diff)
downloadpostgresql-1c634f6647c28354258d114041252475325aea32.tar.gz
ICU: check for U_STRING_NOT_TERMINATED_WARNING.HEADmaster
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.c15
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);