Fix thinko introduced in 6b423ec67
authorDavid Rowley <drowley@postgresql.org>
Sun, 4 Dec 2022 22:55:05 +0000 (11:55 +1300)
committerDavid Rowley <drowley@postgresql.org>
Sun, 4 Dec 2022 22:55:05 +0000 (11:55 +1300)
As pointed out by Dean Rasheed, we really should be using tmp >
-(PG_INTNN_MIN / 10) rather than tmp > (PG_INTNN_MAX / 10) for checking
for overflows in the accumulation in the pg_strtointNN functions.  This
does happen to be the same number when dividing by 10, but there is a
pending patch which adds other bases and this is not the same number if we
were to divide by 2 rather than 10, for example.  If the base 2 parsing
was to follow this example then we could accidentally think a string
containing the value of PG_INT32_MIN was an overflow in pg_strtoint32.
Clearly that shouldn't overflow.

This does not fix any actual live bugs, only some bad examples of overflow
checks for future bases.

Reported-by: Dean Rasheed
Discussion: https://postgr.es/m/CAEZATCVEtwfhdm-K-etZYFB0=qsR0nT6qXta_W+GQx4RYph1dg@mail.gmail.com

src/backend/utils/adt/numutils.c

index a2ba7fcafe6646502e8450ab534b2f0e7cc7ef8d..a64422c8d066a330c3ec33ec1e2d6d4642b5cdb1 100644 (file)
@@ -122,7 +122,7 @@ pg_strtoint16(const char *s)
    /* process digits */
    while (*ptr && isdigit((unsigned char) *ptr))
    {
-       if (unlikely(tmp > (PG_INT16_MAX / 10)))
+       if (unlikely(tmp > -(PG_INT16_MIN / 10)))
            goto out_of_range;
 
        tmp = tmp * 10 + (*ptr++ - '0');
@@ -200,7 +200,7 @@ pg_strtoint32(const char *s)
    /* process digits */
    while (*ptr && isdigit((unsigned char) *ptr))
    {
-       if (unlikely(tmp > (PG_INT32_MAX / 10)))
+       if (unlikely(tmp > -(PG_INT32_MIN / 10)))
            goto out_of_range;
 
        tmp = tmp * 10 + (*ptr++ - '0');
@@ -278,7 +278,7 @@ pg_strtoint64(const char *s)
    /* process digits */
    while (*ptr && isdigit((unsigned char) *ptr))
    {
-       if (unlikely(tmp > (PG_INT64_MAX / 10)))
+       if (unlikely(tmp > -(PG_INT64_MIN / 10)))
            goto out_of_range;
 
        tmp = tmp * 10 + (*ptr++ - '0');