On Mon, Jul 22, 2024 at 04:36:33PM -0500, Nathan Bossart wrote: > Okay. I'll plan on committing v13-0002 in the next couple of days, then.
Actually, I think my concerns about prohibiting more than necessary go away if we do the subtraction first. If "upperIndx[i] - lowerIndx[i]" overflows, we know the array size is too big. Similarly, if adding one to that result overflows, we again know the the array size is too big. This appears to be how the surrounding code handles this problem (e.g., ReadArrayDimensions()). Thoughts? -- nathan
>From 8794c740492bd5113d405638b03518693dfeb0db Mon Sep 17 00:00:00 2001 From: Joseph Koshakow <kosh...@gmail.com> Date: Sat, 6 Jul 2024 14:35:00 -0400 Subject: [PATCH v14 1/1] Remove overflow from array_set_slice This commit removes an overflow from array_set_slice that allows seting absurd slice ranges. --- src/backend/utils/adt/arrayfuncs.c | 9 ++++++++- src/test/regress/expected/arrays.out | 6 ++++++ src/test/regress/sql/arrays.sql | 5 +++++ 3 files changed, 19 insertions(+), 1 deletion(-) diff --git a/src/backend/utils/adt/arrayfuncs.c b/src/backend/utils/adt/arrayfuncs.c index d6641b570d..e5c7e57a5d 100644 --- a/src/backend/utils/adt/arrayfuncs.c +++ b/src/backend/utils/adt/arrayfuncs.c @@ -2887,7 +2887,14 @@ array_set_slice(Datum arraydatum, errdetail("When assigning to a slice of an empty array value," " slice boundaries must be fully specified."))); - dim[i] = 1 + upperIndx[i] - lowerIndx[i]; + /* compute "upperIndx[i] - lowerIndx[i] + 1", detecting overflow */ + if (pg_sub_s32_overflow(upperIndx[i], lowerIndx[i], &dim[i]) || + pg_add_s32_overflow(dim[i], 1, &dim[i])) + ereport(ERROR, + (errcode(ERRCODE_PROGRAM_LIMIT_EXCEEDED), + errmsg("array size exceeds the maximum allowed (%d)", + (int) MaxArraySize))); + lb[i] = lowerIndx[i]; } diff --git a/src/test/regress/expected/arrays.out b/src/test/regress/expected/arrays.out index 23404982f7..7301c96bba 100644 --- a/src/test/regress/expected/arrays.out +++ b/src/test/regress/expected/arrays.out @@ -2699,3 +2699,9 @@ SELECT array_sample('{1,2,3,4,5,6}'::int[], -1); -- fail ERROR: sample size must be between 0 and 6 SELECT array_sample('{1,2,3,4,5,6}'::int[], 7); --fail ERROR: sample size must be between 0 and 6 +-- overflow in array slicing +CREATE TEMP TABLE arroverflowtest (i int[]); +INSERT INTO arroverflowtest(i[0:2147483647]) VALUES ('{1}'); +ERROR: array size exceeds the maximum allowed (134217727) +INSERT INTO arroverflowtest(i[-2147483648:1]) VALUES ('{1}'); +ERROR: array size exceeds the maximum allowed (134217727) diff --git a/src/test/regress/sql/arrays.sql b/src/test/regress/sql/arrays.sql index 50aa539fdc..d6ef059a1d 100644 --- a/src/test/regress/sql/arrays.sql +++ b/src/test/regress/sql/arrays.sql @@ -825,3 +825,8 @@ SELECT array_dims(array_sample('[-1:2][2:3]={{1,2},{3,NULL},{5,6},{7,8}}'::int[] SELECT array_dims(array_sample('{{{1,2},{3,NULL}},{{5,6},{7,8}},{{9,10},{11,12}}}'::int[], 2)); SELECT array_sample('{1,2,3,4,5,6}'::int[], -1); -- fail SELECT array_sample('{1,2,3,4,5,6}'::int[], 7); --fail + +-- overflow in array slicing +CREATE TEMP TABLE arroverflowtest (i int[]); +INSERT INTO arroverflowtest(i[0:2147483647]) VALUES ('{1}'); +INSERT INTO arroverflowtest(i[-2147483648:1]) VALUES ('{1}'); -- 2.39.3 (Apple Git-146)