From 866ffc2fe35f63b06fb6ed63ef1f531a741d920e Mon Sep 17 00:00:00 2001
From: Tom Lane <tgl@sss.pgh.pa.us>
Date: Mon, 15 Aug 2005 19:40:20 +0000
Subject: [PATCH] array_in() and array_recv() need to be more paranoid about
 validating their OID parameter.  It was possible to crash the backend with
 select array_in('{123}',0,0); because that would bypass the needed step of
 initializing the workspace.  These seem to be the only two places with a
 problem, though (record_in and record_recv don't have the issue, and the
 other array functions aren't depending on user-supplied input). Back-patch as
 far as 7.4; 7.3 does not have the bug.

---
 src/backend/utils/adt/arrayfuncs.c | 25 +++++++++++++------------
 1 file changed, 13 insertions(+), 12 deletions(-)

diff --git a/src/backend/utils/adt/arrayfuncs.c b/src/backend/utils/adt/arrayfuncs.c
index 07edd7014da..efb4ea9dc14 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.121 2005/07/10 21:13:58 tgl Exp $
+ *	  $PostgreSQL: pgsql/src/backend/utils/adt/arrayfuncs.c,v 1.122 2005/08/15 19:40:20 tgl Exp $
  *
  *-------------------------------------------------------------------------
  */
@@ -160,7 +160,7 @@ array_in(PG_FUNCTION_ARGS)
 		fcinfo->flinfo->fn_extra = MemoryContextAlloc(fcinfo->flinfo->fn_mcxt,
 												 sizeof(ArrayMetaState));
 		my_extra = (ArrayMetaState *) fcinfo->flinfo->fn_extra;
-		my_extra->element_type = InvalidOid;
+		my_extra->element_type = ~element_type;
 	}
 
 	if (my_extra->element_type != element_type)
@@ -1173,15 +1173,6 @@ array_recv(PG_FUNCTION_ARGS)
 	}
 	nitems = ArrayGetNItems(ndim, dim);
 
-	if (nitems == 0)
-	{
-		/* Return empty array */
-		retval = (ArrayType *) palloc0(sizeof(ArrayType));
-		retval->size = sizeof(ArrayType);
-		retval->elemtype = element_type;
-		PG_RETURN_ARRAYTYPE_P(retval);
-	}
-
 	/*
 	 * We arrange to look up info about element type, including its
 	 * receive conversion proc, only once per series of calls, assuming
@@ -1193,7 +1184,7 @@ array_recv(PG_FUNCTION_ARGS)
 		fcinfo->flinfo->fn_extra = MemoryContextAlloc(fcinfo->flinfo->fn_mcxt,
 												 sizeof(ArrayMetaState));
 		my_extra = (ArrayMetaState *) fcinfo->flinfo->fn_extra;
-		my_extra->element_type = InvalidOid;
+		my_extra->element_type = ~element_type;
 	}
 
 	if (my_extra->element_type != element_type)
@@ -1212,6 +1203,16 @@ array_recv(PG_FUNCTION_ARGS)
 					  fcinfo->flinfo->fn_mcxt);
 		my_extra->element_type = element_type;
 	}
+
+	if (nitems == 0)
+	{
+		/* Return empty array ... but not till we've validated element_type */
+		retval = (ArrayType *) palloc0(sizeof(ArrayType));
+		retval->size = sizeof(ArrayType);
+		retval->elemtype = element_type;
+		PG_RETURN_ARRAYTYPE_P(retval);
+	}
+
 	typlen = my_extra->typlen;
 	typbyval = my_extra->typbyval;
 	typalign = my_extra->typalign;
-- 
GitLab