]> granicus.if.org Git - postgresql/commitdiff
Avoid passing NULL to memcmp() in lookups of zero-argument functions.
authorTom Lane <tgl@sss.pgh.pa.us>
Sat, 27 Jun 2015 21:47:39 +0000 (17:47 -0400)
committerTom Lane <tgl@sss.pgh.pa.us>
Sat, 27 Jun 2015 21:47:39 +0000 (17:47 -0400)
A few places assumed they could pass NULL for the argtypes array when
looking up functions known to have zero arguments.  At first glance
it seems that this should be safe enough, since memcmp() is surely not
allowed to fetch any bytes if its count argument is zero.  However,
close reading of the C standard says that such calls have undefined
behavior, so we'd probably best avoid it.

Since the number of places doing this is quite small, and some other
places looking up zero-argument functions were already passing dummy
arrays, let's standardize on the latter solution rather than hacking
the function lookup code to avoid calling memcmp() in these cases.
I also added Asserts to catch any future violations of the new rule.

Given the utter lack of any evidence that this actually causes any
problems in the field, I don't feel a need to back-patch this change.

Per report from Piotr Stefaniak, though this is not his patch.

src/backend/commands/event_trigger.c
src/backend/commands/foreigncmds.c
src/backend/parser/parse_func.c
src/backend/utils/adt/ruleutils.c

index cc10c5eb1dfcd14a504fb2f9537fc5a331556bc8..bf40881037cbca45d40450745a8f6ae77539f9e9 100644 (file)
@@ -165,6 +165,7 @@ CreateEventTrigger(CreateEventTrigStmt *stmt)
        HeapTuple       tuple;
        Oid                     funcoid;
        Oid                     funcrettype;
+       Oid                     fargtypes[1];   /* dummy */
        Oid                     evtowner = GetUserId();
        ListCell   *lc;
        List       *tags = NULL;
@@ -230,7 +231,7 @@ CreateEventTrigger(CreateEventTrigStmt *stmt)
                                                stmt->trigname)));
 
        /* Find and validate the trigger function. */
-       funcoid = LookupFuncName(stmt->funcname, 0, NULL, false);
+       funcoid = LookupFuncName(stmt->funcname, 0, fargtypes, false);
        funcrettype = get_func_rettype(funcoid);
        if (funcrettype != EVTTRIGGEROID)
                ereport(ERROR,
index 3b85c2c017eec93d1ecba3385173611bd3c8e420..cc912b2a790dc3e4530c33b4c0d03e623ad682e8 100644 (file)
@@ -474,12 +474,13 @@ static Oid
 lookup_fdw_handler_func(DefElem *handler)
 {
        Oid                     handlerOid;
+       Oid                     funcargtypes[1];        /* dummy */
 
        if (handler == NULL || handler->arg == NULL)
                return InvalidOid;
 
        /* handlers have no arguments */
-       handlerOid = LookupFuncName((List *) handler->arg, 0, NULL, false);
+       handlerOid = LookupFuncName((List *) handler->arg, 0, funcargtypes, false);
 
        /* check that handler has correct return type */
        if (get_func_rettype(handlerOid) != FDW_HANDLEROID)
index fa9761bac31fdad370bae80a64fde55bd8bf3ebc..430baff11652721778e3f37ba49b1707fea62247 100644 (file)
@@ -1415,6 +1415,9 @@ func_get_detail(List *funcname,
        FuncCandidateList raw_candidates;
        FuncCandidateList best_candidate;
 
+       /* Passing NULL for argtypes is no longer allowed */
+       Assert(argtypes);
+
        /* initialize output arguments to silence compiler warnings */
        *funcid = InvalidOid;
        *rettype = InvalidOid;
@@ -2043,6 +2046,9 @@ LookupFuncName(List *funcname, int nargs, const Oid *argtypes, bool noError)
 {
        FuncCandidateList clist;
 
+       /* Passing NULL for argtypes is no longer allowed */
+       Assert(argtypes);
+
        clist = FuncnameGetCandidates(funcname, nargs, NIL, false, false, noError);
 
        while (clist)
index e316951cf3f3505eb7ede680b73bb09e2b0fbdb3..2cd4b62701f6faec029dd033501066e1334aa32b 100644 (file)
@@ -718,6 +718,7 @@ pg_get_triggerdef_worker(Oid trigid, bool pretty)
        SysScanDesc tgscan;
        int                     findx = 0;
        char       *tgname;
+       Oid                     argtypes[1];    /* dummy */
        Datum           value;
        bool            isnull;
 
@@ -893,7 +894,7 @@ pg_get_triggerdef_worker(Oid trigid, bool pretty)
 
        appendStringInfo(&buf, "EXECUTE PROCEDURE %s(",
                                         generate_function_name(trigrec->tgfoid, 0,
-                                                                                       NIL, NULL,
+                                                                                       NIL, argtypes,
                                                                                        false, NULL, EXPR_KIND_NONE));
 
        if (trigrec->tgnargs > 0)