From 5ce1cf485c2382fdd40ce54a0a39bece8f67b451 Mon Sep 17 00:00:00 2001 From: Jeff Davis Date: Mon, 24 Aug 2026 13:33:31 -0700 Subject: [PATCH] ltree/crc32.c: fix fragile code. Explicitly make space for the NUL when casefolding. No known bug in the previous code, because the previous buffer (size 12) was more than large enough for folding any codepoint with enough room left for a NUL. The builtin provider's limit is 7; ICU's limit seems to be 7 also; and libc always does 1:1 mappings so the real limit is MAX_MULTIBYTE_CHAR_LEN + 1 (size 5). Reviewed-by: Heikki Linnakangas Reviewed-by: Rithvika Devisetti Discussion: https://postgr.es/m/2cfbc37ae8deccd3825e36b7f31c391cbf8ff9b8.camel@j-davis.com Backpatch-through: 18 --- contrib/ltree/crc32.c | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/contrib/ltree/crc32.c b/contrib/ltree/crc32.c index d21bed31fdd..1269e707ee5 100644 --- a/contrib/ltree/crc32.c +++ b/contrib/ltree/crc32.c @@ -32,13 +32,14 @@ ltree_crc32_sz(const char *buf, int size) INIT_TRADITIONAL_CRC32(crc); while (size > 0) { - char foldstr[UNICODE_CASEMAP_BUFSZ]; + /* max space required to map single codepoint, including NUL */ + char foldstr[UNICODE_CASEMAP_BUFSZ + 1]; int srclen = pg_mblen_range(p, end); size_t foldlen; /* fold one codepoint at a time */ - foldlen = pg_strfold(foldstr, UNICODE_CASEMAP_BUFSZ, p, srclen, - locale); + foldlen = pg_strfold(foldstr, sizeof(foldstr), p, srclen, locale); + Assert(foldlen < sizeof(foldstr)); COMP_TRADITIONAL_CRC32(crc, foldstr, foldlen);