From 2c4c544d902c588fc0654910fba1f0d21d78eab3 Mon Sep 17 00:00:00 2001 From: Lucio Franco Date: Fri, 10 Jul 2020 12:40:55 -0400 Subject: [PATCH] fix: `Status::details` leaking base64 encoding (#395) Fixes #379 --- tonic/src/status.rs | 30 ++++++++++++++++++++++-------- 1 file changed, 22 insertions(+), 8 deletions(-) diff --git a/tonic/src/status.rs b/tonic/src/status.rs index a713ffa21..c54dca922 100644 --- a/tonic/src/status.rs +++ b/tonic/src/status.rs @@ -474,10 +474,11 @@ impl Status { } if !self.details.is_empty() { + let details = base64::encode_config(&self.details[..], base64::STANDARD_NO_PAD); + header_map.insert( GRPC_STATUS_DETAILS_HEADER, - HeaderValue::from_maybe_shared(self.details.clone()) - .map_err(invalid_header_value_byte)?, + HeaderValue::from_maybe_shared(details).map_err(invalid_header_value_byte)?, ); } @@ -501,12 +502,6 @@ impl Status { details: Bytes, metadata: MetadataMap, ) -> Status { - let details = if details.is_empty() { - details - } else { - base64::encode_config(&details[..], base64::STANDARD_NO_PAD).into() - }; - Status { code, message: message.into(), @@ -837,4 +832,23 @@ mod tests { assert_eq!(Status::data_loss("").code(), Code::DataLoss); assert_eq!(Status::unauthenticated("").code(), Code::Unauthenticated); } + + #[test] + fn details() { + const DETAILS: &[u8] = &[0, 2, 3]; + + let status = Status::with_details(Code::Unavailable, "some message", DETAILS.into()); + + assert_eq!(&status.details()[..], DETAILS); + + let header_map = status.to_header_map().unwrap(); + + let b64_details = base64::encode_config(&DETAILS[..], base64::STANDARD_NO_PAD); + + assert_eq!(header_map[super::GRPC_STATUS_DETAILS_HEADER], b64_details); + + let status = Status::from_header_map(&header_map).unwrap(); + + assert_eq!(&status.details()[..], DETAILS); + } }