From f0e8f32d0badc43c85afd0fb54f281a60ba14114 Mon Sep 17 00:00:00 2001 From: Zachary Dremann Date: Fri, 20 Sep 2024 10:21:16 -0400 Subject: [PATCH] fix: another segfault in 64 bit deserialize_safe (#664) actually update the previous_high32 variable to ensure the ghigh keys are actually strictly increasing --- src/roaring64.c | 2 ++ tests/roaring64_serialization.cpp | 53 ++++++++++++++++++++++++++++++- 2 files changed, 54 insertions(+), 1 deletion(-) diff --git a/src/roaring64.c b/src/roaring64.c index 14011c64..914faefe 100644 --- a/src/roaring64.c +++ b/src/roaring64.c @@ -1970,6 +1970,8 @@ roaring64_bitmap_t *roaring64_bitmap_portable_deserialize_safe( 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. size_t bitmap32_size = roaring_bitmap_portable_deserialize_size( diff --git a/tests/roaring64_serialization.cpp b/tests/roaring64_serialization.cpp index d71ea2a7..f7518365 100644 --- a/tests/roaring64_serialization.cpp +++ b/tests/roaring64_serialization.cpp @@ -97,7 +97,7 @@ DEFINE_TEST(test_64deseroverlappingkeys) { // Container count - 1 1, 0, // Run Flag Bitset (no runs) - 0, 0, + 0, // Upper 16 bits of the first container 0, 0, // Cardinality - 1 of the first container @@ -125,6 +125,56 @@ DEFINE_TEST(test_64deseroverlappingkeys) { roaring64_bitmap_free(r); } } + +DEFINE_TEST(test_64deseroverlappingupper32) { + // Two bitmaps, with a single array container each, at the same key (0). + // clang-format off + char simple_bitmap[] = { + // Number of 32 bit bitmaps + 2, 0, 0, 0, 0, 0, 0, 0, + // Top 32 bits of the first bitmap + 0, 0, 0, 0, + // Serial Cookie + 0x3B, 0x30, + // Container count - 1 + 0, 0, + // Run Flag Bitset (not a run) + 0, + // Upper 16 bits of the only container + 0, 0, + // Cardinality - 1 of the only container + 0, 0, + // Only value of first container + 0, 0, + // Top 32 bits of the second bitmap + 0, 0, 0, 0, + // Serial Cookie + 0x3B, 0x30, + // Container count - 1 + 0, 0, + // Run Flag Bitset (not a run) + 0, + // Upper 16 bits of the only container + 0, 0, + // Cardinality - 1 of the only container + 0, 0, + // Only value of only container + 0, 0, + }; + // clang-format on + + roaring64_bitmap_t* r = roaring64_bitmap_portable_deserialize_safe( + simple_bitmap, sizeof(simple_bitmap)); + const char* reason = nullptr; + if (r != nullptr) { + if (roaring64_bitmap_internal_validate(r, &reason)) { + fail_msg( + "Validation must fail if a bitmap was returned, duplicate keys " + "are not allowed."); + } + roaring64_bitmap_free(r); + } +} } // namespace int main() { @@ -142,6 +192,7 @@ int main() { cmocka_unit_test(test_64mapsizetoosmall), cmocka_unit_test(test_64mapspreadvals), cmocka_unit_test(test_64deseroverlappingkeys), + cmocka_unit_test(test_64deseroverlappingupper32), }; return cmocka_run_group_tests(tests, NULL, NULL); #endif // CROARING_IS_BIG_ENDIAN