Skip to content

Commit

Permalink
Fixes ivm-after-nop in the lazy reader
Browse files Browse the repository at this point in the history
  • Loading branch information
zslayton committed Feb 9, 2024
1 parent 9f9a494 commit f46fe89
Showing 1 changed file with 36 additions and 2 deletions.
38 changes: 36 additions & 2 deletions src/lazy/binary/raw/reader.rs
Original file line number Diff line number Diff line change
Expand Up @@ -70,14 +70,25 @@ impl<'data> LazyRawBinaryReader<'data> {
where
'data: 'top,
{
// Get a new buffer view starting beyond the last item we returned.
let mut buffer = self.data.advance_to_next_item()?;
if buffer.is_empty() {
return Ok(LazyRawStreamItem::<BinaryEncoding_1_0>::EndOfStream);
}
let type_descriptor = buffer.peek_type_descriptor()?;
// Peek at the first byte in the new buffer view
let mut type_descriptor = buffer.peek_type_descriptor()?;
// If it's a nop...
if type_descriptor.is_nop() {
// ...advance until we find something that isn't a nop.
(_, buffer) = buffer.consume_nop_padding(type_descriptor)?;
} else if type_descriptor.is_ivm_start() {
if buffer.is_empty() {
return Ok(LazyRawStreamItem::<BinaryEncoding_1_0>::EndOfStream);
}
type_descriptor = buffer.peek_type_descriptor()?;
}
// Now that we're past any nop bytes, the next item is guaranteed to be either an IVM
// or a value. Check whether the next byte indicates an IVM.
if type_descriptor.is_ivm_start() {
return self.read_ivm(buffer);
}

Expand Down Expand Up @@ -310,4 +321,27 @@ mod tests {

Ok(())
}

#[test]
fn ivm_after_nop() -> IonResult<()> {
let data: Vec<u8> = vec![
0xe0, 0x01, 0x00, 0xea, // IVM
0x00, // 1-byte NOP
0x01, 0xff, // 2-byte NOP
0xe0, 0x01, 0x00, 0xea, // IVM
0x02, 0xff, 0xff, // 3-byte NOP
0x0f, // null
];

let mut reader = LazyRawBinaryReader::new(&data);
let _ivm = reader.next()?.expect_ivm()?;
let _ivm = reader.next()?.expect_ivm()?;

assert_eq!(
reader.next()?.expect_value()?.read()?.expect_null()?,
IonType::Null
);

Ok(())
}
}

0 comments on commit f46fe89

Please sign in to comment.