From b2050fa639f580a2fdff56579ab28aecc417c5bd Mon Sep 17 00:00:00 2001 From: Nikolay Volf Date: Mon, 25 Jan 2016 16:23:05 +0400 Subject: [PATCH] untrusted rlp data length check --- util/src/rlp/rlperrors.rs | 2 ++ util/src/rlp/tests.rs | 13 ++++++++++++- util/src/rlp/untrusted_rlp.rs | 7 ++++++- 3 files changed, 20 insertions(+), 2 deletions(-) diff --git a/util/src/rlp/rlperrors.rs b/util/src/rlp/rlperrors.rs index 97adbced1..18ca928ec 100644 --- a/util/src/rlp/rlperrors.rs +++ b/util/src/rlp/rlperrors.rs @@ -21,6 +21,8 @@ pub enum DecoderError { RlpListLenWithZeroPrefix, /// TODO [debris] Please document me RlpInvalidIndirection, + /// Returned when declared length is inconsistent with data specified after + RlpInconsistentLengthAndData } impl StdError for DecoderError { diff --git a/util/src/rlp/tests.rs b/util/src/rlp/tests.rs index f33cec177..e08901d67 100644 --- a/util/src/rlp/tests.rs +++ b/util/src/rlp/tests.rs @@ -4,7 +4,7 @@ use self::json_tests::rlp as rlptest; use std::{fmt, cmp}; use std::str::FromStr; use rlp; -use rlp::{UntrustedRlp, RlpStream, View, Stream}; +use rlp::{UntrustedRlp, RlpStream, View, Stream, DecoderError}; use uint::U256; #[test] @@ -351,3 +351,14 @@ fn test_decoding_array() { assert_eq!(arr[0], 5); assert_eq!(arr[1], 2); } + +#[test] +fn test_rlp_data_length_check() +{ + let data = vec![0x84, b'c', b'a', b't']; + let rlp = UntrustedRlp::new(&data); + + let as_val: Result = rlp.as_val(); + assert_eq!(Err(DecoderError::RlpInconsistentLengthAndData), as_val); +} + diff --git a/util/src/rlp/untrusted_rlp.rs b/util/src/rlp/untrusted_rlp.rs index 768d058c1..58ab2de60 100644 --- a/util/src/rlp/untrusted_rlp.rs +++ b/util/src/rlp/untrusted_rlp.rs @@ -331,10 +331,15 @@ impl<'a> Decoder for BasicDecoder<'a> { Some(l @ 0...0x7f) => Ok(try!(f(&[l]))), // 0-55 bytes Some(l @ 0x80...0xb7) => { - let d = &bytes[1..(1 + l as usize - 0x80)]; + let last_index_of = 1 + l as usize - 0x80; + if bytes.len() < last_index_of { + return Err(DecoderError::RlpInconsistentLengthAndData); + } + let d = &bytes[1..last_index_of]; if l == 0x81 && d[0] < 0x80 { return Err(DecoderError::RlpInvalidIndirection); } + Ok(try!(f(d))) }, // longer than 55 bytes