Skip to content

Commit

Permalink
Return Eof if reader is exhausted AND bytes have been consumed (Closes
Browse files Browse the repository at this point in the history
…#30)

If a call to `.next()` matched all the bytes from the buffer, the next call to
`.consume()` would put the buffer to available_data == position == 0.
But if reader is not exhausted, we should not return Eof, just incomplete, on
the next read.
  • Loading branch information
chifflier committed Jan 22, 2024
1 parent 9ad632f commit 38d4e23
Show file tree
Hide file tree
Showing 3 changed files with 23 additions and 2 deletions.
2 changes: 1 addition & 1 deletion src/capture_pcap.rs
Original file line number Diff line number Diff line change
Expand Up @@ -142,7 +142,7 @@ where
// 1) all bytes have been read
// 2) no more data is available
if self.buffer.available_data() == 0
&& (self.buffer.position() == 0 || self.reader_exhausted)
&& (self.buffer.position() == 0 && self.reader_exhausted)
{
return Err(PcapError::Eof);
}
Expand Down
2 changes: 1 addition & 1 deletion src/capture_pcapng.rs
Original file line number Diff line number Diff line change
Expand Up @@ -154,7 +154,7 @@ where
// 1) all bytes have been read
// 2) no more data is available
if self.buffer.available_data() == 0
&& (self.buffer.position() == 0 || self.reader_exhausted)
&& (self.buffer.position() == 0 && self.reader_exhausted)
{
return Err(PcapError::Eof);
}
Expand Down
21 changes: 21 additions & 0 deletions tests/pcapng.rs
Original file line number Diff line number Diff line change
Expand Up @@ -431,3 +431,24 @@ fn test_reader_buffer_too_small() {
}
assert_eq!(num_blocks, 9);
}

// related issue: https://github.com/rusticata/pcap-parser/issues/30
#[test]
fn test_pcapng_earlyeofandnotexhausted() {
let path = "assets/test001-le.pcapng";
let file = File::open(path).unwrap();
let buffered = BufReader::new(file);

// 96 is exactly the size of the first SHB, so the first consume will empty the buffer
let mut reader = PcapNGReader::new(96, buffered).expect("PcapNGReader");
let (offset, _block) = reader.next().expect("could not read first block");
reader.consume(offset);
// the second read happens in the following situation: buf.available_data == 0 AND buf.position == 0
assert_eq!(reader.position(), 0);
assert!(reader.data().is_empty());
let res = reader.next();
// res should not be Eof
assert!(!matches!(res, Err(PcapError::Eof)));
// res should be Incomplete(4) (attempt to read magic)
assert!(matches!(res, Err(PcapError::Incomplete(4))));
}

0 comments on commit 38d4e23

Please sign in to comment.