Tigthen binary receive functions so that they reject values that the text
authorHeikki Linnakangas
Fri, 4 Sep 2009 11:20:23 +0000 (11:20 +0000)
committerHeikki Linnakangas
Fri, 4 Sep 2009 11:20:23 +0000 (11:20 +0000)
input functions don't accept either. While the backend can handle such
values fine, they can cause trouble in clients and in pg_dump/restore.

This is followup to the original issue on time datatype reported by Andrew
McNamara a while ago. Like that one, none of these seem worth
back-patching.

src/backend/utils/adt/arrayfuncs.c
src/backend/utils/adt/date.c
src/backend/utils/adt/int.c
src/backend/utils/adt/nabstime.c
src/backend/utils/adt/oid.c
src/backend/utils/adt/timestamp.c
src/include/utils/datetime.h

index 4e33bbe2ca9adc150116e08213a2f9c4b3e0666f..e76734edd507d1a60331e0e949095286b5045ac3 100644 (file)
@@ -8,7 +8,7 @@
  *
  *
  * IDENTIFICATION
- *   $PostgreSQL: pgsql/src/backend/utils/adt/arrayfuncs.c,v 1.160 2009/06/22 04:37:18 tgl Exp $
+ *   $PostgreSQL: pgsql/src/backend/utils/adt/arrayfuncs.c,v 1.161 2009/09/04 11:20:22 heikki Exp $
  *
  *-------------------------------------------------------------------------
  */
@@ -1207,8 +1207,17 @@ array_recv(PG_FUNCTION_ARGS)
 
    for (i = 0; i < ndim; i++)
    {
+       int ub;
+
        dim[i] = pq_getmsgint(buf, 4);
        lBound[i] = pq_getmsgint(buf, 4);
+
+       ub = lBound[i] + dim[i] - 1;
+       /* overflow? */
+       if (lBound[i] > ub)
+           ereport(ERROR,
+                   (errcode(ERRCODE_NUMERIC_VALUE_OUT_OF_RANGE),
+                    errmsg("integer out of range")));
    }
 
    /* This checks for overflow of array dimensions */
index 85450e12cdb9b951926b761ee1937eed4332f245..2b82c20efe7334bebbcd7d37dd1050852b4835dc 100644 (file)
@@ -8,7 +8,7 @@
  *
  *
  * IDENTIFICATION
- *   $PostgreSQL: pgsql/src/backend/utils/adt/date.c,v 1.147 2009/07/29 22:19:18 tgl Exp $
+ *   $PostgreSQL: pgsql/src/backend/utils/adt/date.c,v 1.148 2009/09/04 11:20:22 heikki Exp $
  *
  *-------------------------------------------------------------------------
  */
@@ -203,8 +203,17 @@ 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 < 0 || result > JULIAN_MAX)
+       ereport(ERROR,
+               (errcode(ERRCODE_DATETIME_VALUE_OUT_OF_RANGE),
+                errmsg("date out of range")));
+
+   PG_RETURN_DATEADT(result);
 }
 
 /*
index ad4df06572f8e5d4584ff04694dc81b3e7292309..66cbca7079c9c430097cf8f82a7c62129f6125d9 100644 (file)
@@ -8,7 +8,7 @@
  *
  *
  * IDENTIFICATION
- *   $PostgreSQL: pgsql/src/backend/utils/adt/int.c,v 1.85 2009/09/03 18:48:14 tgl Exp $
+ *   $PostgreSQL: pgsql/src/backend/utils/adt/int.c,v 1.86 2009/09/04 11:20:22 heikki Exp $
  *
  *-------------------------------------------------------------------------
  */
@@ -225,13 +225,21 @@ int2vectorrecv(PG_FUNCTION_ARGS)
 
    Assert(!locfcinfo.isnull);
 
-   /* sanity checks: int2vector must be 1-D, no nulls */
+   /* sanity checks: int2vector must be 1-D, 0-based, no nulls */
    if (ARR_NDIM(result) != 1 ||
        ARR_HASNULL(result) ||
-       ARR_ELEMTYPE(result) != INT2OID)
+       ARR_ELEMTYPE(result) != INT2OID ||
+       ARR_LBOUND(result)[0] != 0)
        ereport(ERROR,
                (errcode(ERRCODE_INVALID_BINARY_REPRESENTATION),
                 errmsg("invalid int2vector data")));
+
+   /* check length for consistency with int2vectorin() */
+   if (ARR_DIMS(result)[0] > FUNC_MAX_ARGS)
+       ereport(ERROR,
+               (errcode(ERRCODE_INVALID_PARAMETER_VALUE),
+                errmsg("oidvector has too many elements")));
+
    PG_RETURN_POINTER(result);
 }
 
index d1c41e138fec07eeef0d157b146880227b33cac2..8562679c957a4e9486f484f4111ce320010ec606 100644 (file)
@@ -10,7 +10,7 @@
  *
  *
  * IDENTIFICATION
- *   $PostgreSQL: pgsql/src/backend/utils/adt/nabstime.c,v 1.161 2009/06/11 14:49:03 momjian Exp $
+ *   $PostgreSQL: pgsql/src/backend/utils/adt/nabstime.c,v 1.162 2009/09/04 11:20:22 heikki Exp $
  *
  *-------------------------------------------------------------------------
  */
@@ -786,20 +786,25 @@ tintervalrecv(PG_FUNCTION_ARGS)
 {
    StringInfo  buf = (StringInfo) PG_GETARG_POINTER(0);
    TimeInterval tinterval;
+   int32 status;
 
    tinterval = (TimeInterval) palloc(sizeof(TimeIntervalData));
 
    tinterval->status = pq_getmsgint(buf, sizeof(tinterval->status));
+   tinterval->data[0] = pq_getmsgint(buf, sizeof(tinterval->data[0]));
+   tinterval->data[1] = pq_getmsgint(buf, sizeof(tinterval->data[1]));
+
+   if (tinterval->data[0] == INVALID_ABSTIME ||
+       tinterval->data[1] == INVALID_ABSTIME)
+       status = T_INTERVAL_INVAL;  /* undefined  */
+   else
+       status = T_INTERVAL_VALID;
 
-   if (!(tinterval->status == T_INTERVAL_INVAL ||
-         tinterval->status == T_INTERVAL_VALID))
+   if (status != tinterval->status)
        ereport(ERROR,
                (errcode(ERRCODE_INVALID_BINARY_REPRESENTATION),
                 errmsg("invalid status in external \"tinterval\" value")));
 
-   tinterval->data[0] = pq_getmsgint(buf, sizeof(tinterval->data[0]));
-   tinterval->data[1] = pq_getmsgint(buf, sizeof(tinterval->data[1]));
-
    PG_RETURN_TIMEINTERVAL(tinterval);
 }
 
index d68a5a4ade0c8f88c0e058dfbbc05f52bc6ff75f..0e46ee0314dad34e15f10a3413fd476402365d38 100644 (file)
@@ -8,7 +8,7 @@
  *
  *
  * IDENTIFICATION
- *   $PostgreSQL: pgsql/src/backend/utils/adt/oid.c,v 1.74 2009/01/01 17:23:49 momjian Exp $
+ *   $PostgreSQL: pgsql/src/backend/utils/adt/oid.c,v 1.75 2009/09/04 11:20:22 heikki Exp $
  *
  *-------------------------------------------------------------------------
  */
@@ -276,13 +276,21 @@ oidvectorrecv(PG_FUNCTION_ARGS)
 
    Assert(!locfcinfo.isnull);
 
-   /* sanity checks: oidvector must be 1-D, no nulls */
+   /* sanity checks: oidvector must be 1-D, 0-based, no nulls */
    if (ARR_NDIM(result) != 1 ||
        ARR_HASNULL(result) ||
-       ARR_ELEMTYPE(result) != OIDOID)
+       ARR_ELEMTYPE(result) != OIDOID ||
+       ARR_LBOUND(result)[0] != 0)
        ereport(ERROR,
                (errcode(ERRCODE_INVALID_BINARY_REPRESENTATION),
                 errmsg("invalid oidvector data")));
+
+   /* check length for consistency with oidvectorin() */
+   if (ARR_DIMS(result)[0] > FUNC_MAX_ARGS)
+       ereport(ERROR,
+               (errcode(ERRCODE_INVALID_PARAMETER_VALUE),
+                errmsg("oidvector has too many elements")));
+
    PG_RETURN_POINTER(result);
 }
 
index 9c020f2d10ac39935764d1992115c9a6142a2d48..a0a61a726af225b027789cce5a2f47e511c48f96 100644 (file)
@@ -8,7 +8,7 @@
  *
  *
  * IDENTIFICATION
- *   $PostgreSQL: pgsql/src/backend/utils/adt/timestamp.c,v 1.202 2009/07/06 20:29:23 tgl Exp $
+ *   $PostgreSQL: pgsql/src/backend/utils/adt/timestamp.c,v 1.203 2009/09/04 11:20:22 heikki Exp $
  *
  *-------------------------------------------------------------------------
  */
@@ -253,6 +253,11 @@ timestamp_recv(PG_FUNCTION_ARGS)
    timestamp = (Timestamp) pq_getmsgint64(buf);
 #else
    timestamp = (Timestamp) pq_getmsgfloat8(buf);
+
+   if (isnan(timestamp))
+       ereport(ERROR,
+               (errcode(ERRCODE_DATETIME_VALUE_OUT_OF_RANGE),
+                errmsg("timestamp cannot be NaN")));
 #endif
 
    /* rangecheck: see if timestamp_out would like it */
index 1ba60b2dc3026936610ace27fd511a94b71a3cee..3b1f161de3a8da58e5a55a1f10a8a56a4eb013c6 100644 (file)
@@ -9,7 +9,7 @@
  * Portions Copyright (c) 1996-2009, PostgreSQL Global Development Group
  * Portions Copyright (c) 1994, Regents of the University of California
  *
- * $PostgreSQL: pgsql/src/include/utils/datetime.h,v 1.75 2009/06/11 14:49:13 momjian Exp $
+ * $PostgreSQL: pgsql/src/include/utils/datetime.h,v 1.76 2009/09/04 11:20:23 heikki Exp $
  *
  *-------------------------------------------------------------------------
  */
@@ -262,6 +262,8 @@ extern const int day_tab[2][13];
   || (((m) == JULIAN_MINMONTH) && ((d) >= JULIAN_MINDAY))))) \
  && ((y) < JULIAN_MAXYEAR))
 
+#define JULIAN_MAX (2145031948) /* == date2j(JULIAN_MAXYEAR, 1 ,1) */
+
 /* Julian-date equivalents of Day 0 in Unix and Postgres reckoning */
 #define UNIX_EPOCH_JDATE       2440588 /* == date2j(1970, 1, 1) */
 #define POSTGRES_EPOCH_JDATE   2451545 /* == date2j(2000, 1, 1) */