From 1d8015ef6adebc113e99aa9cd972381dc2048b3e Mon Sep 17 00:00:00 2001 From: "Chao Li (Evan)" Date: Tue, 25 Nov 2025 10:26:16 +0800 Subject: [PATCH v1] Fixes bug in strlower_libc_sb() Fixed a no-impact bug in strlower_libc_sb(), where is lenght check is useless, thus removed the check. Author: Chao Li --- src/backend/utils/adt/pg_locale_libc.c | 163 +++++++++++++------------ 1 file changed, 82 insertions(+), 81 deletions(-) diff --git a/src/backend/utils/adt/pg_locale_libc.c b/src/backend/utils/adt/pg_locale_libc.c index 716f005066a..877fdedf079 100644 --- a/src/backend/utils/adt/pg_locale_libc.c +++ b/src/backend/utils/adt/pg_locale_libc.c @@ -426,39 +426,37 @@ static size_t strlower_libc_sb(char *dest, size_t destsize, const char *src, ssize_t srclen, pg_locale_t locale) { + ssize_t reallen; + locale_t loc = locale->lt; + if (srclen < 0) srclen = strlen(src); - if (srclen + 1 <= destsize) - { - locale_t loc = locale->lt; - char *p; - - if (srclen + 1 > destsize) - return srclen; + reallen = srclen + 1; + if (reallen > destsize) + reallen = destsize; - memcpy(dest, src, srclen); - dest[srclen] = '\0'; + memcpy(dest, src, reallen); + if (reallen < destsize) + dest[reallen] = '\0'; - /* - * Note: we assume that tolower_l() will not be so broken as to need - * an isupper_l() guard test. When using the default collation, we - * apply the traditional Postgres behavior that forces ASCII-style - * treatment of I/i, but in non-default collations you get exactly - * what the collation says. - */ - for (p = dest; *p; p++) + /* + * Note: we assume that tolower_l() will not be so broken as to need an + * isupper_l() guard test. When using the default collation, we apply the + * traditional Postgres behavior that forces ASCII-style treatment of I/i, + * but in non-default collations you get exactly what the collation says. + */ + for (char *p = dest; *p; p++) + { + if (locale->is_default) { - if (locale->is_default) - { - 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 + 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); } return srclen; @@ -516,55 +514,57 @@ static size_t strtitle_libc_sb(char *dest, size_t destsize, const char *src, ssize_t srclen, pg_locale_t locale) { + ssize_t reallen; + locale_t loc = locale->lt; + int wasalnum = false; + if (srclen < 0) srclen = strlen(src); - if (srclen + 1 <= destsize) - { - locale_t loc = locale->lt; - int wasalnum = false; - char *p; + reallen = srclen + 1; + if (reallen > destsize) + reallen = destsize; - memcpy(dest, src, srclen); - dest[srclen] = '\0'; + memcpy(dest, src, reallen); + if (reallen < destsize) + dest[reallen] = '\0'; - /* - * Note: we assume that toupper_l()/tolower_l() will not be so broken - * as to need guard tests. When using the default collation, we apply - * the traditional Postgres behavior that forces ASCII-style treatment - * of I/i, but in non-default collations you get exactly what the - * collation says. - */ - for (p = dest; *p; p++) + /* + * Note: we assume that toupper_l()/tolower_l() will not be so broken as + * to need guard tests. When using the default collation, we apply the + * traditional Postgres behavior that forces ASCII-style treatment of I/i, + * but in non-default collations you get exactly what the collation says. + */ + for (char *p = dest; *p; p++) + { + if (locale->is_default) { - if (locale->is_default) + if (wasalnum) { - if (wasalnum) - { - 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 - { - 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); - } + 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 { - if (wasalnum) - *p = tolower_l((unsigned char) *p, loc); - else + 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); } - wasalnum = isalnum_l((unsigned char) *p, loc); } + else + { + if (wasalnum) + *p = tolower_l((unsigned char) *p, loc); + else + *p = toupper_l((unsigned char) *p, loc); + } + wasalnum = isalnum_l((unsigned char) *p, loc); } + return srclen; } @@ -627,36 +627,37 @@ static size_t strupper_libc_sb(char *dest, size_t destsize, const char *src, ssize_t srclen, pg_locale_t locale) { + ssize_t reallen; + locale_t loc = locale->lt; + if (srclen < 0) srclen = strlen(src); - if (srclen + 1 <= destsize) - { - locale_t loc = locale->lt; - char *p; + reallen = srclen + 1; + if (reallen > destsize) + reallen = destsize; - memcpy(dest, src, srclen); - dest[srclen] = '\0'; + memcpy(dest, src, reallen); + if (reallen < destsize) + dest[reallen] = '\0'; - /* - * Note: we assume that toupper_l() will not be so broken as to need - * an islower_l() guard test. When using the default collation, we - * apply the traditional Postgres behavior that forces ASCII-style - * treatment of I/i, but in non-default collations you get exactly - * what the collation says. - */ - for (p = dest; *p; p++) + /* + * Note: we assume that toupper_l() will not be so broken as to need an + * islower_l() guard test. When using the default collation, we apply the + * traditional Postgres behavior that forces ASCII-style treatment of I/i, + * but in non-default collations you get exactly what the collation says. + */ + for (char *p = dest; *p; p++) + { + if (locale->is_default) { - if (locale->is_default) - { - 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 + 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); } return srclen; -- 2.39.5 (Apple Git-154)