1use std::collections::BTreeMap;
2use std::io::{Cursor, Read, Seek, SeekFrom};
3use {CborError, CborType};
4
5pub const MAX_ARRAY_SIZE: usize = 134_217_728;
9
10const MAX_NESTED_DEPTH: usize = 256;
12
13#[derive(Debug)]
15struct DecoderCursor<'a> {
16 cursor: Cursor<&'a [u8]>,
17 depth: usize,
18}
19
20const INITIAL_VALUE_MASK: u64 = 0b0001_1111;
22
23impl<'a> DecoderCursor<'a> {
24 fn read_bytes(&mut self, len: usize) -> Result<Vec<u8>, CborError> {
26 if len > MAX_ARRAY_SIZE {
27 return Err(CborError::InputTooLarge);
28 }
29 let mut buf: Vec<u8> = vec![0; len];
30 if self.cursor.read_exact(&mut buf).is_err() {
31 Err(CborError::TruncatedInput)
32 } else {
33 Ok(buf)
34 }
35 }
36
37 fn read_uint_from_bytes(&mut self, num: usize) -> Result<u64, CborError> {
39 let x = self.read_bytes(num)?;
40 let mut result: u64 = 0;
41 for i in (0..num).rev() {
42 result += u64::from(x[num - 1 - i]) << (i * 8);
43 }
44 Ok(result)
45 }
46
47 fn read_int(&mut self) -> Result<u64, CborError> {
49 let first_value = self.read_uint_from_bytes(1)? & INITIAL_VALUE_MASK;
50 match first_value {
51 0..=23 => Ok(first_value),
52 24 => self.read_uint_from_bytes(1),
53 25 => self.read_uint_from_bytes(2),
54 26 => self.read_uint_from_bytes(4),
55 27 => self.read_uint_from_bytes(8),
56 _ => Err(CborError::MalformedInput),
57 }
58 }
59
60 fn read_negative_int(&mut self) -> Result<CborType, CborError> {
61 let uint = self.read_int()?;
62 if uint > i64::max_value() as u64 {
63 return Err(CborError::InputValueOutOfRange);
64 }
65 let result: i64 = -1 - uint as i64;
66 Ok(CborType::SignedInteger(result))
67 }
68
69 fn read_array(&mut self) -> Result<CborType, CborError> {
71 let mut array: Vec<CborType> = Vec::new();
73 let num_items = self.read_int()?;
75 for _ in 0..num_items {
77 let new_item = self.decode_item()?;
78 array.push(new_item);
79 }
80 Ok(CborType::Array(array))
81 }
82
83 fn read_byte_string(&mut self) -> Result<CborType, CborError> {
85 let length = self.read_int()?;
86 if length > MAX_ARRAY_SIZE as u64 {
87 return Err(CborError::InputTooLarge);
88 }
89 let byte_string = self.read_bytes(length as usize)?;
90 Ok(CborType::Bytes(byte_string))
91 }
92
93 fn read_map(&mut self) -> Result<CborType, CborError> {
95 let num_items = self.read_int()?;
96 let mut map: BTreeMap<CborType, CborType> = BTreeMap::new();
98 for _ in 0..num_items {
100 let key_val = self.decode_item()?;
101 let item_value = self.decode_item()?;
102 if map.insert(key_val, item_value).is_some() {
103 return Err(CborError::DuplicateMapKey);
104 }
105 }
106 Ok(CborType::Map(map))
107 }
108
109 fn read_null(&mut self) -> Result<CborType, CborError> {
110 let value = self.read_uint_from_bytes(1)? & INITIAL_VALUE_MASK;
111 if value != 22 {
112 return Err(CborError::UnsupportedType);
113 }
114 Ok(CborType::Null)
115 }
116
117 fn peek_byte(&mut self) -> Result<u8, CborError> {
119 let x = self.read_bytes(1)?;
120 if self.cursor.seek(SeekFrom::Current(-1)).is_err() {
121 return Err(CborError::LibraryError);
122 };
123 Ok(x[0])
124 }
125
126 pub fn decode_item(&mut self) -> Result<CborType, CborError> {
128 if self.depth > MAX_NESTED_DEPTH {
129 return Err(CborError::MalformedInput);
130 }
131 self.depth += 1;
132 let major_type = self.peek_byte()? >> 5;
133 let result = match major_type {
134 0 => {
135 let value = self.read_int()?;
136 Ok(CborType::Integer(value))
137 }
138 1 => self.read_negative_int(),
139 2 => self.read_byte_string(),
140 4 => self.read_array(),
141 5 => self.read_map(),
142 6 => {
143 let tag = self.read_int()?;
144 let item = self.decode_item()?;
145 Ok(CborType::Tag(tag, Box::new(item)))
146 }
147 7 => self.read_null(),
148 _ => Err(CborError::UnsupportedType),
149 };
150 self.depth -= 1;
151 result
152 }
153}
154
155pub fn decode(bytes: &[u8]) -> Result<CborType, CborError> {
159 let mut decoder_cursor = DecoderCursor {
160 cursor: Cursor::new(bytes),
161 depth: 0,
162 };
163 decoder_cursor.decode_item()
164 }