Skip to content

Reader::seek doesn't rewind bits read, causing leftover slice error #606

@i404788

Description

@i404788

Hey there I'm currently running into an issue with the Reader::seek implementation.

I've identified my specific case here:

deku/src/reader.rs

Lines 66 to 69 in 0902ae0

SeekFrom::Current(n) => {
if n > 0 {
self.bits_read += (n * 8) as usize;
}

I've made a custom reader till then end and then rewind some amount, as that is currently the easiest way to decode a certain packet:

// WARN: this is not efficient for high `bytes_left` values
fn read_until_remaining<R: Read + Seek>(
    reader: &mut Reader<R>,
    bytes_left: usize,
) -> Result<alloc::vec::Vec<u8>, DekuError> {
    let mut data = <alloc::vec::Vec<u8> as DekuReader<Limit<_, _>>>::from_reader_with_ctx(
        reader,
        Limit::end(),
    )?;
    data.truncate(data.len() - bytes_left);

    reader
        .seek(deku::no_std_io::SeekFrom::Current(-(bytes_left as i64)))
        .map_err(|e| DekuError::Io(e.kind()))?;

    Ok(data)
}

with a struct such as

    #[deku(reader = "read_until_remaining(deku::reader, 4)")]
    pub data: alloc::vec::Vec<u8>,

    pub status: u32,

This works (using logging to verify), however at the end it will slice out of bounds when trying to return the remaining/leftover data.
This is because we are re-reading previous bytes, which are already added to the bits_read cursor, but the internal reader will put it's cursor back.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions