From f098c62372210523e3651929710867666278dbd4 Mon Sep 17 00:00:00 2001 From: David Renshaw Date: Wed, 8 Nov 2023 12:16:07 -0500 Subject: [PATCH] fix another async serialize_packed EOF bug --- capnp-futures/src/serialize_packed.rs | 23 +++++++++++++++++++++++ capnp/src/lib.rs | 1 + 2 files changed, 24 insertions(+) diff --git a/capnp-futures/src/serialize_packed.rs b/capnp-futures/src/serialize_packed.rs index 67ff85be4..10b0fd1c5 100644 --- a/capnp-futures/src/serialize_packed.rs +++ b/capnp-futures/src/serialize_packed.rs @@ -117,6 +117,12 @@ where // add a byte for the count of pass-through words *buf_size = 10 } + if *buf_pos >= *buf_size { + // Skip the BufferingWord stage, because + // there is nothing left to buffer. + *stage = PackedReadStage::DrainingBuffer; + *buf_pos = 1; + } } } } @@ -139,6 +145,11 @@ where PackedReadStage::BufferingWord => { match Pin::new(&mut *inner).poll_read(cx, &mut buf[*buf_pos..*buf_size])? { Poll::Pending => return Poll::Pending, + Poll::Ready(0) => { + return Poll::Ready(Err(std::io::Error::from( + std::io::ErrorKind::UnexpectedEof, + ))) + } Poll::Ready(n) => { *buf_pos += n; if *buf_pos >= *buf_size { @@ -702,4 +713,16 @@ pub mod test { .expect("reading"); assert!(message.is_none()); } + + #[test] + fn eof_mid_message() { + let words = vec![0xfe, 0x3, 0x3]; + let result = + futures::executor::block_on(Box::pin(try_read_message(&words[..], Default::default()))); + + match result { + Ok(_) => panic!("expected error"), + Err(e) => assert_eq!(e.kind, capnp::ErrorKind::PrematureEndOfFile), + } + } } diff --git a/capnp/src/lib.rs b/capnp/src/lib.rs index 845d0c3b3..2185dad27 100644 --- a/capnp/src/lib.rs +++ b/capnp/src/lib.rs @@ -463,6 +463,7 @@ impl core::convert::From<::std::io::Error> for Error { | io::ErrorKind::ConnectionReset | io::ErrorKind::ConnectionAborted | io::ErrorKind::NotConnected => ErrorKind::Disconnected, + io::ErrorKind::UnexpectedEof => ErrorKind::PrematureEndOfFile, _ => ErrorKind::Failed, }; #[cfg(feature = "alloc")]