untrusted rlp data length check

This commit is contained in:
Nikolay Volf 2016-01-25 16:23:05 +04:00
parent eed88df0d4
commit b2050fa639
3 changed files with 20 additions and 2 deletions

View File

@ -21,6 +21,8 @@ pub enum DecoderError {
RlpListLenWithZeroPrefix, RlpListLenWithZeroPrefix,
/// TODO [debris] Please document me /// TODO [debris] Please document me
RlpInvalidIndirection, RlpInvalidIndirection,
/// Returned when declared length is inconsistent with data specified after
RlpInconsistentLengthAndData
} }
impl StdError for DecoderError { impl StdError for DecoderError {

View File

@ -4,7 +4,7 @@ use self::json_tests::rlp as rlptest;
use std::{fmt, cmp}; use std::{fmt, cmp};
use std::str::FromStr; use std::str::FromStr;
use rlp; use rlp;
use rlp::{UntrustedRlp, RlpStream, View, Stream}; use rlp::{UntrustedRlp, RlpStream, View, Stream, DecoderError};
use uint::U256; use uint::U256;
#[test] #[test]
@ -351,3 +351,14 @@ fn test_decoding_array() {
assert_eq!(arr[0], 5); assert_eq!(arr[0], 5);
assert_eq!(arr[1], 2); 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<String, DecoderError> = rlp.as_val();
assert_eq!(Err(DecoderError::RlpInconsistentLengthAndData), as_val);
}

View File

@ -331,10 +331,15 @@ impl<'a> Decoder for BasicDecoder<'a> {
Some(l @ 0...0x7f) => Ok(try!(f(&[l]))), Some(l @ 0...0x7f) => Ok(try!(f(&[l]))),
// 0-55 bytes // 0-55 bytes
Some(l @ 0x80...0xb7) => { 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 { if l == 0x81 && d[0] < 0x80 {
return Err(DecoderError::RlpInvalidIndirection); return Err(DecoderError::RlpInvalidIndirection);
} }
Ok(try!(f(d))) Ok(try!(f(d)))
}, },
// longer than 55 bytes // longer than 55 bytes