commit
d30114b87c
3
.gitignore
vendored
3
.gitignore
vendored
@ -23,4 +23,5 @@ Cargo.lock
|
|||||||
|
|
||||||
/json-tests/target/
|
/json-tests/target/
|
||||||
|
|
||||||
|
# jetbrains ide stuff
|
||||||
|
.idea
|
@ -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 {
|
||||||
|
@ -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,56 @@ 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);
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn test_rlp_long_data_length_check()
|
||||||
|
{
|
||||||
|
let mut data: Vec<u8> = vec![0xb8, 255];
|
||||||
|
for _ in 0..253 {
|
||||||
|
data.push(b'c');
|
||||||
|
}
|
||||||
|
|
||||||
|
let rlp = UntrustedRlp::new(&data);
|
||||||
|
|
||||||
|
let as_val: Result<String, DecoderError> = rlp.as_val();
|
||||||
|
assert_eq!(Err(DecoderError::RlpInconsistentLengthAndData), as_val);
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn test_the_exact_long_string()
|
||||||
|
{
|
||||||
|
let mut data: Vec<u8> = vec![0xb8, 255];
|
||||||
|
for _ in 0..255 {
|
||||||
|
data.push(b'c');
|
||||||
|
}
|
||||||
|
|
||||||
|
let rlp = UntrustedRlp::new(&data);
|
||||||
|
|
||||||
|
let as_val: Result<String, DecoderError> = rlp.as_val();
|
||||||
|
assert!(as_val.is_ok());
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn test_rlp_2bytes_data_length_check()
|
||||||
|
{
|
||||||
|
let mut data: Vec<u8> = vec![0xb9, 2, 255]; // 512+255
|
||||||
|
for _ in 0..700 {
|
||||||
|
data.push(b'c');
|
||||||
|
}
|
||||||
|
|
||||||
|
let rlp = UntrustedRlp::new(&data);
|
||||||
|
|
||||||
|
let as_val: Result<String, DecoderError> = rlp.as_val();
|
||||||
|
assert_eq!(Err(DecoderError::RlpInconsistentLengthAndData), as_val);
|
||||||
|
}
|
||||||
|
|
||||||
|
@ -331,18 +331,31 @@ 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
|
||||||
Some(l @ 0xb8...0xbf) => {
|
Some(l @ 0xb8...0xbf) => {
|
||||||
let len_of_len = l as usize - 0xb7;
|
let len_of_len = l as usize - 0xb7;
|
||||||
let begin_of_value = 1 as usize + len_of_len;
|
let begin_of_value = 1 as usize + len_of_len;
|
||||||
|
if bytes.len() < begin_of_value {
|
||||||
|
return Err(DecoderError::RlpInconsistentLengthAndData);
|
||||||
|
}
|
||||||
let len = try!(usize::from_bytes(&bytes[1..begin_of_value]));
|
let len = try!(usize::from_bytes(&bytes[1..begin_of_value]));
|
||||||
Ok(try!(f(&bytes[begin_of_value..begin_of_value + len])))
|
|
||||||
|
let last_index_of_value = begin_of_value + len;
|
||||||
|
if bytes.len() < last_index_of_value {
|
||||||
|
return Err(DecoderError::RlpInconsistentLengthAndData);
|
||||||
|
}
|
||||||
|
Ok(try!(f(&bytes[begin_of_value..last_index_of_value])))
|
||||||
}
|
}
|
||||||
// we are reading value, not a list!
|
// we are reading value, not a list!
|
||||||
_ => Err(DecoderError::RlpExpectedToBeData)
|
_ => Err(DecoderError::RlpExpectedToBeData)
|
||||||
|
Loading…
Reference in New Issue
Block a user