cser/
binary.rs

1use super::{
2    bits,
3    error::Error,
4    fast,
5    read_writer::{read_uint64_compact, write_uint64_compact, Reader},
6    Decodable,
7};
8
9/// Packs body bytes and bits into raw
10pub(crate) fn binary_from_cser(bbits: &[u8], bbytes: Vec<u8>) -> Vec<u8> {
11    let mut body_bytes = fast::Writer::new(bbytes);
12    body_bytes.write(bbits);
13    // write bits size
14    let mut size_writer = fast::Writer::new(Vec::with_capacity(4));
15    write_uint64_compact(&mut size_writer, bbits.len().try_into().unwrap());
16
17    let mut size_buf = size_writer.buf;
18    size_buf.reverse();
19    body_bytes.write(&size_buf);
20    body_bytes.buf
21}
22
23/// Unpacks raw on body bytes and bits
24pub(crate) fn binary_to_cser(mut raw: &[u8]) -> Result<(&[u8], &[u8]), Error> {
25    // read bitsArray size
26    let mut bits_size_buf = tail(raw, 9).to_vec();
27    bits_size_buf.reverse();
28    let mut bits_size_reader = fast::Reader::new(&bits_size_buf);
29    let bits_size = usize::try_from(read_uint64_compact(&mut bits_size_reader)?).unwrap();
30    raw = &raw[..raw.len() - bits_size_reader.position()];
31
32    if raw.len() < bits_size {
33        return Err(Error::MalformedEncoding);
34    }
35
36    let (bbytes, bbits) = raw.split_at(raw.len() - bits_size);
37
38    Ok((bbits, bbytes))
39}
40
41pub fn deserialize<T>(input: &[u8]) -> Result<T, T::Error>
42where
43    T: Decodable,
44    T::Error: From<Error>,
45{
46    deserialize_cb::<T, T::Error>(input, |handler| T::decode(handler))
47}
48
49fn deserialize_cb<T, E>(
50    input: &[u8],
51    handler: impl FnOnce(&mut Reader) -> Result<T, E>,
52) -> Result<T, E>
53where
54    E: From<Error>,
55{
56    let (bbits, bbytes) = binary_to_cser(input)?;
57
58    let mut body_reader = Reader {
59        bits_r: bits::Reader::new(bbits),
60        bytes_r: fast::Reader::new(bbytes),
61    };
62    let out = (handler)(&mut body_reader)?;
63
64    // check that everything is read
65    if body_reader.bits_r.non_read_bytes() > 1 {
66        return Err(Error::NonCanonicalEncoding.into());
67    }
68    let tail = body_reader.bits_r.read(body_reader.bits_r.non_read_bits());
69    if tail != 0 {
70        return Err(Error::NonCanonicalEncoding.into());
71    }
72    if !body_reader.bytes_r.empty() {
73        return Err(Error::NonCanonicalEncoding.into());
74    }
75
76    Ok(out)
77}
78
79fn tail(b: &[u8], cap: usize) -> &[u8] {
80    if b.len() > cap {
81        &b[b.len() - cap..]
82    } else {
83        b
84    }
85}
86
87#[cfg(test)]
88mod tests {
89    use super::*;
90    use crate::{Decodable, Encodable, Writer, U56};
91    use ethnum::{AsU256, U256};
92
93    #[cfg(test)]
94    fn marshal_binary_adapter(
95        marshal_cser: impl FnOnce(&mut Writer) -> anyhow::Result<()>,
96    ) -> anyhow::Result<Vec<u8>> {
97        let mut w = Writer::new();
98        (marshal_cser)(&mut w)?;
99
100        Ok(w.output())
101    }
102
103    #[test]
104    fn empty() {
105        let buf = marshal_binary_adapter(|_| Ok(())).unwrap();
106
107        deserialize_cb(&buf, |_| Ok::<_, Error>(())).unwrap();
108    }
109
110    #[test]
111    fn err() {
112        let mut buf = vec![];
113
114        // Write
115        buf.append(
116            &mut marshal_binary_adapter(|w| {
117                u64::MAX.encode(w);
118                Ok(())
119            })
120            .unwrap(),
121        );
122
123        // Read None
124        // nothing unmarshal
125        assert_eq!(
126            deserialize_cb(&[], |_| Ok(())),
127            Err(Error::MalformedEncoding)
128        );
129
130        // Read Err
131        let e = Error::Custom("custom");
132        // unmarshal
133        assert_eq!(
134            deserialize_cb(&buf, |r| {
135                assert_eq!(u64::decode(r).unwrap(), u64::MAX);
136                Err::<(), _>(e)
137            }),
138            Err(e)
139        );
140
141        // "Read 0"
142
143        // unpack
144        let (_, bbytes) = binary_to_cser(&buf).unwrap();
145        let l = bbytes.len();
146        // pack with wrong bits size
147        let mut corrupted = fast::Writer::new(bbytes.to_vec());
148        let mut size_writer = fast::Writer::new(Vec::with_capacity(4));
149        write_uint64_compact(&mut size_writer, u64::try_from(l).unwrap() + 1);
150        let mut size_buf = size_writer.buf;
151        size_buf.reverse();
152        corrupted.write(&size_buf);
153        // corrupted unpack
154        assert_eq!(
155            binary_to_cser(&corrupted.buf),
156            Err(Error::MalformedEncoding)
157        );
158        // corrupted unmarshal
159        assert_eq!(
160            deserialize_cb(&corrupted.buf, |r| {
161                assert_eq!(u64::decode(r).unwrap(), u64::MAX);
162                Ok(())
163            }),
164            Err(Error::MalformedEncoding)
165        );
166
167        #[allow(clippy::type_complexity)]
168        let repack_with_defect =
169            |defect: Box<dyn FnOnce(&mut Vec<u8>, &mut Vec<u8>) -> Result<(), Error>>| {
170                // unpack
171                let (bbits, bbytes) = binary_to_cser(&buf).unwrap();
172                let mut bbits = bbits.to_vec();
173                let mut bbytes = bbytes.to_vec();
174                // pack with defect
175                let err_exp = (defect)(&mut bbits, &mut bbytes);
176                let corrupted = binary_from_cser(&bbits, bbytes);
177                // corrupted unmarshal
178                assert_eq!(
179                    deserialize_cb(&corrupted, |r| {
180                        let _ = u64::decode(r);
181                        Ok(())
182                    }),
183                    err_exp
184                );
185            };
186
187        (repack_with_defect)(Box::new(|_, _| {
188            // no defect
189            Ok(())
190        }));
191
192        (repack_with_defect)(Box::new(|_, bbytes| {
193            bbytes.push(0xFF);
194            Err(Error::NonCanonicalEncoding)
195        }));
196
197        (repack_with_defect)(Box::new(|bbits, _| {
198            bbits.push(0x0F);
199            Err(Error::NonCanonicalEncoding)
200        }));
201
202        (repack_with_defect)(Box::new(|_, bbytes| {
203            bbytes.truncate(bbytes.len() - 1);
204            Err(Error::NonCanonicalEncoding)
205        }));
206    }
207
208    #[test]
209    fn vals() {
210        let exp_u256 = [0.as_u256(), 1.as_u256(), 0xF_FF_FF.as_u256(), U256::MAX];
211        let exp_bool = vec![true, false];
212        let exp_fixed_bytes_empty = vec![[]];
213        let exp_fixed_bytes = vec![[rand::random::<u8>(); 0xFF]];
214        let exp_slice_bytes = vec![vec![rand::random::<u8>(); 0xFF]];
215        let exp_u8 = vec![0, 1, u8::MAX];
216        let exp_u16 = vec![0, 1, u16::MAX];
217        let exp_u32 = vec![0, 1, u32::MAX];
218        let exp_u64 = vec![0, 1, u64::MAX];
219        let exp_i64 = vec![0, 1, i64::MIN, i64::MAX];
220        let exp_u56 = [0_u64, 1, 1 << ((8 * 7) - 1)]
221            .into_iter()
222            .map(|v| U56::try_from(v).unwrap())
223            .collect::<Vec<_>>();
224
225        let buf = marshal_binary_adapter(|w| {
226            for v in &exp_u256 {
227                v.encode(w);
228            }
229            for v in &exp_bool {
230                v.encode(w);
231            }
232            for v in &exp_fixed_bytes_empty {
233                v.encode(w);
234            }
235            for v in &exp_fixed_bytes {
236                v.encode(w);
237            }
238            for v in &exp_slice_bytes {
239                v.as_slice().encode(w);
240            }
241            for v in &exp_u8 {
242                v.encode(w);
243            }
244            for v in &exp_u16 {
245                v.encode(w);
246            }
247            for v in &exp_u32 {
248                v.encode(w);
249            }
250            for v in &exp_u64 {
251                v.encode(w);
252            }
253            for v in &exp_i64 {
254                v.encode(w);
255            }
256            for v in &exp_u56 {
257                v.encode(w);
258            }
259            Ok(())
260        })
261        .unwrap();
262
263        deserialize_cb(&buf, |r| {
264            for v in &exp_u256 {
265                assert_eq!(U256::decode(r).unwrap(), *v);
266            }
267            for v in &exp_bool {
268                assert_eq!(bool::decode(r).unwrap(), *v);
269            }
270            for &v in &exp_fixed_bytes_empty {
271                let got = <[u8; 0] as Decodable>::decode(r).unwrap();
272                assert_eq!(got, v);
273            }
274            for &v in &exp_fixed_bytes {
275                let got = <[u8; 255] as Decodable>::decode(r).unwrap();
276                assert_eq!(got, v);
277            }
278            for v in &exp_slice_bytes {
279                assert_eq!(r.slice_bytes(v.len()).unwrap(), *v);
280            }
281            for v in &exp_u8 {
282                assert_eq!(u8::decode(r).unwrap(), *v);
283            }
284            for v in &exp_u16 {
285                assert_eq!(u16::decode(r).unwrap(), *v);
286            }
287            for v in &exp_u32 {
288                assert_eq!(u32::decode(r).unwrap(), *v);
289            }
290            for v in &exp_u64 {
291                assert_eq!(u64::decode(r).unwrap(), *v);
292            }
293            for v in &exp_i64 {
294                assert_eq!(i64::decode(r).unwrap(), *v);
295            }
296            for v in &exp_u56 {
297                assert_eq!(U56::decode(r).unwrap(), *v);
298            }
299            Ok::<_, Error>(())
300        })
301        .unwrap();
302    }
303}