Skip to main content

cuprate_epee_encoding/
value.rs

1//! This module contains a [`EpeeValue`] trait and
2//! impls for some possible base epee values.
3
4use alloc::{string::String, vec, vec::Vec};
5use core::{cmp::min, fmt::Debug};
6
7use bytes::{Buf, BufMut, Bytes, BytesMut};
8
9use cuprate_fixed_bytes::{ByteArray, ByteArrayVec};
10use cuprate_hex::{Hex, HexVec};
11
12use crate::{
13    io::{checked_read_primitive, checked_write_primitive},
14    max_upfront_capacity,
15    varint::{read_varint, write_varint},
16    write_bytes, write_iterator, EpeeObject, Error, InnerMarker, Marker, Result,
17    MAX_STRING_LEN_POSSIBLE,
18};
19
20/// Limits applied while decoding an epee value.
21#[derive(Clone, Copy, Debug, PartialEq, Eq)]
22pub struct EpeeValueLimits {
23    /// This is a safety value that is used to enforce that a minimum number of bytes are
24    /// read for a given element. This is to protect types where their epee wire encoding could be a
25    /// lot smaller than their size in memory. This is allowed to be ignored if it is safe
26    /// for that type to do so.
27    pub min_element_size: usize,
28    /// The maximum number of elements allowed in a sequence. Will be ignored when the type is not a
29    /// sequence.
30    pub max_sequence_len: usize,
31}
32
33impl Default for EpeeValueLimits {
34    /// Default is no limits.
35    fn default() -> Self {
36        Self {
37            min_element_size: 0,
38            max_sequence_len: usize::MAX,
39        }
40    }
41}
42
43/// A trait for epee values.
44///
45/// All [`EpeeObject`] objects automatically implement [`EpeeValue`].
46pub trait EpeeValue: Sized {
47    const MARKER: Marker;
48
49    fn read<B: Buf>(r: &mut B, marker: &Marker, limits: EpeeValueLimits) -> Result<Self>;
50
51    fn should_write(&self) -> bool {
52        true
53    }
54
55    /// This is different than default field values and instead is the default
56    /// value of a whole type.
57    ///
58    /// For example a `Vec` has a default value of a zero length vec as when a
59    /// sequence has no entries it is not encoded.
60    fn epee_default_value() -> Option<Self> {
61        None
62    }
63
64    fn write<B: BufMut>(self, w: &mut B) -> Result<()>;
65}
66
67fn enforce_bytes_read<B: Buf, R>(
68    r: &mut B,
69    f: impl FnOnce(&mut B) -> Result<R>,
70    min_element_size: usize,
71) -> Result<R> {
72    let remaining_before = r.remaining();
73    let value = f(r)?;
74    if remaining_before.saturating_sub(r.remaining()) < min_element_size {
75        return Err(Error::Format(
76            "Element is smaller than the minimum set size",
77        ));
78    }
79
80    Ok(value)
81}
82
83impl<T: EpeeObject> EpeeValue for T {
84    const MARKER: Marker = Marker::new(InnerMarker::Object);
85
86    fn read<B: Buf>(r: &mut B, marker: &Marker, limits: EpeeValueLimits) -> Result<Self> {
87        if marker != &Self::MARKER {
88            return Err(Error::Format("Marker does not match expected Marker"));
89        }
90
91        let mut skipped_objects = 0;
92        enforce_bytes_read(
93            r,
94            |r| crate::read_object(r, &mut skipped_objects),
95            limits.min_element_size,
96        )
97    }
98
99    fn write<B: BufMut>(self, w: &mut B) -> Result<()> {
100        write_varint(self.number_of_fields(), w)?;
101        self.write_fields(w)
102    }
103}
104
105impl<T: EpeeObject> EpeeValue for Vec<T> {
106    const MARKER: Marker = T::MARKER.into_seq();
107
108    fn read<B: Buf>(r: &mut B, marker: &Marker, limits: EpeeValueLimits) -> Result<Self> {
109        if !marker.is_seq {
110            return Err(Error::Format(
111                "Marker is not sequence when a sequence was expected",
112            ));
113        }
114        let len = read_varint(r)?;
115        if len > limits.max_sequence_len {
116            return Err(Error::Format("Sequence exceeded maximum length"));
117        }
118
119        let individual_marker = Marker::new(marker.inner_marker);
120
121        let mut res = Self::with_capacity(min(len, max_upfront_capacity::<T>()));
122        for _ in 0..len {
123            res.push(enforce_bytes_read(
124                r,
125                // We can pass in `Default::default()` here as we deal with checking how many bytes
126                // the element read and enforcing it is at least `min_element_size`.
127                |r| T::read(r, &individual_marker, Default::default()),
128                limits.min_element_size,
129            )?);
130        }
131        Ok(res)
132    }
133
134    fn should_write(&self) -> bool {
135        !self.is_empty()
136    }
137
138    fn epee_default_value() -> Option<Self> {
139        Some(Self::new())
140    }
141
142    fn write<B: BufMut>(self, w: &mut B) -> Result<()> {
143        write_iterator(self.into_iter(), w)
144    }
145}
146
147impl<T: EpeeObject + Debug, const N: usize> EpeeValue for [T; N] {
148    const MARKER: Marker = <T>::MARKER.into_seq();
149
150    fn read<B: Buf>(r: &mut B, marker: &Marker, limits: EpeeValueLimits) -> Result<Self> {
151        let vec = Vec::<T>::read(r, marker, limits)?;
152
153        if vec.len() != N {
154            return Err(Error::Format("Array has incorrect length"));
155        }
156
157        Ok(vec.try_into().unwrap())
158    }
159
160    fn write<B: BufMut>(self, w: &mut B) -> Result<()> {
161        write_iterator(self.into_iter(), w)
162    }
163}
164
165macro_rules! epee_numb {
166    ($numb:ty, $marker:ident, $read_fn:ident, $write_fn:ident) => {
167        impl EpeeValue for $numb {
168            const MARKER: Marker = Marker::new(InnerMarker::$marker);
169
170            fn read<B: Buf>(r: &mut B, marker: &Marker, _: EpeeValueLimits) -> Result<Self> {
171                if marker != &Self::MARKER {
172                    return Err(Error::Format("Marker does not match expected Marker"));
173                }
174
175                checked_read_primitive(r, Buf::$read_fn)
176            }
177
178            fn write<B: BufMut>(self, w: &mut B) -> Result<()> {
179                checked_write_primitive(w, BufMut::$write_fn, self)
180            }
181        }
182    };
183}
184
185epee_numb!(i64, I64, get_i64_le, put_i64_le);
186epee_numb!(i32, I32, get_i32_le, put_i32_le);
187epee_numb!(i16, I16, get_i16_le, put_i16_le);
188epee_numb!(i8, I8, get_i8, put_i8);
189epee_numb!(u8, U8, get_u8, put_u8);
190epee_numb!(u16, U16, get_u16_le, put_u16_le);
191epee_numb!(u32, U32, get_u32_le, put_u32_le);
192epee_numb!(u64, U64, get_u64_le, put_u64_le);
193epee_numb!(f64, F64, get_f64_le, put_f64_le);
194
195impl EpeeValue for bool {
196    const MARKER: Marker = Marker::new(InnerMarker::Bool);
197
198    fn read<B: Buf>(r: &mut B, marker: &Marker, _: EpeeValueLimits) -> Result<Self> {
199        if marker != &Self::MARKER {
200            return Err(Error::Format("Marker does not match expected Marker"));
201        }
202
203        match checked_read_primitive(r, Buf::get_u8)? {
204            0 => Ok(false),
205            1 => Ok(true),
206            _ => Err(Error::Format("Invalid bool value")),
207        }
208    }
209
210    fn write<B: BufMut>(self, w: &mut B) -> Result<()> {
211        checked_write_primitive(w, BufMut::put_u8, if self { 1 } else { 0 })
212    }
213}
214
215impl EpeeValue for Vec<u8> {
216    const MARKER: Marker = Marker::new(InnerMarker::String);
217
218    fn read<B: Buf>(r: &mut B, marker: &Marker, limits: EpeeValueLimits) -> Result<Self> {
219        if marker != &Self::MARKER {
220            return Err(Error::Format("Marker does not match expected Marker"));
221        }
222
223        let len = read_varint(r)?;
224        if len > limits.max_sequence_len {
225            return Err(Error::Format("Sequence exceeded maximum length"));
226        }
227        if len > MAX_STRING_LEN_POSSIBLE {
228            return Err(Error::Format("Byte array exceeded max length"));
229        }
230
231        if r.remaining() < len {
232            return Err(Error::IO("Not enough bytes to fill object"));
233        }
234
235        let mut res = vec![0; len];
236        r.copy_to_slice(&mut res);
237
238        Ok(res)
239    }
240
241    fn epee_default_value() -> Option<Self> {
242        Some(Self::new())
243    }
244
245    fn should_write(&self) -> bool {
246        !self.is_empty()
247    }
248
249    fn write<B: BufMut>(self, w: &mut B) -> Result<()> {
250        write_bytes(self, w)
251    }
252}
253
254impl EpeeValue for Bytes {
255    const MARKER: Marker = Marker::new(InnerMarker::String);
256
257    fn read<B: Buf>(r: &mut B, marker: &Marker, limits: EpeeValueLimits) -> Result<Self> {
258        if marker != &Self::MARKER {
259            return Err(Error::Format("Marker does not match expected Marker"));
260        }
261
262        let len = read_varint(r)?;
263        if len > limits.max_sequence_len {
264            return Err(Error::Format("Sequence exceeded maximum length"));
265        }
266        if len > MAX_STRING_LEN_POSSIBLE {
267            return Err(Error::Format("Byte array exceeded max length"));
268        }
269
270        if r.remaining() < len {
271            return Err(Error::IO("Not enough bytes to fill object"));
272        }
273
274        Ok(r.copy_to_bytes(len))
275    }
276
277    fn epee_default_value() -> Option<Self> {
278        Some(Self::new())
279    }
280
281    fn should_write(&self) -> bool {
282        !self.is_empty()
283    }
284
285    fn write<B: BufMut>(self, w: &mut B) -> Result<()> {
286        write_bytes(self, w)
287    }
288}
289
290impl EpeeValue for BytesMut {
291    const MARKER: Marker = Marker::new(InnerMarker::String);
292
293    fn read<B: Buf>(r: &mut B, marker: &Marker, limits: EpeeValueLimits) -> Result<Self> {
294        if marker != &Self::MARKER {
295            return Err(Error::Format("Marker does not match expected Marker"));
296        }
297
298        let len = read_varint(r)?;
299        if len > limits.max_sequence_len {
300            return Err(Error::Format("Sequence exceeded maximum length"));
301        }
302        if len > MAX_STRING_LEN_POSSIBLE {
303            return Err(Error::Format("Byte array exceeded max length"));
304        }
305
306        if r.remaining() < len {
307            return Err(Error::IO("Not enough bytes to fill object"));
308        }
309
310        let mut bytes = Self::zeroed(len);
311        r.copy_to_slice(&mut bytes);
312        Ok(bytes)
313    }
314
315    fn epee_default_value() -> Option<Self> {
316        Some(Self::new())
317    }
318
319    fn should_write(&self) -> bool {
320        !self.is_empty()
321    }
322
323    fn write<B: BufMut>(self, w: &mut B) -> Result<()> {
324        write_bytes(self, w)
325    }
326}
327
328impl<const N: usize> EpeeValue for ByteArrayVec<N> {
329    const MARKER: Marker = Marker::new(InnerMarker::String);
330
331    fn read<B: Buf>(r: &mut B, marker: &Marker, _: EpeeValueLimits) -> Result<Self> {
332        if marker != &Self::MARKER {
333            return Err(Error::Format("Marker does not match expected Marker"));
334        }
335
336        let len = read_varint::<_, usize>(r)?;
337        if len > MAX_STRING_LEN_POSSIBLE {
338            return Err(Error::Format("Byte array exceeded max length"));
339        }
340
341        if r.remaining() < len {
342            return Err(Error::IO("Not enough bytes to fill object"));
343        }
344
345        Self::try_from(r.copy_to_bytes(len)).map_err(|_| Error::Format("Field has invalid length"))
346    }
347
348    fn epee_default_value() -> Option<Self> {
349        Some(Self::try_from(Bytes::new()).unwrap())
350    }
351
352    fn should_write(&self) -> bool {
353        !self.is_empty()
354    }
355
356    fn write<B: BufMut>(self, w: &mut B) -> Result<()> {
357        let bytes = self.take_bytes();
358        write_bytes(bytes, w)
359    }
360}
361
362impl<const N: usize> EpeeValue for ByteArray<N> {
363    const MARKER: Marker = Marker::new(InnerMarker::String);
364
365    fn read<B: Buf>(r: &mut B, marker: &Marker, _: EpeeValueLimits) -> Result<Self> {
366        if marker != &Self::MARKER {
367            return Err(Error::Format("Marker does not match expected Marker"));
368        }
369
370        let len = read_varint::<_, usize>(r)?;
371        if len != N {
372            return Err(Error::Format("Byte array has incorrect length"));
373        }
374
375        if r.remaining() < N {
376            return Err(Error::IO("Not enough bytes to fill object"));
377        }
378
379        Self::try_from(r.copy_to_bytes(N)).map_err(|_| Error::Format("Field has invalid length"))
380    }
381
382    fn write<B: BufMut>(self, w: &mut B) -> Result<()> {
383        let bytes = self.take_bytes();
384        write_bytes(bytes, w)
385    }
386}
387
388impl EpeeValue for String {
389    const MARKER: Marker = Marker::new(InnerMarker::String);
390
391    fn read<B: Buf>(r: &mut B, marker: &Marker, limits: EpeeValueLimits) -> Result<Self> {
392        let bytes = Vec::<u8>::read(r, marker, limits)?;
393        Self::from_utf8(bytes).map_err(|_| Error::Format("Invalid string"))
394    }
395
396    fn should_write(&self) -> bool {
397        !self.is_empty()
398    }
399
400    fn epee_default_value() -> Option<Self> {
401        Some(Self::new())
402    }
403
404    fn write<B: BufMut>(self, w: &mut B) -> Result<()> {
405        write_bytes(self, w)
406    }
407}
408
409impl<const N: usize> EpeeValue for [u8; N] {
410    const MARKER: Marker = Marker::new(InnerMarker::String);
411
412    fn read<B: Buf>(r: &mut B, marker: &Marker, _: EpeeValueLimits) -> Result<Self> {
413        let bytes = Vec::<u8>::read(r, marker, Default::default())?;
414
415        if bytes.len() != N {
416            return Err(Error::Format("Byte array has incorrect length"));
417        }
418
419        Ok(bytes.try_into().unwrap())
420    }
421
422    fn write<B: BufMut>(self, w: &mut B) -> Result<()> {
423        write_bytes(self, w)
424    }
425}
426
427impl<const N: usize> EpeeValue for Vec<[u8; N]> {
428    const MARKER: Marker = <[u8; N]>::MARKER.into_seq();
429
430    fn read<B: Buf>(r: &mut B, marker: &Marker, limits: EpeeValueLimits) -> Result<Self> {
431        if !marker.is_seq {
432            return Err(Error::Format(
433                "Marker is not sequence when a sequence was expected",
434            ));
435        }
436
437        let len = read_varint(r)?;
438        if len > limits.max_sequence_len {
439            return Err(Error::Format("Sequence exceeded maximum length"));
440        }
441
442        let individual_marker = Marker::new(marker.inner_marker);
443
444        let mut res = Self::with_capacity(min(len, max_upfront_capacity::<[u8; N]>()));
445        for _ in 0..len {
446            res.push(<[u8; N]>::read(r, &individual_marker, Default::default())?);
447        }
448        Ok(res)
449    }
450
451    fn should_write(&self) -> bool {
452        !self.is_empty()
453    }
454
455    fn epee_default_value() -> Option<Self> {
456        Some(Self::new())
457    }
458
459    fn write<B: BufMut>(self, w: &mut B) -> Result<()> {
460        write_iterator(self.into_iter(), w)
461    }
462}
463
464impl<const N: usize> EpeeValue for Hex<N> {
465    const MARKER: Marker = <[u8; N] as EpeeValue>::MARKER;
466
467    fn read<B: Buf>(r: &mut B, marker: &Marker, _: EpeeValueLimits) -> Result<Self> {
468        Ok(Self(<[u8; N] as EpeeValue>::read(
469            r,
470            marker,
471            Default::default(),
472        )?))
473    }
474
475    fn write<B: BufMut>(self, w: &mut B) -> Result<()> {
476        <[u8; N] as EpeeValue>::write(self.0, w)
477    }
478}
479
480impl<const N: usize> EpeeValue for Vec<Hex<N>> {
481    const MARKER: Marker = Vec::<[u8; N]>::MARKER;
482
483    fn read<B: Buf>(r: &mut B, marker: &Marker, limits: EpeeValueLimits) -> Result<Self> {
484        Ok(Vec::<[u8; N]>::read(r, marker, limits)?
485            .into_iter()
486            .map(Hex)
487            .collect())
488    }
489
490    fn should_write(&self) -> bool {
491        !self.is_empty()
492    }
493
494    fn epee_default_value() -> Option<Self> {
495        Some(Self::new())
496    }
497
498    fn write<B: BufMut>(self, w: &mut B) -> Result<()> {
499        write_iterator(self.into_iter(), w)
500    }
501}
502
503impl EpeeValue for HexVec {
504    const MARKER: Marker = <Vec<u8> as EpeeValue>::MARKER;
505
506    fn read<B: Buf>(r: &mut B, marker: &Marker, limits: EpeeValueLimits) -> Result<Self> {
507        Ok(Self(<Vec<u8> as EpeeValue>::read(r, marker, limits)?))
508    }
509
510    fn write<B: BufMut>(self, w: &mut B) -> Result<()> {
511        <Vec<u8> as EpeeValue>::write(self.0, w)
512    }
513}
514
515macro_rules! epee_seq {
516    ($val:ty) => {
517        impl EpeeValue for Vec<$val> {
518            const MARKER: Marker = <$val>::MARKER.into_seq();
519
520            fn read<B: Buf>(r: &mut B, marker: &Marker, limits: EpeeValueLimits) -> Result<Self> {
521                if !marker.is_seq {
522                    return Err(Error::Format(
523                        "Marker is not sequence when a sequence was expected",
524                    ));
525                }
526
527                let len = read_varint(r)?;
528                if len > limits.max_sequence_len {
529                    return Err(Error::Format("Sequence exceeded maximum length"));
530                }
531
532                let individual_marker = Marker::new(marker.inner_marker.clone());
533
534                let mut res = Vec::with_capacity(min(len, max_upfront_capacity::<$val>()));
535                for _ in 0..len {
536                    res.push(enforce_bytes_read(
537                        r,
538                        |r| <$val>::read(r, &individual_marker, Default::default()),
539                        limits.min_element_size,
540                    )?);
541                }
542                Ok(res)
543            }
544
545            fn should_write(&self) -> bool {
546                !self.is_empty()
547            }
548
549            fn epee_default_value() -> Option<Self> {
550                Some(Vec::new())
551            }
552
553            fn write<B: BufMut>(self, w: &mut B) -> Result<()> {
554                write_iterator(self.into_iter(), w)
555            }
556        }
557
558        impl<const N: usize> EpeeValue for [$val; N] {
559            const MARKER: Marker = <$val>::MARKER.into_seq();
560
561            fn read<B: Buf>(r: &mut B, marker: &Marker, limits: EpeeValueLimits) -> Result<Self> {
562                let vec = Vec::<$val>::read(r, marker, limits)?;
563
564                if vec.len() != N {
565                    return Err(Error::Format("Array has incorrect length"));
566                }
567
568                Ok(vec.try_into().unwrap())
569            }
570
571            fn write<B: BufMut>(self, w: &mut B) -> Result<()> {
572                write_iterator(self.into_iter(), w)
573            }
574        }
575    };
576}
577
578epee_seq!(i64);
579epee_seq!(i32);
580epee_seq!(i16);
581epee_seq!(i8);
582epee_seq!(u64);
583epee_seq!(u32);
584epee_seq!(u16);
585epee_seq!(f64);
586epee_seq!(bool);
587epee_seq!(Vec<u8>);
588epee_seq!(HexVec);
589epee_seq!(String);
590epee_seq!(Bytes);
591epee_seq!(BytesMut);
592
593impl<T: EpeeValue> EpeeValue for Option<T> {
594    const MARKER: Marker = T::MARKER;
595
596    fn read<B: Buf>(r: &mut B, marker: &Marker, limits: EpeeValueLimits) -> Result<Self> {
597        Ok(Some(T::read(r, marker, limits)?))
598    }
599
600    fn should_write(&self) -> bool {
601        match self {
602            Some(t) => t.should_write(),
603            None => false,
604        }
605    }
606
607    fn epee_default_value() -> Option<Self> {
608        Some(None)
609    }
610
611    fn write<B: BufMut>(self, w: &mut B) -> Result<()> {
612        match self {
613            Some(t) => t.write(w)?,
614            None => panic!("Can't write an Option::None value, this should be handled elsewhere"),
615        }
616        Ok(())
617    }
618}