Merge pull request #59 from paritytech/issue-48

fix accepting malformed rlp packages
This commit is contained in:
Marek Kotewicz 2018-09-17 15:56:07 +02:00 committed by GitHub
commit ef6e46b2a5
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
2 changed files with 30 additions and 3 deletions

View File

@ -40,6 +40,7 @@ pub enum Prototype {
}
/// Stores basic information about item
#[derive(Debug)]
pub struct PayloadInfo {
/// Header length in bytes
pub header_len: usize,
@ -258,8 +259,10 @@ impl<'a> Rlp<'a> {
/// consumes first found prefix
fn consume_list_payload(&self) -> Result<&'a [u8], DecoderError> {
let item = BasicDecoder::payload_info(self.bytes)?;
let bytes = Rlp::consume(self.bytes, item.header_len)?;
Ok(bytes)
if self.bytes.len() < (item.header_len + item.value_len) {
return Err(DecoderError::RlpIsTooShort);
}
Ok(&self.bytes[item.header_len..item.header_len + item.value_len])
}
/// consumes fixed number of items

View File

@ -437,4 +437,28 @@ fn test_rlp_is_int() {
let rlp = Rlp::new(&data);
assert_eq!(rlp.is_int(), false);
}
}
}
/// test described in
///
/// https://github.com/paritytech/parity-common/issues/48
#[test]
fn test_inner_length_capping_for_short_lists() {
assert_eq!(Rlp::new(&vec![0xc0 + 0, 0x82, b'a', b'b']).val_at::<String>(0), Err(DecoderError::RlpIsTooShort));
assert_eq!(Rlp::new(&vec![0xc0 + 1, 0x82, b'a', b'b']).val_at::<String>(0), Err(DecoderError::RlpIsTooShort));
assert_eq!(Rlp::new(&vec![0xc0 + 2, 0x82, b'a', b'b']).val_at::<String>(0), Err(DecoderError::RlpIsTooShort));
assert_eq!(Rlp::new(&vec![0xc0 + 3, 0x82, b'a', b'b']).val_at::<String>(0), Ok("ab".to_owned()));
assert_eq!(Rlp::new(&vec![0xc0 + 4, 0x82, b'a', b'b']).val_at::<String>(0), Err(DecoderError::RlpIsTooShort));
}
/// test described in
///
/// https://github.com/paritytech/parity-common/issues/48
#[test]
fn test_inner_length_capping_for_long_lists() {
assert_eq!(Rlp::new(&vec![0xf7 + 1, 0, 0x82, b'a', b'b']).val_at::<String>(0), Err(DecoderError::RlpDataLenWithZeroPrefix));
assert_eq!(Rlp::new(&vec![0xf7 + 1, 1, 0x82, b'a', b'b']).val_at::<String>(0), Err(DecoderError::RlpIsTooShort));
assert_eq!(Rlp::new(&vec![0xf7 + 1, 2, 0x82, b'a', b'b']).val_at::<String>(0), Err(DecoderError::RlpIsTooShort));
assert_eq!(Rlp::new(&vec![0xf7 + 1, 3, 0x82, b'a', b'b']).val_at::<String>(0), Ok("ab".to_owned()));
assert_eq!(Rlp::new(&vec![0xf7 + 1, 4, 0x82, b'a', b'b']).val_at::<String>(0), Err(DecoderError::RlpIsTooShort));
}