summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorTom Lane2023-05-04 15:48:23 +0000
committerTom Lane2023-05-04 15:48:23 +0000
commitd5de344a50d3fa03fad38fe41cc3443db4143bb5 (patch)
treecaa1d7a017b954a2914ee582d5ed910767e3e17c
parent9d517339e9912d8e4afe76e26f9a0e5dc54f6f4e (diff)
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
-rw-r--r--src/backend/utils/adt/array_userfuncs.c16
1 files changed, 12 insertions, 4 deletions
diff --git a/src/backend/utils/adt/array_userfuncs.c b/src/backend/utils/adt/array_userfuncs.c
index 42503525b88..057e71e53f5 100644
--- a/src/backend/utils/adt/array_userfuncs.c
+++ b/src/backend/utils/adt/array_userfuncs.c
@@ -651,7 +651,6 @@ array_position_common(FunctionCallInfo fcinfo)
PG_RETURN_NULL();
array = PG_GETARG_ARRAYTYPE_P(0);
- element_type = ARR_ELEMTYPE(array);
/*
* We refuse to search for elements in multi-dimensional arrays, since we
@@ -662,6 +661,10 @@ array_position_common(FunctionCallInfo fcinfo)
(errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
errmsg("searching for elements in multidimensional arrays is not supported")));
+ /* Searching in an empty array is well-defined, though: it always fails */
+ if (ARR_NDIM(array) < 1)
+ PG_RETURN_NULL();
+
if (PG_ARGISNULL(1))
{
/* fast return when the array doesn't have nulls */
@@ -676,6 +679,7 @@ array_position_common(FunctionCallInfo fcinfo)
null_search = false;
}
+ element_type = ARR_ELEMTYPE(array);
position = (ARR_LBOUND(array))[0] - 1;
/* figure out where to start */
@@ -801,9 +805,6 @@ array_positions(PG_FUNCTION_ARGS)
PG_RETURN_NULL();
array = PG_GETARG_ARRAYTYPE_P(0);
- element_type = ARR_ELEMTYPE(array);
-
- position = (ARR_LBOUND(array))[0] - 1;
/*
* We refuse to search for elements in multi-dimensional arrays, since we
@@ -816,6 +817,10 @@ array_positions(PG_FUNCTION_ARGS)
astate = initArrayResult(INT4OID, CurrentMemoryContext, false);
+ /* Searching in an empty array is well-defined, though: it always fails */
+ if (ARR_NDIM(array) < 1)
+ PG_RETURN_DATUM(makeArrayResult(astate, CurrentMemoryContext));
+
if (PG_ARGISNULL(1))
{
/* fast return when the array doesn't have nulls */
@@ -830,6 +835,9 @@ array_positions(PG_FUNCTION_ARGS)
null_search = false;
}
+ element_type = ARR_ELEMTYPE(array);
+ position = (ARR_LBOUND(array))[0] - 1;
+
/*
* We arrange to look up type info for array_create_iterator only once per
* series of calls, assuming the element type doesn't change underneath