Index: src/backend/libpq/ip.c =================================================================== RCS file: /cvsroot/pgsql/src/backend/libpq/ip.c,v retrieving revision 1.33 diff -c -c -r1.33 ip.c *** src/backend/libpq/ip.c 22 Nov 2005 18:17:11 -0000 1.33 --- src/backend/libpq/ip.c 1 Dec 2005 18:40:02 -0000 *************** *** 342,348 **** long bits; char *endptr; ! bits = strtol(numbits, &endptr, 10); if (*numbits == '\0' || *endptr != '\0') return -1; --- 342,348 ---- long bits; char *endptr; ! bits = pg_strtol_range(numbits, &endptr, 10); if (*numbits == '\0' || *endptr != '\0') return -1; Index: src/backend/utils/adt/datetime.c =================================================================== RCS file: /cvsroot/pgsql/src/backend/utils/adt/datetime.c,v retrieving revision 1.161 diff -c -c -r1.161 datetime.c *** src/backend/utils/adt/datetime.c 22 Nov 2005 18:17:22 -0000 1.161 --- src/backend/utils/adt/datetime.c 1 Dec 2005 18:40:03 -0000 *************** *** 1013,1019 **** if (tzp == NULL) return DTERR_BAD_FORMAT; ! val = strtol(field[i], &cp, 10); j2date(val, &tm->tm_year, &tm->tm_mon, &tm->tm_mday); /* Get the time zone from the end of the string */ --- 1013,1019 ---- if (tzp == NULL) return DTERR_BAD_FORMAT; ! val = pg_strtol_range(field[i], &cp, 10); j2date(val, &tm->tm_year, &tm->tm_mon, &tm->tm_mday); /* Get the time zone from the end of the string */ *************** *** 1158,1164 **** char *cp; int val; ! val = strtol(field[i], &cp, 10); /* * only a few kinds are allowed to have an embedded --- 1158,1164 ---- char *cp; int val; ! val = pg_strtol_range(field[i], &cp, 10); /* * only a few kinds are allowed to have an embedded *************** *** 1915,1921 **** break; } ! val = strtol(field[i], &cp, 10); /* * only a few kinds are allowed to have an embedded --- 1915,1921 ---- break; } ! val = pg_strtol_range(field[i], &cp, 10); /* * only a few kinds are allowed to have an embedded *************** *** 2456,2466 **** *tmask = DTK_TIME_M; ! tm->tm_hour = strtol(str, &cp, 10); if (*cp != ':') return DTERR_BAD_FORMAT; str = cp + 1; ! tm->tm_min = strtol(str, &cp, 10); if (*cp == '\0') { tm->tm_sec = 0; --- 2456,2466 ---- *tmask = DTK_TIME_M; ! tm->tm_hour = pg_strtol_range(str, &cp, 10); if (*cp != ':') return DTERR_BAD_FORMAT; str = cp + 1; ! tm->tm_min = pg_strtol_range(str, &cp, 10); if (*cp == '\0') { tm->tm_sec = 0; *************** *** 2471,2477 **** else { str = cp + 1; ! tm->tm_sec = strtol(str, &cp, 10); if (*cp == '\0') *fsec = 0; else if (*cp == '.') --- 2471,2477 ---- else { str = cp + 1; ! tm->tm_sec = pg_strtol_range(str, &cp, 10); if (*cp == '\0') *fsec = 0; else if (*cp == '.') *************** *** 2522,2528 **** *tmask = 0; ! val = strtol(str, &cp, 10); if (cp == str) return DTERR_BAD_FORMAT; --- 2522,2528 ---- *tmask = 0; ! val = pg_strtol_range(str, &cp, 10); if (cp == str) return DTERR_BAD_FORMAT; *************** *** 2809,2819 **** if (*str != '+' && *str != '-') return DTERR_BAD_FORMAT; ! hr = strtol(str + 1, &cp, 10); /* explicit delimiter? */ if (*cp == ':') ! min = strtol(cp + 1, &cp, 10); /* otherwise, might have run things together... */ else if (*cp == '\0' && strlen(str) > 3) { --- 2809,2819 ---- if (*str != '+' && *str != '-') return DTERR_BAD_FORMAT; ! hr = pg_strtol_range(str + 1, &cp, 10); /* explicit delimiter? */ if (*cp == ':') ! min = pg_strtol_range(cp + 1, &cp, 10); /* otherwise, might have run things together... */ else if (*cp == '\0' && strlen(str) > 3) { *************** *** 3056,3062 **** case DTK_DATE: case DTK_NUMBER: ! val = strtol(field[i], &cp, 10); if (type == IGNORE_DTF) type = DTK_SECOND; --- 3056,3062 ---- case DTK_DATE: case DTK_NUMBER: ! val = pg_strtol_range(field[i], &cp, 10); if (type == IGNORE_DTF) type = DTK_SECOND; Index: src/backend/utils/adt/numeric.c =================================================================== RCS file: /cvsroot/pgsql/src/backend/utils/adt/numeric.c,v retrieving revision 1.88 diff -c -c -r1.88 numeric.c *** src/backend/utils/adt/numeric.c 22 Nov 2005 18:17:23 -0000 1.88 --- src/backend/utils/adt/numeric.c 1 Dec 2005 18:40:08 -0000 *************** *** 2812,2818 **** char *endptr; cp++; ! exponent = strtol(cp, &endptr, 10); if (endptr == cp) ereport(ERROR, (errcode(ERRCODE_INVALID_TEXT_REPRESENTATION), --- 2812,2818 ---- char *endptr; cp++; ! exponent = pg_strtol_range(cp, &endptr, 10); if (endptr == cp) ereport(ERROR, (errcode(ERRCODE_INVALID_TEXT_REPRESENTATION), Index: src/include/port.h =================================================================== RCS file: /cvsroot/pgsql/src/include/port.h,v retrieving revision 1.84 diff -c -c -r1.84 port.h *** src/include/port.h 15 Oct 2005 02:49:41 -0000 1.84 --- src/include/port.h 1 Dec 2005 18:40:09 -0000 *************** *** 249,254 **** --- 249,257 ---- #define closesocket close #endif /* WIN32 */ + /* do strtol(), but error out on ERANGE */ + long pg_strtol_range(const char *nptr, char **endptr, int base); + /* * Default "extern" declarations or macro substitutes for library routines. * When necessary, these routines are provided by files in src/port/. Index: src/interfaces/ecpg/pgtypeslib/numeric.c =================================================================== RCS file: /cvsroot/pgsql/src/interfaces/ecpg/pgtypeslib/numeric.c,v retrieving revision 1.24 diff -c -c -r1.24 numeric.c *** src/interfaces/ecpg/pgtypeslib/numeric.c 22 Nov 2005 18:17:32 -0000 1.24 --- src/interfaces/ecpg/pgtypeslib/numeric.c 1 Dec 2005 18:40:11 -0000 *************** *** 218,224 **** char *endptr; (*ptr)++; ! exponent = strtol(*ptr, &endptr, 10); if (endptr == (*ptr)) { errno = PGTYPES_NUM_BAD_NUMERIC; --- 218,224 ---- char *endptr; (*ptr)++; ! exponent = pg_strtol_range(*ptr, &endptr, 10); if (endptr == (*ptr)) { errno = PGTYPES_NUM_BAD_NUMERIC; Index: src/port/exec.c =================================================================== RCS file: /cvsroot/pgsql/src/port/exec.c,v retrieving revision 1.40 diff -c -c -r1.40 exec.c *** src/port/exec.c 22 Nov 2005 18:17:34 -0000 1.40 --- src/port/exec.c 1 Dec 2005 18:40:11 -0000 *************** *** 592,594 **** --- 592,618 ---- return -1; } + + + /* + * This really should be in its own file, but it so small, it hardly + * seems worth it. + */ + long + pg_strtol_range(const char *nptr, char **endptr, int base) + { + long ret = strtol(nptr, endptr, base); + + if (errno == ERANGE) + { + #ifndef FRONTEND + elog(ERROR, _("value not in supported range for an integer: \"%s\""), nptr); + #else + /* Keep strings identical for ease of translation */ + fprintf(stderr, _("value not in supported range for an integer: \"%s\""), nptr); + fputc('\n', stderr); + #endif + return LONG_MAX; + } + return ret; + }