This is an automated email from the ASF dual-hosted git repository.

reshke pushed a commit to branch REL_2_STABLE
in repository https://gitbox.apache.org/repos/asf/cloudberry.git

commit 59678645105a3cba0944b44c249857a644c4507b
Author: Tom Lane <[email protected]>
AuthorDate: Sun Jul 31 13:43:17 2022 -0400

    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/[email protected]
---
 src/backend/utils/adt/arrayfuncs.c   | 9 ++++++---
 src/test/regress/expected/arrays.out | 2 ++
 src/test/regress/sql/arrays.sql      | 1 +
 3 files changed, 9 insertions(+), 3 deletions(-)

diff --git a/src/backend/utils/adt/arrayfuncs.c 
b/src/backend/utils/adt/arrayfuncs.c
index 26cd7458961..6d00be72b16 100644
--- a/src/backend/utils/adt/arrayfuncs.c
+++ b/src/backend/utils/adt/arrayfuncs.c
@@ -6802,7 +6802,7 @@ trim_array(PG_FUNCTION_ARGS)
 {
        ArrayType  *v = PG_GETARG_ARRAYTYPE_P(0);
        int                     n = PG_GETARG_INT32(1);
-       int                     array_length = ARR_DIMS(v)[0];
+       int                     array_length = (ARR_NDIM(v) > 0) ? 
ARR_DIMS(v)[0] : 0;
        int16           elmlen;
        bool            elmbyval;
        char            elmalign;
@@ -6822,8 +6822,11 @@ trim_array(PG_FUNCTION_ARGS)
        /* Set all the bounds as unprovided except the first upper bound */
        memset(lowerProvided, false, sizeof(lowerProvided));
        memset(upperProvided, false, sizeof(upperProvided));
-       upper[0] = ARR_LBOUND(v)[0] + array_length - n - 1;
-       upperProvided[0] = true;
+       if (ARR_NDIM(v) > 0)
+       {
+               upper[0] = ARR_LBOUND(v)[0] + array_length - n - 1;
+               upperProvided[0] = true;
+       }
 
        /* Fetch the needed information about the element type */
        get_typlenbyvalalign(ARR_ELEMTYPE(v), &elmlen, &elmbyval, &elmalign);
diff --git a/src/test/regress/expected/arrays.out 
b/src/test/regress/expected/arrays.out
index a8686405408..d6a8f8f8545 100644
--- a/src/test/regress/expected/arrays.out
+++ b/src/test/regress/expected/arrays.out
@@ -2586,3 +2586,5 @@ SELECT trim_array(ARRAY[1, 2, 3], -1); -- fail
 ERROR:  number of elements to trim must be between 0 and 3
 SELECT trim_array(ARRAY[1, 2, 3], 10); -- fail
 ERROR:  number of elements to trim must be between 0 and 3
+SELECT trim_array(ARRAY[]::int[], 1); -- fail
+ERROR:  number of elements to trim must be between 0 and 0
diff --git a/src/test/regress/sql/arrays.sql b/src/test/regress/sql/arrays.sql
index d10278e32f0..cefe5b05b3b 100644
--- a/src/test/regress/sql/arrays.sql
+++ b/src/test/regress/sql/arrays.sql
@@ -875,3 +875,4 @@ FROM
 
 SELECT trim_array(ARRAY[1, 2, 3], -1); -- fail
 SELECT trim_array(ARRAY[1, 2, 3], 10); -- fail
+SELECT trim_array(ARRAY[]::int[], 1); -- fail


---------------------------------------------------------------------
To unsubscribe, e-mail: [email protected]
For additional commands, e-mail: [email protected]

Reply via email to