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

Commit bdd8ed9

Browse files
committed
Fix miscalculation of itemsafter in array_set_slice().
If the slice to be assigned to was before the existing array lower bound (requiring at least one null element to spring into existence to fill the gap), the code miscalculated how many entries needed to be copied from the old array's null bitmap. This could result in trashing the array's data area (as seen in bug #5840 from Karsten Loesing), or worse. This has been broken since we first allowed the behavior of assigning to non-adjacent slices, in 8.2. Back-patch to all affected versions.
1 parent 978445b commit bdd8ed9

File tree

1 file changed

+5
-1
lines changed

1 file changed

+5
-1
lines changed

src/backend/utils/adt/arrayfuncs.c

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2500,6 +2500,7 @@ array_set_slice(ArrayType *array,
25002500
{
25012501
/*
25022502
* here we must allow for possibility of slice larger than orig array
2503+
* and/or not adjacent to orig array subscripts
25032504
*/
25042505
int oldlb = ARR_LBOUND(array)[0];
25052506
int oldub = oldlb + ARR_DIMS(array)[0] - 1;
@@ -2508,10 +2509,12 @@ array_set_slice(ArrayType *array,
25082509
char *oldarraydata = ARR_DATA_PTR(array);
25092510
bits8 *oldarraybitmap = ARR_NULLBITMAP(array);
25102511

2512+
/* count/size of old array entries that will go before the slice */
25112513
itemsbefore = Min(slicelb, oldub + 1) - oldlb;
25122514
lenbefore = array_nelems_size(oldarraydata, 0, oldarraybitmap,
25132515
itemsbefore,
25142516
elmlen, elmbyval, elmalign);
2517+
/* count/size of old array entries that will be replaced by slice */
25152518
if (slicelb > sliceub)
25162519
{
25172520
nolditems = 0;
@@ -2525,7 +2528,8 @@ array_set_slice(ArrayType *array,
25252528
nolditems,
25262529
elmlen, elmbyval, elmalign);
25272530
}
2528-
itemsafter = oldub - sliceub;
2531+
/* count/size of old array entries that will go after the slice */
2532+
itemsafter = oldub + 1 - Max(sliceub + 1, oldlb);
25292533
lenafter = olddatasize - lenbefore - olditemsize;
25302534
}
25312535

0 commit comments

Comments
 (0)