1
0
Fork 0
mirror of https://codeberg.org/icewind/bitbuffer.git synced 2026-06-03 16:44:06 +02:00

fix some subbuffer end handling

This commit is contained in:
Robin Appelman 2025-07-14 20:06:45 +02:00
commit c03bf99c3b
3 changed files with 22 additions and 23 deletions

View file

@ -910,7 +910,8 @@ where
bytes: self.bytes.clone(),
bit_len,
endianness: PhantomData,
slice: self.slice,
// SAFETY: we've done our bounds check above
slice: unsafe { self.slice.get_unchecked(0..bit_len.div_ceil(8)) },
})
}

View file

@ -446,29 +446,9 @@ where
let str = result.as_ref(output);
let read = match byte_len {
Some(len) => len * 8,
None => (str.len() + 1) * 8,
None => (str.len() + 1).min(max_length) * 8,
};
// due to how sub buffer/streams work, the result string can be longer than the current stream
// (but not the top level buffer)
// thus we trim the resulting string to make sure it fits in the source stream
if read > self.bits_left() {
let mut target_length = str.len().min(max_length);
// find the closest char boundary
while !str.is_char_boundary(target_length) {
target_length -= 1;
}
let trimmed = match result {
MaybeBorrowed::Owned => {
output.truncate(target_length);
MaybeBorrowed::Owned
}
MaybeBorrowed::Borrowed(s) => MaybeBorrowed::Borrowed(&s[0..target_length]),
};
self.pos += target_length * 8;
return Ok(trimmed);
}
self.pos += read;
Ok(result)
}

View file

@ -3,7 +3,9 @@ use std::num::NonZeroU16;
use maplit::hashmap;
use bitbuffer::{BigEndian, BitError, BitRead, BitReadBuffer, BitReadStream, LittleEndian};
use bitbuffer::{
BigEndian, BitError, BitRead, BitReadBuffer, BitReadStream, BitWriteStream, LittleEndian,
};
const BYTES: &[u8] = &[
0b1011_0101,
@ -519,3 +521,19 @@ fn test_invalid_utf8() {
assert_eq!(stream.pos(), 6 * 8);
}
#[test]
fn test_read_string_substream() {
let mut data = Vec::new();
{
let mut write = BitWriteStream::new(&mut data, LittleEndian);
write.write_int(3u32, 3).unwrap();
write.write_string("dummy content", None).unwrap();
}
let mut stream = BitReadStream::<LittleEndian>::from(data.as_slice());
let _ = stream.read_int::<u8>(3).unwrap();
let mut sub = stream.read_bits(5 * 8).unwrap();
let result = sub.read_string(None).unwrap();
assert_eq!("dummy", result);
assert_eq!(5 * 8, sub.pos());
}