Location via proxy:   [ UP ]  
[Report a bug]   [Manage cookies]                
Skip to content

Commit 4c40995

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 0553528 commit 4c40995

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
@@ -1275,7 +1275,6 @@ array_position_common(FunctionCallInfo fcinfo)
12751275
PG_RETURN_NULL();
12761276

12771277
array = PG_GETARG_ARRAYTYPE_P(0);
1278-
element_type = ARR_ELEMTYPE(array);
12791278

12801279
/*
12811280
* We refuse to search for elements in multi-dimensional arrays, since we
@@ -1286,6 +1285,10 @@ array_position_common(FunctionCallInfo fcinfo)
12861285
(errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
12871286
errmsg("searching for elements in multidimensional arrays is not supported")));
12881287

1288+
/* Searching in an empty array is well-defined, though: it always fails */
1289+
if (ARR_NDIM(array) < 1)
1290+
PG_RETURN_NULL();
1291+
12891292
if (PG_ARGISNULL(1))
12901293
{
12911294
/* fast return when the array doesn't have nulls */
@@ -1300,6 +1303,7 @@ array_position_common(FunctionCallInfo fcinfo)
13001303
null_search = false;
13011304
}
13021305

1306+
element_type = ARR_ELEMTYPE(array);
13031307
position = (ARR_LBOUND(array))[0] - 1;
13041308

13051309
/* figure out where to start */
@@ -1425,9 +1429,6 @@ array_positions(PG_FUNCTION_ARGS)
14251429
PG_RETURN_NULL();
14261430

14271431
array = PG_GETARG_ARRAYTYPE_P(0);
1428-
element_type = ARR_ELEMTYPE(array);
1429-
1430-
position = (ARR_LBOUND(array))[0] - 1;
14311432

14321433
/*
14331434
* We refuse to search for elements in multi-dimensional arrays, since we
@@ -1440,6 +1441,10 @@ array_positions(PG_FUNCTION_ARGS)
14401441

14411442
astate = initArrayResult(INT4OID, CurrentMemoryContext, false);
14421443

1444+
/* Searching in an empty array is well-defined, though: it always fails */
1445+
if (ARR_NDIM(array) < 1)
1446+
PG_RETURN_DATUM(makeArrayResult(astate, CurrentMemoryContext));
1447+
14431448
if (PG_ARGISNULL(1))
14441449
{
14451450
/* fast return when the array doesn't have nulls */
@@ -1454,6 +1459,9 @@ array_positions(PG_FUNCTION_ARGS)
14541459
null_search = false;
14551460
}
14561461

1462+
element_type = ARR_ELEMTYPE(array);
1463+
position = (ARR_LBOUND(array))[0] - 1;
1464+
14571465
/*
14581466
* We arrange to look up type info for array_create_iterator only once per
14591467
* series of calls, assuming the element type doesn't change underneath

0 commit comments

Comments
 (0)