use decoder::{decode, MAX_ARRAY_SIZE}; use std::collections::BTreeMap; use {CborError, CborType}; // First test all the basic types fn test_decoder(bytes: Vec, expected: CborType) { let result = decode(&bytes); assert!(result.is_ok()); assert_eq!(result.unwrap(), expected); } fn test_decoder_error(bytes: Vec, expected_error: CborError) { let result = decode(&bytes); assert!(result.is_err()); assert_eq!(result.unwrap_err(), expected_error); } fn test_integer(bytes: Vec, expected: u64) { let decoded = decode(&bytes).unwrap(); match decoded { CborType::Integer(val) => assert_eq!(val, expected), _ => assert_eq!(1, 0), } } fn test_integer_all(bytes: Vec, expected_value: u64) { let expected = CborType::Integer(expected_value); test_decoder(bytes.clone(), expected); test_integer(bytes, expected_value); } #[test] fn test_integer_objects() { let bytes: Vec = vec![0x00]; test_integer_all(bytes, 0); let bytes = vec![0x01]; test_integer_all(bytes, 1); let bytes = vec![0x0A]; test_integer_all(bytes, 10); let bytes = vec![0x17]; test_integer_all(bytes, 23); let bytes = vec![0x18, 0x18]; test_integer_all(bytes, 24); let bytes = vec![0x18, 0x19]; test_integer_all(bytes, 25); let bytes = vec![0x18, 0x64]; test_integer_all(bytes, 100); let bytes = vec![0x19, 0x03, 0xe8]; test_integer_all(bytes, 1000); let bytes = vec![0x1a, 0x00, 0x0f, 0x42, 0x40]; test_integer_all(bytes, 1000000); let bytes = vec![0x1b, 0x00, 0x00, 0x00, 0xe8, 0xd4, 0xa5, 0x10, 0x00]; test_integer_all(bytes, 1000000000000); let bytes = vec![0x1b, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff]; test_integer_all(bytes, 18446744073709551615); } #[cfg(test)] fn test_tag(bytes: Vec, expected_tag: u64, expected_value: CborType) { let decoded = decode(&bytes).unwrap(); match decoded { CborType::Tag(tag, value) => { assert_eq!(expected_tag, tag); assert_eq!(expected_value, *value); } _ => assert_eq!(1, 0), } } #[test] fn test_tagged_objects() { let bytes: Vec = vec![0xD2, 0x02]; let expected_tag_value = 0x12; let expected_value = CborType::Integer(2); let expected = CborType::Tag(expected_tag_value, Box::new(expected_value.clone())); test_decoder(bytes.clone(), expected); test_tag(bytes, expected_tag_value, expected_value); } #[test] #[cfg_attr(rustfmt, rustfmt_skip)] fn test_arrays() { // [] let bytes: Vec = vec![0x80]; let expected = CborType::Array(vec![]); test_decoder(bytes, expected); // [1, 2, 3] let bytes: Vec = vec![0x83, 0x01, 0x02, 0x03]; let tmp = vec![ CborType::Integer(1), CborType::Integer(2), CborType::Integer(3), ]; let expected = CborType::Array(tmp); test_decoder(bytes, expected); // [1, [2, 3], [4, 5]] let bytes: Vec = vec![0x83, 0x01, 0x82, 0x02, 0x03, 0x82, 0x04, 0x05]; let tmp1 = vec![CborType::Integer(2), CborType::Integer(3)]; let tmp2 = vec![CborType::Integer(4), CborType::Integer(5)]; let tmp = vec![ CborType::Integer(1), CborType::Array(tmp1), CborType::Array(tmp2), ]; let expected = CborType::Array(tmp); test_decoder(bytes, expected); // [1, [[[[1]]]], [1]] let bytes: Vec = vec![0x83, 0x01, 0x81, 0x81, 0x81, 0x81, 0x01, 0x81, 0x02]; let tmp = vec![ CborType::Integer(1), CborType::Array(vec![ CborType::Array(vec![ CborType::Array(vec![ CborType::Array(vec![ CborType::Integer(1)])])])]), CborType::Array(vec![CborType::Integer(2)]), ]; let expected = CborType::Array(tmp); test_decoder(bytes, expected); let bytes: Vec = vec![0x98, 0x1A, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, 0x18, 0x18, 0x18, 0x19, 0x82, 0x81, 0x81, 0x81, 0x05, 0x81, 0x1A, 0x49, 0x96, 0x02, 0xD2]; // [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, // 21, 22, 23, 24, 25, [[[[5]]], [1234567890]]] let tmp = vec![ CborType::Integer(1), CborType::Integer(2), CborType::Integer(3), CborType::Integer(4), CborType::Integer(5), CborType::Integer(6), CborType::Integer(7), CborType::Integer(8), CborType::Integer(9), CborType::Integer(10), CborType::Integer(11), CborType::Integer(12), CborType::Integer(13), CborType::Integer(14), CborType::Integer(15), CborType::Integer(16), CborType::Integer(17), CborType::Integer(18), CborType::Integer(19), CborType::Integer(20), CborType::Integer(21), CborType::Integer(22), CborType::Integer(23), CborType::Integer(24), CborType::Integer(25), CborType::Array(vec![ CborType::Array(vec![ CborType::Array(vec![ CborType::Array(vec![ CborType::Integer(5)])])]), CborType::Array(vec![CborType::Integer(1234567890)])]) ]; let expected = CborType::Array(tmp); test_decoder(bytes, expected); } #[test] fn test_signed_integer() { let bytes: Vec = vec![0x20]; let expected = CborType::SignedInteger(-1); test_decoder(bytes, expected); let bytes = vec![0x29]; let expected = CborType::SignedInteger(-10); test_decoder(bytes, expected); let bytes = vec![0x38, 0x63]; let expected = CborType::SignedInteger(-100); test_decoder(bytes, expected); let bytes = vec![0x39, 0x03, 0xe7]; let expected = CborType::SignedInteger(-1000); test_decoder(bytes, expected); let bytes = vec![0x39, 0x27, 0x0F]; let expected = CborType::SignedInteger(-10000); test_decoder(bytes, expected); let bytes = vec![0x3A, 0x00, 0x01, 0x86, 0x9F]; let expected = CborType::SignedInteger(-100000); test_decoder(bytes, expected); let bytes = vec![0x3B, 0x00, 0x00, 0x00, 0xE8, 0xD4, 0xA5, 0x0F, 0xFF]; let expected = CborType::SignedInteger(-1000000000000); test_decoder(bytes, expected); } #[test] fn test_byte_strings() { let bytes: Vec = vec![0x40]; let expected = CborType::Bytes(vec![]); test_decoder(bytes, expected); // 01020304 let bytes: Vec = vec![0x44, 0x01, 0x02, 0x03, 0x04]; let expected = CborType::Bytes(vec![0x01, 0x02, 0x03, 0x04]); test_decoder(bytes, expected); // 0102030405060708090A0B0C0D0E0F10203040506070 let bytes: Vec = vec![ 0x56, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, 0x10, 0x20, 0x30, 0x40, 0x50, 0x60, 0x70, ]; let expected = CborType::Bytes(vec![ 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, 0x10, 0x20, 0x30, 0x40, 0x50, 0x60, 0x70, ]); test_decoder(bytes, expected); let bytes: Vec = vec![ 0x59, 0x01, 0x0E, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, ]; let expected = CborType::Bytes(vec![ 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, ]); test_decoder(bytes, expected); } #[test] fn test_maps() { // {} let bytes: Vec = vec![0xa0]; let expected: BTreeMap = BTreeMap::new(); test_decoder(bytes, CborType::Map(expected)); // {1: 2, 3: 4} let bytes: Vec = vec![0xa2, 0x01, 0x02, 0x03, 0x04]; let mut expected: BTreeMap = BTreeMap::new(); expected.insert(CborType::Integer(1), CborType::Integer(2)); expected.insert(CborType::Integer(3), CborType::Integer(4)); test_decoder(bytes, CborType::Map(expected)); // TODO: strings aren't properly supported as keys yet. // {"a": 1, "b": [2, 3]} // let bytes: Vec = vec![0xa2, 0x61, 0x61, 0x01, 0x61, 0x62, 0x82, 0x02, 0x03]; // let expected = // CborType::Map(vec![ // CborMap{key: CborType::Integer(1), value: CborType::Integer(2)}, // CborMap{key: CborType::Integer(3), value: CborType::Integer(4)}]); // test_decoder(bytes, expected); // let bytes: Vec = vec![0x82, 0x61, 0x61, 0xa1, 0x61, 0x62, 0x61, 0x63]; // test_decoder(bytes, "[a, {b: c}]"); // let bytes: Vec = vec![0xa5, 0x61, 0x61, 0x61, 0x41, 0x61, 0x62, 0x61, // 0x42, 0x61, 0x63, 0x61, 0x43, 0x61, 0x64, 0x61, // 0x44, 0x61, 0x65, 0x61, 0x45]; // test_decoder(bytes, "{a: A, b: B, c: C, d: D, e: E}"); } #[test] fn test_map_duplicate_keys() { let bytes: Vec = vec![0xa4, 0x01, 0x02, 0x02, 0x03, 0x01, 0x03, 0x04, 0x04]; test_decoder_error(bytes, CborError::DuplicateMapKey); } #[test] fn test_tag_with_no_value() { let bytes: Vec = vec![0xc0]; test_decoder_error(bytes, CborError::TruncatedInput); } #[test] fn test_truncated_int() { let bytes: Vec = vec![0x19, 0x03]; test_decoder_error(bytes, CborError::TruncatedInput); } #[test] fn test_truncated_array() { let bytes: Vec = vec![0x83, 0x01, 0x02]; test_decoder_error(bytes, CborError::TruncatedInput); } #[test] fn test_truncated_map() { let bytes: Vec = vec![0xa2, 0x01, 0x02, 0x00]; test_decoder_error(bytes, CborError::TruncatedInput); } #[test] fn test_malformed_integer() { let bytes: Vec = vec![0x1c]; test_decoder_error(bytes, CborError::MalformedInput); } #[test] fn test_signed_integer_too_large() { let bytes = vec![0x3b, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff]; test_decoder_error(bytes, CborError::InputValueOutOfRange); } #[test] fn test_null() { let bytes = vec![0xf6]; test_decoder(bytes, CborType::Null); } #[test] fn test_null_in_array() { let bytes = vec![0x82, 0xf6, 0xf6]; test_decoder(bytes, CborType::Array(vec![CborType::Null, CborType::Null])); } #[test] fn test_major_type_7() { for i in 0..0x20 { if i != 22 { let bytes = vec![0xe0 | i]; test_decoder_error(bytes, CborError::UnsupportedType); } } } #[test] fn test_large_input() { let array = vec![0xFF; MAX_ARRAY_SIZE]; let expected = CborType::Bytes(array.clone()); let mut bytes = vec![0x5A, 0x08, 0x00, 0x00, 0x00]; bytes.extend_from_slice(&array); test_decoder(bytes, expected); } #[test] fn test_too_large_input() { let array = vec![0xFF; MAX_ARRAY_SIZE + 1]; let mut bytes = vec![0x5A, 0x08, 0x00, 0x00, 0x01]; bytes.extend_from_slice(&array); test_decoder_error(bytes, CborError::InputTooLarge); } // We currently don't support CBOR strings (issue #39). #[test] fn test_invalid_input() { let bytes = vec![0x60]; test_decoder_error(bytes, CborError::UnsupportedType); } #[test] fn test_avoid_stack_exhaustion_with_arrays() { let mut bytes: Vec = Vec::new(); // Create a payload representing Array(Array(Array(Array(...(Array(0)))))) // If the implementation is not careful, this will exhaust the stack. for _ in 1..10000 { bytes.push(0b1000_0001); } bytes.push(0); test_decoder_error(bytes, CborError::MalformedInput); } #[test] fn test_avoid_stack_exhaustion_with_maps_1() { let mut bytes: Vec = Vec::new(); // Create a payload representing Map(0: Map(0: Map(0: Map(...Map())))) // If the implementation is not careful, this will exhaust the stack. for _ in 1..10000 { bytes.push(0b1010_0001); bytes.push(0); } bytes.push(0b1010_0000); test_decoder_error(bytes, CborError::MalformedInput); } #[test] fn test_avoid_stack_exhaustion_with_maps_2() { let mut bytes: Vec = Vec::new(); // Create a payload representing Map(Map(Map(...(Map(): 0): 0): 0): 0) // If the implementation is not careful, this will exhaust the stack. for _ in 1..10000 { bytes.push(0b1010_0001); } bytes.push(0b1010_0000); for _ in 1..9999 { bytes.push(0); } test_decoder_error(bytes, CborError::MalformedInput); } #[test] fn test_avoid_stack_exhaustion_with_tags() { let mut bytes: Vec = Vec::new(); // Create a payload representing Tag(6: Tag(6: Tag(6: Tag(...Tag(0))))) // If the implementation is not careful, this will exhaust the stack. for _ in 1..10000 { bytes.push(0b1100_0110); } bytes.push(0); test_decoder_error(bytes, CborError::MalformedInput); }