]> granicus.if.org Git - postgresql/commitdiff
plperl: Correctly handle empty arrays in plperl_ref_from_pg_array.
authorAndres Freund <andres@anarazel.de>
Tue, 8 Mar 2016 21:33:24 +0000 (13:33 -0800)
committerAndres Freund <andres@anarazel.de>
Tue, 8 Mar 2016 21:42:57 +0000 (13:42 -0800)
plperl_ref_from_pg_array() didn't consider the case that postgrs arrays
can have 0 dimensions (when they're empty) and accessed the first
dimension without a check. Fix that by special casing the empty array
case.

Author: Alex Hunsaker
Reported-By: Andres Freund / valgrind / buildfarm animal skink
Discussion: 20160308063240.usnzg6bsbjrne667@alap3.anarazel.de
Backpatch: 9.1-

src/pl/plperl/plperl.c

index b35ef3f64bcd504404800df84ad427a3a849dc67..cd917ab8e46ddc13a293144184a3f45e71cab01c 100644 (file)
@@ -1450,17 +1450,25 @@ plperl_ref_from_pg_array(Datum arg, Oid typid)
        info->ndims = ARR_NDIM(ar);
        dims = ARR_DIMS(ar);
 
-       deconstruct_array(ar, elementtype, typlen, typbyval,
-                                         typalign, &info->elements, &info->nulls,
-                                         &nitems);
+       /* No dimensions? Return an empty array */
+       if (info->ndims == 0)
+       {
+               av = newRV_noinc((SV *) newAV());
+       }
+       else
+       {
+               deconstruct_array(ar, elementtype, typlen, typbyval,
+                                                 typalign, &info->elements, &info->nulls,
+                                                 &nitems);
 
-       /* Get total number of elements in each dimension */
-       info->nelems = palloc(sizeof(int) * info->ndims);
-       info->nelems[0] = nitems;
-       for (i = 1; i < info->ndims; i++)
-               info->nelems[i] = info->nelems[i - 1] / dims[i - 1];
+               /* Get total number of elements in each dimension */
+               info->nelems = palloc(sizeof(int) * info->ndims);
+               info->nelems[0] = nitems;
+               for (i = 1; i < info->ndims; i++)
+                       info->nelems[i] = info->nelems[i - 1] / dims[i - 1];
 
-       av = split_array(info, 0, nitems, 0);
+               av = split_array(info, 0, nitems, 0);
+       }
 
        hv = newHV();
        (void) hv_store(hv, "array", 5, av, 0);
@@ -1479,6 +1487,9 @@ split_array(plperl_array_info *info, int first, int last, int nest)
        int                     i;
        AV                 *result;
 
+       /* we should only be called when we have something to split */
+       Assert(info->ndims > 0);
+
        /* since this function recurses, it could be driven to stack overflow */
        check_stack_depth();