Movatterモバイル変換


[0]ホーム

URL:


Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings

Commitad5fe74

Browse files
committed
Fix oversights in array manipulation.
The nested-arrays code path in ExecEvalArrayExpr() used palloc toallocate the result array, whereas every other array-creating functionhas used palloc0 since18c0b4e. This mostly works, but unused bitspast the end of the nulls bitmap may end up undefined. That causesvalgrind complaints with -DWRITE_READ_PARSE_PLAN_TREES, and couldcause planner misbehavior as cited in18c0b4e. There seems no verygood reason why we should strive to avoid palloc0 in just this one case,so fix it the easy way with s/palloc/palloc0/.While looking at that I noted that we also failed to check for overflowof "nbytes" and "nitems" while summing the sizes of the sub-arrays,potentially allowing a crash due to undersized output allocation.For "nbytes", follow the policy used by other array-munging code ofchecking for overflow after each addition. (As elsewhere, the lastaddition of the array's overhead space doesn't need an extra check,since palloc itself will catch a value between 1Gb and 2Gb.)For "nitems", there's no very good reason to sum the inputs at all,since we can perfectly well use ArrayGetNItems' result instead ofignoring it.Per discussion of this bug, also remove redundant zeroing of thenulls bitmap in array_set_element and array_set_slice.Patch by Alexander Lakhin and myself, per bug #17858 from AlexanderLakhin; thanks also to Richard Guo. These bugs are a dozen years old,so back-patch to all supported branches.Discussion:https://postgr.es/m/17858-8fd287fd3663d051@postgresql.org
1 parent0f2d4ad commitad5fe74

File tree

2 files changed

+11
-8
lines changed

2 files changed

+11
-8
lines changed

‎src/backend/executor/execExprInterp.c

Lines changed: 9 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -2608,7 +2608,7 @@ ExecEvalArrayExpr(ExprState *state, ExprEvalStep *op)
26082608
{
26092609
/* Must be nested array expressions */
26102610
intnbytes=0;
2611-
intnitems=0;
2611+
intnitems;
26122612
intouter_nelems=0;
26132613
intelem_ndims=0;
26142614
int*elem_dims=NULL;
@@ -2705,9 +2705,14 @@ ExecEvalArrayExpr(ExprState *state, ExprEvalStep *op)
27052705
subbitmaps[outer_nelems]=ARR_NULLBITMAP(array);
27062706
subbytes[outer_nelems]=ARR_SIZE(array)-ARR_DATA_OFFSET(array);
27072707
nbytes+=subbytes[outer_nelems];
2708+
/* check for overflow of total request */
2709+
if (!AllocSizeIsValid(nbytes))
2710+
ereport(ERROR,
2711+
(errcode(ERRCODE_PROGRAM_LIMIT_EXCEEDED),
2712+
errmsg("array size exceeds the maximum allowed (%d)",
2713+
(int)MaxAllocSize)));
27082714
subnitems[outer_nelems]=ArrayGetNItems(this_ndims,
27092715
ARR_DIMS(array));
2710-
nitems+=subnitems[outer_nelems];
27112716
havenulls |=ARR_HASNULL(array);
27122717
outer_nelems++;
27132718
}
@@ -2741,7 +2746,7 @@ ExecEvalArrayExpr(ExprState *state, ExprEvalStep *op)
27412746
}
27422747

27432748
/* check for subscript overflow */
2744-
(void)ArrayGetNItems(ndims,dims);
2749+
nitems=ArrayGetNItems(ndims,dims);
27452750
ArrayCheckBounds(ndims,dims,lbs);
27462751

27472752
if (havenulls)
@@ -2755,7 +2760,7 @@ ExecEvalArrayExpr(ExprState *state, ExprEvalStep *op)
27552760
nbytes+=ARR_OVERHEAD_NONULLS(ndims);
27562761
}
27572762

2758-
result= (ArrayType*)palloc(nbytes);
2763+
result= (ArrayType*)palloc0(nbytes);
27592764
SET_VARSIZE(result,nbytes);
27602765
result->ndim=ndims;
27612766
result->dataoffset=dataoffset;

‎src/backend/utils/adt/arrayfuncs.c

Lines changed: 2 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -2435,8 +2435,7 @@ array_set_element(Datum arraydatum,
24352435
{
24362436
bits8*newnullbitmap=ARR_NULLBITMAP(newarray);
24372437

2438-
/* Zero the bitmap to take care of marking inserted positions null */
2439-
MemSet(newnullbitmap,0, (newnitems+7) /8);
2438+
/* palloc0 above already marked any inserted positions as nulls */
24402439
/* Fix the inserted value */
24412440
if (addedafter)
24422441
array_set_isnull(newnullbitmap,newnitems-1,isNull);
@@ -3048,8 +3047,7 @@ array_set_slice(Datum arraydatum,
30483047
bits8*newnullbitmap=ARR_NULLBITMAP(newarray);
30493048
bits8*oldnullbitmap=ARR_NULLBITMAP(array);
30503049

3051-
/* Zero the bitmap to handle marking inserted positions null */
3052-
MemSet(newnullbitmap,0, (nitems+7) /8);
3050+
/* palloc0 above already marked any inserted positions as nulls */
30533051
array_bitmap_copy(newnullbitmap,addedbefore,
30543052
oldnullbitmap,0,
30553053
itemsbefore);

0 commit comments

Comments
 (0)

[8]ページ先頭

©2009-2025 Movatter.jp