Skip to content

Commit 86cd93d

Browse files
committed
primitives: delegate witness decoder
Delegate to the consensus_encoding byte vector decoder instead of duplicating the logic over in this crate. Also allows DoS protections to live entirely in consensus_encoding.
1 parent 233e08b commit 86cd93d

1 file changed

Lines changed: 18 additions & 159 deletions

File tree

primitives/src/witness.rs

Lines changed: 18 additions & 159 deletions
Original file line numberDiff line numberDiff line change
@@ -12,10 +12,7 @@ use core::ops::Index;
1212
use arbitrary::{Arbitrary, Unstructured};
1313
#[cfg(doc)]
1414
use encoding::Decoder4;
15-
use encoding::{
16-
self, BytesEncoder, CompactSizeDecoder, CompactSizeDecoderError, CompactSizeEncoder, Decoder,
17-
Encodable, Encoder, Encoder2, LengthPrefixExceedsMaxError,
18-
};
15+
use encoding::{self, BytesEncoder, CompactSizeEncoder, Decoder, Encodable, Encoder, Encoder2};
1916
#[cfg(feature = "hex")]
2017
use hex::{error::HexToBytesError, FromHex};
2118
use internals::slice::SliceExt;
@@ -300,38 +297,12 @@ impl Encoder for WitnessEncoder<'_> {
300297
/// The decoder for the [`Witness`] type.
301298
#[cfg(feature = "alloc")]
302299
pub struct WitnessDecoder {
303-
/// A decoder for the initial length prefix and subsequent per-element prefixes.
304-
prefix_decoder: Option<CompactSizeDecoder>,
305-
/// Holds the elements.
306-
buffer: Vec<Vec<u8>>,
307-
/// True if the initial compact size has been read.
308-
initial_length_prefix_read: bool, // I.e not the one for each element.
309-
/// Set after the initial length prefix is read.
310-
///
311-
/// This is read as a u64, checked to be below 4,000,000 then
312-
/// cast to a `usize` to make usage easier.
313-
witness_elements: usize,
314-
/// Index of the element we are going to decode next.
315-
idx: usize,
316-
/// True if the element length prefix has been read.
317-
element_length_prefix_read: bool,
318-
/// Bytes left to read for this element.
319-
bytes_to_read: usize,
300+
inner: encoding::VecDecoder<Vec<u8>>,
320301
}
321302

322303
impl WitnessDecoder {
323304
/// Constructs a new witness decoder.
324-
pub fn new() -> Self {
325-
Self {
326-
prefix_decoder: None,
327-
buffer: Vec::new(),
328-
initial_length_prefix_read: false,
329-
witness_elements: 0,
330-
idx: 0,
331-
element_length_prefix_read: false,
332-
bytes_to_read: 0,
333-
}
334-
}
305+
pub fn new() -> Self { Self { inner: encoding::VecDecoder::new() } }
335306
}
336307

337308
impl Default for WitnessDecoder {
@@ -343,91 +314,15 @@ impl Decoder for WitnessDecoder {
343314
type Error = WitnessDecoderError;
344315

345316
fn push_bytes(&mut self, bytes: &mut &[u8]) -> Result<bool, Self::Error> {
346-
use {WitnessDecoderError as E, WitnessDecoderErrorInner as Inner};
347-
348-
// First call to `push_bytes`.
349-
if !self.initial_length_prefix_read {
350-
let mut decoder = self.prefix_decoder.take().unwrap_or_default();
351-
352-
if decoder.push_bytes(bytes).map_err(|e| E(Inner::LengthPrefixDecode(e)))? {
353-
self.prefix_decoder = Some(decoder);
354-
return Ok(true);
355-
}
356-
let length = decoder.end().map_err(|e| E(Inner::LengthPrefixDecode(e)))?;
357-
358-
self.witness_elements = encoding::cast_to_usize_if_valid(length)
359-
.map_err(|e| E(Inner::LengthPrefixInvalid(e)))?;
360-
self.initial_length_prefix_read = true;
361-
362-
if self.witness_elements == 0 {
363-
return Ok(false);
364-
}
365-
366-
// `cast_to_usize_if_valid` asserts length < 4,000,000, so no DoS vector here.
367-
self.buffer = Vec::with_capacity(self.witness_elements);
368-
}
369-
370-
loop {
371-
if bytes.is_empty() {
372-
return Ok(true);
373-
}
374-
375-
if self.element_length_prefix_read {
376-
let v = self.buffer.get_mut(self.idx).expect("we created this last call");
377-
let copy_len = bytes.len().min(self.bytes_to_read);
378-
379-
v.extend_from_slice(&bytes[..copy_len]);
380-
*bytes = &bytes[copy_len..];
381-
self.bytes_to_read -= copy_len;
382-
383-
if self.bytes_to_read == 0 {
384-
self.element_length_prefix_read = false;
385-
self.idx += 1;
386-
if self.idx == self.witness_elements {
387-
return Ok(false);
388-
}
389-
}
390-
} else {
391-
let mut decoder = self.prefix_decoder.take().unwrap_or_default();
392-
393-
if decoder.push_bytes(bytes).map_err(|e| E(Inner::LengthPrefixDecode(e)))? {
394-
self.prefix_decoder = Some(decoder);
395-
return Ok(true);
396-
}
397-
let length = decoder.end().map_err(|e| E(Inner::LengthPrefixDecode(e)))?;
398-
self.bytes_to_read = encoding::cast_to_usize_if_valid(length)
399-
.map_err(|e| E(Inner::LengthPrefixInvalid(e)))?;
400-
self.element_length_prefix_read = true;
401-
402-
// `cast_to_usize_if_valid` asserts length < 4,000,000, so no DoS vector here.
403-
let v = Vec::with_capacity(self.bytes_to_read);
404-
self.buffer.push(v);
405-
}
406-
}
317+
self.inner.push_bytes(bytes).map_err(WitnessDecoderError::from)
407318
}
408319

409320
fn end(self) -> Result<Self::Output, Self::Error> {
410-
use {WitnessDecoderError as E, WitnessDecoderErrorInner as Inner};
411-
412-
let remaining = self.witness_elements - self.idx;
413-
414-
if remaining == 0 {
415-
Ok(Witness::from_slice(&self.buffer))
416-
} else {
417-
Err(E(Inner::UnexpectedEof(UnexpectedEofError { missing_elements: remaining })))
418-
}
321+
let vec = self.inner.end().map_err(WitnessDecoderError::from)?;
322+
Ok(Witness::from_slice(&vec))
419323
}
420324

421-
fn read_limit(&self) -> usize {
422-
if !self.initial_length_prefix_read {
423-
return match &self.prefix_decoder {
424-
Some(compact_size_decoder) => compact_size_decoder.read_limit(),
425-
None => 1,
426-
};
427-
}
428-
// The only assumption we can make is that each witness element is at least one byte.
429-
self.witness_elements.saturating_sub(self.buffer.len())
430-
}
325+
fn read_limit(&self) -> usize { self.inner.read_limit() }
431326
}
432327

433328
impl encoding::Decodable for Witness {
@@ -644,7 +539,7 @@ impl<'de> serde::Deserialize<'de> for Witness {
644539

645540
while let Some(elem) = a.next_element::<String>()? {
646541
let vec = Vec::<u8>::from_hex(&elem).map_err(|e| match e {
647-
E::InvalidChar(ref e) =>
542+
E::InvalidChar(ref e) => {
648543
match core::char::from_u32(e.invalid_char().into()) {
649544
Some(c) => de::Error::invalid_value(
650545
Unexpected::Char(c),
@@ -654,7 +549,8 @@ impl<'de> serde::Deserialize<'de> for Witness {
654549
Unexpected::Unsigned(e.invalid_char().into()),
655550
&"a valid hex character",
656551
),
657-
},
552+
}
553+
}
658554
E::OddLengthString(ref e) =>
659555
de::Error::invalid_length(e.length(), &"an even length string"),
660556
})?;
@@ -740,63 +636,27 @@ impl Default for Witness {
740636

741637
/// An error when consensus decoding a [`Witness`].
742638
#[derive(Debug, Clone, PartialEq, Eq)]
743-
pub struct WitnessDecoderError(WitnessDecoderErrorInner);
744-
745-
#[derive(Debug, Clone, PartialEq, Eq)]
746-
enum WitnessDecoderErrorInner {
747-
/// Error decoding the vector length prefix.
748-
LengthPrefixDecode(CompactSizeDecoderError),
749-
/// Length prefix exceeds 4,000,000.
750-
LengthPrefixInvalid(LengthPrefixExceedsMaxError),
751-
/// Not enough bytes given to decoder.
752-
UnexpectedEof(UnexpectedEofError),
753-
}
639+
pub struct WitnessDecoderError(encoding::VecDecoderError<encoding::ByteVecDecoderError>);
754640

755641
impl From<Infallible> for WitnessDecoderError {
756642
fn from(never: Infallible) -> Self { match never {} }
757643
}
758644

645+
impl From<encoding::VecDecoderError<encoding::ByteVecDecoderError>> for WitnessDecoderError {
646+
fn from(e: encoding::VecDecoderError<encoding::ByteVecDecoderError>) -> Self { Self(e) }
647+
}
648+
759649
impl fmt::Display for WitnessDecoderError {
760650
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
761-
use WitnessDecoderErrorInner as E;
762-
763-
match self.0 {
764-
E::LengthPrefixDecode(ref e) => write_err!(f, "vec decoder error"; e),
765-
E::LengthPrefixInvalid(ref e) => write_err!(f, "vec decoder error"; e),
766-
E::UnexpectedEof(ref e) => write_err!(f, "decoder error"; e),
767-
}
651+
write_err!(f, "witness decoder error"; self.0)
768652
}
769653
}
770654

771655
#[cfg(feature = "std")]
772656
impl std::error::Error for WitnessDecoderError {
773-
fn source(&self) -> Option<&(dyn std::error::Error + 'static)> {
774-
use WitnessDecoderErrorInner as E;
775-
776-
match self.0 {
777-
E::LengthPrefixDecode(ref e) => Some(e),
778-
E::LengthPrefixInvalid(ref e) => Some(e),
779-
E::UnexpectedEof(ref e) => Some(e),
780-
}
781-
}
782-
}
783-
784-
/// Not enough witness elements (bytes) given to decoder.
785-
#[derive(Debug, Clone, PartialEq, Eq)]
786-
pub struct UnexpectedEofError {
787-
/// Number of elements missing to complete decoder.
788-
missing_elements: usize,
789-
}
790-
791-
impl core::fmt::Display for UnexpectedEofError {
792-
fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
793-
write!(f, "not enough witness elements for decoder, missing {}", self.missing_elements)
794-
}
657+
fn source(&self) -> Option<&(dyn std::error::Error + 'static)> { Some(&self.0) }
795658
}
796659

797-
#[cfg(feature = "std")]
798-
impl std::error::Error for UnexpectedEofError {}
799-
800660
#[cfg(feature = "arbitrary")]
801661
impl<'a> Arbitrary<'a> for Witness {
802662
fn arbitrary(u: &mut Unstructured<'a>) -> arbitrary::Result<Self> {
@@ -1297,7 +1157,6 @@ mod test {
12971157

12981158
let mut slice = encoded.as_slice();
12991159
let mut decoder = WitnessDecoder::new();
1300-
let err = decoder.push_bytes(&mut slice).unwrap_err();
1301-
assert!(matches!(err, WitnessDecoderError(WitnessDecoderErrorInner::LengthPrefixInvalid(_))));
1160+
decoder.push_bytes(&mut slice).unwrap_err();
13021161
}
13031162
}

0 commit comments

Comments
 (0)