Skip to content

Commit

Permalink
fix: handle incomplete packets in a safer way
Browse files Browse the repository at this point in the history
  • Loading branch information
dignifiedquire committed Sep 26, 2019
1 parent 5c71963 commit f0a831a
Show file tree
Hide file tree
Showing 2 changed files with 33 additions and 9 deletions.
41 changes: 32 additions & 9 deletions src/packet/many.rs
Original file line number Diff line number Diff line change
Expand Up @@ -70,18 +70,18 @@ impl<R: Read> Iterator for PacketParser<R> {
second_round = true;
}

let res = match {
match single::parser(b.buf()) {
Ok(v) => Ok(v),
Err(err) => Err(err.into()),
}
let res_header = match single::parser(b.buf()) {
Ok(v) => Ok(v),
Err(err) => Err(err.into()),
}
.and_then(|(rest, (ver, tag, _packet_length, body))| match body {
ParseResult::Indeterminated => {
let mut body = rest.to_vec();
inner.read_to_end(&mut body)?;
let p = single::body_parser(ver, tag, &body);
Ok((rest.len() + body.len(), p))
match single::body_parser(ver, tag, &body) {
Err(Error::Incomplete(n)) => Err(Error::Incomplete(n)),
p => Ok((rest.len() + body.len(), p)),
}
}
ParseResult::Fixed(body) => {
let p = single::body_parser(ver, tag, body);
Expand All @@ -91,7 +91,9 @@ impl<R: Read> Iterator for PacketParser<R> {
let p = single::body_parser(ver, tag, &body.concat());
Ok((b.buf().offset(rest), p))
}
}) {
});

let res_body = match res_header {
Ok(val) => Some(val),
Err(err) => match err {
Error::Incomplete(n) => {
Expand All @@ -107,8 +109,9 @@ impl<R: Read> Iterator for PacketParser<R> {
},
};

if let Some((length, p)) = res {
if let Some((length, p)) = res_body {
info!("got packet: {:#?} {}", p, length);
assert!(length > 0);
b.consume(length);
return Some(p);
}
Expand Down Expand Up @@ -276,4 +279,24 @@ mod tests {
assert_eq!(tag, packet.tag(), "missmatch in packet {:?} ({})", p, e);
}
}

#[test]
fn incomplete_packet_parser() {
let _ = pretty_env_logger::try_init();
use std::io::Cursor;

let bytes: [u8; 1] = [0x97];
let parser = PacketParser::new(Cursor::new(bytes));
let mut packets = parser.filter_map(|p| {
// for now we are skipping any packets that we failed to parse
match p {
Ok(pp) => Some(pp),
Err(err) => {
warn!("skipping packet: {:?}", err);
None
}
}
});
assert!(packets.next().is_none());
}
}
1 change: 1 addition & 0 deletions src/packet/single.rs
Original file line number Diff line number Diff line change
Expand Up @@ -170,6 +170,7 @@ pub fn body_parser(ver: Version, tag: Tag, body: &[u8]) -> Result<Packet> {

match res {
Ok(res) => Ok(res),
Err(Error::Incomplete(n)) => Err(Error::Incomplete(n)),
Err(err) => {
warn!("invalid packet: {:?} {:?}\n{}", err, tag, hex::encode(body));
Err(Error::InvalidPacketContent(Box::new(err)))
Expand Down

0 comments on commit f0a831a

Please sign in to comment.