diff --git a/base64ct/src/decoder.rs b/base64ct/src/decoder.rs index 1dbb66c65..d711906e0 100644 --- a/base64ct/src/decoder.rs +++ b/base64ct/src/decoder.rs @@ -104,7 +104,7 @@ impl<'i, E: Encoding> Decoder<'i, E> { /// - `Ok(bytes)` if the expected amount of data was read /// - `Err(Error::InvalidLength)` if the exact amount of data couldn't be read pub fn decode<'o>(&mut self, out: &'o mut [u8]) -> Result<&'o [u8], Error> { - if self.is_finished() { + if self.is_finished() && !out.is_empty() { return Err(InvalidLength); } @@ -591,6 +591,21 @@ mod tests { assert_eq!(buf.as_slice(), MULTILINE_PADDED_BIN); } + #[cfg(feature = "std")] + #[test] + fn decode_empty_at_end() { + let mut decoder = Decoder::::new(b"AAAA").unwrap(); + + // Strip initial bytes + let mut buf = vec![0u8; 3]; + assert_eq!(decoder.decode(&mut buf), Ok(&vec![0u8; 3][..])); + + // Now try to read nothing from the end + let mut buf: Vec = vec![]; + + assert_eq!(decoder.decode(&mut buf), Ok(&[][..])); + } + /// Core functionality of a decoding test #[allow(clippy::arithmetic_side_effects)] fn decode_test<'a, F, V>(expected: &[u8], f: F) diff --git a/der/tests/pem.rs b/der/tests/pem.rs index ffae99da6..4f656fed5 100644 --- a/der/tests/pem.rs +++ b/der/tests/pem.rs @@ -3,7 +3,7 @@ #![cfg(all(feature = "derive", feature = "oid", feature = "pem"))] use der::{ - Decode, DecodePem, EncodePem, Sequence, + Any, Decode, DecodePem, EncodePem, Sequence, asn1::{BitString, ObjectIdentifier}, pem::{LineEnding, PemLabel}, }; @@ -15,14 +15,14 @@ const SPKI_DER: &[u8] = include_bytes!("examples/spki.der"); const SPKI_PEM: &str = include_str!("examples/spki.pem"); /// X.509 `AlgorithmIdentifier` -#[derive(Copy, Clone, Debug, Eq, PartialEq, Sequence)] +#[derive(Clone, Debug, Eq, PartialEq, Sequence)] pub struct AlgorithmIdentifier { pub algorithm: ObjectIdentifier, - // pub parameters: ... (not used in spki.pem) + pub parameters: Option, } /// X.509 `SubjectPublicKeyInfo` (SPKI) in borrowed form -#[derive(Copy, Clone, Debug, Eq, PartialEq, Sequence)] +#[derive(Clone, Debug, Eq, PartialEq, Sequence)] pub struct SpkiBorrowed<'a> { pub algorithm: AlgorithmIdentifier, #[asn1(type = "BIT STRING")] @@ -65,3 +65,17 @@ fn to_pem() { let pem = spki.to_pem(LineEnding::LF).unwrap(); assert_eq!(&pem, SPKI_PEM); } + +#[test] +fn read_zero_slices_from_pem() { + let spki = SpkiOwned { + algorithm: AlgorithmIdentifier { + algorithm: ObjectIdentifier::new_unwrap("1.2.840.113549.1.1.11"), + parameters: Some(Any::null()), + }, + subject_public_key: BitString::new(0, []).unwrap(), + }; + + let pem = spki.to_pem(LineEnding::LF).unwrap(); + SpkiOwned::from_pem(pem).unwrap(); +}