Skip to content

Commit a24a8f9

Browse files
authored
Serialized bitmaps with run bitmaps should have bitmaps (#778)
* Serialized bitmaps with run bitmaps should have bitmaps * lint * lint * lint * updating cifuzz
1 parent 732712a commit a24a8f9

File tree

6 files changed

+45
-7
lines changed

6 files changed

+45
-7
lines changed

.github/workflows/cifuzz.yml

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -8,12 +8,12 @@ jobs:
88
steps:
99
- name: Build Fuzzers
1010
id: build
11-
uses: google/oss-fuzz/infra/cifuzz/actions/build_fuzzers@d318097b285bc695f785b98d40c2d058c0f438b5 # master
11+
uses: google/oss-fuzz/infra/cifuzz/actions/build_fuzzers@master
1212
with:
1313
oss-fuzz-project-name: 'croaring'
1414
dry-run: false
1515
- name: Run Fuzzers
16-
uses: google/oss-fuzz/infra/cifuzz/actions/run_fuzzers@d318097b285bc695f785b98d40c2d058c0f438b5 # master
16+
uses: google/oss-fuzz/infra/cifuzz/actions/run_fuzzers@master
1717
with:
1818
oss-fuzz-project-name: 'croaring'
1919
fuzz-seconds: 300

cpp/roaring/roaring.hh

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -686,6 +686,15 @@ class Roaring {
686686
return Roaring(r);
687687
}
688688

689+
/**
690+
* Compute how many bytes would be read by readSafe. Returns 0 if the
691+
* serialized data is invalid.
692+
* This is meant to be compatible with the Java and Go versions.
693+
*/
694+
static size_t serializedSizeInBytesSafe(const char *buf, size_t maxbytes) {
695+
return api::roaring_bitmap_portable_deserialize_size(buf, maxbytes);
696+
}
697+
689698
/**
690699
* How many bytes are required to serialize this bitmap (meant to be
691700
* compatible with Java and Go versions)

cpp/roaring/roaring64map.hh

Lines changed: 10 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1204,6 +1204,9 @@ class Roaring64Map {
12041204
ROARING_TERMINATE("ran out of bytes");
12051205
}
12061206
Roaring64Map result;
1207+
if (maxbytes < sizeof(uint64_t)) {
1208+
ROARING_TERMINATE("ran out of bytes");
1209+
}
12071210
uint64_t map_size;
12081211
std::memcpy(&map_size, buf, sizeof(uint64_t));
12091212
buf += sizeof(uint64_t);
@@ -1219,11 +1222,15 @@ class Roaring64Map {
12191222
buf += sizeof(uint32_t);
12201223
maxbytes -= sizeof(uint32_t);
12211224
// read map value Roaring
1225+
size_t needed_bytes =
1226+
Roaring::serializedSizeInBytesSafe(buf, maxbytes);
1227+
if (needed_bytes == 0) {
1228+
ROARING_TERMINATE("invalid serialized data");
1229+
}
12221230
Roaring read_var = Roaring::readSafe(buf, maxbytes);
12231231
// forward buffer past the last Roaring Bitmap
1224-
size_t tz = read_var.getSizeInBytes(true);
1225-
buf += tz;
1226-
maxbytes -= tz;
1232+
buf += needed_bytes;
1233+
maxbytes -= needed_bytes;
12271234
result.emplaceOrInsert(key, std::move(read_var));
12281235
}
12291236
return result;

include/roaring/containers/containers.h

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -548,9 +548,9 @@ static inline container_t *container_remove(
548548
}
549549

550550
/**
551-
* Check whether a value is in a container, requires a typecode
551+
* Check whether a value is in a container, requires a typecode
552552
*/
553-
static inline bool container_contains(
553+
inline bool container_contains(
554554
const container_t *c, uint16_t val,
555555
uint8_t typecode // !!! should be second argument?
556556
) {

src/containers/containers.c

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -50,6 +50,10 @@ extern bool container_iterator_next(const container_t *c, uint8_t typecode,
5050
extern bool container_iterator_prev(const container_t *c, uint8_t typecode,
5151
roaring_container_iterator_t *it,
5252
uint16_t *value);
53+
extern bool container_contains(
54+
const container_t *c, uint16_t val,
55+
uint8_t typecode // !!! should be second argument?
56+
);
5357

5458
void container_free(container_t *c, uint8_t type) {
5559
switch (type) {

tests/cpp_random_unit.cpp

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -353,6 +353,21 @@ DEFINE_TEST(random_doublecheck_test) {
353353
}
354354
}
355355

356+
#if ROARING_EXCEPTIONS
357+
// credit: Oleg Lazari
358+
DEFINE_TEST(safe_test_lazari) {
359+
unsigned char payload[] = {0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
360+
0x00, 0x00, 0x00, 0x00, 0x00, 0x3b, 0x30,
361+
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
362+
0x00, 0x6a, 0x6a, 0xd4};
363+
try {
364+
roaring::Roaring64Map::readSafe((const char *)payload, sizeof(payload));
365+
assert_false(true); // it should not reach here
366+
} catch (...) {
367+
}
368+
}
369+
#endif
370+
356371
DEFINE_TEST(random_doublecheck_test_64) {
357372
//
358373
// Make a group of bitsets to choose from when performing operations.
@@ -487,6 +502,9 @@ int main() {
487502
gravity64 = (static_cast<uint64_t>(rand()) << 32) + rand() % 20000 - 10000;
488503

489504
const struct CMUnitTest tests[] = {
505+
#if ROARING_EXCEPTIONS
506+
cmocka_unit_test(safe_test_lazari),
507+
#endif
490508
cmocka_unit_test(sanity_check_doublechecking),
491509
cmocka_unit_test(sanity_check_doublechecking_64),
492510
cmocka_unit_test(random_doublecheck_test),

0 commit comments

Comments
 (0)