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

Commit8ef289d

Browse files
committed
Defend against nulls-in-arrays in contrib/intarray. I may have put in
more tests than strictly necessary, but did not feel like tracing callpaths in detail ...
1 parent25c0083 commit8ef289d

File tree

6 files changed

+131
-44
lines changed

6 files changed

+131
-44
lines changed

‎contrib/intarray/_int.h

Lines changed: 17 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -19,13 +19,24 @@
1919

2020
/* useful macros for accessing int4 arrays */
2121
#defineARRPTR(x) ( (int4 *) ARR_DATA_PTR(x) )
22-
#defineARRNELEMS(x) ArrayGetNItems(ARR_NDIM(x), ARR_DIMS(x))
22+
#defineARRNELEMS(x) ArrayGetNItems(ARR_NDIM(x), ARR_DIMS(x))
2323

24-
#defineARRISVOID(x) ( (x) ? ( ( ARR_NDIM(x) == NDIM ) ? ( ( ARRNELEMS( x ) ) ? 0 : 1 ) : ( ( ARR_NDIM(x) ) ? ( \
25-
ereport(ERROR, \
26-
(errcode(ERRCODE_ARRAY_SUBSCRIPT_ERROR), \
27-
errmsg("array must be one-dimensional, not %d dimensions", ARRNELEMS( x )))) \
28-
,1) : 0 ) ) : 0 )
24+
/* reject arrays we can't handle; but allow a NULL or empty array */
25+
#defineCHECKARRVALID(x) \
26+
do { \
27+
if (x) { \
28+
if (ARR_NDIM(x) != NDIM && ARR_NDIM(x) != 0) \
29+
ereport(ERROR, \
30+
(errcode(ERRCODE_ARRAY_SUBSCRIPT_ERROR), \
31+
errmsg("array must be one-dimensional"))); \
32+
if (ARR_HASNULL(x)) \
33+
ereport(ERROR, \
34+
(errcode(ERRCODE_NULL_VALUE_NOT_ALLOWED), \
35+
errmsg("array must not contain nulls"))); \
36+
} \
37+
} while(0)
38+
39+
#defineARRISVOID(x) ((x) == NULL || ARRNELEMS(x) == 0)
2940

3041
#defineSORT(x) \
3142
do { \
@@ -52,9 +63,6 @@
5263
typedefcharBITVEC[SIGLEN];
5364
typedefchar*BITVECP;
5465

55-
#defineSIGPTR(x) ( (BITVECP) ARR_DATA_PTR(x) )
56-
57-
5866
#defineLOOPBYTE(a) \
5967
for(i=0;i<SIGLEN;i++) {\
6068
a;\

‎contrib/intarray/_int_bool.c

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -309,6 +309,7 @@ execconsistent(QUERYTYPE * query, ArrayType *array, bool calcnot)
309309
{
310310
CHKVALchkval;
311311

312+
CHECKARRVALID(array);
312313
chkval.arrb=ARRPTR(array);
313314
chkval.arre=chkval.arrb+ARRNELEMS(array);
314315
returnexecute(
@@ -339,6 +340,7 @@ boolop(PG_FUNCTION_ARGS)
339340
CHKVALchkval;
340341
boolresult;
341342

343+
CHECKARRVALID(val);
342344
if (ARRISVOID(val))
343345
{
344346
pfree(val);

‎contrib/intarray/_int_gist.c

Lines changed: 22 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -44,6 +44,7 @@ g_int_consistent(PG_FUNCTION_ARGS)
4444
/* XXX are we sure it's safe to scribble on the query object here? */
4545
/* XXX what about toasted input? */
4646
/* sort query for fast search, key is already sorted */
47+
CHECKARRVALID(query);
4748
if (ARRISVOID(query))
4849
PG_RETURN_BOOL(false);
4950
PREPAREARR(query);
@@ -89,21 +90,30 @@ g_int_union(PG_FUNCTION_ARGS)
8990
{
9091
GistEntryVector*entryvec= (GistEntryVector*)PG_GETARG_POINTER(0);
9192
int*size= (int*)PG_GETARG_POINTER(1);
92-
int4i;
93-
ArrayType*res;
94-
inttotlen=0,
93+
int4i,
9594
*ptr;
95+
ArrayType*res;
96+
inttotlen=0;
9697

9798
for (i=0;i<entryvec->n;i++)
98-
totlen+=ARRNELEMS(GETENTRY(entryvec,i));
99+
{
100+
ArrayType*ent=GETENTRY(entryvec,i);
101+
102+
CHECKARRVALID(ent);
103+
totlen+=ARRNELEMS(ent);
104+
}
99105

100106
res=new_intArrayType(totlen);
101107
ptr=ARRPTR(res);
102108

103109
for (i=0;i<entryvec->n;i++)
104110
{
105-
memcpy(ptr,ARRPTR(GETENTRY(entryvec,i)),ARRNELEMS(GETENTRY(entryvec,i))*sizeof(int4));
106-
ptr+=ARRNELEMS(GETENTRY(entryvec,i));
111+
ArrayType*ent=GETENTRY(entryvec,i);
112+
intnel;
113+
114+
nel=ARRNELEMS(ent);
115+
memcpy(ptr,ARRPTR(ent),nel*sizeof(int4));
116+
ptr+=nel;
107117
}
108118

109119
QSORT(res,1);
@@ -130,6 +140,7 @@ g_int_compress(PG_FUNCTION_ARGS)
130140
if (entry->leafkey)
131141
{
132142
r= (ArrayType*)PG_DETOAST_DATUM_COPY(entry->key);
143+
CHECKARRVALID(r);
133144
PREPAREARR(r);
134145

135146
if (ARRNELEMS(r)>=2*MAXNUMRANGE)
@@ -147,6 +158,7 @@ g_int_compress(PG_FUNCTION_ARGS)
147158
so now we work only with internal keys */
148159

149160
r= (ArrayType*)PG_DETOAST_DATUM(entry->key);
161+
CHECKARRVALID(r);
150162
if (ARRISVOID(r))
151163
{
152164
if (r!= (ArrayType*)DatumGetPointer(entry->key))
@@ -207,6 +219,7 @@ g_int_decompress(PG_FUNCTION_ARGS)
207219

208220
in= (ArrayType*)PG_DETOAST_DATUM(entry->key);
209221

222+
CHECKARRVALID(in);
210223
if (ARRISVOID(in))
211224
PG_RETURN_POINTER(entry);
212225

@@ -280,6 +293,9 @@ g_int_same(PG_FUNCTION_ARGS)
280293
int4*da,
281294
*db;
282295

296+
CHECKARRVALID(a);
297+
CHECKARRVALID(b);
298+
283299
if (n!=ARRNELEMS(b))
284300
{
285301
*result= false;

‎contrib/intarray/_int_op.c

Lines changed: 46 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -37,6 +37,8 @@ _int_contains(PG_FUNCTION_ARGS)
3737
ArrayType*b= (ArrayType*)DatumGetPointer(PG_DETOAST_DATUM_COPY(PG_GETARG_DATUM(1)));
3838
boolres;
3939

40+
CHECKARRVALID(a);
41+
CHECKARRVALID(b);
4042
if (ARRISVOID(a)||ARRISVOID(b))
4143
return FALSE;
4244

@@ -71,9 +73,13 @@ _int_same(PG_FUNCTION_ARGS)
7173
int*da,
7274
*db;
7375
boolresult;
74-
boolavoid=ARRISVOID(a);
75-
boolbvoid=ARRISVOID(b);
76+
boolavoid;
77+
boolbvoid;
7678

79+
CHECKARRVALID(a);
80+
CHECKARRVALID(b);
81+
avoid=ARRISVOID(a);
82+
bvoid=ARRISVOID(b);
7783
if (avoid||bvoid)
7884
return (avoid&&bvoid) ? TRUE : FALSE;
7985

@@ -112,6 +118,8 @@ _int_overlap(PG_FUNCTION_ARGS)
112118
ArrayType*b= (ArrayType*)DatumGetPointer(PG_DETOAST_DATUM_COPY(PG_GETARG_DATUM(1)));
113119
boolresult;
114120

121+
CHECKARRVALID(a);
122+
CHECKARRVALID(b);
115123
if (ARRISVOID(a)||ARRISVOID(b))
116124
return FALSE;
117125

@@ -133,6 +141,9 @@ _int_union(PG_FUNCTION_ARGS)
133141
ArrayType*b= (ArrayType*)DatumGetPointer(PG_DETOAST_DATUM_COPY(PG_GETARG_DATUM(1)));
134142
ArrayType*result;
135143

144+
CHECKARRVALID(a);
145+
CHECKARRVALID(b);
146+
136147
if (!ARRISVOID(a))
137148
SORT(a);
138149
if (!ARRISVOID(b))
@@ -155,6 +166,8 @@ _int_inter(PG_FUNCTION_ARGS)
155166
ArrayType*b= (ArrayType*)DatumGetPointer(PG_DETOAST_DATUM_COPY(PG_GETARG_DATUM(1)));
156167
ArrayType*result;
157168

169+
CHECKARRVALID(a);
170+
CHECKARRVALID(b);
158171
if (ARRISVOID(a)||ARRISVOID(b))
159172
PG_RETURN_POINTER(new_intArrayType(0));
160173

@@ -197,12 +210,6 @@ Datumintarray_del_elem(PG_FUNCTION_ARGS);
197210
Datumintset_union_elem(PG_FUNCTION_ARGS);
198211
Datumintset_subtract(PG_FUNCTION_ARGS);
199212

200-
#defineQSORT(a,direction)\
201-
if (ARRNELEMS(a) > 1)\
202-
qsort((void*)ARRPTR(a), ARRNELEMS(a),sizeof(int4),\
203-
(direction) ? compASC : compDESC )
204-
205-
206213
Datum
207214
intset(PG_FUNCTION_ARGS)
208215
{
@@ -213,7 +220,7 @@ Datum
213220
icount(PG_FUNCTION_ARGS)
214221
{
215222
ArrayType*a= (ArrayType*)DatumGetPointer(PG_DETOAST_DATUM(PG_GETARG_DATUM(0)));
216-
int32count=(ARRISVOID(a)) ?0 :ARRNELEMS(a);
223+
int32count=ARRNELEMS(a);
217224

218225
PG_FREE_IF_COPY(a,0);
219226
PG_RETURN_INT32(count);
@@ -228,6 +235,7 @@ sort(PG_FUNCTION_ARGS)
228235
char*d= (dirstr) ?VARDATA(dirstr) :NULL;
229236
intdir=-1;
230237

238+
CHECKARRVALID(a);
231239
if (ARRISVOID(a)||ARRNELEMS(a)<2)
232240
PG_RETURN_POINTER(a);
233241

@@ -255,6 +263,7 @@ sort_asc(PG_FUNCTION_ARGS)
255263
{
256264
ArrayType*a= (ArrayType*)DatumGetPointer(PG_DETOAST_DATUM_COPY(PG_GETARG_DATUM(0)));
257265

266+
CHECKARRVALID(a);
258267
if (ARRISVOID(a))
259268
PG_RETURN_POINTER(a);
260269
QSORT(a,1);
@@ -266,6 +275,7 @@ sort_desc(PG_FUNCTION_ARGS)
266275
{
267276
ArrayType*a= (ArrayType*)DatumGetPointer(PG_DETOAST_DATUM_COPY(PG_GETARG_DATUM(0)));
268277

278+
CHECKARRVALID(a);
269279
if (ARRISVOID(a))
270280
PG_RETURN_POINTER(a);
271281
QSORT(a,0);
@@ -277,6 +287,7 @@ uniq(PG_FUNCTION_ARGS)
277287
{
278288
ArrayType*a= (ArrayType*)DatumGetPointer(PG_DETOAST_DATUM_COPY(PG_GETARG_DATUM(0)));
279289

290+
CHECKARRVALID(a);
280291
if (ARRISVOID(a)||ARRNELEMS(a)<2)
281292
PG_RETURN_POINTER(a);
282293
a=_int_unique(a);
@@ -287,8 +298,10 @@ Datum
287298
idx(PG_FUNCTION_ARGS)
288299
{
289300
ArrayType*a= (ArrayType*)DatumGetPointer(PG_DETOAST_DATUM(PG_GETARG_DATUM(0)));
290-
int32result= (ARRISVOID(a)) ?0 :ARRNELEMS(a);
301+
int32result;
291302

303+
CHECKARRVALID(a);
304+
result= (ARRISVOID(a)) ?0 :ARRNELEMS(a);
292305
if (result)
293306
result=intarray_match_first(a,PG_GETARG_INT32(1));
294307
PG_FREE_IF_COPY(a,0);
@@ -305,6 +318,7 @@ subarray(PG_FUNCTION_ARGS)
305318
int32end=0;
306319
int32c;
307320

321+
CHECKARRVALID(a);
308322
if (ARRISVOID(a))
309323
{
310324
PG_FREE_IF_COPY(a,0);
@@ -371,22 +385,29 @@ Datum
371385
intarray_del_elem(PG_FUNCTION_ARGS)
372386
{
373387
ArrayType*a= (ArrayType*)DatumGetPointer(PG_DETOAST_DATUM_COPY(PG_GETARG_DATUM(0)));
374-
int32c= (ARRISVOID(a)) ?0 :ARRNELEMS(a);
375-
int32*aa=ARRPTR(a);
388+
int32elem=PG_GETARG_INT32(1);
389+
int32c;
390+
int32*aa;
376391
int32n=0,
377392
i;
378-
int32elem=PG_GETARG_INT32(1);
379393

380-
for (i=0;i<c;i++)
381-
if (aa[i]!=elem)
394+
CHECKARRVALID(a);
395+
if (!ARRISVOID(a))
396+
{
397+
c=ARRNELEMS(a);
398+
aa=ARRPTR(a);
399+
for (i=0;i<c;i++)
382400
{
383-
if (i>n)
384-
aa[n++]=aa[i];
385-
else
386-
n++;
401+
if (aa[i]!=elem)
402+
{
403+
if (i>n)
404+
aa[n++]=aa[i];
405+
else
406+
n++;
407+
}
387408
}
388-
if (c>0)
389409
a=resize_intArrayType(a,n);
410+
}
390411
PG_RETURN_POINTER(a);
391412
}
392413

@@ -408,15 +429,18 @@ intset_subtract(PG_FUNCTION_ARGS)
408429
ArrayType*a= (ArrayType*)DatumGetPointer(PG_DETOAST_DATUM_COPY(PG_GETARG_DATUM(0)));
409430
ArrayType*b= (ArrayType*)DatumGetPointer(PG_DETOAST_DATUM_COPY(PG_GETARG_DATUM(1)));
410431
ArrayType*result;
411-
int32ca=ARRISVOID(a);
412-
int32cb=ARRISVOID(b);
432+
int32ca;
433+
int32cb;
413434
int32*aa,
414435
*bb,
415436
*r;
416437
int32n=0,
417438
i=0,
418439
k=0;
419440

441+
CHECKARRVALID(a);
442+
CHECKARRVALID(b);
443+
420444
QSORT(a,1);
421445
a=_int_unique(a);
422446
ca=ARRNELEMS(a);

0 commit comments

Comments
 (0)

[8]ページ先頭

©2009-2025 Movatter.jp