summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAlexander Korotkov2023-12-27 01:34:12 +0000
committerAlexander Korotkov2023-12-27 01:57:57 +0000
commit71a3e8c43ba8f3d026ae0cb2c2df27455ffdca76 (patch)
tree94d7241794d0b41ceefdeebacdcfd83cbf7bbfdd
parent059de3ca4766012743b4ff7c8e7193abb71f7189 (diff)
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
-rw-r--r--src/backend/nodes/bitmapset.c77
1 files changed, 63 insertions, 14 deletions
diff --git a/src/backend/nodes/bitmapset.c b/src/backend/nodes/bitmapset.c
index 704879f5660..1627922ef7a 100644
--- a/src/backend/nodes/bitmapset.c
+++ b/src/backend/nodes/bitmapset.c
@@ -84,6 +84,7 @@ bms_copy(const Bitmapset *a)
if (a == NULL)
return NULL;
+ Assert(IsA(a, Bitmapset));
size = BITMAPSET_SIZE(a->nwords);
result = (Bitmapset *) palloc(size);
memcpy(result, a, size);
@@ -98,8 +99,8 @@ bms_equal(const Bitmapset *a, const Bitmapset *b)
{
int i;
- Assert(a == NULL || a->words[a->nwords - 1] != 0);
- Assert(b == NULL || b->words[b->nwords - 1] != 0);
+ Assert(a == NULL || (IsA(a, Bitmapset) && a->words[a->nwords - 1] != 0));
+ Assert(b == NULL || (IsA(b, Bitmapset) && b->words[b->nwords - 1] != 0));
/* Handle cases where either input is NULL */
if (a == NULL)
@@ -139,8 +140,8 @@ bms_compare(const Bitmapset *a, const Bitmapset *b)
{
int i;
- Assert(a == NULL || a->words[a->nwords - 1] != 0);
- Assert(b == NULL || b->words[b->nwords - 1] != 0);
+ Assert(a == NULL || (IsA(a, Bitmapset) && a->words[a->nwords - 1] != 0));
+ Assert(b == NULL || (IsA(b, Bitmapset) && b->words[b->nwords - 1] != 0));
/* Handle cases where either input is NULL */
if (a == NULL)
@@ -215,6 +216,9 @@ bms_union(const Bitmapset *a, const Bitmapset *b)
int otherlen;
int i;
+ Assert(a == NULL || IsA(a, Bitmapset));
+ Assert(b == NULL || IsA(b, Bitmapset));
+
/* Handle cases where either input is NULL */
if (a == NULL)
return bms_copy(b);
@@ -253,6 +257,9 @@ bms_intersect(const Bitmapset *a, const Bitmapset *b)
int resultlen;
int i;
+ Assert(a == NULL || IsA(a, Bitmapset));
+ Assert(b == NULL || IsA(b, Bitmapset));
+
/* Handle cases where either input is NULL */
if (a == NULL || b == NULL)
return NULL;
@@ -299,8 +306,8 @@ bms_difference(const Bitmapset *a, const Bitmapset *b)
Bitmapset *result;
int i;
- Assert(a == NULL || a->words[a->nwords - 1] != 0);
- Assert(b == NULL || b->words[b->nwords - 1] != 0);
+ Assert(a == NULL || (IsA(a, Bitmapset) && a->words[a->nwords - 1] != 0));
+ Assert(b == NULL || (IsA(b, Bitmapset) && b->words[b->nwords - 1] != 0));
/* Handle cases where either input is NULL */
if (a == NULL)
@@ -308,6 +315,8 @@ bms_difference(const Bitmapset *a, const Bitmapset *b)
if (b == NULL)
return bms_copy(a);
+ Assert(IsA(a, Bitmapset) && IsA(b, Bitmapset));
+
/*
* In Postgres' usage, an empty result is a very common case, so it's
* worth optimizing for that by testing bms_nonempty_difference(). This
@@ -364,8 +373,8 @@ bms_is_subset(const Bitmapset *a, const Bitmapset *b)
{
int i;
- Assert(a == NULL || a->words[a->nwords - 1] != 0);
- Assert(b == NULL || b->words[b->nwords - 1] != 0);
+ Assert(a == NULL || (IsA(a, Bitmapset) && a->words[a->nwords - 1] != 0));
+ Assert(b == NULL || (IsA(b, Bitmapset) && b->words[b->nwords - 1] != 0));
/* Handle cases where either input is NULL */
if (a == NULL)
@@ -373,6 +382,8 @@ bms_is_subset(const Bitmapset *a, const Bitmapset *b)
if (b == NULL)
return false;
+ Assert(IsA(a, Bitmapset) && IsA(b, Bitmapset));
+
/* 'a' can't be a subset of 'b' if it contains more words */
if (a->nwords > b->nwords)
return false;
@@ -399,8 +410,8 @@ bms_subset_compare(const Bitmapset *a, const Bitmapset *b)
int shortlen;
int i;
- Assert(a == NULL || a->words[a->nwords - 1] != 0);
- Assert(b == NULL || b->words[b->nwords - 1] != 0);
+ Assert(a == NULL || (IsA(a, Bitmapset) && a->words[a->nwords - 1] != 0));
+ Assert(b == NULL || (IsA(b, Bitmapset) && b->words[b->nwords - 1] != 0));
/* Handle cases where either input is NULL */
if (a == NULL)
@@ -411,6 +422,9 @@ bms_subset_compare(const Bitmapset *a, const Bitmapset *b)
}
if (b == NULL)
return BMS_SUBSET2;
+
+ Assert(IsA(a, Bitmapset) && IsA(b, Bitmapset));
+
/* Check common words */
result = BMS_EQUAL; /* status so far */
shortlen = Min(a->nwords, b->nwords);
@@ -467,6 +481,9 @@ bms_is_member(int x, const Bitmapset *a)
elog(ERROR, "negative bitmapset member not allowed");
if (a == NULL)
return false;
+
+ Assert(IsA(a, Bitmapset));
+
wordnum = WORDNUM(x);
bitnum = BITNUM(x);
if (wordnum >= a->nwords)
@@ -495,6 +512,8 @@ bms_member_index(Bitmapset *a, int x)
if (!bms_is_member(x, a))
return -1;
+ Assert(IsA(a, Bitmapset));
+
wordnum = WORDNUM(x);
bitnum = BITNUM(x);
@@ -529,6 +548,9 @@ bms_overlap(const Bitmapset *a, const Bitmapset *b)
int shortlen;
int i;
+ Assert(a == NULL || IsA(a, Bitmapset));
+ Assert(b == NULL || IsA(b, Bitmapset));
+
/* Handle cases where either input is NULL */
if (a == NULL || b == NULL)
return false;
@@ -553,6 +575,8 @@ bms_overlap_list(const Bitmapset *a, const List *b)
int wordnum,
bitnum;
+ Assert(a == NULL || IsA(a, Bitmapset));
+
if (a == NULL || b == NIL)
return false;
@@ -582,8 +606,8 @@ bms_nonempty_difference(const Bitmapset *a, const Bitmapset *b)
{
int i;
- Assert(a == NULL || a->words[a->nwords - 1] != 0);
- Assert(b == NULL || b->words[b->nwords - 1] != 0);
+ Assert(a == NULL || (IsA(a, Bitmapset) && a->words[a->nwords - 1] != 0));
+ Assert(b == NULL || (IsA(b, Bitmapset) && b->words[b->nwords - 1] != 0));
/* Handle cases where either input is NULL */
if (a == NULL)
@@ -617,6 +641,9 @@ bms_singleton_member(const Bitmapset *a)
if (a == NULL)
elog(ERROR, "bitmapset is empty");
+
+ Assert(IsA(a, Bitmapset));
+
nwords = a->nwords;
wordnum = 0;
do
@@ -657,6 +684,7 @@ bms_get_singleton_member(const Bitmapset *a, int *member)
if (a == NULL)
return false;
+ Assert(IsA(a, Bitmapset));
nwords = a->nwords;
wordnum = 0;
do
@@ -690,6 +718,7 @@ bms_num_members(const Bitmapset *a)
if (a == NULL)
return 0;
+ Assert(IsA(a, Bitmapset));
nwords = a->nwords;
wordnum = 0;
do
@@ -717,6 +746,7 @@ bms_membership(const Bitmapset *a)
if (a == NULL)
return BMS_EMPTY_SET;
+ Assert(IsA(a, Bitmapset));
nwords = a->nwords;
wordnum = 0;
do
@@ -759,6 +789,7 @@ bms_add_member(Bitmapset *a, int x)
elog(ERROR, "negative bitmapset member not allowed");
if (a == NULL)
return bms_make_singleton(x);
+ Assert(IsA(a, Bitmapset));
wordnum = WORDNUM(x);
bitnum = BITNUM(x);
@@ -799,6 +830,9 @@ bms_del_member(Bitmapset *a, int x)
elog(ERROR, "negative bitmapset member not allowed");
if (a == NULL)
return NULL;
+
+ Assert(IsA(a, Bitmapset));
+
wordnum = WORDNUM(x);
bitnum = BITNUM(x);
@@ -839,6 +873,9 @@ bms_add_members(Bitmapset *a, const Bitmapset *b)
int otherlen;
int i;
+ Assert(a == NULL || IsA(a, Bitmapset));
+ Assert(b == NULL || IsA(b, Bitmapset));
+
/* Handle cases where either input is NULL */
if (a == NULL)
return bms_copy(b);
@@ -884,6 +921,8 @@ bms_add_range(Bitmapset *a, int lower, int upper)
ushiftbits,
wordnum;
+ Assert(a == NULL || IsA(a, Bitmapset));
+
/* do nothing if nothing is called for, without further checking */
if (upper < lower)
return a;
@@ -954,6 +993,9 @@ bms_int_members(Bitmapset *a, const Bitmapset *b)
int shortlen;
int i;
+ Assert(a == NULL || IsA(a, Bitmapset));
+ Assert(b == NULL || IsA(b, Bitmapset));
+
/* Handle cases where either input is NULL */
if (a == NULL)
return NULL;
@@ -994,8 +1036,8 @@ bms_del_members(Bitmapset *a, const Bitmapset *b)
{
int i;
- Assert(a == NULL || a->words[a->nwords - 1] != 0);
- Assert(b == NULL || b->words[b->nwords - 1] != 0);
+ Assert(a == NULL || (IsA(a, Bitmapset) && a->words[a->nwords - 1] != 0));
+ Assert(b == NULL || (IsA(b, Bitmapset) && b->words[b->nwords - 1] != 0));
/* Handle cases where either input is NULL */
if (a == NULL)
@@ -1055,6 +1097,9 @@ bms_join(Bitmapset *a, Bitmapset *b)
int otherlen;
int i;
+ Assert(a == NULL || IsA(a, Bitmapset));
+ Assert(b == NULL || IsA(b, Bitmapset));
+
/* Handle cases where either input is NULL */
if (a == NULL)
return b;
@@ -1109,6 +1154,8 @@ bms_next_member(const Bitmapset *a, int prevbit)
int wordnum;
bitmapword mask;
+ Assert(a == NULL || IsA(a, Bitmapset));
+
if (a == NULL)
return -2;
nwords = a->nwords;
@@ -1168,6 +1215,8 @@ bms_prev_member(const Bitmapset *a, int prevbit)
int ushiftbits;
bitmapword mask;
+ Assert(a == NULL || IsA(a, Bitmapset));
+
/*
* If set is NULL or if there are no more bits to the right then we've
* nothing to do.