]> granicus.if.org Git - postgresql/blobdiff - src/backend/utils/adt/date.c
Update copyright for the year 2010.
[postgresql] / src / backend / utils / adt / date.c
index ffeb7541093d0cd82238d99578846a9d6cf03a32..c722e47e352e18ae2bb378b37b122c91461360ed 100644 (file)
@@ -3,12 +3,12 @@
  * date.c
  *       implements DATE and TIME data types specified in SQL-92 standard
  *
- * Portions Copyright (c) 1996-2008, PostgreSQL Global Development Group
+ * Portions Copyright (c) 1996-2010, PostgreSQL Global Development Group
  * Portions Copyright (c) 1994-5, Regents of the University of California
  *
  *
  * IDENTIFICATION
- *       $PostgreSQL: pgsql/src/backend/utils/adt/date.c,v 1.143 2008/10/14 17:12:33 tgl Exp $
+ *       $PostgreSQL: pgsql/src/backend/utils/adt/date.c,v 1.150 2010/01/02 16:57:53 momjian Exp $
  *
  *-------------------------------------------------------------------------
  */
@@ -203,8 +203,18 @@ Datum
 date_recv(PG_FUNCTION_ARGS)
 {
        StringInfo      buf = (StringInfo) PG_GETARG_POINTER(0);
+       DateADT result;
 
-       PG_RETURN_DATEADT((DateADT) pq_getmsgint(buf, sizeof(DateADT)));
+       result = (DateADT) pq_getmsgint(buf, sizeof(DateADT));
+
+       /* Limit to the same range that date_in() accepts. */
+       if (result < -POSTGRES_EPOCH_JDATE ||
+               result >= JULIAN_MAX - POSTGRES_EPOCH_JDATE)
+               ereport(ERROR,
+                               (errcode(ERRCODE_DATETIME_VALUE_OUT_OF_RANGE),
+                                errmsg("date out of range")));
+
+       PG_RETURN_DATEADT(result);
 }
 
 /*
@@ -231,7 +241,7 @@ EncodeSpecialDate(DateADT dt, char *str)
                strcpy(str, EARLY);
        else if (DATE_IS_NOEND(dt))
                strcpy(str, LATE);
-       else                                            /* shouldn't happen */
+       else    /* shouldn't happen */
                elog(ERROR, "invalid argument for EncodeSpecialDate");
 }
 
@@ -1088,8 +1098,18 @@ time_recv(PG_FUNCTION_ARGS)
 
 #ifdef HAVE_INT64_TIMESTAMP
        result = pq_getmsgint64(buf);
+
+       if (result < INT64CONST(0) || result > USECS_PER_DAY)
+               ereport(ERROR,
+                               (errcode(ERRCODE_DATETIME_VALUE_OUT_OF_RANGE),
+                                errmsg("time out of range")));
 #else
        result = pq_getmsgfloat8(buf);
+
+       if (result < 0 || result > (double) SECS_PER_DAY)
+               ereport(ERROR,
+                               (errcode(ERRCODE_DATETIME_VALUE_OUT_OF_RANGE),
+                                errmsg("time out of range")));
 #endif
 
        AdjustTimeForTypmod(&result, typmod);
@@ -1691,7 +1711,7 @@ time_part(PG_FUNCTION_ARGS)
                {
                        case DTK_MICROSEC:
 #ifdef HAVE_INT64_TIMESTAMP
-                               result = tm->tm_sec * USECS_PER_SEC + fsec;
+                               result = tm->tm_sec * 1000000.0 + fsec;
 #else
                                result = (tm->tm_sec + fsec) * 1000000;
 #endif
@@ -1699,7 +1719,7 @@ time_part(PG_FUNCTION_ARGS)
 
                        case DTK_MILLISEC:
 #ifdef HAVE_INT64_TIMESTAMP
-                               result = tm->tm_sec * INT64CONST(1000) + fsec / INT64CONST(1000);
+                               result = tm->tm_sec * 1000.0 + fsec / 1000.0;
 #else
                                result = (tm->tm_sec + fsec) * 1000;
 #endif
@@ -1707,7 +1727,7 @@ time_part(PG_FUNCTION_ARGS)
 
                        case DTK_SECOND:
 #ifdef HAVE_INT64_TIMESTAMP
-                               result = tm->tm_sec + fsec / USECS_PER_SEC;
+                               result = tm->tm_sec + fsec / 1000000.0;
 #else
                                result = tm->tm_sec + fsec;
 #endif
@@ -1853,11 +1873,29 @@ timetz_recv(PG_FUNCTION_ARGS)
 
 #ifdef HAVE_INT64_TIMESTAMP
        result->time = pq_getmsgint64(buf);
+
+       if (result->time < INT64CONST(0) || result->time > USECS_PER_DAY)
+               ereport(ERROR,
+                               (errcode(ERRCODE_DATETIME_VALUE_OUT_OF_RANGE),
+                                errmsg("time out of range")));
 #else
        result->time = pq_getmsgfloat8(buf);
+
+       if (result->time < 0 || result->time > (double) SECS_PER_DAY)
+               ereport(ERROR,
+                               (errcode(ERRCODE_DATETIME_VALUE_OUT_OF_RANGE),
+                                errmsg("time out of range")));
 #endif
+
        result->zone = pq_getmsgint(buf, sizeof(result->zone));
 
+       /* we allow GMT displacements up to 14:59:59, cf DecodeTimezone() */
+       if (result->zone <= -15 * SECS_PER_HOUR ||
+               result->zone >= 15 * SECS_PER_HOUR)
+               ereport(ERROR,
+                               (errcode(ERRCODE_INVALID_TIME_ZONE_DISPLACEMENT_VALUE),
+                                errmsg("time zone displacement out of range")));
+
        AdjustTimeForTypmod(&(result->time), typmod);
 
        PG_RETURN_TIMETZADT_P(result);
@@ -2441,7 +2479,7 @@ timetz_part(PG_FUNCTION_ARGS)
 
                        case DTK_MICROSEC:
 #ifdef HAVE_INT64_TIMESTAMP
-                               result = tm->tm_sec * USECS_PER_SEC + fsec;
+                               result = tm->tm_sec * 1000000.0 + fsec;
 #else
                                result = (tm->tm_sec + fsec) * 1000000;
 #endif
@@ -2449,7 +2487,7 @@ timetz_part(PG_FUNCTION_ARGS)
 
                        case DTK_MILLISEC:
 #ifdef HAVE_INT64_TIMESTAMP
-                               result = tm->tm_sec * INT64CONST(1000) + fsec / INT64CONST(1000);
+                               result = tm->tm_sec * 1000.0 + fsec / 1000.0;
 #else
                                result = (tm->tm_sec + fsec) * 1000;
 #endif
@@ -2457,7 +2495,7 @@ timetz_part(PG_FUNCTION_ARGS)
 
                        case DTK_SECOND:
 #ifdef HAVE_INT64_TIMESTAMP
-                               result = tm->tm_sec + fsec / USECS_PER_SEC;
+                               result = tm->tm_sec + fsec / 1000000.0;
 #else
                                result = tm->tm_sec + fsec;
 #endif
@@ -2524,7 +2562,7 @@ timetz_zone(PG_FUNCTION_ARGS)
        pg_tz      *tzp;
 
        /*
-        * Look up the requested timezone.  First we look in the date token table
+        * Look up the requested timezone.      First we look in the date token table
         * (to handle cases like "EST"), and if that fails, we look in the
         * timezone database (to handle cases like "America/New_York").  (This
         * matches the order in which timestamp input checks the cases; it's