From 7be39bb0be87a2fe6ea64c9d48130b78412968a8 Mon Sep 17 00:00:00 2001
From: Heikki Linnakangas <heikki.linnakangas@iki.fi>
Date: Fri, 4 Sep 2009 11:20:23 +0000
Subject: [PATCH] Tigthen binary receive functions so that they reject values
 that the text 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 | 11 ++++++++++-
 src/backend/utils/adt/date.c       | 13 +++++++++++--
 src/backend/utils/adt/int.c        | 14 +++++++++++---
 src/backend/utils/adt/nabstime.c   | 17 +++++++++++------
 src/backend/utils/adt/oid.c        | 14 +++++++++++---
 src/backend/utils/adt/timestamp.c  |  7 ++++++-
 src/include/utils/datetime.h       |  4 +++-
 7 files changed, 63 insertions(+), 17 deletions(-)

diff --git a/src/backend/utils/adt/arrayfuncs.c b/src/backend/utils/adt/arrayfuncs.c
index 4e33bbe2ca9..e76734edd50 100644
--- a/src/backend/utils/adt/arrayfuncs.c
+++ b/src/backend/utils/adt/arrayfuncs.c
@@ -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 */
diff --git a/src/backend/utils/adt/date.c b/src/backend/utils/adt/date.c
index 85450e12cdb..2b82c20efe7 100644
--- a/src/backend/utils/adt/date.c
+++ b/src/backend/utils/adt/date.c
@@ -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);
 }
 
 /*
diff --git a/src/backend/utils/adt/int.c b/src/backend/utils/adt/int.c
index ad4df06572f..66cbca7079c 100644
--- a/src/backend/utils/adt/int.c
+++ b/src/backend/utils/adt/int.c
@@ -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);
 }
 
diff --git a/src/backend/utils/adt/nabstime.c b/src/backend/utils/adt/nabstime.c
index d1c41e138fe..8562679c957 100644
--- a/src/backend/utils/adt/nabstime.c
+++ b/src/backend/utils/adt/nabstime.c
@@ -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);
 }
 
diff --git a/src/backend/utils/adt/oid.c b/src/backend/utils/adt/oid.c
index d68a5a4ade0..0e46ee0314d 100644
--- a/src/backend/utils/adt/oid.c
+++ b/src/backend/utils/adt/oid.c
@@ -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);
 }
 
diff --git a/src/backend/utils/adt/timestamp.c b/src/backend/utils/adt/timestamp.c
index 9c020f2d10a..a0a61a726af 100644
--- a/src/backend/utils/adt/timestamp.c
+++ b/src/backend/utils/adt/timestamp.c
@@ -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 */
diff --git a/src/include/utils/datetime.h b/src/include/utils/datetime.h
index 1ba60b2dc30..3b1f161de3a 100644
--- a/src/include/utils/datetime.h
+++ b/src/include/utils/datetime.h
@@ -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) */
-- 
GitLab