1use super::{
2 bits,
3 error::Error,
4 fast,
5 read_writer::{read_uint64_compact, write_uint64_compact, Reader},
6 Decodable,
7};
8
9pub(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 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
23pub(crate) fn binary_to_cser(mut raw: &[u8]) -> Result<(&[u8], &[u8]), Error> {
25 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 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 buf.append(
116 &mut marshal_binary_adapter(|w| {
117 u64::MAX.encode(w);
118 Ok(())
119 })
120 .unwrap(),
121 );
122
123 assert_eq!(
126 deserialize_cb(&[], |_| Ok(())),
127 Err(Error::MalformedEncoding)
128 );
129
130 let e = Error::Custom("custom");
132 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 let (_, bbytes) = binary_to_cser(&buf).unwrap();
145 let l = bbytes.len();
146 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 assert_eq!(
155 binary_to_cser(&corrupted.buf),
156 Err(Error::MalformedEncoding)
157 );
158 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 let (bbits, bbytes) = binary_to_cser(&buf).unwrap();
172 let mut bbits = bbits.to_vec();
173 let mut bbytes = bbytes.to_vec();
174 let err_exp = (defect)(&mut bbits, &mut bbytes);
176 let corrupted = binary_from_cser(&bbits, bbytes);
177 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 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}