]> git.ipfire.org Git - thirdparty/postgresql.git/commitdiff
Fix crash introduced by incorrect backport 806555e300.
authorJeff Davis <jdavis@postgresql.org>
Tue, 27 Jan 2026 16:16:07 +0000 (08:16 -0800)
committerJeff Davis <jdavis@postgresql.org>
Tue, 27 Jan 2026 16:16:07 +0000 (08:16 -0800)
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
contrib/ltree/lquery_op.c

index ce1b0f28e21b8cc67f4e194a561193aa8f5d7f5b..1eeda14651ed55d2fcc283f64ec434fa7f6010ad 100644 (file)
@@ -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;
index 9b1de10121367023e6db4818a174d8ec88b1b7c8..f4a507a27c776aea5e8d24d521740a5b80e84e02 100644 (file)
@@ -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);