Skip to content

Commit

Permalink
Create binding for internal validation function
Browse files Browse the repository at this point in the history
Call internal validation function after each step in fuzzing
  • Loading branch information
Dr-Emann committed Oct 4, 2023
1 parent c7f471b commit 5e8e0ee
Show file tree
Hide file tree
Showing 3 changed files with 46 additions and 2 deletions.
36 changes: 35 additions & 1 deletion croaring/src/bitmap/imp.rs
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
use crate::Bitset;
use ffi::roaring_bitmap_t;
use std::convert::TryInto;
use std::ffi::c_void;
use std::ffi::{c_void, CStr};
use std::ops::{Bound, RangeBounds};
use std::{mem, ptr};

Expand Down Expand Up @@ -1469,6 +1469,40 @@ impl Bitmap {
let success = unsafe { ffi::roaring_bitmap_to_bitset(&self.bitmap, bitset.as_raw_mut()) };
success.then_some(bitset)
}

/// Ensure the bitmap is internally valid
///
/// This is useful for development, but is not needed for normal use:
/// bitmaps should _always_ be internally valid.
///
/// # Errors
///
/// Returns an error if the bitmap is not valid, with a description of the problem.
///
/// # Examples
///
/// ```
/// use croaring::Bitmap;
///
/// let bitmap = Bitmap::from_range(0..100);
/// bitmap.internal_validate().unwrap();
/// ```
#[inline]
#[doc(alias = "roaring_bitmap_internal_validate")]
#[doc(hidden)]
pub fn internal_validate(&self) -> Result<(), String> {
let mut error_str = ptr::null();
let valid = unsafe { ffi::roaring_bitmap_internal_validate(&self.bitmap, &mut error_str) };
if valid {
Ok(())
} else {
if error_str.is_null() {
return Err(String::from("Unknown error"));
}
let reason = unsafe { CStr::from_ptr(error_str) };
Err(reason.to_string_lossy().into_owned())
}
}
}

fn range_to_inclusive<R: RangeBounds<u32>>(range: R) -> (u32, u32) {
Expand Down
2 changes: 2 additions & 0 deletions fuzz/fuzz_targets/against_bitvec.rs
Original file line number Diff line number Diff line change
Expand Up @@ -151,6 +151,7 @@ impl ReadBitmapOp {
b.add_offset(i);
}
}
b.internal_validate().unwrap();
}
}

Expand Down Expand Up @@ -246,6 +247,7 @@ impl BitmapCompOperation {
}
}
}
rhs.internal_validate().unwrap();
}
}

Expand Down
10 changes: 9 additions & 1 deletion fuzz/fuzz_targets/arbitrary_ops/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -134,15 +134,17 @@ impl MutableBitmapOperation {
b.add_range(start..=end)
}
}
b.internal_validate().unwrap();
b.remove_range(MAX_NUM..);
b.internal_validate().unwrap();
}
}

impl BitmapCompOperation {
pub fn on_roaring(&self, lhs: &mut Bitmap, rhs: &Bitmap) {
match *self {
BitmapCompOperation::Eq => {
drop(lhs == rhs);
_ = lhs == rhs;
assert_eq!(lhs, lhs);
}
BitmapCompOperation::IsSubset => {
Expand All @@ -165,6 +167,7 @@ impl BitmapCompOperation {
assert_eq!(lhs.and(lhs), *lhs);

let res = lhs.and(rhs);
res.internal_validate().unwrap();
assert_eq!(res.cardinality(), lhs.and_cardinality(rhs));
lhs.and_inplace(rhs);
assert_eq!(*lhs, res);
Expand All @@ -173,6 +176,7 @@ impl BitmapCompOperation {
assert_eq!(lhs.or(lhs), *lhs);

let res = lhs.or(rhs);
res.internal_validate().unwrap();
assert_eq!(res.cardinality(), lhs.or_cardinality(rhs));
assert_eq!(res, Bitmap::fast_or(&[lhs, rhs]));
assert_eq!(res, Bitmap::fast_or_heap(&[lhs, rhs]));
Expand All @@ -184,6 +188,7 @@ impl BitmapCompOperation {
assert!(lhs.xor(lhs).is_empty());

let res = lhs.xor(rhs);
res.internal_validate().unwrap();
assert_eq!(res.cardinality(), lhs.xor_cardinality(rhs));
assert_eq!(res, Bitmap::fast_xor(&[lhs, rhs]));

Expand All @@ -194,11 +199,14 @@ impl BitmapCompOperation {
assert!(lhs.andnot(lhs).is_empty());

let res = lhs.andnot(rhs);
res.internal_validate().unwrap();
assert_eq!(res.cardinality(), lhs.andnot_cardinality(rhs));

lhs.andnot_inplace(rhs);
assert_eq!(*lhs, res);
}
}
lhs.internal_validate().unwrap();
rhs.internal_validate().unwrap();
}
}

0 comments on commit 5e8e0ee

Please sign in to comment.