diff --git a/src/bitmap/immutable.rs b/src/bitmap/immutable.rs index 45d8e89e4e5..b63310b07cb 100644 --- a/src/bitmap/immutable.rs +++ b/src/bitmap/immutable.rs @@ -239,7 +239,12 @@ impl Bitmap { pub fn make_mut(self) -> MutableBitmap { match self.into_mut() { Either::Left(data) => { - MutableBitmap::from_vec(data.bytes.as_ref().to_vec(), data.length) + if data.offset > 0 { + // we have to recreate the bytes because a MutableBitmap does not have an `offset`. + data.iter().collect() + } else { + MutableBitmap::from_vec(data.bytes.as_ref().to_vec(), data.length) + } } Either::Right(data) => data, } diff --git a/tests/it/bitmap/assign_ops.rs b/tests/it/bitmap/assign_ops.rs index bea2b0dcbf8..ef01fdd2089 100644 --- a/tests/it/bitmap/assign_ops.rs +++ b/tests/it/bitmap/assign_ops.rs @@ -18,6 +18,24 @@ fn basics() { ); } +#[test] +fn binary_assign_oob() { + // this check we don't have an oob access if the bitmaps are size T + 1 + // and we do some slicing. + let a = MutableBitmap::from_iter(std::iter::repeat(true).take(65)); + let b = MutableBitmap::from_iter(std::iter::repeat(true).take(65)); + + let a: Bitmap = a.into(); + let a = a.slice(10, 20); + + let b: Bitmap = b.into(); + let b = b.slice(10, 20); + + let mut a = a.make_mut(); + + binary_assign(&mut a, &b, |x: u64, y| x & y); +} + #[test] fn fast_paths() { let b = MutableBitmap::from([true, false]);