Repository: RoaringBitmap/CRoaring (C)

Issue:
Out of bounds read on run_container_is_subset_array
Using amalgamation generated from v0.9.3.

Code:

```c
#include "roaring.h"
#include <stdio.h>

int main() {
  roaring_bitmap_t *b1 = roaring_bitmap_create();

  roaring_bitmap_add(b1, 100);
  roaring_bitmap_flip_inplace(b1, 0, 100 + 1);

  roaring_bitmap_t *b2 = roaring_bitmap_create();
  roaring_bitmap_add_range(b2, 50, 100 + 1);

  roaring_bitmap_printf_describe(b1);
  puts("");
  roaring_bitmap_printf_describe(b2);
  puts("");

  roaring_bitmap_is_subset(b2, b1);

  roaring_bitmap_free(b2);
  roaring_bitmap_free(b1);
  return 0;
}
```

Compiled with `cc -g main.c roaring.c -o main -Wall`

Output under valgrind:
```
==291898== Memcheck, a memory error detector
==291898== Copyright (C) 2002-2022, and GNU GPL'd, by Julian Seward et al.
==291898== Using Valgrind-3.20.0 and LibVEX; rerun with -h for copyright info
==291898== Command: ./main
==291898==
{0: array (100)}
{0: run (51)}
==291898== Invalid read of size 2
==291898==    at 0x11F724: run_container_is_subset_array (roaring.c:13406)
==291898==    by 0x10D387: container_is_subset (roaring.c:4959)
==291898==    by 0x12AD1F: roaring_bitmap_is_subset (roaring.c:17149)
==291898==    by 0x108EB3: main (main.c:18)
==291898==  Address 0x4a3a2c8 is 0 bytes after a block of size 200 alloc'd
==291898==    at 0x4865250: malloc (vg_replace_malloc.c:393)
==291898==    by 0x12493B: roaring_malloc (roaring.c:15152)
==291898==    by 0x113917: array_container_create_given_capacity (roaring.c:10047)
==291898==    by 0x11ECD3: array_container_negation_range (roaring.c:13140)
==291898==    by 0x11EEBB: array_container_negation_range_inplace (roaring.c:13178)
==291898==    by 0x11046F: container_inot_range (roaring.c:6463)
==291898==    by 0x12AFFF: inplace_flip_container (roaring.c:17201)
==291898==    by 0x12B5D3: roaring_bitmap_flip_inplace (roaring.c:17338)
==291898==    by 0x108E67: main (main.c:8)
==291898==
==291898==
==291898== HEAP SUMMARY:
==291898==     in use at exit: 0 bytes in 0 blocks
==291898==   total heap usage: 11 allocs, 11 frees, 1,402 bytes allocated
==291898==
==291898== All heap blocks were freed -- no leaks are possible
==291898==
==291898== For lists of detected and suppressed errors, rerun with: -s
==291898== ERROR SUMMARY: 1 errors from 1 contexts (suppressed: 0 from 0)
```

Found by saulius/croaring-rs#98


Discussion: Looks like a real issue. I will issue a patch release.



Fix (patch):
diff --git a/src/containers/mixed_subset.c b/src/containers/mixed_subset.c
index af6f03e79..86fe098f5 100644
--- a/src/containers/mixed_subset.c
+++ b/src/containers/mixed_subset.c
@@ -32,7 +32,7 @@ bool run_container_is_subset_array(const run_container_t* container1,
                                  container2->cardinality, start);
         stop_pos = advanceUntil(container2->array, stop_pos,
                                 container2->cardinality, stop);
-        if (start_pos == container2->cardinality) {
+        if (stop_pos == container2->cardinality) {
             return false;
         } else if (stop_pos - start_pos != stop - start ||
                    container2->array[start_pos] != start ||