Relax check for return value from second call of pg_strnxfrm().
authorJeff Davis <[email protected]>
Tue, 30 Jul 2024 23:23:20 +0000 (16:23 -0700)
committerJeff Davis <[email protected]>
Tue, 30 Jul 2024 23:23:20 +0000 (16:23 -0700)
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[email protected]
Reviewed-by: Heikki Linnakangas
Backpatch-through: 16

src/backend/access/hash/hashfunc.c
src/backend/utils/adt/pg_locale.c
src/backend/utils/adt/varchar.c

index ce8ee0ea2efdb634a89c81dd26286edafc012c6c..c3a67b51afe0b9e49b5c077d701506c4b1c6e6ba 100644 (file)
@@ -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");
 
        /*
index 627ab89d7cc39cfcc685fcaa747f813c4126aab4..02f64f957d1e962706198c1a413c62f46039c5ad 100644 (file)
@@ -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
index 02dfe219f5463d7475101041a590de502f576414..1ba5f9d9f6c87574586de595e676d087e59f11f3 100644 (file)
@@ -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");
 
        /*