Defend against function calls with more than 8 arguments (code

used to overrun its fixed-size arrays before detecting error; not cool).
Also, replace uses of magic constant '8' with 'MAXFARGS'.
This commit is contained in:
Tom Lane 1999-06-17 22:21:41 +00:00
parent 4c65382596
commit 5f74d499bf
4 changed files with 33 additions and 23 deletions

View File

@ -7,7 +7,7 @@
* *
* *
* IDENTIFICATION * IDENTIFICATION
* $Header: /cvsroot/pgsql/src/backend/parser/parse_coerce.c,v 2.17 1999/05/29 03:17:19 tgl Exp $ * $Header: /cvsroot/pgsql/src/backend/parser/parse_coerce.c,v 2.18 1999/06/17 22:21:41 tgl Exp $
* *
*------------------------------------------------------------------------- *-------------------------------------------------------------------------
*/ */
@ -20,6 +20,7 @@
#include "parser/parse_expr.h" #include "parser/parse_expr.h"
#include "catalog/pg_type.h" #include "catalog/pg_type.h"
#include "parser/parse_func.h"
#include "parser/parse_type.h" #include "parser/parse_type.h"
#include "parser/parse_target.h" #include "parser/parse_target.h"
#include "parser/parse_coerce.h" #include "parser/parse_coerce.h"
@ -132,7 +133,7 @@ can_coerce_type(int nargs, Oid *input_typeids, Oid *func_typeids)
HeapTuple ftup; HeapTuple ftup;
int i; int i;
Type tp; Type tp;
Oid oid_array[8]; Oid oid_array[MAXFARGS];
/* run through argument list... */ /* run through argument list... */
for (i = 0; i < nargs; i++) for (i = 0; i < nargs; i++)
@ -160,7 +161,7 @@ can_coerce_type(int nargs, Oid *input_typeids, Oid *func_typeids)
*/ */
else if (input_typeids[i] != UNKNOWNOID) else if (input_typeids[i] != UNKNOWNOID)
{ {
MemSet(&oid_array[0], 0, 8 * sizeof(Oid)); MemSet(oid_array, 0, MAXFARGS * sizeof(Oid));
oid_array[0] = input_typeids[i]; oid_array[0] = input_typeids[i];
/* /*

View File

@ -7,7 +7,7 @@
* *
* *
* IDENTIFICATION * IDENTIFICATION
* $Header: /cvsroot/pgsql/src/backend/parser/parse_func.c,v 1.46 1999/05/25 16:10:17 momjian Exp $ * $Header: /cvsroot/pgsql/src/backend/parser/parse_func.c,v 1.47 1999/06/17 22:21:40 tgl Exp $
* *
*------------------------------------------------------------------------- *-------------------------------------------------------------------------
*/ */
@ -83,8 +83,6 @@ static Oid agg_select_candidate(Oid typeid, CandidateList candidates);
#define ISCOMPLEX(type) (typeidTypeRelid(type) ? true : false) #define ISCOMPLEX(type) (typeidTypeRelid(type) ? true : false)
#define MAXFARGS 8 /* max # args to a c or postquel function */
typedef struct _SuperQE typedef struct _SuperQE
{ {
Oid sqe_relid; Oid sqe_relid;
@ -241,9 +239,9 @@ Node *
ParseFuncOrColumn(ParseState *pstate, char *funcname, List *fargs, ParseFuncOrColumn(ParseState *pstate, char *funcname, List *fargs,
int *curr_resno, int precedence) int *curr_resno, int precedence)
{ {
Oid rettype = (Oid) 0; Oid rettype = InvalidOid;
Oid argrelid = (Oid) 0; Oid argrelid = InvalidOid;
Oid funcid = (Oid) 0; Oid funcid = InvalidOid;
List *i = NIL; List *i = NIL;
Node *first_arg = NULL; Node *first_arg = NULL;
char *relname = NULL; char *relname = NULL;
@ -252,12 +250,12 @@ ParseFuncOrColumn(ParseState *pstate, char *funcname, List *fargs,
Oid relid; Oid relid;
int nargs; int nargs;
Func *funcnode; Func *funcnode;
Oid oid_array[8]; Oid oid_array[MAXFARGS];
Oid *true_oid_array; Oid *true_oid_array;
Node *retval; Node *retval;
bool retset; bool retset;
bool attisset = false; bool attisset = false;
Oid toid = (Oid) 0; Oid toid = InvalidOid;
Expr *expr; Expr *expr;
if (fargs) if (fargs)
@ -425,7 +423,7 @@ ParseFuncOrColumn(ParseState *pstate, char *funcname, List *fargs,
* transform relation name arguments into varnodes of the appropriate * transform relation name arguments into varnodes of the appropriate
* form. * form.
*/ */
MemSet(&oid_array[0], 0, 8 * sizeof(Oid)); MemSet(oid_array, 0, MAXFARGS * sizeof(Oid));
nargs = 0; nargs = 0;
foreach(i, fargs) foreach(i, fargs)
@ -477,6 +475,14 @@ ParseFuncOrColumn(ParseState *pstate, char *funcname, List *fargs,
toid = exprType(pair); toid = exprType(pair);
} }
/* Most of the rest of the parser just assumes that functions do not
* have more than MAXFARGS parameters. We have to test here to protect
* against array overruns, etc.
*/
if (nargs >= MAXFARGS)
elog(ERROR, "Cannot pass more than %d arguments to a function",
MAXFARGS);
oid_array[nargs++] = toid; oid_array[nargs++] = toid;
} }
@ -638,7 +644,7 @@ static Oid
funcid_get_rettype(Oid funcid) funcid_get_rettype(Oid funcid)
{ {
HeapTuple func_tuple = NULL; HeapTuple func_tuple = NULL;
Oid funcrettype = (Oid) 0; Oid funcrettype = InvalidOid;
func_tuple = SearchSysCacheTuple(PROOID, func_tuple = SearchSysCacheTuple(PROOID,
ObjectIdGetDatum(funcid), ObjectIdGetDatum(funcid),
@ -701,8 +707,8 @@ func_get_candidates(char *funcname, int nargs)
current_candidate = (CandidateList) current_candidate = (CandidateList)
palloc(sizeof(struct _CandidateList)); palloc(sizeof(struct _CandidateList));
current_candidate->args = (Oid *) current_candidate->args = (Oid *)
palloc(8 * sizeof(Oid)); palloc(MAXFARGS * sizeof(Oid));
MemSet(current_candidate->args, 0, 8 * sizeof(Oid)); MemSet(current_candidate->args, 0, MAXFARGS * sizeof(Oid));
for (i = 0; i < nargs; i++) for (i = 0; i < nargs; i++)
current_candidate->args[i] = pgProcP->proargtypes[i]; current_candidate->args[i] = pgProcP->proargtypes[i];
@ -1337,7 +1343,7 @@ setup_tlist(char *attname, Oid relid)
type_mod, type_mod,
get_attname(relid, attno), get_attname(relid, attno),
0, 0,
(Oid) 0, InvalidOid,
false); false);
varnode = makeVar(-1, attno, typeid, type_mod, 0, -1, attno); varnode = makeVar(-1, attno, typeid, type_mod, 0, -1, attno);
@ -1362,7 +1368,7 @@ setup_base_tlist(Oid typeid)
-1, -1,
"<noname>", "<noname>",
0, 0,
(Oid) 0, InvalidOid,
false); false);
varnode = makeVar(-1, 1, typeid, -1, 0, -1, 1); varnode = makeVar(-1, 1, typeid, -1, 0, -1, 1);
tle = makeTargetEntry(resnode, (Node *) varnode); tle = makeTargetEntry(resnode, (Node *) varnode);

View File

@ -7,7 +7,7 @@
* *
* *
* IDENTIFICATION * IDENTIFICATION
* $Header: /cvsroot/pgsql/src/backend/parser/parse_target.c,v 1.41 1999/05/29 03:17:20 tgl Exp $ * $Header: /cvsroot/pgsql/src/backend/parser/parse_target.c,v 1.42 1999/06/17 22:21:41 tgl Exp $
* *
*------------------------------------------------------------------------- *-------------------------------------------------------------------------
*/ */
@ -712,7 +712,7 @@ SizeTargetExpr(ParseState *pstate,
int i; int i;
HeapTuple ftup; HeapTuple ftup;
char *funcname; char *funcname;
Oid oid_array[8]; Oid oid_array[MAXFARGS];
FuncCall *func; FuncCall *func;
A_Const *cons; A_Const *cons;
@ -720,7 +720,7 @@ SizeTargetExpr(ParseState *pstate,
funcname = typeidTypeName(attrtype); funcname = typeidTypeName(attrtype);
oid_array[0] = attrtype; oid_array[0] = attrtype;
oid_array[1] = INT4OID; oid_array[1] = INT4OID;
for (i = 2; i < 8; i++) for (i = 2; i < MAXFARGS; i++)
oid_array[i] = InvalidOid; oid_array[i] = InvalidOid;
/* attempt to find with arguments exactly as specified... */ /* attempt to find with arguments exactly as specified... */

View File

@ -6,7 +6,7 @@
* *
* Copyright (c) 1994, Regents of the University of California * Copyright (c) 1994, Regents of the University of California
* *
* $Id: parse_func.h,v 1.15 1999/05/25 16:14:27 momjian Exp $ * $Id: parse_func.h,v 1.16 1999/06/17 22:21:40 tgl Exp $
* *
*------------------------------------------------------------------------- *-------------------------------------------------------------------------
*/ */
@ -20,6 +20,9 @@
#include <parser/parse_func.h> #include <parser/parse_func.h>
#include <parser/parse_node.h> #include <parser/parse_node.h>
#define MAXFARGS 8 /* max # args to a c or postquel function */
/* /*
* This structure is used to explore the inheritance hierarchy above * This structure is used to explore the inheritance hierarchy above
* nodes in the type tree in order to disambiguate among polymorphic * nodes in the type tree in order to disambiguate among polymorphic
@ -47,7 +50,7 @@ extern Node *ParseNestedFuncOrColumn(ParseState *pstate, Attr *attr,
extern Node *ParseFuncOrColumn(ParseState *pstate, char *funcname, List *fargs, extern Node *ParseFuncOrColumn(ParseState *pstate, char *funcname, List *fargs,
int *curr_resno, int precedence); int *curr_resno, int precedence);
extern void extern void func_error(char *caller, char *funcname,
func_error(char *caller, char *funcname, int nargs, Oid *argtypes, char *msg); int nargs, Oid *argtypes, char *msg);
#endif /* PARSE_FUNC_H */ #endif /* PARSE_FUNC_H */