Skip to content

Commit d5de344

Browse files
committed
In array_position()/array_positions(), beware of empty input array.
These functions incautiously fetched the array's first lower bound even when the array is zero-dimensional, thus fetching the word after the allocated array space. While almost always harmless, with very bad luck this could result in SIGSEGV. Fix by adding an early exit for empty input. Per bug #17920 from Alexander Lakhin. Discussion: https://postgr.es/m/17920-f7c228c627b6d02e%40postgresql.org
1 parent 9d51733 commit d5de344

File tree

1 file changed

+12
-4
lines changed

1 file changed

+12
-4
lines changed

src/backend/utils/adt/array_userfuncs.c

Lines changed: 12 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -651,7 +651,6 @@ array_position_common(FunctionCallInfo fcinfo)
651651
PG_RETURN_NULL();
652652

653653
array = PG_GETARG_ARRAYTYPE_P(0);
654-
element_type = ARR_ELEMTYPE(array);
655654

656655
/*
657656
* We refuse to search for elements in multi-dimensional arrays, since we
@@ -662,6 +661,10 @@ array_position_common(FunctionCallInfo fcinfo)
662661
(errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
663662
errmsg("searching for elements in multidimensional arrays is not supported")));
664663

664+
/* Searching in an empty array is well-defined, though: it always fails */
665+
if (ARR_NDIM(array) < 1)
666+
PG_RETURN_NULL();
667+
665668
if (PG_ARGISNULL(1))
666669
{
667670
/* fast return when the array doesn't have nulls */
@@ -676,6 +679,7 @@ array_position_common(FunctionCallInfo fcinfo)
676679
null_search = false;
677680
}
678681

682+
element_type = ARR_ELEMTYPE(array);
679683
position = (ARR_LBOUND(array))[0] - 1;
680684

681685
/* figure out where to start */
@@ -801,9 +805,6 @@ array_positions(PG_FUNCTION_ARGS)
801805
PG_RETURN_NULL();
802806

803807
array = PG_GETARG_ARRAYTYPE_P(0);
804-
element_type = ARR_ELEMTYPE(array);
805-
806-
position = (ARR_LBOUND(array))[0] - 1;
807808

808809
/*
809810
* We refuse to search for elements in multi-dimensional arrays, since we
@@ -816,6 +817,10 @@ array_positions(PG_FUNCTION_ARGS)
816817

817818
astate = initArrayResult(INT4OID, CurrentMemoryContext, false);
818819

820+
/* Searching in an empty array is well-defined, though: it always fails */
821+
if (ARR_NDIM(array) < 1)
822+
PG_RETURN_DATUM(makeArrayResult(astate, CurrentMemoryContext));
823+
819824
if (PG_ARGISNULL(1))
820825
{
821826
/* fast return when the array doesn't have nulls */
@@ -830,6 +835,9 @@ array_positions(PG_FUNCTION_ARGS)
830835
null_search = false;
831836
}
832837

838+
element_type = ARR_ELEMTYPE(array);
839+
position = (ARR_LBOUND(array))[0] - 1;
840+
833841
/*
834842
* We arrange to look up type info for array_create_iterator only once per
835843
* series of calls, assuming the element type doesn't change underneath

0 commit comments

Comments
 (0)