Andres Freund <and...@anarazel.de> writes:
> On 2023-01-15 14:39:41 -0500, Tom Lane wrote:
>> But I suppose we are stuck with that, seeing that this datatype choice
>> is effectively part of the logrep protocol now.  I think the only
>> reasonable solution is to get rid of the FUNC_MAX_ARGS restriction
>> in int2vectorin.  We probably ought to back-patch that as far as
>> pg_publication_rel.prattrs exists, too.

> Are you thinking of introducing another, or just "rely" on too long arrays to
> trigger errors when forming tuples?

There's enough protections already, eg repalloc will complain if you
try to go past 1GB.  I'm thinking of the attached for HEAD (it'll
take minor mods to back-patch).

                        regards, tom lane

diff --git a/src/backend/utils/adt/int.c b/src/backend/utils/adt/int.c
index e47c15a54f..44d1c7ad0c 100644
--- a/src/backend/utils/adt/int.c
+++ b/src/backend/utils/adt/int.c
@@ -143,11 +143,13 @@ int2vectorin(PG_FUNCTION_ARGS)
 	char	   *intString = PG_GETARG_CSTRING(0);
 	Node	   *escontext = fcinfo->context;
 	int2vector *result;
+	int			nalloc;
 	int			n;
 
-	result = (int2vector *) palloc0(Int2VectorSize(FUNC_MAX_ARGS));
+	nalloc = 32;				/* arbitrary initial size guess */
+	result = (int2vector *) palloc0(Int2VectorSize(nalloc));
 
-	for (n = 0; n < FUNC_MAX_ARGS; n++)
+	for (n = 0;; n++)
 	{
 		long		l;
 		char	   *endp;
@@ -157,6 +159,12 @@ int2vectorin(PG_FUNCTION_ARGS)
 		if (*intString == '\0')
 			break;
 
+		if (n >= nalloc)
+		{
+			nalloc *= 2;
+			result = (int2vector *) repalloc(result, Int2VectorSize(nalloc));
+		}
+
 		errno = 0;
 		l = strtol(intString, &endp, 10);
 
@@ -176,17 +184,11 @@ int2vectorin(PG_FUNCTION_ARGS)
 			ereturn(escontext, (Datum) 0,
 					(errcode(ERRCODE_INVALID_TEXT_REPRESENTATION),
 					 errmsg("invalid input syntax for type %s: \"%s\"",
-							"integer", intString)));
+							"smallint", intString)));
 
 		result->values[n] = l;
 		intString = endp;
 	}
-	while (*intString && isspace((unsigned char) *intString))
-		intString++;
-	if (*intString)
-		ereturn(escontext, (Datum) 0,
-				(errcode(ERRCODE_INVALID_PARAMETER_VALUE),
-				 errmsg("int2vector has too many elements")));
 
 	SET_VARSIZE(result, Int2VectorSize(n));
 	result->ndim = 1;
@@ -261,12 +263,6 @@ int2vectorrecv(PG_FUNCTION_ARGS)
 				(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/oid.c b/src/backend/utils/adt/oid.c
index 697588313d..3f7af5b3a0 100644
--- a/src/backend/utils/adt/oid.c
+++ b/src/backend/utils/adt/oid.c
@@ -115,27 +115,30 @@ oidvectorin(PG_FUNCTION_ARGS)
 	char	   *oidString = PG_GETARG_CSTRING(0);
 	Node	   *escontext = fcinfo->context;
 	oidvector  *result;
+	int			nalloc;
 	int			n;
 
-	result = (oidvector *) palloc0(OidVectorSize(FUNC_MAX_ARGS));
+	nalloc = 32;				/* arbitrary initial size guess */
+	result = (oidvector *) palloc0(OidVectorSize(nalloc));
 
-	for (n = 0; n < FUNC_MAX_ARGS; n++)
+	for (n = 0;; n++)
 	{
 		while (*oidString && isspace((unsigned char) *oidString))
 			oidString++;
 		if (*oidString == '\0')
 			break;
+
+		if (n >= nalloc)
+		{
+			nalloc *= 2;
+			result = (oidvector *) repalloc(result, OidVectorSize(nalloc));
+		}
+
 		result->values[n] = uint32in_subr(oidString, &oidString,
 										  "oid", escontext);
 		if (SOFT_ERROR_OCCURRED(escontext))
 			PG_RETURN_NULL();
 	}
-	while (*oidString && isspace((unsigned char) *oidString))
-		oidString++;
-	if (*oidString)
-		ereturn(escontext, (Datum) 0,
-				(errcode(ERRCODE_INVALID_PARAMETER_VALUE),
-				 errmsg("oidvector has too many elements")));
 
 	SET_VARSIZE(result, OidVectorSize(n));
 	result->ndim = 1;
@@ -212,12 +215,6 @@ oidvectorrecv(PG_FUNCTION_ARGS)
 				(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);
 }
 

Reply via email to