From: Jeff Davis Date: Tue, 30 Jul 2024 23:23:20 +0000 (-0700) Subject: Relax check for return value from second call of pg_strnxfrm(). X-Git-Tag: REL_18_BETA1~2247 X-Git-Url: http://git.postgresql.org/gitweb/?a=commitdiff_plain;h=679c5084cf210c6e958276b657039e8ba0c077c0;p=postgresql.git Relax check for return value from second call of pg_strnxfrm(). strxfrm() is not guaranteed to return the exact number of bytes needed to store the result; it may return a higher value. Discussion: https://postgr.es/m/32f85d88d1f64395abfe5a10dd97a62a4d3474ce.camel@j-davis.com Reviewed-by: Heikki Linnakangas Backpatch-through: 16 --- diff --git a/src/backend/access/hash/hashfunc.c b/src/backend/access/hash/hashfunc.c index ce8ee0ea2ef..c3a67b51afe 100644 --- a/src/backend/access/hash/hashfunc.c +++ b/src/backend/access/hash/hashfunc.c @@ -298,7 +298,9 @@ hashtext(PG_FUNCTION_ARGS) buf = palloc(bsize + 1); rsize = pg_strnxfrm(buf, bsize + 1, keydata, keylen, mylocale); - if (rsize != bsize) + + /* the second call may return a smaller value than the first */ + if (rsize > bsize) elog(ERROR, "pg_strnxfrm() returned unexpected result"); /* @@ -352,7 +354,9 @@ hashtextextended(PG_FUNCTION_ARGS) buf = palloc(bsize + 1); rsize = pg_strnxfrm(buf, bsize + 1, keydata, keylen, mylocale); - if (rsize != bsize) + + /* the second call may return a smaller value than the first */ + if (rsize > bsize) elog(ERROR, "pg_strnxfrm() returned unexpected result"); /* diff --git a/src/backend/utils/adt/pg_locale.c b/src/backend/utils/adt/pg_locale.c index 627ab89d7cc..02f64f957d1 100644 --- a/src/backend/utils/adt/pg_locale.c +++ b/src/backend/utils/adt/pg_locale.c @@ -2353,9 +2353,9 @@ pg_strxfrm_enabled(pg_locale_t locale) * The provided 'src' must be nul-terminated. If 'destsize' is zero, 'dest' * may be NULL. * - * Returns the number of bytes needed to store the transformed string, - * excluding the terminating nul byte. If the value returned is 'destsize' or - * greater, the resulting contents of 'dest' are undefined. + * Returns the number of bytes needed (or more) to store the transformed + * string, excluding the terminating nul byte. If the value returned is + * 'destsize' or greater, the resulting contents of 'dest' are undefined. */ size_t pg_strxfrm(char *dest, const char *src, size_t destsize, pg_locale_t locale) @@ -2385,9 +2385,9 @@ pg_strxfrm(char *dest, const char *src, size_t destsize, pg_locale_t locale) * 'src' does not need to be nul-terminated. If 'destsize' is zero, 'dest' may * be NULL. * - * Returns the number of bytes needed to store the transformed string, - * excluding the terminating nul byte. If the value returned is 'destsize' or - * greater, the resulting contents of 'dest' are undefined. + * Returns the number of bytes needed (or more) to store the transformed + * string, excluding the terminating nul byte. If the value returned is + * 'destsize' or greater, the resulting contents of 'dest' are undefined. * * This function may need to nul-terminate the argument for libc functions; * so if the caller already has a nul-terminated string, it should call diff --git a/src/backend/utils/adt/varchar.c b/src/backend/utils/adt/varchar.c index 02dfe219f54..1ba5f9d9f6c 100644 --- a/src/backend/utils/adt/varchar.c +++ b/src/backend/utils/adt/varchar.c @@ -1028,7 +1028,9 @@ hashbpchar(PG_FUNCTION_ARGS) buf = palloc(bsize + 1); rsize = pg_strnxfrm(buf, bsize + 1, keydata, keylen, mylocale); - if (rsize != bsize) + + /* the second call may return a smaller value than the first */ + if (rsize > bsize) elog(ERROR, "pg_strnxfrm() returned unexpected result"); /* @@ -1084,7 +1086,9 @@ hashbpcharextended(PG_FUNCTION_ARGS) buf = palloc(bsize + 1); rsize = pg_strnxfrm(buf, bsize + 1, keydata, keylen, mylocale); - if (rsize != bsize) + + /* the second call may return a smaller value than the first */ + if (rsize > bsize) elog(ERROR, "pg_strnxfrm() returned unexpected result"); /*