From 177af51c04528f0edb4d5dc632297c3c796a47f9 Mon Sep 17 00:00:00 2001 From: Tom Lane Date: Tue, 3 May 2005 16:51:00 +0000 Subject: Change tsearch2 to not use the unsafe practice of creating functions that return INTERNAL without also having INTERNAL arguments. Since the functions in question aren't meant to be called by hand anyway, I just redeclared them to take 'internal' instead of 'text'. Also add code to ProcedureCreate() to enforce the restriction, as I should have done to start with :-( --- src/backend/catalog/pg_proc.c | 63 ++++++++++++++++++++++++++++--------------- 1 file changed, 41 insertions(+), 22 deletions(-) (limited to 'src') diff --git a/src/backend/catalog/pg_proc.c b/src/backend/catalog/pg_proc.c index 1f8b3388db2..12f6c64634f 100644 --- a/src/backend/catalog/pg_proc.c +++ b/src/backend/catalog/pg_proc.c @@ -8,7 +8,7 @@ * * * IDENTIFICATION - * $PostgreSQL: pgsql/src/backend/catalog/pg_proc.c,v 1.128 2005/04/14 20:03:23 tgl Exp $ + * $PostgreSQL: pgsql/src/backend/catalog/pg_proc.c,v 1.129 2005/05/03 16:51:00 tgl Exp $ * *------------------------------------------------------------------------- */ @@ -81,6 +81,9 @@ ProcedureCreate(const char *procedureName, int allParamCount; Oid *allParams; bool genericInParam = false; + bool genericOutParam = false; + bool internalInParam = false; + bool internalOutParam = false; Relation rel; HeapTuple tup; HeapTuple oldtup; @@ -133,43 +136,59 @@ ProcedureCreate(const char *procedureName, /* * Do not allow return type ANYARRAY or ANYELEMENT unless at least one - * input argument is also ANYARRAY or ANYELEMENT + * input argument is ANYARRAY or ANYELEMENT. Also, do not allow + * return type INTERNAL unless at least one input argument is INTERNAL. */ for (i = 0; i < parameterCount; i++) { - if (parameterTypes->values[i] == ANYARRAYOID || - parameterTypes->values[i] == ANYELEMENTOID) + switch (parameterTypes->values[i]) { - genericInParam = true; - break; + case ANYARRAYOID: + case ANYELEMENTOID: + genericInParam = true; + break; + case INTERNALOID: + internalInParam = true; + break; } } - if (!genericInParam) + if (allParameterTypes != PointerGetDatum(NULL)) { - bool genericOutParam = false; - - if (allParameterTypes != PointerGetDatum(NULL)) + for (i = 0; i < allParamCount; i++) { - for (i = 0; i < allParamCount; i++) + /* + * We don't bother to distinguish input and output params here, + * so if there is, say, just an input INTERNAL param then we will + * still set internalOutParam. This is OK since we don't really + * care. + */ + switch (allParams[i]) { - if (allParams[i] == ANYARRAYOID || - allParams[i] == ANYELEMENTOID) - { + case ANYARRAYOID: + case ANYELEMENTOID: genericOutParam = true; break; - } + case INTERNALOID: + internalOutParam = true; + break; } } - - if (returnType == ANYARRAYOID || returnType == ANYELEMENTOID || - genericOutParam) - ereport(ERROR, - (errcode(ERRCODE_INVALID_FUNCTION_DEFINITION), - errmsg("cannot determine result data type"), - errdetail("A function returning \"anyarray\" or \"anyelement\" must have at least one argument of either type."))); } + if ((returnType == ANYARRAYOID || returnType == ANYELEMENTOID || + genericOutParam) && !genericInParam) + ereport(ERROR, + (errcode(ERRCODE_INVALID_FUNCTION_DEFINITION), + errmsg("cannot determine result data type"), + errdetail("A function returning \"anyarray\" or \"anyelement\" must have at least one argument of either type."))); + + if ((returnType == INTERNALOID || internalOutParam) && !internalInParam) + ereport(ERROR, + (errcode(ERRCODE_INVALID_FUNCTION_DEFINITION), + errmsg("unsafe use of INTERNAL pseudo-type"), + errdetail("A function returning \"internal\" must have at least one \"internal\" argument."))); + /* * don't allow functions of complex types that have the same name as * existing attributes of the type -- cgit v1.2.3