Skip to content

Commit d8b3c81

Browse files
committed
Refine memory allocation in ICU conversions
The simple calculations done to estimate the size of the output buffers for ucnv_fromUChars() and ucnv_toUChars() could overflow int32_t for large strings. To avoid that, go the long way and run the function first without an output buffer to get the correct output buffer size requirement.
1 parent b0f069d commit d8b3c81

File tree

1 file changed

+20
-4
lines changed

1 file changed

+20
-4
lines changed

src/backend/utils/adt/pg_locale.c

Lines changed: 20 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1511,14 +1511,22 @@ icu_to_uchar(UChar **buff_uchar, const char *buff, size_t nbytes)
15111511

15121512
init_icu_converter();
15131513

1514-
len_uchar = 2 * nbytes + 1; /* max length per docs */
1515-
*buff_uchar = palloc(len_uchar * sizeof(**buff_uchar));
15161514
status = U_ZERO_ERROR;
1517-
len_uchar = ucnv_toUChars(icu_converter, *buff_uchar, len_uchar,
1515+
len_uchar = ucnv_toUChars(icu_converter, NULL, 0,
1516+
buff, nbytes, &status);
1517+
if (U_FAILURE(status) && status != U_BUFFER_OVERFLOW_ERROR)
1518+
ereport(ERROR,
1519+
(errmsg("ucnv_toUChars failed: %s", u_errorName(status))));
1520+
1521+
*buff_uchar = palloc((len_uchar + 1) * sizeof(**buff_uchar));
1522+
1523+
status = U_ZERO_ERROR;
1524+
len_uchar = ucnv_toUChars(icu_converter, *buff_uchar, len_uchar + 1,
15181525
buff, nbytes, &status);
15191526
if (U_FAILURE(status))
15201527
ereport(ERROR,
15211528
(errmsg("ucnv_toUChars failed: %s", u_errorName(status))));
1529+
15221530
return len_uchar;
15231531
}
15241532

@@ -1541,14 +1549,22 @@ icu_from_uchar(char **result, const UChar *buff_uchar, int32_t len_uchar)
15411549

15421550
init_icu_converter();
15431551

1544-
len_result = UCNV_GET_MAX_BYTES_FOR_STRING(len_uchar, ucnv_getMaxCharSize(icu_converter));
1552+
status = U_ZERO_ERROR;
1553+
len_result = ucnv_fromUChars(icu_converter, NULL, 0,
1554+
buff_uchar, len_uchar, &status);
1555+
if (U_FAILURE(status) && status != U_BUFFER_OVERFLOW_ERROR)
1556+
ereport(ERROR,
1557+
(errmsg("ucnv_fromUChars failed: %s", u_errorName(status))));
1558+
15451559
*result = palloc(len_result + 1);
1560+
15461561
status = U_ZERO_ERROR;
15471562
len_result = ucnv_fromUChars(icu_converter, *result, len_result + 1,
15481563
buff_uchar, len_uchar, &status);
15491564
if (U_FAILURE(status))
15501565
ereport(ERROR,
15511566
(errmsg("ucnv_fromUChars failed: %s", u_errorName(status))));
1567+
15521568
return len_result;
15531569
}
15541570
#endif /* USE_ICU */

0 commit comments

Comments
 (0)
pFad - Phonifier reborn

Pfad - The Proxy pFad of © 2024 Garber Painting. All rights reserved.

Note: This service is not intended for secure transactions such as banking, social media, email, or purchasing. Use at your own risk. We assume no liability whatsoever for broken pages.


Alternative Proxies:

Alternative Proxy

pFad Proxy

pFad v3 Proxy

pFad v4 Proxy