Greetings,
The attached patch adds some error-checking to the timestamp_recv
function so that it's not possible to put an invalid timestamp into a
timestamp column (hopefully). The check is done in basically the
exact same way the out-of-bounds check in timestamp2tm is done.
There's probably an easier/cleaner way but this should work or at
least generate discussion and a better patch. :)
Thanks,
Stephen
Index: timestamp.c
===================================================================
RCS file: /projects/cvsroot/pgsql-server/src/backend/utils/adt/timestamp.c,v
retrieving revision 1.103
diff -u -r1.103 timestamp.c
--- timestamp.c 30 Mar 2004 15:53:18 -0000 1.103
+++ timestamp.c 5 Apr 2004 15:24:14 -0000
@@ -164,13 +164,47 @@
Datum
timestamp_recv(PG_FUNCTION_ARGS)
{
+ Timestamp time;
+#ifdef HAVE_INT64_TIMESTAMP
+ int date, date0;
+ int64 timetest;
+#else
+ double date, date0;
+ double timetest;
+#endif
StringInfo buf = (StringInfo) PG_GETARG_POINTER(0);
#ifdef HAVE_INT64_TIMESTAMP
- PG_RETURN_TIMESTAMP((Timestamp) pq_getmsgint64(buf));
+ time = pq_getmsgint64(buf);
+#else
+ time = pq_getmsgfloat8(buf);
+#endif
+
+ date0 = POSTGRES_EPOCH_JDATE;
+
+ /* Verify timestamp as valid */
+ /* Check if the timestamp is infinity or -infinity, if not then
+ * we need to verify that it's a valid, finite timestamp. */
+ timetest = time;
+ if(!TIMESTAMP_NOT_FINITE(timetest))
+ {
+#ifdef HAVE_INT64_TIMESTAMP
+ TMODULO(timetest, date, INT64CONST(86400000000));
+ if (timetest < INT64CONST(0))
+ date -= 1;
#else
- PG_RETURN_TIMESTAMP((Timestamp) pq_getmsgfloat8(buf));
+ TMODULO(timetest, date, 86400e0);
+ if (timetest < 0)
+ date -= 1;
#endif
+
+ if (date < -date0)
+ ereport(ERROR,
+ (errcode(ERRCODE_INVALID_BINARY_REPRESENTATION),
+ errmsg("invalid date in external \"timestamp\" value")));
+ }
+
+ PG_RETURN_TIMESTAMP(time);
}
/*
---------------------------(end of broadcast)---------------------------
TIP 6: Have you searched our list archives?
http://archives.postgresql.org