Defend against function calls with more than 8 arguments (code
authorTom Lane
Thu, 17 Jun 1999 22:21:41 +0000 (22:21 +0000)
committerTom Lane
Thu, 17 Jun 1999 22:21:41 +0000 (22:21 +0000)
used to overrun its fixed-size arrays before detecting error; not cool).
Also, replace uses of magic constant '8' with 'MAXFARGS'.

src/backend/parser/parse_coerce.c
src/backend/parser/parse_func.c
src/backend/parser/parse_target.c
src/include/parser/parse_func.h

index 9e0e77b051b6ac7a794653e9ea7b9f65a192bb10..1563a0eef731e97644d05cc059d2852650669375 100644 (file)
@@ -7,7 +7,7 @@
  *
  *
  * 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 "catalog/pg_type.h"
+#include "parser/parse_func.h"
 #include "parser/parse_type.h"
 #include "parser/parse_target.h"
 #include "parser/parse_coerce.h"
@@ -132,7 +133,7 @@ can_coerce_type(int nargs, Oid *input_typeids, Oid *func_typeids)
    HeapTuple   ftup;
    int         i;
    Type        tp;
-   Oid         oid_array[8];
+   Oid         oid_array[MAXFARGS];
 
    /* run through argument list... */
    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)
            {
-               MemSet(&oid_array[0], 0, 8 * sizeof(Oid));
+               MemSet(oid_array, 0, MAXFARGS * sizeof(Oid));
                oid_array[0] = input_typeids[i];
 
                /*
index 8fa8fb8b365a3cc8d7348220cf6978158b4bf4ee..6f676618474ad26c99f8afcc3b303a684d36dbd4 100644 (file)
@@ -7,7 +7,7 @@
  *
  *
  * 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 MAXFARGS 8             /* max # args to a c or postquel function */
-
 typedef struct _SuperQE
 {
    Oid         sqe_relid;
@@ -241,9 +239,9 @@ Node *
 ParseFuncOrColumn(ParseState *pstate, char *funcname, List *fargs,
                  int *curr_resno, int precedence)
 {
-   Oid         rettype = (Oid) 0;
-   Oid         argrelid = (Oid) 0;
-   Oid         funcid = (Oid) 0;
+   Oid         rettype = InvalidOid;
+   Oid         argrelid = InvalidOid;
+   Oid         funcid = InvalidOid;
    List       *i = NIL;
    Node       *first_arg = NULL;
    char       *relname = NULL;
@@ -252,12 +250,12 @@ ParseFuncOrColumn(ParseState *pstate, char *funcname, List *fargs,
    Oid         relid;
    int         nargs;
    Func       *funcnode;
-   Oid         oid_array[8];
+   Oid         oid_array[MAXFARGS];
    Oid        *true_oid_array;
    Node       *retval;
    bool        retset;
    bool        attisset = false;
-   Oid         toid = (Oid) 0;
+   Oid         toid = InvalidOid;
    Expr       *expr;
 
    if (fargs)
@@ -425,7 +423,7 @@ ParseFuncOrColumn(ParseState *pstate, char *funcname, List *fargs,
     * transform relation name arguments into varnodes of the appropriate
     * form.
     */
-   MemSet(&oid_array[0], 0, 8 * sizeof(Oid));
+   MemSet(oid_array, 0, MAXFARGS * sizeof(Oid));
 
    nargs = 0;
    foreach(i, fargs)
@@ -477,6 +475,14 @@ ParseFuncOrColumn(ParseState *pstate, char *funcname, List *fargs,
                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;
    }
 
@@ -638,7 +644,7 @@ static Oid
 funcid_get_rettype(Oid funcid)
 {
    HeapTuple   func_tuple = NULL;
-   Oid         funcrettype = (Oid) 0;
+   Oid         funcrettype = InvalidOid;
 
    func_tuple = SearchSysCacheTuple(PROOID,
                                     ObjectIdGetDatum(funcid),
@@ -701,8 +707,8 @@ func_get_candidates(char *funcname, int nargs)
                    current_candidate = (CandidateList)
                        palloc(sizeof(struct _CandidateList));
                    current_candidate->args = (Oid *)
-                       palloc(8 * sizeof(Oid));
-                   MemSet(current_candidate->args, 0, 8 * sizeof(Oid));
+                       palloc(MAXFARGS * sizeof(Oid));
+                   MemSet(current_candidate->args, 0, MAXFARGS * sizeof(Oid));
                    for (i = 0; i < nargs; i++)
                        current_candidate->args[i] = pgProcP->proargtypes[i];
 
@@ -1337,7 +1343,7 @@ setup_tlist(char *attname, Oid relid)
                         type_mod,
                         get_attname(relid, attno),
                         0,
-                        (Oid) 0,
+                        InvalidOid,
                         false);
    varnode = makeVar(-1, attno, typeid, type_mod, 0, -1, attno);
 
@@ -1362,7 +1368,7 @@ setup_base_tlist(Oid typeid)
                         -1,
                         "",
                         0,
-                        (Oid) 0,
+                        InvalidOid,
                         false);
    varnode = makeVar(-1, 1, typeid, -1, 0, -1, 1);
    tle = makeTargetEntry(resnode, (Node *) varnode);
index 563a48e1b4eaae8077d670b996db6a38e84f3e62..09f624fc7607b498e8f76365b67b5ce005d13079 100644 (file)
@@ -7,7 +7,7 @@
  *
  *
  * 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;
    HeapTuple   ftup;
    char       *funcname;
-   Oid         oid_array[8];
+   Oid         oid_array[MAXFARGS];
 
    FuncCall   *func;
    A_Const    *cons;
@@ -720,7 +720,7 @@ SizeTargetExpr(ParseState *pstate,
    funcname = typeidTypeName(attrtype);
    oid_array[0] = attrtype;
    oid_array[1] = INT4OID;
-   for (i = 2; i < 8; i++)
+   for (i = 2; i < MAXFARGS; i++)
        oid_array[i] = InvalidOid;
 
    /* attempt to find with arguments exactly as specified... */
index b83929358c514a79903367b271c9f09e9c701bab..d3441a0ce89c52cf3b181554a58e8913c263ecbe 100644 (file)
@@ -6,7 +6,7 @@
  *
  * 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 
 #include 
 
+
+#define MAXFARGS 8             /* max # args to a c or postquel function */
+
 /*
  * This structure is used to explore the inheritance hierarchy above
  * 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,
                  int *curr_resno, int precedence);
 
-extern void
-           func_error(char *caller, char *funcname, int nargs, Oid *argtypes, char *msg);
+extern void func_error(char *caller, char *funcname,
+                      int nargs, Oid *argtypes, char *msg);
 
 #endif  /* PARSE_FUNC_H */