Repair incorrect check for coercion of unknown literal to ANYARRAY, a bug
authorTom Lane <tgl@sss.pgh.pa.us>
Wed, 11 Oct 2006 20:21:19 +0000 (20:21 +0000)
committerTom Lane <tgl@sss.pgh.pa.us>
Wed, 11 Oct 2006 20:21:19 +0000 (20:21 +0000)
I introduced in 7.4.1 :-(.  It's correct to allow unknown to be coerced to
ANY or ANYELEMENT, since it's a real-enough data type, but it most certainly
isn't an array datatype.  This can cause a backend crash but AFAICT is not
exploitable as a security hole.  Per report from Michael Fuhr.

Note: as fixed in HEAD, this changes a constant in the pg_stats view,
resulting in a change in the expected regression outputs.  The back-branch
patches have been hacked to avoid that, so that pre-existing installations
won't start failing their regression tests.

src/backend/parser/parse_coerce.c

index 869e870b66c76ec4da480f3c332b0a88a80702be..703c72ac8a0213f61ac645c0beb3d84e2dc43449 100644 (file)
@@ -8,7 +8,7 @@
  *
  *
  * IDENTIFICATION
- *   $PostgreSQL: pgsql/src/backend/parser/parse_coerce.c,v 2.126.4.2 2006/01/17 17:33:34 tgl Exp $
+ *   $PostgreSQL: pgsql/src/backend/parser/parse_coerce.c,v 2.126.4.3 2006/10/11 20:21:19 tgl Exp $
  *
  *-------------------------------------------------------------------------
  */
@@ -130,11 +130,28 @@ coerce_type(ParseState *pstate, Node *node,
        return node;
    }
    if (targetTypeId == ANYOID ||
-       targetTypeId == ANYARRAYOID ||
-       targetTypeId == ANYELEMENTOID)
+       targetTypeId == ANYELEMENTOID ||
+       (targetTypeId == ANYARRAYOID &&
+        (inputTypeId != UNKNOWNOID ||
+         (IsA(node, Const) && ((Const *) node)->constisnull)))) /* HACK */
    {
-       /* assume can_coerce_type verified that implicit coercion is okay */
-       /* NB: we do NOT want a RelabelType here */
+       /*
+        * Assume can_coerce_type verified that implicit coercion is okay.
+        *
+        * Note: by returning the unmodified node here, we are saying that
+        * it's OK to treat an UNKNOWN constant as a valid input for a
+        * function accepting ANY or ANYELEMENT.  This should be all right,
+        * since an UNKNOWN value is still a perfectly valid Datum.  However
+        * an UNKNOWN value is definitely *not* an array, and so we mustn't
+        * accept it for ANYARRAY.  (Instead, we will call anyarray_in below,
+        * which will produce an error.)
+        *
+        * HACK: if it's a NULL UNKNOWN constant, return it as-is, same as
+        * before.  This is just to avoid changing the pg_stats view and thus
+        * the expected regression test results in back branches.
+        *
+        * NB: we do NOT want a RelabelType here.
+        */
        return node;
    }
    if (inputTypeId == UNKNOWNOID && IsA(node, Const))