From ac8bc48b48f133ff3a876e7cf64d7e97ffe73c29 Mon Sep 17 00:00:00 2001 From: Zak Henry Date: Wed, 21 Aug 2024 19:56:19 +1200 Subject: [PATCH] fix(tonic-web): fix panic caused in trailer parsing when there is more than one trailer --- tonic-web/src/call.rs | 23 ++++++++++++++++++++++- 1 file changed, 22 insertions(+), 1 deletion(-) diff --git a/tonic-web/src/call.rs b/tonic-web/src/call.rs index 0c45bf314..2bdcdc60c 100644 --- a/tonic-web/src/call.rs +++ b/tonic-web/src/call.rs @@ -393,11 +393,15 @@ fn decode_trailers_frame(mut buf: Bytes) -> Result, Status> { let mut cursor_pos = 0; for (i, b) in buf.iter().enumerate() { + // if we are at a trailer delimiter (\r\n) if b == &b'\r' && buf.get(i + 1) == Some(&b'\n') { + // read the bytes of the trailer passed so far let trailer = temp_buf.copy_to_bytes(i - cursor_pos); - cursor_pos = i; + // increment cursor beyond the delimiter + cursor_pos = i + 2; trailers.push(trailer); if temp_buf.has_remaining() { + // advance buf beyond the delimiters temp_buf.get_u8(); temp_buf.get_u8(); } @@ -612,4 +616,21 @@ mod tests { assert_eq!(out.code(), Code::Internal); } + + #[test] + fn decode_multiple_trailers() { + let buf = b"\x80\0\0\0\x0fgrpc-status:0\r\ngrpc-message:\r\na:1\r\nb:2\r\n"; + + let trailers = decode_trailers_frame(Bytes::copy_from_slice(&buf[..])) + .unwrap() + .unwrap(); + + let mut expected = HeaderMap::new(); + expected.insert("grpc-status", "0".parse().unwrap()); + expected.insert("grpc-message", "".parse().unwrap()); + expected.insert("a", "1".parse().unwrap()); + expected.insert("b", "2".parse().unwrap()); + + assert_eq!(trailers, expected); + } }