aboutsummaryrefslogtreecommitdiffstats
path: root/contrib/libs/croaring/src/roaring64.c
diff options
context:
space:
mode:
authorrobot-piglet <robot-piglet@yandex-team.com>2024-10-05 22:20:55 +0300
committerrobot-piglet <robot-piglet@yandex-team.com>2024-10-05 22:32:53 +0300
commit2eec23b402e467c4997cae5f4fea19abad3195a6 (patch)
tree7bd2721e854318523c28c0915c235407f78cdfef /contrib/libs/croaring/src/roaring64.c
parentc3797467c201a8de261c9da5475b2386197cb4b0 (diff)
downloadydb-2eec23b402e467c4997cae5f4fea19abad3195a6.tar.gz
Intermediate changes
commit_hash:89e9af18f838d98d46029c1a50881e032a4efa72
Diffstat (limited to 'contrib/libs/croaring/src/roaring64.c')
-rw-r--r--contrib/libs/croaring/src/roaring64.c25
1 files changed, 25 insertions, 0 deletions
diff --git a/contrib/libs/croaring/src/roaring64.c b/contrib/libs/croaring/src/roaring64.c
index e63d3d965c..914faefe0b 100644
--- a/contrib/libs/croaring/src/roaring64.c
+++ b/contrib/libs/croaring/src/roaring64.c
@@ -1954,6 +1954,7 @@ roaring64_bitmap_t *roaring64_bitmap_portable_deserialize_safe(
roaring64_bitmap_t *r = roaring64_bitmap_create();
// Iterate through buckets ordered by increasing keys.
+ int64_t previous_high32 = -1;
for (uint64_t bucket = 0; bucket < buckets; ++bucket) {
// Read as uint32 the most significant 32 bits of the bucket.
uint32_t high32;
@@ -1964,6 +1965,12 @@ roaring64_bitmap_t *roaring64_bitmap_portable_deserialize_safe(
memcpy(&high32, buf, sizeof(high32));
buf += sizeof(high32);
read_bytes += sizeof(high32);
+ // High 32 bits must be strictly increasing.
+ if (high32 <= previous_high32) {
+ roaring64_bitmap_free(r);
+ return NULL;
+ }
+ previous_high32 = high32;
// Read the 32-bit Roaring bitmaps representing the least significant
// bits of a set of elements.
@@ -1983,6 +1990,24 @@ roaring64_bitmap_t *roaring64_bitmap_portable_deserialize_safe(
buf += bitmap32_size;
read_bytes += bitmap32_size;
+ // While we don't attempt to validate much, we must ensure that there
+ // is no duplication in the high 48 bits - inserting into the ART
+ // assumes (or UB) no duplicate keys. The top 32 bits must be unique
+ // because we check for strict increasing values of high32, but we
+ // must also ensure the top 16 bits within each 32-bit bitmap are also
+ // at least unique (we ensure they're strictly increasing as well,
+ // which they must be for a _valid_ bitmap, since it's cheaper to check)
+ int32_t last_bitmap_key = -1;
+ for (int i = 0; i < bitmap32->high_low_container.size; i++) {
+ uint16_t key = bitmap32->high_low_container.keys[i];
+ if (key <= last_bitmap_key) {
+ roaring_bitmap_free(bitmap32);
+ roaring64_bitmap_free(r);
+ return NULL;
+ }
+ last_bitmap_key = key;
+ }
+
// Insert all containers of the 32-bit bitmap into the 64-bit bitmap.
move_from_roaring32_offset(r, bitmap32, high32);
roaring_bitmap_free(bitmap32);