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

Commit 71a3e8c

Browse files
committed
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 059de3c commit 71a3e8c

File tree

1 file changed

+63
-14
lines changed

1 file changed

+63
-14
lines changed

src/backend/nodes/bitmapset.c

+63-14
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)