Files
OpenSK/libraries/cbor/src/reader.rs
Jean-Michel Picod f91d2fd3db Initial commit
2020-01-30 11:47:29 +01:00

812 lines
27 KiB
Rust

// Copyright 2019 Google LLC
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
use super::values::{Constants, KeyType, SimpleValue, Value};
use alloc::collections::BTreeMap;
use alloc::str;
use alloc::vec::Vec;
#[derive(Debug, PartialEq)]
pub enum DecoderError {
UnsupportedMajorType,
UnknownAdditionalInfo,
IncompleteCborData,
IncorrectMapKeyType,
TooMuchNesting,
InvalidUtf8,
ExtranousData,
OutOfOrderKey,
NonMinimalCborEncoding,
UnsupportedSimpleValue,
UnsupportedFloatingPointValue,
OutOfRangeIntegerValue,
}
pub fn read(encoded_cbor: &[u8]) -> Result<Value, DecoderError> {
let mut reader = Reader::new(encoded_cbor);
let value = reader.decode_complete_data_item(Reader::MAX_NESTING_DEPTH)?;
if !reader.remaining_cbor.is_empty() {
return Err(DecoderError::ExtranousData);
}
Ok(value)
}
struct Reader<'a> {
remaining_cbor: &'a [u8],
}
impl<'a> Reader<'a> {
const MAX_NESTING_DEPTH: i8 = 4;
pub fn new(cbor: &'a [u8]) -> Reader<'a> {
Reader {
remaining_cbor: cbor,
}
}
pub fn decode_complete_data_item(
&mut self,
remaining_depth: i8,
) -> Result<Value, DecoderError> {
if remaining_depth < 0 {
return Err(DecoderError::TooMuchNesting);
}
match self.read_bytes(1) {
Some([first_byte]) => {
// Unsigned byte means logical shift, so only zeros get shifted in.
let major_type_value = first_byte >> Constants::MAJOR_TYPE_BIT_SHIFT;
let additional_info = first_byte & Constants::ADDITIONAL_INFORMATION_MASK;
let size_result = self.read_variadic_length_integer(additional_info);
match size_result {
Ok(size_value) => match major_type_value {
0 => self.decode_value_to_unsigned(size_value),
1 => self.decode_value_to_negative(size_value),
2 => self.read_byte_string_content(size_value),
3 => self.read_text_string_content(size_value),
4 => self.read_array_content(size_value, remaining_depth),
5 => self.read_map_content(size_value, remaining_depth),
7 => self.decode_to_simple_value(size_value, additional_info),
_ => Err(DecoderError::UnsupportedMajorType),
},
Err(decode_error) => Err(decode_error),
}
}
_ => Err(DecoderError::IncompleteCborData),
}
}
fn read_bytes(&mut self, num_bytes: usize) -> Option<&[u8]> {
if num_bytes > self.remaining_cbor.len() {
None
} else {
let (left, right) = self.remaining_cbor.split_at(num_bytes);
self.remaining_cbor = right;
Some(left)
}
}
fn read_variadic_length_integer(&mut self, additional_info: u8) -> Result<u64, DecoderError> {
let additional_bytes_num = match additional_info {
0..=Constants::ADDITIONAL_INFORMATION_MAX_INT => return Ok(additional_info as u64),
Constants::ADDITIONAL_INFORMATION_1_BYTE => 1,
Constants::ADDITIONAL_INFORMATION_2_BYTES => 2,
Constants::ADDITIONAL_INFORMATION_4_BYTES => 4,
Constants::ADDITIONAL_INFORMATION_8_BYTES => 8,
_ => return Err(DecoderError::UnknownAdditionalInfo),
};
match self.read_bytes(additional_bytes_num) {
Some(bytes) => {
let mut size_value = 0u64;
for byte in bytes {
size_value <<= 8;
size_value += *byte as u64;
}
if (additional_bytes_num == 1 && size_value < 24)
|| size_value < (1u64 << (8 * (additional_bytes_num >> 1)))
{
Err(DecoderError::NonMinimalCborEncoding)
} else {
Ok(size_value)
}
}
None => Err(DecoderError::IncompleteCborData),
}
}
fn decode_value_to_unsigned(&self, size_value: u64) -> Result<Value, DecoderError> {
Ok(cbor_unsigned!(size_value))
}
fn decode_value_to_negative(&self, size_value: u64) -> Result<Value, DecoderError> {
let signed_size = size_value as i64;
if signed_size < 0 {
Err(DecoderError::OutOfRangeIntegerValue)
} else {
Ok(Value::KeyValue(KeyType::Negative(-(size_value as i64) - 1)))
}
}
fn read_byte_string_content(&mut self, size_value: u64) -> Result<Value, DecoderError> {
match self.read_bytes(size_value as usize) {
Some(bytes) => Ok(cbor_bytes_lit!(bytes)),
None => Err(DecoderError::IncompleteCborData),
}
}
fn read_text_string_content(&mut self, size_value: u64) -> Result<Value, DecoderError> {
match self.read_bytes(size_value as usize) {
Some(bytes) => match str::from_utf8(bytes) {
Ok(s) => Ok(cbor_text!(s)),
Err(_) => Err(DecoderError::InvalidUtf8),
},
None => Err(DecoderError::IncompleteCborData),
}
}
fn read_array_content(
&mut self,
size_value: u64,
remaining_depth: i8,
) -> Result<Value, DecoderError> {
// Don't set the capacity already, it is an unsanitized input.
let mut value_array = Vec::new();
for _ in 0..size_value {
value_array.push(self.decode_complete_data_item(remaining_depth - 1)?);
}
Ok(cbor_array_vec!(value_array))
}
fn read_map_content(
&mut self,
size_value: u64,
remaining_depth: i8,
) -> Result<Value, DecoderError> {
let mut value_map = BTreeMap::new();
let mut last_key_option = None;
for _ in 0..size_value {
let key_value = self.decode_complete_data_item(remaining_depth - 1)?;
if let Value::KeyValue(key) = key_value {
if let Some(last_key) = last_key_option {
if last_key >= key {
return Err(DecoderError::OutOfOrderKey);
}
}
last_key_option = Some(key.clone());
value_map.insert(key, self.decode_complete_data_item(remaining_depth - 1)?);
} else {
return Err(DecoderError::IncorrectMapKeyType);
}
}
Ok(cbor_map_btree!(value_map))
}
fn decode_to_simple_value(
&self,
size_value: u64,
additional_info: u8,
) -> Result<Value, DecoderError> {
if additional_info > Constants::ADDITIONAL_INFORMATION_MAX_INT
&& additional_info != Constants::ADDITIONAL_INFORMATION_1_BYTE
{
// TODO(kaczmarczyck) the chromium C++ reference allows equality to 24 here, why?
// Also, why not just disallow ANY additional_info != size_value?
return Err(DecoderError::UnsupportedFloatingPointValue);
}
match SimpleValue::from_integer(size_value) {
Some(simple_value) => Ok(Value::Simple(simple_value)),
None => Err(DecoderError::UnsupportedSimpleValue),
}
}
}
#[cfg(test)]
mod test {
use super::*;
#[test]
fn test_read_unsigned() {
let cases = vec![
(0, vec![0x00]),
(1, vec![0x01]),
(10, vec![0x0A]),
(23, vec![0x17]),
(24, vec![0x18, 0x18]),
(255, vec![0x18, 0xFF]),
(256, vec![0x19, 0x01, 0x00]),
(65535, vec![0x19, 0xFF, 0xFF]),
(65536, vec![0x1A, 0x00, 0x01, 0x00, 0x00]),
(0xFFFFFFFF, vec![0x1A, 0xFF, 0xFF, 0xFF, 0xFF]),
(
0x100000000,
vec![0x1B, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00],
),
(
std::i64::MAX,
vec![0x1B, 0x7F, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF],
),
];
for (unsigned, mut cbor) in cases {
assert_eq!(read(&cbor), Ok(cbor_int!(unsigned)));
cbor.push(0x01);
assert_eq!(read(&cbor), Err(DecoderError::ExtranousData));
}
}
#[test]
fn test_read_unsigned_non_minimum_byte_length() {
let encodings = vec![
// Uint 23 encoded with 1 byte.
vec![0x18, 0x17],
// Uint 255 encoded with 2 bytes.
vec![0x19, 0x00, 0xff],
// Uint 65535 encoded with 4 bytes.
vec![0x1a, 0x00, 0x00, 0xff, 0xff],
// Uint 4294967295 encoded with 8 bytes.
vec![0x1b, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff],
// When decoding byte has more than one syntax error, the first syntax
// error encountered during deserialization is returned as the error code.
vec![
0xa2, // map with non-minimally encoded key
0x17, // key 24
0x61, 0x42, // value :"B"
0x18, 0x17, // key 23 encoded with extra byte
0x61, 0x45, // value "E"
],
vec![
0xa2, // map with out of order and non-minimally encoded key
0x18, 0x17, // key 23 encoded with extra byte
0x61, 0x45, // value "E"
0x17, // key 23
0x61, 0x42, // value :"B"
],
vec![
0xa2, // map with duplicate non-minimally encoded key
0x18, 0x17, // key 23 encoded with extra byte
0x61, 0x45, // value "E"
0x18, 0x17, // key 23 encoded with extra byte
0x61, 0x42, // value :"B"
],
];
for encoding in encodings {
assert_eq!(read(&encoding), Err(DecoderError::NonMinimalCborEncoding));
}
}
#[test]
fn test_read_negative() {
let cases = vec![
(-1, vec![0x20]),
(-24, vec![0x37]),
(-25, vec![0x38, 0x18]),
(-256, vec![0x38, 0xFF]),
(-1000, vec![0x39, 0x03, 0xE7]),
(-1000000, vec![0x3A, 0x00, 0x0F, 0x42, 0x3F]),
(-4294967296, vec![0x3A, 0xFF, 0xFF, 0xFF, 0xFF]),
(
std::i64::MIN,
vec![0x3B, 0x7F, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF],
),
];
for (negative, mut cbor) in cases {
assert_eq!(read(&cbor), Ok(cbor_int!(negative)));
cbor.push(0x01);
assert_eq!(read(&cbor), Err(DecoderError::ExtranousData));
}
}
#[test]
fn test_read_byte_string() {
let cases = vec![
(Vec::new(), vec![0x40]),
(
vec![0x01, 0x02, 0x03, 0x04],
vec![0x44, 0x01, 0x02, 0x03, 0x04],
),
];
for (byte_string, mut cbor) in cases {
assert_eq!(read(&cbor), Ok(cbor_bytes!(byte_string)));
cbor.push(0x01);
assert_eq!(read(&cbor), Err(DecoderError::ExtranousData));
}
}
#[test]
fn test_read_text_string() {
let unicode_3byte = vec![0xE6, 0xB0, 0xB4];
let cases = vec![
("", vec![0x60]),
("a", vec![0x61, 0x61]),
("IETF", vec![0x64, 0x49, 0x45, 0x54, 0x46]),
("\"\\", vec![0x62, 0x22, 0x5C]),
("ü", vec![0x62, 0xC3, 0xBC]),
(
std::str::from_utf8(&unicode_3byte).unwrap(),
vec![0x63, 0xE6, 0xB0, 0xB4],
),
("𐅑", vec![0x64, 0xF0, 0x90, 0x85, 0x91]),
];
for (text_string, mut cbor) in cases {
assert_eq!(read(&cbor), Ok(cbor_text!(text_string)));
cbor.push(0x01);
assert_eq!(read(&cbor), Err(DecoderError::ExtranousData));
}
}
#[test]
fn test_read_text_string_with_nul() {
let cases = vec![
(
"string_without_nul",
vec![
0x72, 0x73, 0x74, 0x72, 0x69, 0x6E, 0x67, 0x5F, 0x77, 0x69, 0x74, 0x68, 0x6F,
0x75, 0x74, 0x5F, 0x6E, 0x75, 0x6C,
],
),
(
"nul_terminated_string\0",
vec![
0x76, 0x6E, 0x75, 0x6C, 0x5F, 0x74, 0x65, 0x72, 0x6D, 0x69, 0x6E, 0x61, 0x74,
0x65, 0x64, 0x5F, 0x73, 0x74, 0x72, 0x69, 0x6E, 0x67, 0x00,
],
),
(
"embedded\0nul",
vec![
0x6C, 0x65, 0x6D, 0x62, 0x65, 0x64, 0x64, 0x65, 0x64, 0x00, 0x6E, 0x75, 0x6C,
],
),
(
"trailing_nuls\0\0",
vec![
0x6F, 0x74, 0x72, 0x61, 0x69, 0x6C, 0x69, 0x6E, 0x67, 0x5F, 0x6E, 0x75, 0x6C,
0x73, 0x00, 0x00,
],
),
];
for (text_string, mut cbor) in cases {
assert_eq!(read(&cbor), Ok(cbor_text!(text_string)));
cbor.push(0x01);
assert_eq!(read(&cbor), Err(DecoderError::ExtranousData));
}
}
#[test]
fn test_read_text_string_with_invalid_byte_sequence_after_nul() {
assert_eq!(
read(&vec![0x63, 0x00, 0x00, 0xA6]),
Err(DecoderError::InvalidUtf8)
);
}
#[test]
fn test_read_array() {
let value_vec: Vec<_> = (1..26).collect();
let mut test_cbor = vec![
0x98, 0x19, 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,
];
assert_eq!(read(&test_cbor.clone()), Ok(cbor_array_vec!(value_vec)));
test_cbor.push(0x01);
assert_eq!(read(&test_cbor), Err(DecoderError::ExtranousData));
}
#[test]
fn test_read_map() {
let value_map = cbor_map! {
24 => "abc",
"" => ".",
"b" => "B",
"aa" => "AA",
};
let mut test_cbor = vec![
0xa4, // map with 4 key value pairs:
0x18, 0x18, // 24
0x63, 0x61, 0x62, 0x63, // "abc"
0x60, // ""
0x61, 0x2e, // "."
0x61, 0x62, // "b"
0x61, 0x42, // "B"
0x62, 0x61, 0x61, // "aa"
0x62, 0x41, 0x41, // "AA"
];
assert_eq!(read(&test_cbor), Ok(value_map));
test_cbor.push(0x01);
assert_eq!(read(&test_cbor), Err(DecoderError::ExtranousData));
}
#[test]
fn test_read_map_with_unsigned_keys() {
let value_map = cbor_map! {
1 => "a",
9 => "b",
999 => "c",
1111 => "d",
};
let mut test_cbor = vec![
0xa4, // map with 4 key value pairs:
0x01, // key : 1
0x61, 0x61, // value : "a"
0x09, // key : 9
0x61, 0x62, // value : "b"
0x19, 0x03, 0xE7, // key : 999
0x61, 0x63, // value "c"
0x19, 0x04, 0x57, // key : 1111
0x61, 0x64, // value : "d"
];
assert_eq!(read(&test_cbor), Ok(value_map));
test_cbor.push(0x01);
assert_eq!(read(&test_cbor), Err(DecoderError::ExtranousData));
}
#[test]
fn test_read_map_with_negative_keys() {
let value_map = cbor_map! {
-1 => 1,
-2 => 2,
-100 => 3,
};
let mut test_cbor = vec![
0xA3, // map with 3 key value pairs
0x20, // key : -1
0x01, // value : 1
0x21, // key : -2
0x02, // value : 2
0x38, 0x63, // key : -100
0x03, // value : 3
];
assert_eq!(read(&test_cbor), Ok(value_map));
test_cbor.push(0x01);
assert_eq!(read(&test_cbor), Err(DecoderError::ExtranousData));
}
#[test]
fn test_read_map_with_array() {
let value_map = cbor_map! {
"a" => 1,
"b" => cbor_array![2, 3],
};
let mut test_cbor = vec![
0xa2, // map of 2 pairs
0x61, 0x61, // "a"
0x01, 0x61, 0x62, // "b"
0x82, // array with 2 elements
0x02, 0x03,
];
assert_eq!(read(&test_cbor), Ok(value_map));
test_cbor.push(0x01);
assert_eq!(read(&test_cbor), Err(DecoderError::ExtranousData));
}
#[test]
fn test_read_map_with_text_string_keys() {
let value_map = cbor_map! {
"k" => "v",
"foo" => "bar",
};
let mut test_cbor = vec![
0xa2, // map of 2 pairs
0x61, b'k', // text string "k"
0x61, b'v', 0x63, b'f', b'o', b'o', // text string "foo"
0x63, b'b', b'a', b'r',
];
assert_eq!(read(&test_cbor), Ok(value_map));
test_cbor.push(0x01);
assert_eq!(read(&test_cbor), Err(DecoderError::ExtranousData));
}
#[test]
fn test_read_map_with_byte_string_keys() {
let value_map = cbor_map! {
b"k" => b"v",
b"foo" => b"bar",
};
let mut test_cbor = vec![
0xa2, // map of 2 pairs
0x41, b'k', // text string "k"
0x41, b'v', 0x43, b'f', b'o', b'o', // text string "foo"
0x43, b'b', b'a', b'r',
];
assert_eq!(read(&test_cbor), Ok(value_map));
test_cbor.push(0x01);
assert_eq!(read(&test_cbor), Err(DecoderError::ExtranousData));
}
#[test]
fn test_read_nested_map() {
let value_map = cbor_map! {
"a" => 1,
"b" => cbor_map! {
"c" => 2,
"d" => 3,
},
};
let mut test_cbor = vec![
0xa2, // map of 2 pairs
0x61, 0x61, 0x01, // "a"
0x61, 0x62, // "b"
0xa2, // map of 2 pairs
0x61, 0x63, 0x02, // "c"
0x61, 0x64, 0x03, // "d"
];
assert_eq!(read(&test_cbor), Ok(value_map));
test_cbor.push(0x01);
assert_eq!(read(&test_cbor), Err(DecoderError::ExtranousData));
}
#[test]
fn test_read_integer_out_of_range() {
let cases = vec![
// The positive case is impossible since we support u64.
// vec![0x1B, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00],
vec![0x3B, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00],
];
for cbor in cases {
assert_eq!(read(&cbor), Err(DecoderError::OutOfRangeIntegerValue));
}
}
#[test]
fn test_read_simple_value() {
let cases = vec![
(cbor_false!(), vec![0xF4]),
(cbor_true!(), vec![0xF5]),
(cbor_null!(), vec![0xF6]),
(cbor_undefined!(), vec![0xF7]),
];
for (simple, mut cbor) in cases {
assert_eq!(read(&cbor.clone()), Ok(simple));
cbor.push(0x01);
assert_eq!(read(&cbor), Err(DecoderError::ExtranousData));
}
}
#[test]
fn test_read_unsupported_floating_point_numbers() {
let cases = vec![
vec![0xF9, 0x10, 0x00],
vec![0xFA, 0x10, 0x00, 0x00, 0x00],
vec![0xFB, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00],
];
for cbor in cases {
assert_eq!(
read(&cbor),
Err(DecoderError::UnsupportedFloatingPointValue)
);
}
}
#[test]
fn test_read_incomplete_cbor_data_error() {
let cases = vec![
vec![0x19, 0x03],
vec![0x44, 0x01, 0x02, 0x03],
vec![0x65, 0x49, 0x45, 0x54, 0x46],
vec![0x82, 0x02],
vec![0xA2, 0x61, 0x61, 0x01],
vec![0x18],
vec![0x99],
vec![0xBA],
vec![0x5B],
vec![0x3B],
vec![0x99, 0x01],
vec![0xBA, 0x01, 0x02, 0x03],
vec![0x3B, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07],
];
for cbor in cases {
assert_eq!(read(&cbor), Err(DecoderError::IncompleteCborData));
}
}
#[test]
fn test_read_unsupported_map_key_format_error() {
// While CBOR can handle all types as map keys, we only support a subset.
let bad_map_cbor = vec![
0xa2, // map of 2 pairs
0x82, 0x01, 0x02, // invalid key : [1, 2]
0x02, // value : 2
0x61, 0x64, // key : "d"
0x03, // value : 3
];
assert_eq!(read(&bad_map_cbor), Err(DecoderError::IncorrectMapKeyType));
}
#[test]
fn test_read_unknown_additional_info_error() {
let cases = vec![
vec![0x7C, 0x49, 0x45, 0x54, 0x46],
vec![0x7D, 0x22, 0x5C],
vec![0x7E, 0xC3, 0xBC],
vec![0x7F, 0xE6, 0xB0, 0xB4],
vec![0xFC],
vec![0xFD],
vec![0xFE],
vec![0xFF],
];
for cbor in cases {
assert_eq!(read(&cbor), Err(DecoderError::UnknownAdditionalInfo));
}
}
#[test]
fn test_read_too_much_nesting_error() {
let cases = vec![
vec![0x18, 0x64],
vec![0x44, 0x01, 0x02, 0x03, 0x04],
vec![0x64, 0x49, 0x45, 0x54, 0x46],
vec![0x80],
vec![0xA0],
];
for cbor in cases {
let mut reader = Reader::new(&cbor);
assert!(reader.decode_complete_data_item(0).is_ok());
}
let map_cbor = vec![
0xa2, // map of 2 pairs
0x61, 0x61, // "a"
0x01, 0x61, 0x62, // "b"
0x82, // array with 2 elements
0x02, 0x03,
];
let mut reader = Reader::new(&map_cbor);
assert_eq!(
reader.decode_complete_data_item(1),
Err(DecoderError::TooMuchNesting)
);
reader = Reader::new(&map_cbor);
assert!(reader.decode_complete_data_item(2).is_ok());
}
#[test]
fn test_read_out_of_order_key_error() {
let cases = vec![
vec![
0xa2, // map with 2 keys with same major type and length
0x61, 0x62, // key "b"
0x61, 0x42, // value "B"
0x61, 0x61, // key "a" (out of order byte-wise lexically)
0x61, 0x45, // value "E"
],
vec![
0xa2, // map with 2 keys with different major type
0x61, 0x62, // key "b"
0x02, // value 2
// key 1000 (out of order since lower major type sorts first)
0x19, 0x03, 0xe8, 0x61, 0x61, // value a
],
vec![
0xa2, // map with 2 keys with same major type
0x19, 0x03, 0xe8, // key 1000 (out of order due to longer length)
0x61, 0x61, //value "a"
0x0a, // key 10
0x61, 0x62, // value "b"
],
vec![
0xa2, // map with 2 text string keys
0x62, b'a', b'a', // key text string "aa"
// (out of order due to longer length)
0x02, 0x61, b'b', // key "b"
0x01,
],
vec![
0xa2, // map with 2 byte string keys
0x42, b'x', b'x', // key byte string "xx"
// (out of order due to longer length)
0x02, 0x41, b'y', // key byte string "y"
0x01,
],
];
for cbor in cases {
assert_eq!(read(&cbor), Err(DecoderError::OutOfOrderKey));
}
}
#[test]
fn test_read_duplicate_key_error() {
let map_with_duplicate_key = vec![
0xa6, // map of 6 pairs:
0x60, // ""
0x61, 0x2e, // "."
0x61, 0x62, // "b"
0x61, 0x42, // "B"
0x61, 0x62, // "b" (Duplicate key)
0x61, 0x43, // "C"
0x61, 0x64, // "d"
0x61, 0x44, // "D"
0x61, 0x65, // "e"
0x61, 0x44, // "D"
0x62, 0x61, 0x61, // "aa"
0x62, 0x41, 0x41, // "AA"
];
assert_eq!(
read(&map_with_duplicate_key),
Err(DecoderError::OutOfOrderKey)
);
}
#[test]
fn test_read_incorrect_string_encoding_error() {
let cases = vec![
vec![0x63, 0xED, 0x9F, 0xBF],
vec![0x63, 0xEE, 0x80, 0x80],
vec![0x63, 0xEF, 0xBF, 0xBD],
];
for cbor in cases {
assert!(read(&cbor).is_ok());
}
let impossible_utf_byte = vec![0x64, 0xFE, 0xFE, 0xFF, 0xFF];
assert_eq!(read(&impossible_utf_byte), Err(DecoderError::InvalidUtf8));
}
#[test]
fn test_read_extranous_cbor_data_error() {
let cases = vec![
vec![0x19, 0x03, 0x05, 0x00],
vec![0x44, 0x01, 0x02, 0x03, 0x04, 0x00],
vec![0x64, 0x49, 0x45, 0x54, 0x46, 0x00],
vec![0x82, 0x01, 0x02, 0x00],
vec![0xa1, 0x61, 0x63, 0x02, 0x61, 0x64, 0x03],
];
for cbor in cases {
assert_eq!(read(&cbor), Err(DecoderError::ExtranousData));
}
}
#[test]
fn test_read_unsupported_simple_type() {
let cases = vec![
vec![0xE0],
vec![0xF3],
vec![0xF8, 0x18],
vec![0xF8, 0x1C],
vec![0xF8, 0x1D],
vec![0xF8, 0x1E],
vec![0xF8, 0x1F],
vec![0xF8, 0x20],
vec![0xF8, 0xFF],
];
for cbor in cases {
assert_eq!(read(&cbor), Err(DecoderError::UnsupportedSimpleValue));
}
}
#[test]
fn test_read_super_long_content_dont_crash() {
let cases = vec![
vec![0x9B, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF],
vec![0xBB, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF],
];
for cbor in cases {
assert_eq!(read(&cbor), Err(DecoderError::IncompleteCborData));
}
}
#[test]
fn test_read_unsupported_major_type() {
let cases = vec![
vec![0xC0],
vec![0xD8, 0xFF],
// multi-dimensional array example using tags
vec![
0x82, 0x82, 0x02, 0x03, 0xd8, 0x41, 0x4a, 0x00, 0x00, 0x00, 0x01, 0x00, 0x02, 0x00,
0x03, 0x00, 0x04, 0x00, 0x05,
],
];
for cbor in cases {
assert_eq!(read(&cbor), Err(DecoderError::UnsupportedMajorType));
}
}
}