zip_core/raw/parse/
digital_signature.rs

1use super::{
2    super::{DigitalSignature, DigitalSignatureFixed},
3    preview_u16_from_buf, validate_length, validate_length_fixed, DynamicSizeError, FixedSizeError, Parse, ParseExtend,
4};
5
6extern crate alloc;
7use alloc::vec;
8
9impl Parse for DigitalSignatureFixed {
10    type Error = FixedSizeError;
11
12    fn from_buf<T: bytes::Buf>(buf: &mut T) -> Result<Self, Self::Error>
13    where
14        Self: Sized,
15    {
16        let remaining = buf.remaining();
17        validate_length(remaining, Self::SIZE_IN_BYTES, FixedSizeError::UnsufficientExactBytes)?;
18        Ok(Self {
19            header_signature: buf.get_u32_le(),
20            size_of_data:     buf.get_u16_le(),
21        })
22    }
23
24    fn to_buf<T: bytes::BufMut>(&self, buf: &mut T) -> Result<(), Self::Error> {
25        let remaining = buf.remaining_mut();
26        validate_length(remaining, Self::SIZE_IN_BYTES, FixedSizeError::UnsufficientExactBytes)?;
27        buf.put_u32_le(self.header_signature);
28        buf.put_u16_le(self.size_of_data);
29        Ok(())
30    }
31}
32
33impl ParseExtend for DigitalSignature {
34    type Error = DynamicSizeError;
35    type Fixed = DigitalSignatureFixed;
36
37    fn from_buf_fixed<T: bytes::Buf>(buf: &mut T, fixed: Self::Fixed) -> Result<Self, (Self::Error, Self::Fixed)>
38    where
39        Self: Sized,
40    {
41        let total = fixed.size_of_data as usize;
42        let fixed = validate_length_fixed(buf.remaining(), total, fixed, DynamicSizeError::UnsufficientExactBytes)?;
43
44        let mut signature_data = vec![0; fixed.size_of_data as usize];
45        buf.copy_to_slice(&mut signature_data);
46
47        Ok(Self { fixed, signature_data })
48    }
49}
50
51impl Parse for DigitalSignature {
52    type Error = DynamicSizeError;
53
54    fn from_buf<T: bytes::Buf>(buf: &mut T) -> Result<Self, Self::Error>
55    where
56        Self: Sized,
57    {
58        let remaining = buf.remaining();
59        const SIZE: usize = DigitalSignatureFixed::SIZE_IN_BYTES;
60        validate_length(remaining, SIZE, DynamicSizeError::UnsufficientAtLeastBytes)?;
61        const PEEK_START: usize = SIZE - 2;
62        let chunk = buf.chunk();
63        let size_of_data: u16 = preview_u16_from_buf(chunk, PEEK_START).ok_or(DynamicSizeError::NotContiguous(SIZE))?;
64        let total = SIZE + size_of_data as usize;
65        validate_length(remaining, total, DynamicSizeError::UnsufficientExactBytes)?;
66
67        let fixed = DigitalSignatureFixed::from_buf(buf).map_err(FixedSizeError::in_dynamic)?;
68        Self::from_buf_fixed(buf, fixed).map_err(|e| e.0)
69    }
70
71    fn to_buf<T: bytes::BufMut>(&self, buf: &mut T) -> Result<(), Self::Error> {
72        let remaining = buf.remaining_mut();
73        let total = DigitalSignatureFixed::SIZE_IN_BYTES + self.signature_data.len();
74        validate_length(remaining, total, DynamicSizeError::UnsufficientExactBytes)?;
75        self.fixed.to_buf(buf).map_err(FixedSizeError::in_dynamic)?;
76        buf.put_slice(&self.signature_data);
77        Ok(())
78    }
79}
80
81#[cfg(test)]
82mod tests {
83    use super::{super::*, *};
84
85    #[test]
86    fn cycle_digital_signature() {
87        let signature_data = vec![48, 49, 32, 50];
88        let ds = DigitalSignature {
89            fixed: DigitalSignatureFixed {
90                header_signature: DigitalSignatureFixed::HEADER_SIGNATURE,
91                size_of_data:     signature_data.len() as u16,
92            },
93            signature_data: signature_data.clone(),
94        };
95        let mut buf = vec![];
96        ds.to_buf(&mut buf).unwrap();
97        assert_eq!(buf.len(), DigitalSignatureFixed::SIZE_IN_BYTES + signature_data.len());
98        let mut readbuf = buf.as_slice();
99        let ds2 = DigitalSignature::from_buf(&mut readbuf).unwrap();
100        assert_eq!(ds, ds2);
101        assert_eq!(ds2.signature_data, signature_data);
102    }
103
104    #[test]
105    fn parseextend_digital_signature() {
106        let buf: Vec<u8> = vec![48, 49, 32, 50];
107        let mut fixed = DigitalSignatureFixed {
108            header_signature: DigitalSignatureFixed::HEADER_SIGNATURE,
109            size_of_data:     buf.len() as u16,
110        };
111        assert!(DigitalSignature::from_buf_fixed(&mut buf.as_slice(), fixed.clone()).is_ok());
112        fixed.size_of_data += 1;
113        assert!(DigitalSignature::from_buf_fixed(&mut buf.as_slice(), fixed).is_err());
114    }
115}