From e72445c46ec9a7ae8f16d9f96b11527e3a89ed41 Mon Sep 17 00:00:00 2001 From: Matt Palmer Date: Wed, 24 Apr 2024 14:36:24 +1000 Subject: [PATCH] base64ct: reject zero-length decode requests --- base64ct/src/decoder.rs | 19 ++++++++++++++++++- 1 file changed, 18 insertions(+), 1 deletion(-) diff --git a/base64ct/src/decoder.rs b/base64ct/src/decoder.rs index 01daf3867..840df16ce 100644 --- a/base64ct/src/decoder.rs +++ b/base64ct/src/decoder.rs @@ -103,8 +103,13 @@ impl<'i, E: Encoding> Decoder<'i, E> { /// /// # Returns /// - `Ok(bytes)` if the expected amount of data was read - /// - `Err(Error::InvalidLength)` if the exact amount of data couldn't be read + /// - `Err(Error::InvalidLength)` if the exact amount of data couldn't be read, or + /// if the output buffer has a length of 0 pub fn decode<'o>(&mut self, out: &'o mut [u8]) -> Result<&'o [u8], Error> { + if out.is_empty() { + return Err(InvalidLength); + } + if self.is_finished() { return Err(InvalidLength); } @@ -547,6 +552,8 @@ impl<'i> Iterator for LineReader<'i> { mod tests { use crate::{alphabet::Alphabet, test_vectors::*, Base64, Base64Unpadded, Decoder}; + #[cfg(feature = "std")] + use crate::Error::InvalidLength; #[cfg(feature = "std")] use {alloc::vec::Vec, std::io::Read}; @@ -592,6 +599,16 @@ mod tests { assert_eq!(buf.as_slice(), MULTILINE_PADDED_BIN); } + #[cfg(feature = "std")] + #[test] + fn reject_empty_read() { + let mut decoder = Decoder::::new(b"AAAA").unwrap(); + + let mut buf: Vec = vec![]; + + assert_eq!(decoder.decode(&mut buf), Err(InvalidLength)); + } + /// Core functionality of a decoding test #[allow(clippy::arithmetic_side_effects)] fn decode_test<'a, F, V>(expected: &[u8], f: F)