Avoid global LC_CTYPE dependency in pg_locale_libc.c.
authorJeff Davis <jdavis@postgresql.org>
Mon, 24 Nov 2025 22:55:09 +0000 (14:55 -0800)
committerJeff Davis <jdavis@postgresql.org>
Mon, 24 Nov 2025 22:55:09 +0000 (14:55 -0800)
Call tolower_l() directly instead of through pg_tolower(), because the
latter depends on the global LC_CTYPE.

Discussion: https://postgr.es/m/8186b28a1a39e61a0d833a4c25a8909ebbbabd48.camel@j-davis.com

src/backend/utils/adt/pg_locale_libc.c

index 9c7fcd1fc7a81ea0dcb6a8d0f8e378492b62e010..716f005066a81c0f75e8fb7405835f40815cc555 100644 (file)
@@ -450,7 +450,12 @@ strlower_libc_sb(char *dest, size_t destsize, const char *src, ssize_t srclen,
        for (p = dest; *p; p++)
        {
            if (locale->is_default)
-               *p = pg_tolower((unsigned char) *p);
+           {
+               if (*p >= 'A' && *p <= 'Z')
+                   *p += 'a' - 'A';
+               else if (IS_HIGHBIT_SET(*p) && isupper_l(*p, loc))
+                   *p = tolower_l((unsigned char) *p, loc);
+           }
            else
                *p = tolower_l((unsigned char) *p, loc);
        }
@@ -535,9 +540,19 @@ strtitle_libc_sb(char *dest, size_t destsize, const char *src, ssize_t srclen,
            if (locale->is_default)
            {
                if (wasalnum)
-                   *p = pg_tolower((unsigned char) *p);
+               {
+                   if (*p >= 'A' && *p <= 'Z')
+                       *p += 'a' - 'A';
+                   else if (IS_HIGHBIT_SET(*p) && isupper_l(*p, loc))
+                       *p = tolower_l((unsigned char) *p, loc);
+               }
                else
-                   *p = pg_toupper((unsigned char) *p);
+               {
+                   if (*p >= 'a' && *p <= 'z')
+                       *p -= 'a' - 'A';
+                   else if (IS_HIGHBIT_SET(*p) && islower_l(*p, loc))
+                       *p = toupper_l((unsigned char) *p, loc);
+               }
            }
            else
            {
@@ -633,7 +648,12 @@ strupper_libc_sb(char *dest, size_t destsize, const char *src, ssize_t srclen,
        for (p = dest; *p; p++)
        {
            if (locale->is_default)
-               *p = pg_toupper((unsigned char) *p);
+           {
+               if (*p >= 'a' && *p <= 'z')
+                   *p -= 'a' - 'A';
+               else if (IS_HIGHBIT_SET(*p) && islower_l(*p, loc))
+                   *p = toupper_l((unsigned char) *p, loc);
+           }
            else
                *p = toupper_l((unsigned char) *p, loc);
        }