Location via proxy:   [ UP ]  
[Report a bug]   [Manage cookies]                
Be more paranoid in ruleutils.c's get_variable().
authorTom Lane <tgl@sss.pgh.pa.us>
Fri, 1 Jul 2016 15:40:22 +0000 (11:40 -0400)
committerTom Lane <tgl@sss.pgh.pa.us>
Fri, 1 Jul 2016 15:40:22 +0000 (11:40 -0400)
We were merely Assert'ing that the Var matched the RTE it's supposedly
from.  But if the user passes incorrect information to pg_get_expr(),
the RTE might in fact not match; this led either to Assert failures
or core dumps, as reported by Chris Hanks in bug #14220.  To fix, just
convert the Asserts to test-and-elog.  Adjust an existing test-and-elog
elsewhere in the same function to be consistent in wording.

(If we really felt these were user-facing errors, we might promote them to
ereport's; but I can't convince myself that they're worth translating.)

Back-patch to 9.3; the problematic code doesn't exist before that, and
a quick check says that 9.2 doesn't crash on such cases.

Michael Paquier and Thomas Munro

Report: <20160629224349.1407.32667@wrigleys.postgresql.org>

src/backend/utils/adt/ruleutils.c

index c4d9fca3d727d95cbd709e0e0b0ce6646f61fa1f..fc4ab71f97b4b067006c55755182ee356d0d03f7 100644 (file)
@@ -5672,7 +5672,8 @@ get_variable(Var *var, int levelsup, bool istoplevel, deparse_context *context)
 
        tle = get_tle_by_resno(dpns->inner_tlist, var->varattno);
        if (!tle)
-           elog(ERROR, "bogus varattno for subquery var: %d", var->varattno);
+           elog(ERROR, "invalid attnum %d for relation \"%s\"",
+                var->varattno, rte->eref->aliasname);
 
        Assert(netlevelsup == 0);
        push_child_plan(dpns, dpns->inner_planstate, &save_dpns);
@@ -5733,9 +5734,13 @@ get_variable(Var *var, int levelsup, bool istoplevel, deparse_context *context)
    else if (attnum > 0)
    {
        /* Get column name to use from the colinfo struct */
-       Assert(attnum <= colinfo->num_cols);
+       if (attnum > colinfo->num_cols)
+           elog(ERROR, "invalid attnum %d for relation \"%s\"",
+                attnum, rte->eref->aliasname);
        attname = colinfo->colnames[attnum - 1];
-       Assert(attname != NULL);
+       if (attname == NULL)    /* dropped column? */
+           elog(ERROR, "invalid attnum %d for relation \"%s\"",
+                attnum, rte->eref->aliasname);
    }
    else
    {