Skip to content

Commit 5a5b90a

Browse files
authored
Fix to support finding an IVM after a NOP in binary v1.0 (#706)
1 parent 1a6e388 commit 5a5b90a

File tree

1 file changed

+31
-2
lines changed

1 file changed

+31
-2
lines changed

src/binary/non_blocking/raw_binary_reader.rs

+31-2
Original file line numberDiff line numberDiff line change
@@ -1207,9 +1207,11 @@ impl<'a, A: AsRef<[u8]>> TxReader<'a, A> {
12071207
}
12081208
}
12091209

1210-
/// Looks for zero or more NOP pads followed by either:
1210+
/// Looks for zero or more NOP pads followed by any of these:
12111211
/// * an annotated value
12121212
/// * a value
1213+
/// * the end of the stream
1214+
/// * (at the top level) an Ion version marker starting a new stream
12131215
#[inline]
12141216
fn read_sequence_item(
12151217
&mut self,
@@ -1218,7 +1220,8 @@ impl<'a, A: AsRef<[u8]>> TxReader<'a, A> {
12181220
if type_descriptor.is_nop() {
12191221
if let Some(item) = self.consume_nop_padding(&mut type_descriptor)? {
12201222
// We may encounter the end of the file or container while reading NOP padding,
1221-
// in which case `item` will be RawStreamItem::Nothing.
1223+
// in which case `item` will be RawStreamItem::Nothing. At the top level, it is
1224+
// possible to encounter an IVM at the end of the NOP pad.
12221225
return Ok(item);
12231226
}
12241227
// Note that if `consume_nop_padding` reads NOP bytes but doesn't hit EOF, it will
@@ -1361,6 +1364,9 @@ impl<'a, A: AsRef<[u8]>> TxReader<'a, A> {
13611364
return Ok(Some(RawStreamItem::Nothing));
13621365
}
13631366
*type_descriptor = self.tx_buffer.peek_type_descriptor()?;
1367+
if type_descriptor.is_ivm_start() {
1368+
return self.read_ivm().map(Some);
1369+
}
13641370
}
13651371
Ok(None)
13661372
}
@@ -1947,6 +1953,29 @@ mod tests {
19471953
Ok(())
19481954
}
19491955

1956+
#[test]
1957+
fn ivm_after_nop() -> IonResult<()> {
1958+
let data = &[
1959+
0xE0, 0x01, 0x00, 0xEA, // IVM
1960+
0x00, // 1-byte NOP
1961+
0x01, 0xff, // 2-byte NOP
1962+
0xE0, 0x01, 0x00, 0xEA, // IVM
1963+
0x83, 0x66, 0x6f, 0x6f, // "foo"
1964+
0x02, 0xff, 0xff, // 3-byte NOP
1965+
]; // Empty string
1966+
let mut reader = RawBinaryReader::new(data);
1967+
let item = reader.next()?;
1968+
assert_eq!(item, RawStreamItem::VersionMarker(1, 0));
1969+
let item = reader.next()?;
1970+
assert_eq!(item, RawStreamItem::VersionMarker(1, 0));
1971+
let item = reader.next()?;
1972+
assert_eq!(item, RawStreamItem::Value(IonType::String));
1973+
assert_eq!(reader.read_str()?, "foo");
1974+
let item = reader.next()?;
1975+
assert_eq!(item, RawStreamItem::Nothing);
1976+
Ok(())
1977+
}
1978+
19501979
#[test]
19511980
fn debug() -> IonResult<()> {
19521981
let data = &[

0 commit comments

Comments
 (0)