Index: int8.c =================================================================== RCS file: /projects/cvsroot/pgsql/src/backend/utils/adt/int8.c,v retrieving revision 1.35 diff -u -3 -p -r1.35 int8.c --- int8.c 2001/10/25 14:10:06 1.35 +++ int8.c 2001/11/22 08:48:09 @@ -28,6 +28,12 @@ #define MAXINT8LEN 25 +#ifndef INT64_MAX +#define INT64_MAX (0x7FFFFFFFFFFFFFFFLL) +#endif +#ifndef INT64_MIN +#define INT64_MIN (-INT64_MAX-1) +#endif #ifndef INT_MAX #define INT_MAX (0x7FFFFFFFL) #endif @@ -62,6 +68,7 @@ int8in(PG_FUNCTION_ARGS) char *ptr = str; int64 tmp = 0; int sign = 1; + int64 limit; /* * Do our own scan, rather than relying on sscanf which might be @@ -75,18 +82,26 @@ int8in(PG_FUNCTION_ARGS) ptr++; if (!isdigit((unsigned char) *ptr)) /* require at least one digit */ elog(ERROR, "Bad int8 external representation \"%s\"", str); + if (sign < 0) + limit = INT64_MIN; + else + limit = -INT64_MAX; while (*ptr && isdigit((unsigned char) *ptr)) /* process digits */ { - int64 newtmp = tmp * 10 + (*ptr++ - '0'); + int digit; - if ((newtmp / 10) != tmp) /* overflow? */ + if (tmp < -(INT64_MAX/10)) /* overflow? */ + elog(ERROR, "int8 value out of range: \"%s\"", str); + digit = *ptr++ - '0'; + tmp *= 10; + if (tmp < limit + digit) elog(ERROR, "int8 value out of range: \"%s\"", str); - tmp = newtmp; + tmp -= digit; } if (*ptr) /* trailing junk? */ elog(ERROR, "Bad int8 external representation \"%s\"", str); - result = (sign < 0) ? -tmp : tmp; + result = (sign < 0) ? tmp : -tmp; PG_RETURN_INT64(result); }