v1-0001-Fix-crash-introduced-by-incorrect-backport-806555.patch
text/x-patch
Filename: v1-0001-Fix-crash-introduced-by-incorrect-backport-806555.patch
Type: text/x-patch
Part: 0
Patch
Same data as JSON:
GET /api/v1/attachments/:id/patch
the parsed metadata as JSON — format, series position, per-file stats; never the diff bytes.
API reference →
Format: format-patch
Series: patch v1-0001
Subject: Fix crash introduced by incorrect backport 806555e300.
| File | + | − |
|---|---|---|
| contrib/ltree/crc32.c | 20 | 9 |
| contrib/ltree/lquery_op.c | 19 | 2 |
From 51ee12ca009678a5eac5a4b4e94d0eddb3531c9f Mon Sep 17 00:00:00 2001
From: Jeff Davis <jeff@j-davis.com>
Date: Wed, 21 Jan 2026 10:26:07 -0800
Subject: [PATCH v1] Fix crash introduced by incorrect backport 806555e300.
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
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: Александр Кожемякин <a.kozhemyakin@postgrespro.ru>
Discussion: https://postgr.es/m/456f7143-51ea-4342-b4a1-85f0d9b6c79f@postgrespro.ru
---
contrib/ltree/crc32.c | 29 ++++++++++++++++++++---------
contrib/ltree/lquery_op.c | 21 +++++++++++++++++++--
2 files changed, 39 insertions(+), 11 deletions(-)
diff --git a/contrib/ltree/crc32.c b/contrib/ltree/crc32.c
index ce1b0f28e21..0aa6e08c61e 100644
--- a/contrib/ltree/crc32.c
+++ b/contrib/ltree/crc32.c
@@ -32,18 +32,29 @@ ltree_crc32_sz(const char *buf, int size)
INIT_TRADITIONAL_CRC32(crc);
while (size > 0)
{
- char foldstr[UNICODE_CASEMAP_BUFSZ];
- int srclen = pg_mblen(p);
- size_t foldlen;
+ if (locale->ctype_is_c)
+ {
+ char c = pg_ascii_tolower(*p);
- /* fold one codepoint at a time */
- foldlen = pg_strfold(foldstr, UNICODE_CASEMAP_BUFSZ, p, srclen,
- locale);
+ COMP_TRADITIONAL_CRC32(crc, &c, 1);
+ size--;
+ p++;
+ }
+ else
+ {
+ char foldstr[UNICODE_CASEMAP_BUFSZ];
+ int srclen = pg_mblen(p);
+ size_t foldlen;
- COMP_TRADITIONAL_CRC32(crc, foldstr, foldlen);
+ /* fold one codepoint at a time */
+ foldlen = pg_strfold(foldstr, UNICODE_CASEMAP_BUFSZ, p, srclen,
+ locale);
- size -= srclen;
- p += srclen;
+ COMP_TRADITIONAL_CRC32(crc, foldstr, foldlen);
+
+ 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);
--
2.43.0