From: Jeff Davis Date: Tue, 27 Jan 2026 16:16:07 +0000 (-0800) Subject: Fix crash introduced by incorrect backport 806555e300. X-Git-Tag: REL_18_2~38 X-Git-Url: http://git.ipfire.org/gitweb.cgi?a=commitdiff_plain;h=8993bf0991d876c878fe3739d6d4e200a1e122f3;p=thirdparty%2Fpostgresql.git Fix crash introduced by incorrect backport 806555e300. Commit 7f007e4a04 in master depends on 1476028225, but the latter was not backported. Therefore 806555e300 (the backport of commit 7f007e4a04) incorrectly used pg_strfold() in a locale where ctype_is_c. The fix is to simply have the callers check for ctype_is_c. Because 7f007e4a04 was only backported to version 18, and because the commit in master is fine, this fix only exists in version 18. Reported-by: Александр Кожемякин Discussion: https://postgr.es/m/456f7143-51ea-4342-b4a1-85f0d9b6c79f@postgrespro.ru --- diff --git a/contrib/ltree/crc32.c b/contrib/ltree/crc32.c index ce1b0f28e21..1eeda14651e 100644 --- a/contrib/ltree/crc32.c +++ b/contrib/ltree/crc32.c @@ -30,20 +30,34 @@ ltree_crc32_sz(const char *buf, int size) locale = pg_newlocale_from_collation(DEFAULT_COLLATION_OID); INIT_TRADITIONAL_CRC32(crc); - while (size > 0) + if (locale->ctype_is_c) + { + while (size > 0) + { + char c = pg_ascii_tolower(*p); + + COMP_TRADITIONAL_CRC32(crc, &c, 1); + size--; + p++; + } + } + else { - char foldstr[UNICODE_CASEMAP_BUFSZ]; - int srclen = pg_mblen(p); - size_t foldlen; + while (size > 0) + { + char foldstr[UNICODE_CASEMAP_BUFSZ]; + int srclen = pg_mblen(p); + size_t foldlen; - /* fold one codepoint at a time */ - foldlen = pg_strfold(foldstr, UNICODE_CASEMAP_BUFSZ, p, srclen, - locale); + /* fold one codepoint at a time */ + foldlen = pg_strfold(foldstr, UNICODE_CASEMAP_BUFSZ, p, srclen, + locale); - COMP_TRADITIONAL_CRC32(crc, foldstr, foldlen); + COMP_TRADITIONAL_CRC32(crc, foldstr, foldlen); - size -= srclen; - p += srclen; + size -= srclen; + p += srclen; + } } FIN_TRADITIONAL_CRC32(crc); return (unsigned int) crc; diff --git a/contrib/ltree/lquery_op.c b/contrib/ltree/lquery_op.c index 9b1de101213..f4a507a27c7 100644 --- a/contrib/ltree/lquery_op.c +++ b/contrib/ltree/lquery_op.c @@ -96,15 +96,32 @@ ltree_prefix_eq_ci(const char *a, size_t a_sz, const char *b, size_t b_sz) static pg_locale_t locale = NULL; size_t al_sz = a_sz + 1; size_t al_len; - char *al = palloc(al_sz); + char *al; size_t bl_sz = b_sz + 1; size_t bl_len; - char *bl = palloc(bl_sz); + char *bl; bool res; if (!locale) locale = pg_newlocale_from_collation(DEFAULT_COLLATION_OID); + if (locale->ctype_is_c) + { + if (a_sz > b_sz) + return false; + + for (int i = 0; i < a_sz; i++) + { + if (pg_ascii_tolower(a[i]) != pg_ascii_tolower(b[i])) + return false; + } + + return true; + } + + al = palloc(al_sz); + bl = palloc(bl_sz); + /* casefold both a and b */ al_len = pg_strfold(al, al_sz, a, a_sz, locale);