Skip to content

Commit 6196ea5

Browse files
akorotkovpull[bot]
authored andcommitted
Add asserts to bimapset manipulation functions
New asserts validate that arguments are really bitmapsets. This should help to early detect accesses to dangling pointers. Discussion: https://postgr.es/m/CAMbWs4_wJthNtYBL%2BSsebpgF-5L2r5zFFk6xYbS0A78GKOTFHw%40mail.gmail.com Reviewed-by: Richard Guo, Andres Freund, Ashutosh Bapat, Andrei Lepikhov
1 parent 5b0b463 commit 6196ea5

File tree

1 file changed

+63
-14
lines changed

1 file changed

+63
-14
lines changed

src/backend/nodes/bitmapset.c

Lines changed: 63 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -84,6 +84,7 @@ bms_copy(const Bitmapset *a)
8484

8585
if (a == NULL)
8686
return NULL;
87+
Assert(IsA(a, Bitmapset));
8788
size = BITMAPSET_SIZE(a->nwords);
8889
result = (Bitmapset *) palloc(size);
8990
memcpy(result, a, size);
@@ -98,8 +99,8 @@ bms_equal(const Bitmapset *a, const Bitmapset *b)
9899
{
99100
int i;
100101

101-
Assert(a == NULL || a->words[a->nwords - 1] != 0);
102-
Assert(b == NULL || b->words[b->nwords - 1] != 0);
102+
Assert(a == NULL || (IsA(a, Bitmapset) && a->words[a->nwords - 1] != 0));
103+
Assert(b == NULL || (IsA(b, Bitmapset) && b->words[b->nwords - 1] != 0));
103104

104105
/* Handle cases where either input is NULL */
105106
if (a == NULL)
@@ -139,8 +140,8 @@ bms_compare(const Bitmapset *a, const Bitmapset *b)
139140
{
140141
int i;
141142

142-
Assert(a == NULL || a->words[a->nwords - 1] != 0);
143-
Assert(b == NULL || b->words[b->nwords - 1] != 0);
143+
Assert(a == NULL || (IsA(a, Bitmapset) && a->words[a->nwords - 1] != 0));
144+
Assert(b == NULL || (IsA(b, Bitmapset) && b->words[b->nwords - 1] != 0));
144145

145146
/* Handle cases where either input is NULL */
146147
if (a == NULL)
@@ -215,6 +216,9 @@ bms_union(const Bitmapset *a, const Bitmapset *b)
215216
int otherlen;
216217
int i;
217218

219+
Assert(a == NULL || IsA(a, Bitmapset));
220+
Assert(b == NULL || IsA(b, Bitmapset));
221+
218222
/* Handle cases where either input is NULL */
219223
if (a == NULL)
220224
return bms_copy(b);
@@ -253,6 +257,9 @@ bms_intersect(const Bitmapset *a, const Bitmapset *b)
253257
int resultlen;
254258
int i;
255259

260+
Assert(a == NULL || IsA(a, Bitmapset));
261+
Assert(b == NULL || IsA(b, Bitmapset));
262+
256263
/* Handle cases where either input is NULL */
257264
if (a == NULL || b == NULL)
258265
return NULL;
@@ -299,15 +306,17 @@ bms_difference(const Bitmapset *a, const Bitmapset *b)
299306
Bitmapset *result;
300307
int i;
301308

302-
Assert(a == NULL || a->words[a->nwords - 1] != 0);
303-
Assert(b == NULL || b->words[b->nwords - 1] != 0);
309+
Assert(a == NULL || (IsA(a, Bitmapset) && a->words[a->nwords - 1] != 0));
310+
Assert(b == NULL || (IsA(b, Bitmapset) && b->words[b->nwords - 1] != 0));
304311

305312
/* Handle cases where either input is NULL */
306313
if (a == NULL)
307314
return NULL;
308315
if (b == NULL)
309316
return bms_copy(a);
310317

318+
Assert(IsA(a, Bitmapset) && IsA(b, Bitmapset));
319+
311320
/*
312321
* In Postgres' usage, an empty result is a very common case, so it's
313322
* worth optimizing for that by testing bms_nonempty_difference(). This
@@ -364,15 +373,17 @@ bms_is_subset(const Bitmapset *a, const Bitmapset *b)
364373
{
365374
int i;
366375

367-
Assert(a == NULL || a->words[a->nwords - 1] != 0);
368-
Assert(b == NULL || b->words[b->nwords - 1] != 0);
376+
Assert(a == NULL || (IsA(a, Bitmapset) && a->words[a->nwords - 1] != 0));
377+
Assert(b == NULL || (IsA(b, Bitmapset) && b->words[b->nwords - 1] != 0));
369378

370379
/* Handle cases where either input is NULL */
371380
if (a == NULL)
372381
return true; /* empty set is a subset of anything */
373382
if (b == NULL)
374383
return false;
375384

385+
Assert(IsA(a, Bitmapset) && IsA(b, Bitmapset));
386+
376387
/* 'a' can't be a subset of 'b' if it contains more words */
377388
if (a->nwords > b->nwords)
378389
return false;
@@ -399,8 +410,8 @@ bms_subset_compare(const Bitmapset *a, const Bitmapset *b)
399410
int shortlen;
400411
int i;
401412

402-
Assert(a == NULL || a->words[a->nwords - 1] != 0);
403-
Assert(b == NULL || b->words[b->nwords - 1] != 0);
413+
Assert(a == NULL || (IsA(a, Bitmapset) && a->words[a->nwords - 1] != 0));
414+
Assert(b == NULL || (IsA(b, Bitmapset) && b->words[b->nwords - 1] != 0));
404415

405416
/* Handle cases where either input is NULL */
406417
if (a == NULL)
@@ -411,6 +422,9 @@ bms_subset_compare(const Bitmapset *a, const Bitmapset *b)
411422
}
412423
if (b == NULL)
413424
return BMS_SUBSET2;
425+
426+
Assert(IsA(a, Bitmapset) && IsA(b, Bitmapset));
427+
414428
/* Check common words */
415429
result = BMS_EQUAL; /* status so far */
416430
shortlen = Min(a->nwords, b->nwords);
@@ -467,6 +481,9 @@ bms_is_member(int x, const Bitmapset *a)
467481
elog(ERROR, "negative bitmapset member not allowed");
468482
if (a == NULL)
469483
return false;
484+
485+
Assert(IsA(a, Bitmapset));
486+
470487
wordnum = WORDNUM(x);
471488
bitnum = BITNUM(x);
472489
if (wordnum >= a->nwords)
@@ -495,6 +512,8 @@ bms_member_index(Bitmapset *a, int x)
495512
if (!bms_is_member(x, a))
496513
return -1;
497514

515+
Assert(IsA(a, Bitmapset));
516+
498517
wordnum = WORDNUM(x);
499518
bitnum = BITNUM(x);
500519

@@ -529,6 +548,9 @@ bms_overlap(const Bitmapset *a, const Bitmapset *b)
529548
int shortlen;
530549
int i;
531550

551+
Assert(a == NULL || IsA(a, Bitmapset));
552+
Assert(b == NULL || IsA(b, Bitmapset));
553+
532554
/* Handle cases where either input is NULL */
533555
if (a == NULL || b == NULL)
534556
return false;
@@ -553,6 +575,8 @@ bms_overlap_list(const Bitmapset *a, const List *b)
553575
int wordnum,
554576
bitnum;
555577

578+
Assert(a == NULL || IsA(a, Bitmapset));
579+
556580
if (a == NULL || b == NIL)
557581
return false;
558582

@@ -582,8 +606,8 @@ bms_nonempty_difference(const Bitmapset *a, const Bitmapset *b)
582606
{
583607
int i;
584608

585-
Assert(a == NULL || a->words[a->nwords - 1] != 0);
586-
Assert(b == NULL || b->words[b->nwords - 1] != 0);
609+
Assert(a == NULL || (IsA(a, Bitmapset) && a->words[a->nwords - 1] != 0));
610+
Assert(b == NULL || (IsA(b, Bitmapset) && b->words[b->nwords - 1] != 0));
587611

588612
/* Handle cases where either input is NULL */
589613
if (a == NULL)
@@ -617,6 +641,9 @@ bms_singleton_member(const Bitmapset *a)
617641

618642
if (a == NULL)
619643
elog(ERROR, "bitmapset is empty");
644+
645+
Assert(IsA(a, Bitmapset));
646+
620647
nwords = a->nwords;
621648
wordnum = 0;
622649
do
@@ -657,6 +684,7 @@ bms_get_singleton_member(const Bitmapset *a, int *member)
657684

658685
if (a == NULL)
659686
return false;
687+
Assert(IsA(a, Bitmapset));
660688
nwords = a->nwords;
661689
wordnum = 0;
662690
do
@@ -690,6 +718,7 @@ bms_num_members(const Bitmapset *a)
690718

691719
if (a == NULL)
692720
return 0;
721+
Assert(IsA(a, Bitmapset));
693722
nwords = a->nwords;
694723
wordnum = 0;
695724
do
@@ -717,6 +746,7 @@ bms_membership(const Bitmapset *a)
717746

718747
if (a == NULL)
719748
return BMS_EMPTY_SET;
749+
Assert(IsA(a, Bitmapset));
720750
nwords = a->nwords;
721751
wordnum = 0;
722752
do
@@ -759,6 +789,7 @@ bms_add_member(Bitmapset *a, int x)
759789
elog(ERROR, "negative bitmapset member not allowed");
760790
if (a == NULL)
761791
return bms_make_singleton(x);
792+
Assert(IsA(a, Bitmapset));
762793
wordnum = WORDNUM(x);
763794
bitnum = BITNUM(x);
764795

@@ -799,6 +830,9 @@ bms_del_member(Bitmapset *a, int x)
799830
elog(ERROR, "negative bitmapset member not allowed");
800831
if (a == NULL)
801832
return NULL;
833+
834+
Assert(IsA(a, Bitmapset));
835+
802836
wordnum = WORDNUM(x);
803837
bitnum = BITNUM(x);
804838

@@ -839,6 +873,9 @@ bms_add_members(Bitmapset *a, const Bitmapset *b)
839873
int otherlen;
840874
int i;
841875

876+
Assert(a == NULL || IsA(a, Bitmapset));
877+
Assert(b == NULL || IsA(b, Bitmapset));
878+
842879
/* Handle cases where either input is NULL */
843880
if (a == NULL)
844881
return bms_copy(b);
@@ -884,6 +921,8 @@ bms_add_range(Bitmapset *a, int lower, int upper)
884921
ushiftbits,
885922
wordnum;
886923

924+
Assert(a == NULL || IsA(a, Bitmapset));
925+
887926
/* do nothing if nothing is called for, without further checking */
888927
if (upper < lower)
889928
return a;
@@ -954,6 +993,9 @@ bms_int_members(Bitmapset *a, const Bitmapset *b)
954993
int shortlen;
955994
int i;
956995

996+
Assert(a == NULL || IsA(a, Bitmapset));
997+
Assert(b == NULL || IsA(b, Bitmapset));
998+
957999
/* Handle cases where either input is NULL */
9581000
if (a == NULL)
9591001
return NULL;
@@ -994,8 +1036,8 @@ bms_del_members(Bitmapset *a, const Bitmapset *b)
9941036
{
9951037
int i;
9961038

997-
Assert(a == NULL || a->words[a->nwords - 1] != 0);
998-
Assert(b == NULL || b->words[b->nwords - 1] != 0);
1039+
Assert(a == NULL || (IsA(a, Bitmapset) && a->words[a->nwords - 1] != 0));
1040+
Assert(b == NULL || (IsA(b, Bitmapset) && b->words[b->nwords - 1] != 0));
9991041

10001042
/* Handle cases where either input is NULL */
10011043
if (a == NULL)
@@ -1055,6 +1097,9 @@ bms_join(Bitmapset *a, Bitmapset *b)
10551097
int otherlen;
10561098
int i;
10571099

1100+
Assert(a == NULL || IsA(a, Bitmapset));
1101+
Assert(b == NULL || IsA(b, Bitmapset));
1102+
10581103
/* Handle cases where either input is NULL */
10591104
if (a == NULL)
10601105
return b;
@@ -1109,6 +1154,8 @@ bms_next_member(const Bitmapset *a, int prevbit)
11091154
int wordnum;
11101155
bitmapword mask;
11111156

1157+
Assert(a == NULL || IsA(a, Bitmapset));
1158+
11121159
if (a == NULL)
11131160
return -2;
11141161
nwords = a->nwords;
@@ -1168,6 +1215,8 @@ bms_prev_member(const Bitmapset *a, int prevbit)
11681215
int ushiftbits;
11691216
bitmapword mask;
11701217

1218+
Assert(a == NULL || IsA(a, Bitmapset));
1219+
11711220
/*
11721221
* If set is NULL or if there are no more bits to the right then we've
11731222
* nothing to do.

0 commit comments

Comments
 (0)