bv-rs icon indicating copy to clipboard operation
bv-rs copied to clipboard

Potential Undefined Behavior due to `BitSliceMut::from_slice`

Open vnrst opened this issue 1 year ago • 0 comments

The lifetime annotations on BitSliceMut::from_slice can lead to undefined behavior. The following example fails Miri.

extern crate bv;

use bv::{BitVec, BlockType, BitSliceMut, Bits, BitSlice};

fn main() {
    let mut myvec: Vec<usize> = Vec::from([0, 1, 0, 1, 1, 0, 0, 1]);

    let mut slice = &mut myvec[..];
    let mut bitslice = BitSliceMut::from_slice(slice);

    drop(slice); // This shouldn't be allowed
    let bit = bitslice.get_bit(2);
    println!("Bit at position 2: {}", bit);
}

The current signature of this function is

impl<'a, Block: BlockType> BitSliceMut<'a, Block> {
    /// Creates a `BitSliceMut` from a mutable array slice of blocks.
    ///
    /// The size is always a multiple of `Block::nbits()`. If you want a different size,
    /// slice.
    pub fn from_slice(blocks: &mut [Block]) -> Self {

This allows Self to outlive the slice. If this were modified as:

impl<'a, Block: BlockType> BitSliceMut<'a, Block> {
    /// Creates a `BitSliceMut` from a mutable array slice of blocks.
    ///
    /// The size is always a multiple of `Block::nbits()`. If you want a different size,
    /// slice.
    pub fn from_slice(blocks: &'a mut [Block]) -> Self {

This would prevent the earlier example from compiling and ensure safety.

vnrst avatar Feb 15 '24 15:02 vnrst