From: Tom Lane Date: Thu, 9 Feb 2006 03:40:42 +0000 (+0000) Subject: Reject out-of-range dates in date_in(). X-Git-Url: http://git.postgresql.org/gitweb/static/gitweb.js?a=commitdiff_plain;h=cc539bdd44c7cd7c23077a9c325d07693e45bfce;p=users%2Fbernd%2Fpostgres.git Reject out-of-range dates in date_in(). Kris Jurka --- diff --git a/doc/src/sgml/datatype.sgml b/doc/src/sgml/datatype.sgml index 02859de7b0..ff52183598 100644 --- a/doc/src/sgml/datatype.sgml +++ b/doc/src/sgml/datatype.sgml @@ -1358,7 +1358,7 @@ SELECT b, char_length(b) FROM test2; 4 bytes dates only 4713 BC - 32767 AD + 5874897 AD 1 day @@ -1645,7 +1645,7 @@ SELECT b, char_length(b) FROM test2; 04:05 PM - same as 16:05; input hour must be <= 12 + same as 16:05; input hour must be <= 12 04:05:06.789-8 @@ -2367,7 +2367,7 @@ SELECT * FROM test1 WHERE a; circle 24 bytes Circle - <(x,y),r> (center and radius) + <(x,y),r> (center and radius) diff --git a/src/backend/utils/adt/date.c b/src/backend/utils/adt/date.c index e7d36eec64..6a94674cf4 100644 --- a/src/backend/utils/adt/date.c +++ b/src/backend/utils/adt/date.c @@ -65,12 +65,10 @@ date_in(PG_FUNCTION_ARGS) int dterr; char *field[MAXDATEFIELDS]; int ftype[MAXDATEFIELDS]; - char lowstr[MAXDATELEN + 1]; + char workbuf[MAXDATELEN + 1]; - if (strlen(str) >= sizeof(lowstr)) - dterr = DTERR_BAD_FORMAT; - else - dterr = ParseDateTime(str, lowstr, field, ftype, MAXDATEFIELDS, &nf); + dterr = ParseDateTime(str, workbuf, sizeof(workbuf), + field, ftype, MAXDATEFIELDS, &nf); if (dterr == 0) dterr = DecodeDateTime(field, ftype, nf, &dtype, tm, &fsec, &tzp); if (dterr != 0) @@ -98,6 +96,11 @@ date_in(PG_FUNCTION_ARGS) break; } + if (!IS_VALID_JULIAN(tm->tm_year, tm->tm_mon, tm->tm_mday)) + ereport(ERROR, + (errcode(ERRCODE_DATETIME_VALUE_OUT_OF_RANGE), + errmsg("date out of range: \"%s\"", str))); + date = date2j(tm->tm_year, tm->tm_mon, tm->tm_mday) - POSTGRES_EPOCH_JDATE; PG_RETURN_DATEADT(date); @@ -894,15 +897,13 @@ time_in(PG_FUNCTION_ARGS) int tz; int nf; int dterr; - char lowstr[MAXDATELEN + 1]; + char workbuf[MAXDATELEN + 1]; char *field[MAXDATEFIELDS]; int dtype; int ftype[MAXDATEFIELDS]; - if (strlen(str) >= sizeof(lowstr)) - dterr = DTERR_BAD_FORMAT; - else - dterr = ParseDateTime(str, lowstr, field, ftype, MAXDATEFIELDS, &nf); + dterr = ParseDateTime(str, workbuf, sizeof(workbuf), + field, ftype, MAXDATEFIELDS, &nf); if (dterr == 0) dterr = DecodeTimeOnly(field, ftype, nf, &dtype, tm, &fsec, &tz); if (dterr != 0) @@ -1734,15 +1735,13 @@ timetz_in(PG_FUNCTION_ARGS) int tz; int nf; int dterr; - char lowstr[MAXDATELEN + 1]; + char workbuf[MAXDATELEN + 1]; char *field[MAXDATEFIELDS]; int dtype; int ftype[MAXDATEFIELDS]; - if (strlen(str) >= sizeof(lowstr)) - dterr = DTERR_BAD_FORMAT; - else - dterr = ParseDateTime(str, lowstr, field, ftype, MAXDATEFIELDS, &nf); + dterr = ParseDateTime(str, workbuf, sizeof(workbuf), + field, ftype, MAXDATEFIELDS, &nf); if (dterr == 0) dterr = DecodeTimeOnly(field, ftype, nf, &dtype, tm, &fsec, &tz); if (dterr != 0) @@ -1869,12 +1868,20 @@ timetz_scale(PG_FUNCTION_ARGS) static int timetz_cmp_internal(TimeTzADT *time1, TimeTzADT *time2) { + /* Primary sort is by true (GMT-equivalent) time */ +#ifdef HAVE_INT64_TIMESTAMP + int64 t1, + t2; + + t1 = time1->time + (time1->zone * INT64CONST(1000000)); + t2 = time2->time + (time2->zone * INT64CONST(1000000)); +#else double t1, t2; - /* Primary sort is by true (GMT-equivalent) time */ t1 = time1->time + time1->zone; t2 = time2->time + time2->zone; +#endif if (t1 > t2) return 1; @@ -2443,9 +2450,9 @@ timetz_part(PG_FUNCTION_ARGS) else if ((type == RESERV) && (val == DTK_EPOCH)) { #ifdef HAVE_INT64_TIMESTAMP - result = ((time->time / 1000000e0) - time->zone); + result = ((time->time / 1000000e0) + time->zone); #else - result = (time->time - time->zone); + result = (time->time + time->zone); #endif } else