From 62c8cd14964b7f3b8a131913220463168f701bd1 Mon Sep 17 00:00:00 2001 From: leemeo3 <117142323+leemeo3@users.noreply.github.com> Date: Mon, 22 Jun 2026 08:33:13 +0900 Subject: [PATCH] Fix API parse_from_suffix buffer selection --- rosenpass/src/api/boilerplate/request_ref.rs | 30 ++++++++++++++++--- rosenpass/src/api/boilerplate/response_ref.rs | 30 ++++++++++++++++--- 2 files changed, 52 insertions(+), 8 deletions(-) diff --git a/rosenpass/src/api/boilerplate/request_ref.rs b/rosenpass/src/api/boilerplate/request_ref.rs index 74997edc..92802b8d 100644 --- a/rosenpass/src/api/boilerplate/request_ref.rs +++ b/rosenpass/src/api/boilerplate/request_ref.rs @@ -22,7 +22,7 @@ impl RequestRef { /// ``` /// use zerocopy::IntoBytes; /// - /// use rosenpass::api::{PingRequest, RequestRef, RequestMsgType}; + /// use rosenpass::api::{PingRequest, RequestMsgType, RequestRef}; /// /// let msg = PingRequest::new([0u8; 256]); /// @@ -50,7 +50,7 @@ impl RequestRef { RequestRefMaker::new(buf)?.from_prefix()?.parse() } - /// Produce a [ResponseRef] from the prefix of a raw message buffer, + /// Produce a [ResponseRef] from the suffix of a raw message buffer, /// reading the type from the buffer. pub fn parse_from_suffix(buf: B) -> anyhow::Result { RequestRefMaker::new(buf)?.from_suffix()?.parse() @@ -136,9 +136,9 @@ impl RequestRefMaker { self.ensure_fit()?; let point = self.buf.len() - self.target_size(); let Self { buf, msg_type } = self; - let (buf, _) = buf + let (_, buf) = buf .split_at(point) - .map_err(|_| anyhow!("RequestRefMaker::from_suffix: can not split buffer"))?; + .map_err(|_| anyhow!("split_at failed after ensure_fit; this should be unreachable"))?; Ok(Self { buf, msg_type }) } @@ -194,3 +194,25 @@ where } } } + +#[cfg(test)] +mod tests { + use zerocopy::IntoBytes; + + use super::*; + + #[test] + fn parse_from_suffix_returns_suffix_request() -> anyhow::Result<()> { + let prefix = PingRequest::new([1; 256]); + let suffix = PingRequest::new([2; 256]); + let mut buf = Vec::new(); + buf.extend_from_slice(prefix.as_bytes()); + buf.extend_from_slice(suffix.as_bytes()); + + let msg_ref = RequestRef::parse_from_suffix(buf.as_slice())?; + + assert!(matches!(msg_ref, RequestRef::Ping(_))); + assert_eq!(msg_ref.bytes(), suffix.as_bytes()); + Ok(()) + } +} diff --git a/rosenpass/src/api/boilerplate/response_ref.rs b/rosenpass/src/api/boilerplate/response_ref.rs index a8a463cf..4896fc89 100644 --- a/rosenpass/src/api/boilerplate/response_ref.rs +++ b/rosenpass/src/api/boilerplate/response_ref.rs @@ -25,7 +25,7 @@ impl ResponseRef { /// ``` /// use zerocopy::IntoBytes; /// - /// use rosenpass::api::{PingResponse, ResponseRef, ResponseMsgType}; + /// use rosenpass::api::{PingResponse, ResponseMsgType, ResponseRef}; /// // Produce the original PingResponse /// let msg = PingResponse::new([0u8; 256]); /// @@ -54,7 +54,7 @@ impl ResponseRef { ResponseRefMaker::new(buf)?.from_prefix()?.parse() } - /// Produce a [ResponseRef] from the prefix of a raw message buffer, + /// Produce a [ResponseRef] from the suffix of a raw message buffer, /// reading the type from the buffer. pub fn parse_from_suffix(buf: B) -> anyhow::Result { ResponseRefMaker::new(buf)?.from_suffix()?.parse() @@ -140,9 +140,9 @@ impl ResponseRefMaker { self.ensure_fit()?; let point = self.buf.len() - self.target_size(); let Self { buf, msg_type } = self; - let (buf, _) = buf + let (_, buf) = buf .split_at(point) - .map_err(|_| anyhow!("ResponseRefMaker::from_suffix: can not split buiffer"))?; + .map_err(|_| anyhow!("split_at failed after ensure_fit; this should be unreachable"))?; Ok(Self { buf, msg_type }) } @@ -198,3 +198,25 @@ where } } } + +#[cfg(test)] +mod tests { + use zerocopy::IntoBytes; + + use super::*; + + #[test] + fn parse_from_suffix_returns_suffix_response() -> anyhow::Result<()> { + let prefix = PingResponse::new([1; 256]); + let suffix = PingResponse::new([2; 256]); + let mut buf = Vec::new(); + buf.extend_from_slice(prefix.as_bytes()); + buf.extend_from_slice(suffix.as_bytes()); + + let msg_ref = ResponseRef::parse_from_suffix(buf.as_slice())?; + + assert!(matches!(msg_ref, ResponseRef::Ping(_))); + assert_eq!(msg_ref.bytes(), suffix.as_bytes()); + Ok(()) + } +}