Check integer conversion for overflow in datetime functions. Problem reported by Christopher Kings-Lynne:
http://archives.postgresql.org/pgsql-hackers/2005-11/msg01385.php In one place (line 60 in the patch) the code sets errno to 0 when it should still be 0 after similar code a few lines above (otherwise the function would have returned an error). I wasn't sure what would be preferred: clearing errno again "just to be sure," a comment explaining why it isn't necessary, or nothing at all. This patch should apply cleanly against HEAD and 8.1. If the patch looks good then I'll submit patches for earlier branches when I get a chance to build and test those versions. -- Michael Fuhr
Index: src/backend/utils/adt/datetime.c =================================================================== RCS file: /projects/cvsroot/pgsql/src/backend/utils/adt/datetime.c,v retrieving revision 1.160.2.1 diff -c -r1.160.2.1 datetime.c *** src/backend/utils/adt/datetime.c 22 Nov 2005 18:23:21 -0000 1.160.2.1 --- src/backend/utils/adt/datetime.c 1 Dec 2005 01:12:01 -0000 *************** *** 1013,1019 **** --- 1013,1022 ---- 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 */ *************** *** 1158,1164 **** --- 1161,1170 ---- 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 *************** *** 1915,1921 **** --- 1921,1930 ---- 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 *************** *** 2456,2466 **** --- 2465,2481 ---- *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; *************** *** 2471,2477 **** --- 2486,2495 ---- 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 == '.') *************** *** 2522,2528 **** --- 2540,2549 ---- *tmask = 0; + errno = 0; val = strtol(str, &cp, 10); + if (errno == ERANGE) + return DTERR_FIELD_OVERFLOW; if (cp == str) return DTERR_BAD_FORMAT; *************** *** 2809,2819 **** --- 2830,2848 ---- 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) { *************** *** 3056,3062 **** --- 3085,3094 ---- 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;
---------------------------(end of broadcast)--------------------------- TIP 2: Don't 'kill -9' the postmaster