#![allow(clippy::blacklisted_name)]
#![allow(clippy::many_single_char_names)]
use crate::*;
use byteorder::WriteBytesExt;
use failure::Result;
use proptest::prelude::*;
use proptest_derive::Arbitrary;
use std::collections::BTreeMap;
const TEST_VECTOR: &str = "ffffffffffffffff060000006463584d4237640000000000000009000000000102\
03040506070820000000050505050505050505050505050505050505050505050505\
05050505050505056300000001030000000100000001030000001615430300000000\
381503000000160a05040000001415596903000000c9175a";
#[derive(Arbitrary, Clone, Debug, Eq, PartialEq)]
pub struct Addr(pub [u8; 32]);
impl Addr {
fn new(bytes: [u8; 32]) -> Self {
Addr(bytes)
}
}
impl CanonicalDeserialize for Addr {
fn deserialize(deserializer: &mut impl CanonicalDeserializer) -> Result<Self> {
let mut data_slice: [u8; 32] = [0; 32];
let data_decoded = deserializer.decode_bytes()?;
data_slice.copy_from_slice(data_decoded.as_slice());
Ok(Addr::new(data_slice))
}
}
impl CanonicalSerialize for Addr {
fn serialize(&self, serializer: &mut impl CanonicalSerializer) -> Result<()> {
serializer.encode_bytes(&self.0)?;
Ok(())
}
}
#[derive(Arbitrary, Clone, Debug, Eq, PartialEq)]
struct Bar {
a: u64,
b: Vec<u8>,
c: Addr,
d: u32,
}
impl CanonicalDeserialize for Bar {
fn deserialize(deserializer: &mut impl CanonicalDeserializer) -> Result<Self> {
Ok(Bar {
a: deserializer.decode_u64()?,
b: deserializer.decode_bytes()?,
c: deserializer.decode_struct()?,
d: deserializer.decode_u32()?,
})
}
}
impl CanonicalSerialize for Bar {
fn serialize(&self, serializer: &mut impl CanonicalSerializer) -> Result<()> {
serializer
.encode_u64(self.a)?
.encode_bytes(&self.b)?
.encode_struct(&self.c)?
.encode_u32(self.d)?;
Ok(())
}
}
#[derive(Arbitrary, Clone, Debug, Eq, PartialEq)]
struct Foo {
a: u64,
b: Vec<u8>,
c: Bar,
d: bool,
e: BTreeMap<Vec<u8>, Vec<u8>>,
}
impl CanonicalDeserialize for Foo {
fn deserialize(deserializer: &mut impl CanonicalDeserializer) -> Result<Self> {
Ok(Foo {
a: deserializer.decode_u64()?,
b: deserializer.decode_bytes()?,
c: deserializer.decode_struct()?,
d: deserializer.decode_bool()?,
e: deserializer.decode_btreemap()?,
})
}
}
impl CanonicalSerialize for Foo {
fn serialize(&self, serializer: &mut impl CanonicalSerializer) -> Result<()> {
serializer
.encode_u64(self.a)?
.encode_bytes(&self.b)?
.encode_struct(&self.c)?
.encode_bool(self.d)?
.encode_btreemap(&self.e)?;
Ok(())
}
}
proptest! {
#[test]
fn serializer_bar(value in any::<Bar>()) {
test_helper::assert_canonical_encode_decode(&value);
}
#[test]
fn serializer_bool(value in any::<bool>()) {
test_helper::assert_canonical_encode_decode(&value);
}
#[test]
fn serialize_btreemap(value in any::<BTreeMap<Vec<u8>, Vec<u8>>>()) {
test_helper::assert_canonical_encode_decode(&value);
}
#[test]
fn serialize_byte_array(value in any::<Vec<u8>>()) {
test_helper::assert_canonical_encode_decode(&value);
}
#[test]
fn serializer_foo(value in any::<Foo>()) {
test_helper::assert_canonical_encode_decode(&value);
}
#[test]
fn serialize_i8(value in any::<i8>()) {
test_helper::assert_canonical_encode_decode(&value);
}
#[test]
fn serialize_i16(value in any::<i16>()) {
test_helper::assert_canonical_encode_decode(&value);
}
#[test]
fn serialize_i32(value in any::<i32>()) {
test_helper::assert_canonical_encode_decode(&value);
}
#[test]
fn serialize_i64(value in any::<i64>()) {
test_helper::assert_canonical_encode_decode(&value);
}
#[test]
fn serialize_string(value in any::<String>()) {
test_helper::assert_canonical_encode_decode(&value);
}
#[test]
fn serialize_tuple2(value in any::<(i16, String)>()) {
test_helper::assert_canonical_encode_decode(&value);
}
#[test]
fn serialize_tuple3(value in any::<(bool, u32, String)>()) {
test_helper::assert_canonical_encode_decode(&value);
}
#[test]
fn serialize_u8(value in any::<u8>()) {
test_helper::assert_canonical_encode_decode(&value);
}
#[test]
fn serialize_u16(value in any::<u16>()) {
test_helper::assert_canonical_encode_decode(&value);
}
#[test]
fn serialize_u32(value in any::<u32>()) {
test_helper::assert_canonical_encode_decode(&value);
}
#[test]
fn serialize_u64(value in any::<u64>()) {
test_helper::assert_canonical_encode_decode(&value);
}
}
#[test]
fn test_serialization_correctness_using_known_vector() {
let bar = Bar {
a: 100,
b: vec![0, 1, 2, 3, 4, 5, 6, 7, 8],
c: Addr::new([5u8; 32]),
d: 99,
};
let mut map = BTreeMap::new();
map.insert(vec![0, 56, 21], vec![22, 10, 5]);
map.insert(vec![1], vec![22, 21, 67]);
map.insert(vec![20, 21, 89, 105], vec![201, 23, 90]);
let foo = Foo {
a: u64::max_value(),
b: vec![100, 99, 88, 77, 66, 55],
c: bar,
d: true,
e: map,
};
let mut serializer = SimpleSerializer::<Vec<u8>>::new();
foo.serialize(&mut serializer).unwrap();
let serialized_bytes = serializer.get_output();
assert_eq!(TEST_VECTOR, hex::encode(serialized_bytes));
let test_vector_bytes = hex::decode(TEST_VECTOR).unwrap();
let deserialized_foo: Foo = SimpleDeserializer::deserialize(&test_vector_bytes).unwrap();
assert_eq!(foo, deserialized_foo);
}
#[test]
fn test_btreemap_lexicographic_order() {
let mut map = BTreeMap::new();
let value = vec![54, 20, 21, 200];
let key1 = vec![0]; let key2 = vec![0, 6]; let key3 = vec![1]; let key4 = vec![2]; map.insert(key1.clone(), value.clone());
map.insert(key2.clone(), value.clone());
map.insert(key3.clone(), value.clone());
map.insert(key4.clone(), value.clone());
let serialized_bytes = SimpleSerializer::<Vec<u8>>::serialize(&map).unwrap();
let mut deserializer = SimpleDeserializer::new(&serialized_bytes);
assert_eq!(deserializer.decode_u32().unwrap(), 4);
assert_eq!(deserializer.decode_bytes().unwrap(), key1);
assert_eq!(deserializer.decode_bytes().unwrap(), value);
assert_eq!(deserializer.decode_bytes().unwrap(), key3);
assert_eq!(deserializer.decode_bytes().unwrap(), value);
assert_eq!(deserializer.decode_bytes().unwrap(), key4);
assert_eq!(deserializer.decode_bytes().unwrap(), value);
assert_eq!(deserializer.decode_bytes().unwrap(), key2);
assert_eq!(deserializer.decode_bytes().unwrap(), value);
}
#[test]
fn test_serialization_optional() {
let bar1: Option<u32> = Some(42);
test_helper::assert_canonical_encode_decode(&bar1);
let bar2: Option<u32> = None;
test_helper::assert_canonical_encode_decode(&bar2);
}
#[test]
fn test_serialization_failure_cases() {
let bar = Bar {
a: 100,
b: vec![0; i32::max_value() as usize + 1],
c: Addr::new([0u8; 32]),
d: 222,
};
let mut serializer = SimpleSerializer::<Vec<u8>>::new();
assert!(bar.serialize(&mut serializer).is_err());
}
#[test]
fn test_deserialization_failure_cases() {
let bytes_len_2 = vec![0; 2];
let mut deserializer = SimpleDeserializer::new(&bytes_len_2);
assert!(deserializer.clone().decode_u64().is_err());
assert!(deserializer.clone().decode_bytes().is_err());
assert!(deserializer.clone().decode_struct::<Foo>().is_err());
assert!(Foo::deserialize(&mut deserializer.clone()).is_err());
let mut long_bytes = Vec::new();
long_bytes
.write_u32::<Endianness>(ARRAY_MAX_LENGTH as u32 + 1)
.unwrap();
deserializer = SimpleDeserializer::new(&long_bytes);
assert!(deserializer.clone().decode_bytes().is_err());
let mut bytes_len_10 = Vec::new();
bytes_len_10.write_u32::<Endianness>(32).unwrap();
deserializer = SimpleDeserializer::new(&bytes_len_10);
assert!(deserializer.clone().decode_bytes().is_err());
let mut some_bytes = Vec::new();
some_bytes.write_u64::<Endianness>(10).unwrap();
some_bytes.write_u32::<Endianness>(50).unwrap();
deserializer = SimpleDeserializer::new(&some_bytes);
assert!(deserializer.clone().decode_struct::<Foo>().is_err());
let mut evil_bytes = Vec::new();
evil_bytes.write_u32::<Endianness>(500).unwrap();
evil_bytes.resize_with(4 + 499, Default::default);
deserializer = SimpleDeserializer::new(&evil_bytes);
assert!(deserializer.clone().decode_bytes().is_err());
let mut bool_bytes = Vec::new();
bool_bytes.write_u8(2).unwrap();
deserializer = SimpleDeserializer::new(&bool_bytes);
assert!(deserializer.clone().decode_bool().is_err());
}