From eb7a9414f0b8a8c6c64e7249b5ed4aab1177d633 Mon Sep 17 00:00:00 2001
From: Jeff Davis <jeff@j-davis.com>
Date: Tue, 18 Aug 2026 14:57:32 -0700
Subject: [PATCH v2 1/2] 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 <hlinnaka@iki.fi>
Discussion: https://postgr.es/m/2cfbc37ae8deccd3825e36b7f31c391cbf8ff9b8.camel@j-davis.com
Backpatch-through: 18
---
 contrib/ltree/crc32.c | 6 +++---
 1 file changed, 3 insertions(+), 3 deletions(-)

diff --git a/contrib/ltree/crc32.c b/contrib/ltree/crc32.c
index d21bed31fdd..617cc652a7a 100644
--- a/contrib/ltree/crc32.c
+++ b/contrib/ltree/crc32.c
@@ -32,13 +32,13 @@ ltree_crc32_sz(const char *buf, int size)
 	INIT_TRADITIONAL_CRC32(crc);
 	while (size > 0)
 	{
-		char		foldstr[UNICODE_CASEMAP_BUFSZ];
+		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);
 
-- 
2.43.0

