Skip to content

Commit 5967864

Browse files
tglsfdcreshke
authored andcommitted
Fix trim_array() for zero-dimensional array argument.
The code tried to access ARR_DIMS(v)[0] and ARR_LBOUND(v)[0] whether or not those values exist. This made the range check on the "n" argument unstable --- it might or might not fail, and if it did it would report garbage for the allowed upper limit. These bogus accesses would probably annoy Valgrind, and if you were very unlucky even lead to SIGSEGV. Report and fix by Martin Kalcher. Back-patch to v14 where this function was added. Discussion: https://postgr.es/m/baaeb413-b8a8-4656-5757-ef347e5ec11f@aboutsource.net
1 parent e42fcdd commit 5967864

3 files changed

Lines changed: 9 additions & 3 deletions

File tree

src/backend/utils/adt/arrayfuncs.c

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -6802,7 +6802,7 @@ trim_array(PG_FUNCTION_ARGS)
68026802
{
68036803
ArrayType *v = PG_GETARG_ARRAYTYPE_P(0);
68046804
int n = PG_GETARG_INT32(1);
6805-
int array_length = ARR_DIMS(v)[0];
6805+
int array_length = (ARR_NDIM(v) > 0) ? ARR_DIMS(v)[0] : 0;
68066806
int16 elmlen;
68076807
bool elmbyval;
68086808
char elmalign;
@@ -6822,8 +6822,11 @@ trim_array(PG_FUNCTION_ARGS)
68226822
/* Set all the bounds as unprovided except the first upper bound */
68236823
memset(lowerProvided, false, sizeof(lowerProvided));
68246824
memset(upperProvided, false, sizeof(upperProvided));
6825-
upper[0] = ARR_LBOUND(v)[0] + array_length - n - 1;
6826-
upperProvided[0] = true;
6825+
if (ARR_NDIM(v) > 0)
6826+
{
6827+
upper[0] = ARR_LBOUND(v)[0] + array_length - n - 1;
6828+
upperProvided[0] = true;
6829+
}
68276830

68286831
/* Fetch the needed information about the element type */
68296832
get_typlenbyvalalign(ARR_ELEMTYPE(v), &elmlen, &elmbyval, &elmalign);

src/test/regress/expected/arrays.out

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2586,3 +2586,5 @@ SELECT trim_array(ARRAY[1, 2, 3], -1); -- fail
25862586
ERROR: number of elements to trim must be between 0 and 3
25872587
SELECT trim_array(ARRAY[1, 2, 3], 10); -- fail
25882588
ERROR: number of elements to trim must be between 0 and 3
2589+
SELECT trim_array(ARRAY[]::int[], 1); -- fail
2590+
ERROR: number of elements to trim must be between 0 and 0

src/test/regress/sql/arrays.sql

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -875,3 +875,4 @@ FROM
875875

876876
SELECT trim_array(ARRAY[1, 2, 3], -1); -- fail
877877
SELECT trim_array(ARRAY[1, 2, 3], 10); -- fail
878+
SELECT trim_array(ARRAY[]::int[], 1); -- fail

0 commit comments

Comments
 (0)