Location via proxy:   [ UP ]  
[Report a bug]   [Manage cookies]                
Skip to content

Commit 5e4dd86

Browse files
committed
Add range-checking in timestamp_recv and timestamptz_recv, per
Stephen Frost. Also tighten date range check in timestamp2tm.
1 parent 90015d4 commit 5e4dd86

File tree

1 file changed

+42
-17
lines changed

1 file changed

+42
-17
lines changed

src/backend/utils/adt/timestamp.c

Lines changed: 42 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@
88
*
99
*
1010
* IDENTIFICATION
11-
* $PostgreSQL: pgsql/src/backend/utils/adt/timestamp.c,v 1.108 2004/06/03 02:08:04 tgl Exp $
11+
* $PostgreSQL: pgsql/src/backend/utils/adt/timestamp.c,v 1.109 2004/06/03 17:57:09 tgl Exp $
1212
*
1313
*-------------------------------------------------------------------------
1414
*/
@@ -166,12 +166,26 @@ Datum
166166
timestamp_recv(PG_FUNCTION_ARGS)
167167
{
168168
StringInfo buf = (StringInfo) PG_GETARG_POINTER(0);
169+
Timestamp timestamp;
170+
struct pg_tm tt,
171+
*tm = &tt;
172+
fsec_t fsec;
169173

170174
#ifdef HAVE_INT64_TIMESTAMP
171-
PG_RETURN_TIMESTAMP((Timestamp) pq_getmsgint64(buf));
175+
timestamp = (Timestamp) pq_getmsgint64(buf);
172176
#else
173-
PG_RETURN_TIMESTAMP((Timestamp) pq_getmsgfloat8(buf));
177+
timestamp = (Timestamp) pq_getmsgfloat8(buf);
174178
#endif
179+
180+
/* rangecheck: see if timestamp_out would like it */
181+
if (TIMESTAMP_NOT_FINITE(timestamp))
182+
/* ok */;
183+
else if (timestamp2tm(timestamp, NULL, tm, &fsec, NULL) != 0)
184+
ereport(ERROR,
185+
(errcode(ERRCODE_DATETIME_VALUE_OUT_OF_RANGE),
186+
errmsg("timestamp out of range")));
187+
188+
PG_RETURN_TIMESTAMP(timestamp);
175189
}
176190

177191
/*
@@ -393,12 +407,28 @@ Datum
393407
timestamptz_recv(PG_FUNCTION_ARGS)
394408
{
395409
StringInfo buf = (StringInfo) PG_GETARG_POINTER(0);
410+
TimestampTz timestamp;
411+
int tz;
412+
struct pg_tm tt,
413+
*tm = &tt;
414+
fsec_t fsec;
415+
char *tzn;
396416

397417
#ifdef HAVE_INT64_TIMESTAMP
398-
PG_RETURN_TIMESTAMPTZ((TimestampTz) pq_getmsgint64(buf));
418+
timestamp = (TimestampTz) pq_getmsgint64(buf);
399419
#else
400-
PG_RETURN_TIMESTAMPTZ((TimestampTz) pq_getmsgfloat8(buf));
420+
timestamp = (TimestampTz) pq_getmsgfloat8(buf);
401421
#endif
422+
423+
/* rangecheck: see if timestamptz_out would like it */
424+
if (TIMESTAMP_NOT_FINITE(timestamp))
425+
/* ok */;
426+
else if (timestamp2tm(timestamp, &tz, tm, &fsec, &tzn) != 0)
427+
ereport(ERROR,
428+
(errcode(ERRCODE_DATETIME_VALUE_OUT_OF_RANGE),
429+
errmsg("timestamp out of range")));
430+
431+
PG_RETURN_TIMESTAMPTZ(timestamp);
402432
}
403433

404434
/*
@@ -933,13 +963,8 @@ dt2time(Timestamp jd, int *hour, int *min, int *sec, fsec_t *fsec)
933963
int
934964
timestamp2tm(Timestamp dt, int *tzp, struct pg_tm *tm, fsec_t *fsec, char **tzn)
935965
{
936-
#ifdef HAVE_INT64_TIMESTAMP
937-
int date;
938-
int64 time;
939-
#else
940-
double date;
941-
double time;
942-
#endif
966+
Timestamp date;
967+
Timestamp time;
943968
pg_time_t utime;
944969

945970
/*
@@ -950,7 +975,7 @@ timestamp2tm(Timestamp dt, int *tzp, struct pg_tm *tm, fsec_t *fsec, char **tzn)
950975
if (HasCTZSet && (tzp != NULL))
951976
{
952977
#ifdef HAVE_INT64_TIMESTAMP
953-
dt -= (CTimeZone * INT64CONST(1000000));
978+
dt -= CTimeZone * INT64CONST(1000000);
954979
#else
955980
dt -= CTimeZone;
956981
#endif
@@ -975,13 +1000,13 @@ timestamp2tm(Timestamp dt, int *tzp, struct pg_tm *tm, fsec_t *fsec, char **tzn)
9751000
}
9761001
#endif
9771002

978-
/* Julian day routine does not work for negative Julian days */
979-
if (date < -POSTGRES_EPOCH_JDATE)
980-
return -1;
981-
9821003
/* add offset to go from J2000 back to standard Julian date */
9831004
date += POSTGRES_EPOCH_JDATE;
9841005

1006+
/* Julian day routine does not work for negative Julian days */
1007+
if (date < 0 || date > (Timestamp) INT_MAX)
1008+
return -1;
1009+
9851010
j2date((int) date, &tm->tm_year, &tm->tm_mon, &tm->tm_mday);
9861011
dt2time(time, &tm->tm_hour, &tm->tm_min, &tm->tm_sec, fsec);
9871012

0 commit comments

Comments
 (0)