From 22fff8b9f1a98fc1f431340fb069b2851271a8ba Mon Sep 17 00:00:00 2001 From: Tom Lane Date: Thu, 1 Dec 2005 17:57:07 +0000 Subject: [PATCH] Check for overflow in strtol() while parsing datetime inputs. Michael Fuhr. --- src/backend/utils/adt/datetime.c | 34 +++++++++++++++++++++++++++++++- 1 file changed, 33 insertions(+), 1 deletion(-) diff --git a/src/backend/utils/adt/datetime.c b/src/backend/utils/adt/datetime.c index 27241c31d9a..5cdb5d4fb42 100644 --- a/src/backend/utils/adt/datetime.c +++ b/src/backend/utils/adt/datetime.c @@ -8,7 +8,7 @@ * * * IDENTIFICATION - * $Header: /cvsroot/pgsql/src/backend/utils/adt/datetime.c,v 1.118.2.6 2005/05/26 02:14:31 neilc Exp $ + * $Header: /cvsroot/pgsql/src/backend/utils/adt/datetime.c,v 1.118.2.7 2005/12/01 17:57:07 tgl Exp $ * *------------------------------------------------------------------------- */ @@ -977,7 +977,10 @@ DecodeDateTime(char **field, int *ftype, int nf, if (tzp == NULL) return DTERR_BAD_FORMAT; + errno = 0; val = strtol(field[i], &cp, 10); + if (errno == ERANGE) + return DTERR_FIELD_OVERFLOW; j2date(val, &tm->tm_year, &tm->tm_mon, &tm->tm_mday); /* Get the time zone from the end of the string */ @@ -1122,7 +1125,10 @@ DecodeDateTime(char **field, int *ftype, int nf, char *cp; int val; + errno = 0; val = strtol(field[i], &cp, 10); + if (errno == ERANGE) + return DTERR_FIELD_OVERFLOW; /* * only a few kinds are allowed to have an embedded @@ -1863,7 +1869,10 @@ DecodeTimeOnly(char **field, int *ftype, int nf, break; } + errno = 0; val = strtol(field[i], &cp, 10); + if (errno == ERANGE) + return DTERR_FIELD_OVERFLOW; /* * only a few kinds are allowed to have an embedded @@ -2405,11 +2414,17 @@ DecodeTime(char *str, int fmask, int *tmask, struct tm * tm, fsec_t *fsec) *tmask = DTK_TIME_M; + errno = 0; tm->tm_hour = strtol(str, &cp, 10); + if (errno == ERANGE) + return DTERR_FIELD_OVERFLOW; if (*cp != ':') return DTERR_BAD_FORMAT; str = cp + 1; + errno = 0; tm->tm_min = strtol(str, &cp, 10); + if (errno == ERANGE) + return DTERR_FIELD_OVERFLOW; if (*cp == '\0') { tm->tm_sec = 0; @@ -2420,7 +2435,10 @@ DecodeTime(char *str, int fmask, int *tmask, struct tm * tm, fsec_t *fsec) else { str = cp + 1; + errno = 0; tm->tm_sec = strtol(str, &cp, 10); + if (errno == ERANGE) + return DTERR_FIELD_OVERFLOW; if (*cp == '\0') *fsec = 0; else if (*cp == '.') @@ -2474,7 +2492,10 @@ DecodeNumber(int flen, char *str, bool haveTextMonth, int fmask, *tmask = 0; + errno = 0; val = strtol(str, &cp, 10); + if (errno == ERANGE) + return DTERR_FIELD_OVERFLOW; if (cp == str) return DTERR_BAD_FORMAT; @@ -2762,11 +2783,19 @@ DecodeTimezone(char *str, int *tzp) if (*str != '+' && *str != '-') return DTERR_BAD_FORMAT; + errno = 0; hr = strtol((str + 1), &cp, 10); + if (errno == ERANGE) + return DTERR_TZDISP_OVERFLOW; /* explicit delimiter? */ if (*cp == ':') + { + errno = 0; min = strtol((cp + 1), &cp, 10); + if (errno == ERANGE) + return DTERR_TZDISP_OVERFLOW; + } /* otherwise, might have run things together... */ else if ((*cp == '\0') && (strlen(str) > 3)) { @@ -3011,7 +3040,10 @@ DecodeInterval(char **field, int *ftype, int nf, int *dtype, struct tm * tm, fse case DTK_DATE: case DTK_NUMBER: + errno = 0; val = strtol(field[i], &cp, 10); + if (errno == ERANGE) + return DTERR_FIELD_OVERFLOW; if (type == IGNORE_DTF) type = DTK_SECOND;