Skip to content

Commit 633af84

Browse files
committed
Safe deserialization for roaring64
1 parent 7b0694a commit 633af84

File tree

3 files changed

+11
-5
lines changed

3 files changed

+11
-5
lines changed

pyroaring/abstract_bitmap.pxi

Lines changed: 9 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -28,11 +28,16 @@ cdef croaring.roaring_bitmap_t *deserialize_ptr(bytes buff):
2828

2929
cdef croaring.roaring64_bitmap_t *deserialize64_ptr(bytes buff):
3030
cdef croaring.roaring64_bitmap_t *ptr
31+
cdef const char *reason_failure = NULL
3132
buff_size = len(buff)
32-
bm_size = croaring.roaring64_bitmap_portable_deserialize_size(buff, buff_size)
33-
if bm_size == 0:
34-
raise ValueError("Invalid bitmap serialization")
35-
ptr = croaring.roaring64_bitmap_portable_deserialize_safe(buff, bm_size)
33+
ptr = croaring.roaring64_bitmap_portable_deserialize_safe(buff, buff_size)
34+
if ptr == NULL:
35+
raise ValueError("Could not deserialize bitmap")
36+
# Validate the bitmap
37+
if not croaring.roaring64_bitmap_internal_validate(ptr, &reason_failure):
38+
# If validation fails, free the bitmap and raise an exception
39+
croaring.roaring64_bitmap_free(ptr)
40+
raise ValueError(f"Invalid bitmap after deserialization: {reason_failure.decode('utf-8')}")
3641
return ptr
3742

3843
def _string_rep(bm):

pyroaring/croaring.pxd

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -165,6 +165,7 @@ cdef extern from "roaring.h":
165165
size_t roaring64_bitmap_portable_serialize(const roaring64_bitmap_t *r, char *buf)
166166
size_t roaring64_bitmap_portable_deserialize_size(const char *buf, size_t maxbytes)
167167
roaring64_bitmap_t *roaring64_bitmap_portable_deserialize_safe(const char *buf, size_t maxbytes)
168+
bool roaring64_bitmap_internal_validate(const roaring64_bitmap_t *r, const char **reason)
168169
roaring64_iterator_t *roaring64_iterator_create(const roaring64_bitmap_t *r)
169170
void roaring64_iterator_free(roaring64_iterator_t *it)
170171
bool roaring64_iterator_has_value(const roaring64_iterator_t *it)

test.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -906,7 +906,7 @@ def test_invalid_deserialization(
906906
bitmap_bytes = bm.serialize()
907907
bitmap_bytes = bitmap_bytes[:42] + wrong_input + bitmap_bytes[42:]
908908
with pytest.raises(ValueError, match='Invalid bitmap after deserialization'):
909-
bitmap = pyroaring.FrozenBitMap.deserialize(bitmap_bytes)
909+
bitmap = cls.deserialize(bitmap_bytes)
910910

911911

912912
class TestStatistics(Util):

0 commit comments

Comments
 (0)