array_in() and array_recv() need to be more paranoid about validating
authorTom Lane
Mon, 15 Aug 2005 19:40:20 +0000 (19:40 +0000)
committerTom Lane
Mon, 15 Aug 2005 19:40:20 +0000 (19:40 +0000)
their OID parameter.  It was possible to crash the backend with
select array_in('{123}',0,0); because that would bypass the needed step
of initializing the workspace.  These seem to be the only two places
with a problem, though (record_in and record_recv don't have the issue,
and the other array functions aren't depending on user-supplied input).
Back-patch as far as 7.4; 7.3 does not have the bug.

src/backend/utils/adt/arrayfuncs.c

index 07edd7014da341c0233046af9342164624fc573b..efb4ea9dc14421aaac772225049829b62ba7d4fc 100644 (file)
@@ -8,7 +8,7 @@
  *
  *
  * IDENTIFICATION
- *   $PostgreSQL: pgsql/src/backend/utils/adt/arrayfuncs.c,v 1.121 2005/07/10 21:13:58 tgl Exp $
+ *   $PostgreSQL: pgsql/src/backend/utils/adt/arrayfuncs.c,v 1.122 2005/08/15 19:40:20 tgl Exp $
  *
  *-------------------------------------------------------------------------
  */
@@ -160,7 +160,7 @@ array_in(PG_FUNCTION_ARGS)
        fcinfo->flinfo->fn_extra = MemoryContextAlloc(fcinfo->flinfo->fn_mcxt,
                                                 sizeof(ArrayMetaState));
        my_extra = (ArrayMetaState *) fcinfo->flinfo->fn_extra;
-       my_extra->element_type = InvalidOid;
+       my_extra->element_type = ~element_type;
    }
 
    if (my_extra->element_type != element_type)
@@ -1173,15 +1173,6 @@ array_recv(PG_FUNCTION_ARGS)
    }
    nitems = ArrayGetNItems(ndim, dim);
 
-   if (nitems == 0)
-   {
-       /* Return empty array */
-       retval = (ArrayType *) palloc0(sizeof(ArrayType));
-       retval->size = sizeof(ArrayType);
-       retval->elemtype = element_type;
-       PG_RETURN_ARRAYTYPE_P(retval);
-   }
-
    /*
     * We arrange to look up info about element type, including its
     * receive conversion proc, only once per series of calls, assuming
@@ -1193,7 +1184,7 @@ array_recv(PG_FUNCTION_ARGS)
        fcinfo->flinfo->fn_extra = MemoryContextAlloc(fcinfo->flinfo->fn_mcxt,
                                                 sizeof(ArrayMetaState));
        my_extra = (ArrayMetaState *) fcinfo->flinfo->fn_extra;
-       my_extra->element_type = InvalidOid;
+       my_extra->element_type = ~element_type;
    }
 
    if (my_extra->element_type != element_type)
@@ -1212,6 +1203,16 @@ array_recv(PG_FUNCTION_ARGS)
                      fcinfo->flinfo->fn_mcxt);
        my_extra->element_type = element_type;
    }
+
+   if (nitems == 0)
+   {
+       /* Return empty array ... but not till we've validated element_type */
+       retval = (ArrayType *) palloc0(sizeof(ArrayType));
+       retval->size = sizeof(ArrayType);
+       retval->elemtype = element_type;
+       PG_RETURN_ARRAYTYPE_P(retval);
+   }
+
    typlen = my_extra->typlen;
    typbyval = my_extra->typbyval;
    typalign = my_extra->typalign;