/src/OpenSK/libraries/cbor/src/reader.rs
Line | Count | Source |
1 | | // Copyright 2019 Google LLC |
2 | | // |
3 | | // Licensed under the Apache License, Version 2.0 (the "License"); |
4 | | // you may not use this file except in compliance with the License. |
5 | | // You may obtain a copy of the License at |
6 | | // |
7 | | // http://www.apache.org/licenses/LICENSE-2.0 |
8 | | // |
9 | | // Unless required by applicable law or agreed to in writing, software |
10 | | // distributed under the License is distributed on an "AS IS" BASIS, |
11 | | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
12 | | // See the License for the specific language governing permissions and |
13 | | // limitations under the License. |
14 | | |
15 | | //! Functionality for deserializing CBOR data into values. |
16 | | |
17 | | use super::values::{Constants, SimpleValue, Value, ValueImpl}; |
18 | | use crate::{ |
19 | | cbor_array_vec, cbor_bytes_lit, cbor_map_collection, cbor_tagged, cbor_text, cbor_unsigned, |
20 | | }; |
21 | | use alloc::str; |
22 | | use alloc::vec::Vec; |
23 | | |
24 | | /// Possible errors from a deserialization operation. |
25 | | #[derive(Debug, PartialEq)] |
26 | | pub enum DecoderError { |
27 | | UnsupportedMajorType, |
28 | | UnknownAdditionalInfo, |
29 | | IncompleteCborData, |
30 | | TooMuchNesting, |
31 | | InvalidUtf8, |
32 | | ExtraneousData, |
33 | | OutOfOrderKey, |
34 | | NonMinimalCborEncoding, |
35 | | UnsupportedSimpleValue, |
36 | | UnsupportedFloatingPointValue, |
37 | | OutOfRangeIntegerValue, |
38 | | } |
39 | | |
40 | | /// Deserialize CBOR binary data to produce a single [`Value`], expecting that there is no additional data. |
41 | | /// Maximum level of nesting supported is 127; more deeply nested structures will fail with |
42 | | /// [`DecoderError::TooMuchNesting`]. |
43 | 3.32k | pub fn read(encoded_cbor: &[u8]) -> Result<Value, DecoderError> { |
44 | 3.32k | read_nested(encoded_cbor, Some(i8::MAX)) |
45 | 3.32k | } |
46 | | |
47 | | /// Deserialize CBOR binary data to produce a single [`Value`], expecting that there is no additional data. If |
48 | | /// `max_nest` is `Some(max)`, then nested structures are only supported up to the given limit (returning |
49 | | /// [`DecoderError::TooMuchNesting`] if the limit is hit). |
50 | 26.0k | pub fn read_nested(encoded_cbor: &[u8], max_nest: Option<i8>) -> Result<Value, DecoderError> { |
51 | 26.0k | let mut reader = Reader::new(encoded_cbor); |
52 | 26.0k | let value = reader.decode_complete_data_item(max_nest)?; |
53 | 19.5k | if !reader.remaining_cbor.is_empty() { |
54 | 341 | return Err(DecoderError::ExtraneousData); |
55 | 19.1k | } |
56 | 19.1k | Ok(value) |
57 | 26.0k | } |
58 | | |
59 | | struct Reader<'a> { |
60 | | remaining_cbor: &'a [u8], |
61 | | } |
62 | | |
63 | | impl<'a> Reader<'a> { |
64 | 26.0k | pub fn new(cbor: &'a [u8]) -> Reader<'a> { |
65 | 26.0k | Reader { |
66 | 26.0k | remaining_cbor: cbor, |
67 | 26.0k | } |
68 | 26.0k | } |
69 | | |
70 | 18.3M | pub fn decode_complete_data_item( |
71 | 18.3M | &mut self, |
72 | 18.3M | remaining_depth: Option<i8>, |
73 | 18.3M | ) -> Result<Value, DecoderError> { |
74 | 18.3M | if remaining_depth.is_some_and(|d| d < 0) { |
75 | 38 | return Err(DecoderError::TooMuchNesting); |
76 | 18.3M | } |
77 | | |
78 | 18.3M | match self.read_bytes(1) { |
79 | 18.3M | Some([first_byte]) => { |
80 | | // Unsigned byte means logical shift, so only zeros get shifted in. |
81 | 18.3M | let major_type_value = first_byte >> Constants::MAJOR_TYPE_BIT_SHIFT; |
82 | 18.3M | let additional_info = first_byte & Constants::ADDITIONAL_INFORMATION_MASK; |
83 | 18.3M | let size_value = self.read_variadic_length_integer(additional_info)?; |
84 | 18.3M | match major_type_value { |
85 | 9.46M | 0 => self.decode_value_to_unsigned(size_value), |
86 | 3.85M | 1 => self.decode_value_to_negative(size_value), |
87 | 931k | 2 => self.read_byte_string_content(size_value), |
88 | 150k | 3 => self.read_text_string_content(size_value), |
89 | 2.04M | 4 => self.read_array_content(size_value, remaining_depth), |
90 | 407k | 5 => self.read_map_content(size_value, remaining_depth), |
91 | 1.48M | 6 => self.read_tagged_content(size_value, remaining_depth), |
92 | 44.2k | 7 => self.decode_to_simple_value(size_value, additional_info), |
93 | 0 | _ => Err(DecoderError::UnsupportedMajorType), |
94 | | } |
95 | | } |
96 | 3.57k | _ => Err(DecoderError::IncompleteCborData), |
97 | | } |
98 | 18.3M | } |
99 | | |
100 | 20.7M | fn read_bytes(&mut self, num_bytes: usize) -> Option<&[u8]> { |
101 | 20.7M | if num_bytes > self.remaining_cbor.len() { |
102 | 4.77k | None |
103 | | } else { |
104 | 20.7M | let (left, right) = self.remaining_cbor.split_at(num_bytes); |
105 | 20.7M | self.remaining_cbor = right; |
106 | 20.7M | Some(left) |
107 | | } |
108 | 20.7M | } |
109 | | |
110 | 18.3M | fn read_variadic_length_integer(&mut self, additional_info: u8) -> Result<u64, DecoderError> { |
111 | 18.3M | let additional_bytes_num = match additional_info { |
112 | 18.3M | 0..=Constants::ADDITIONAL_INFORMATION_MAX_INT => return Ok(additional_info as u64), |
113 | 849k | Constants::ADDITIONAL_INFORMATION_1_BYTE => 1, |
114 | 181k | Constants::ADDITIONAL_INFORMATION_2_BYTES => 2, |
115 | 183k | Constants::ADDITIONAL_INFORMATION_4_BYTES => 4, |
116 | 70.3k | Constants::ADDITIONAL_INFORMATION_8_BYTES => 8, |
117 | 82 | _ => return Err(DecoderError::UnknownAdditionalInfo), |
118 | | }; |
119 | 1.28M | match self.read_bytes(additional_bytes_num) { |
120 | 1.28M | Some(bytes) => { |
121 | 1.28M | let mut size_value = 0u64; |
122 | 3.79M | for byte in bytes { |
123 | 2.51M | size_value <<= 8; |
124 | 2.51M | size_value += *byte as u64; |
125 | 2.51M | } |
126 | 1.28M | if (additional_bytes_num == 1 && size_value < 24) |
127 | 1.28M | || size_value < (1u64 << (8 * (additional_bytes_num >> 1))) |
128 | | { |
129 | 45 | Err(DecoderError::NonMinimalCborEncoding) |
130 | | } else { |
131 | 1.28M | Ok(size_value) |
132 | | } |
133 | | } |
134 | 134 | None => Err(DecoderError::IncompleteCborData), |
135 | | } |
136 | 18.3M | } |
137 | | |
138 | 9.46M | fn decode_value_to_unsigned(&self, size_value: u64) -> Result<Value, DecoderError> { |
139 | 9.46M | Ok(cbor_unsigned!(size_value)) |
140 | 9.46M | } |
141 | | |
142 | 3.85M | fn decode_value_to_negative(&self, size_value: u64) -> Result<Value, DecoderError> { |
143 | 3.85M | let signed_size = size_value as i64; |
144 | 3.85M | if signed_size < 0 { |
145 | 362 | Err(DecoderError::OutOfRangeIntegerValue) |
146 | | } else { |
147 | 3.85M | Ok(Value(ValueImpl::Negative(-(size_value as i64) - 1))) |
148 | | } |
149 | 3.85M | } |
150 | | |
151 | 931k | fn read_byte_string_content(&mut self, size_value: u64) -> Result<Value, DecoderError> { |
152 | 931k | match self.read_bytes(size_value as usize) { |
153 | 931k | Some(bytes) => Ok(cbor_bytes_lit!(bytes)), |
154 | 514 | None => Err(DecoderError::IncompleteCborData), |
155 | | } |
156 | 931k | } |
157 | | |
158 | 150k | fn read_text_string_content(&mut self, size_value: u64) -> Result<Value, DecoderError> { |
159 | 150k | match self.read_bytes(size_value as usize) { |
160 | 149k | Some(bytes) => match str::from_utf8(bytes) { |
161 | 149k | Ok(s) => Ok(cbor_text!(s)), |
162 | 46 | Err(_) => Err(DecoderError::InvalidUtf8), |
163 | | }, |
164 | 545 | None => Err(DecoderError::IncompleteCborData), |
165 | | } |
166 | 150k | } |
167 | | |
168 | 2.04M | fn read_array_content( |
169 | 2.04M | &mut self, |
170 | 2.04M | size_value: u64, |
171 | 2.04M | remaining_depth: Option<i8>, |
172 | 2.04M | ) -> Result<Value, DecoderError> { |
173 | | // Don't set the capacity already, it is an unsanitized input. |
174 | 2.04M | let mut value_array = Vec::new(); |
175 | 2.04M | for _ in 0..size_value { |
176 | 15.4M | value_array.push(self.decode_complete_data_item(remaining_depth.map(|d| d - 1))?); |
177 | | } |
178 | 2.03M | Ok(cbor_array_vec!(value_array)) |
179 | 2.04M | } |
180 | | |
181 | 407k | fn read_map_content( |
182 | 407k | &mut self, |
183 | 407k | size_value: u64, |
184 | 407k | remaining_depth: Option<i8>, |
185 | 407k | ) -> Result<Value, DecoderError> { |
186 | 407k | let mut value_map = Vec::<(Value, Value)>::new(); |
187 | 407k | for _ in 0..size_value { |
188 | 708k | let key = self.decode_complete_data_item(remaining_depth.map(|d| d - 1))?; |
189 | 705k | if let Some(last_item) = value_map.last() |
190 | 334k | && last_item.0 >= key |
191 | | { |
192 | 1.14k | return Err(DecoderError::OutOfOrderKey); |
193 | 704k | } |
194 | 704k | value_map.push(( |
195 | 704k | key, |
196 | 704k | self.decode_complete_data_item(remaining_depth.map(|d| d - 1))?, |
197 | | )); |
198 | | } |
199 | 401k | Ok(cbor_map_collection!(value_map)) |
200 | 407k | } |
201 | | |
202 | 1.48M | fn read_tagged_content( |
203 | 1.48M | &mut self, |
204 | 1.48M | tag_value: u64, |
205 | 1.48M | remaining_depth: Option<i8>, |
206 | 1.48M | ) -> Result<Value, DecoderError> { |
207 | 1.48M | let inner_value = self.decode_complete_data_item(remaining_depth.map(|d| d - 1))?; |
208 | 1.48M | Ok(cbor_tagged!(tag_value, inner_value)) |
209 | 1.48M | } |
210 | | |
211 | 44.2k | fn decode_to_simple_value( |
212 | 44.2k | &self, |
213 | 44.2k | size_value: u64, |
214 | 44.2k | additional_info: u8, |
215 | 44.2k | ) -> Result<Value, DecoderError> { |
216 | 44.2k | if additional_info > Constants::ADDITIONAL_INFORMATION_MAX_INT |
217 | 51 | && additional_info != Constants::ADDITIONAL_INFORMATION_1_BYTE |
218 | | { |
219 | | // TODO(kaczmarczyck) the chromium C++ reference allows equality to 24 here, why? |
220 | | // Also, why not just disallow ANY additional_info != size_value? |
221 | 15 | return Err(DecoderError::UnsupportedFloatingPointValue); |
222 | 44.1k | } |
223 | 44.1k | match SimpleValue::from_integer(size_value) { |
224 | 44.1k | Some(simple_value) => Ok(Value(ValueImpl::Simple(simple_value))), |
225 | 81 | None => Err(DecoderError::UnsupportedSimpleValue), |
226 | | } |
227 | 44.2k | } |
228 | | } |
229 | | |
230 | | #[cfg(test)] |
231 | | mod test { |
232 | | use super::*; |
233 | | use crate::{ |
234 | | cbor_array, cbor_bytes, cbor_false, cbor_int, cbor_map, cbor_null, cbor_true, |
235 | | cbor_undefined, |
236 | | }; |
237 | | use alloc::vec; |
238 | | |
239 | | #[test] |
240 | | fn test_read_unsigned() { |
241 | | let cases = vec![ |
242 | | (0, vec![0x00]), |
243 | | (1, vec![0x01]), |
244 | | (10, vec![0x0A]), |
245 | | (23, vec![0x17]), |
246 | | (24, vec![0x18, 0x18]), |
247 | | (255, vec![0x18, 0xFF]), |
248 | | (256, vec![0x19, 0x01, 0x00]), |
249 | | (65535, vec![0x19, 0xFF, 0xFF]), |
250 | | (65536, vec![0x1A, 0x00, 0x01, 0x00, 0x00]), |
251 | | (0xFFFFFFFF, vec![0x1A, 0xFF, 0xFF, 0xFF, 0xFF]), |
252 | | ( |
253 | | 0x100000000, |
254 | | vec![0x1B, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00], |
255 | | ), |
256 | | ( |
257 | | core::i64::MAX, |
258 | | vec![0x1B, 0x7F, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF], |
259 | | ), |
260 | | ]; |
261 | | for (unsigned, mut cbor) in cases { |
262 | | assert_eq!(read(&cbor), Ok(cbor_int!(unsigned))); |
263 | | cbor.push(0x01); |
264 | | assert_eq!(read(&cbor), Err(DecoderError::ExtraneousData)); |
265 | | } |
266 | | } |
267 | | |
268 | | #[test] |
269 | | fn test_read_unsigned_non_minimum_byte_length() { |
270 | | let encodings = vec![ |
271 | | // Uint 23 encoded with 1 byte. |
272 | | vec![0x18, 0x17], |
273 | | // Uint 255 encoded with 2 bytes. |
274 | | vec![0x19, 0x00, 0xff], |
275 | | // Uint 65535 encoded with 4 bytes. |
276 | | vec![0x1a, 0x00, 0x00, 0xff, 0xff], |
277 | | // Uint 4294967295 encoded with 8 bytes. |
278 | | vec![0x1b, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff], |
279 | | // When decoding byte has more than one syntax error, the first syntax |
280 | | // error encountered during deserialization is returned as the error code. |
281 | | vec![ |
282 | | 0xa2, // map with non-minimally encoded key |
283 | | 0x17, // key 24 |
284 | | 0x61, 0x42, // value :"B" |
285 | | 0x18, 0x17, // key 23 encoded with extra byte |
286 | | 0x61, 0x45, // value "E" |
287 | | ], |
288 | | vec![ |
289 | | 0xa2, // map with out of order and non-minimally encoded key |
290 | | 0x18, 0x17, // key 23 encoded with extra byte |
291 | | 0x61, 0x45, // value "E" |
292 | | 0x17, // key 23 |
293 | | 0x61, 0x42, // value :"B" |
294 | | ], |
295 | | vec![ |
296 | | 0xa2, // map with duplicate non-minimally encoded key |
297 | | 0x18, 0x17, // key 23 encoded with extra byte |
298 | | 0x61, 0x45, // value "E" |
299 | | 0x18, 0x17, // key 23 encoded with extra byte |
300 | | 0x61, 0x42, // value :"B" |
301 | | ], |
302 | | ]; |
303 | | for encoding in encodings { |
304 | | assert_eq!(read(&encoding), Err(DecoderError::NonMinimalCborEncoding)); |
305 | | } |
306 | | } |
307 | | |
308 | | #[test] |
309 | | fn test_read_negative() { |
310 | | let cases = vec![ |
311 | | (-1, vec![0x20]), |
312 | | (-24, vec![0x37]), |
313 | | (-25, vec![0x38, 0x18]), |
314 | | (-256, vec![0x38, 0xFF]), |
315 | | (-1000, vec![0x39, 0x03, 0xE7]), |
316 | | (-1000000, vec![0x3A, 0x00, 0x0F, 0x42, 0x3F]), |
317 | | (-4294967296, vec![0x3A, 0xFF, 0xFF, 0xFF, 0xFF]), |
318 | | ( |
319 | | core::i64::MIN, |
320 | | vec![0x3B, 0x7F, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF], |
321 | | ), |
322 | | ]; |
323 | | for (negative, mut cbor) in cases { |
324 | | assert_eq!(read(&cbor), Ok(cbor_int!(negative))); |
325 | | cbor.push(0x01); |
326 | | assert_eq!(read(&cbor), Err(DecoderError::ExtraneousData)); |
327 | | } |
328 | | } |
329 | | |
330 | | #[test] |
331 | | fn test_read_byte_string() { |
332 | | let cases = vec![ |
333 | | (Vec::new(), vec![0x40]), |
334 | | ( |
335 | | vec![0x01, 0x02, 0x03, 0x04], |
336 | | vec![0x44, 0x01, 0x02, 0x03, 0x04], |
337 | | ), |
338 | | ]; |
339 | | for (byte_string, mut cbor) in cases { |
340 | | assert_eq!(read(&cbor), Ok(cbor_bytes!(byte_string))); |
341 | | cbor.push(0x01); |
342 | | assert_eq!(read(&cbor), Err(DecoderError::ExtraneousData)); |
343 | | } |
344 | | } |
345 | | |
346 | | #[test] |
347 | | fn test_read_text_string() { |
348 | | let unicode_3byte = vec![0xE6, 0xB0, 0xB4]; |
349 | | let cases = vec![ |
350 | | ("", vec![0x60]), |
351 | | ("a", vec![0x61, 0x61]), |
352 | | ("IETF", vec![0x64, 0x49, 0x45, 0x54, 0x46]), |
353 | | ("\"\\", vec![0x62, 0x22, 0x5C]), |
354 | | ("ü", vec![0x62, 0xC3, 0xBC]), |
355 | | ( |
356 | | core::str::from_utf8(&unicode_3byte).unwrap(), |
357 | | vec![0x63, 0xE6, 0xB0, 0xB4], |
358 | | ), |
359 | | ("𐅑", vec![0x64, 0xF0, 0x90, 0x85, 0x91]), |
360 | | ]; |
361 | | for (text_string, mut cbor) in cases { |
362 | | assert_eq!(read(&cbor), Ok(cbor_text!(text_string))); |
363 | | cbor.push(0x01); |
364 | | assert_eq!(read(&cbor), Err(DecoderError::ExtraneousData)); |
365 | | } |
366 | | } |
367 | | |
368 | | #[test] |
369 | | fn test_read_text_string_with_nul() { |
370 | | let cases = vec![ |
371 | | ( |
372 | | "string_without_nul", |
373 | | vec![ |
374 | | 0x72, 0x73, 0x74, 0x72, 0x69, 0x6E, 0x67, 0x5F, 0x77, 0x69, 0x74, 0x68, 0x6F, |
375 | | 0x75, 0x74, 0x5F, 0x6E, 0x75, 0x6C, |
376 | | ], |
377 | | ), |
378 | | ( |
379 | | "nul_terminated_string\0", |
380 | | vec![ |
381 | | 0x76, 0x6E, 0x75, 0x6C, 0x5F, 0x74, 0x65, 0x72, 0x6D, 0x69, 0x6E, 0x61, 0x74, |
382 | | 0x65, 0x64, 0x5F, 0x73, 0x74, 0x72, 0x69, 0x6E, 0x67, 0x00, |
383 | | ], |
384 | | ), |
385 | | ( |
386 | | "embedded\0nul", |
387 | | vec![ |
388 | | 0x6C, 0x65, 0x6D, 0x62, 0x65, 0x64, 0x64, 0x65, 0x64, 0x00, 0x6E, 0x75, 0x6C, |
389 | | ], |
390 | | ), |
391 | | ( |
392 | | "trailing_nuls\0\0", |
393 | | vec![ |
394 | | 0x6F, 0x74, 0x72, 0x61, 0x69, 0x6C, 0x69, 0x6E, 0x67, 0x5F, 0x6E, 0x75, 0x6C, |
395 | | 0x73, 0x00, 0x00, |
396 | | ], |
397 | | ), |
398 | | ]; |
399 | | for (text_string, mut cbor) in cases { |
400 | | assert_eq!(read(&cbor), Ok(cbor_text!(text_string))); |
401 | | cbor.push(0x01); |
402 | | assert_eq!(read(&cbor), Err(DecoderError::ExtraneousData)); |
403 | | } |
404 | | } |
405 | | |
406 | | #[test] |
407 | | fn test_read_text_string_with_invalid_byte_sequence_after_nul() { |
408 | | assert_eq!( |
409 | | read(&vec![0x63, 0x00, 0x00, 0xA6]), |
410 | | Err(DecoderError::InvalidUtf8) |
411 | | ); |
412 | | } |
413 | | |
414 | | #[test] |
415 | | fn test_read_array() { |
416 | | let value_vec: Vec<_> = (1..26).collect(); |
417 | | let mut test_cbor = vec![ |
418 | | 0x98, 0x19, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0a, 0x0b, 0x0c, |
419 | | 0x0d, 0x0e, 0x0f, 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, 0x18, 0x18, 0x18, |
420 | | 0x19, |
421 | | ]; |
422 | | assert_eq!(read(&test_cbor.clone()), Ok(cbor_array_vec!(value_vec))); |
423 | | test_cbor.push(0x01); |
424 | | assert_eq!(read(&test_cbor), Err(DecoderError::ExtraneousData)); |
425 | | } |
426 | | |
427 | | #[test] |
428 | | fn test_read_map() { |
429 | | let value_map = cbor_map! { |
430 | | 24 => "abc", |
431 | | "" => ".", |
432 | | "b" => "B", |
433 | | "aa" => "AA", |
434 | | }; |
435 | | let mut test_cbor = vec![ |
436 | | 0xa4, // map with 4 key value pairs: |
437 | | 0x18, 0x18, // 24 |
438 | | 0x63, 0x61, 0x62, 0x63, // "abc" |
439 | | 0x60, // "" |
440 | | 0x61, 0x2e, // "." |
441 | | 0x61, 0x62, // "b" |
442 | | 0x61, 0x42, // "B" |
443 | | 0x62, 0x61, 0x61, // "aa" |
444 | | 0x62, 0x41, 0x41, // "AA" |
445 | | ]; |
446 | | assert_eq!(read(&test_cbor), Ok(value_map)); |
447 | | test_cbor.push(0x01); |
448 | | assert_eq!(read(&test_cbor), Err(DecoderError::ExtraneousData)); |
449 | | } |
450 | | |
451 | | #[test] |
452 | | fn test_read_map_with_unsigned_keys() { |
453 | | let value_map = cbor_map! { |
454 | | 1 => "a", |
455 | | 9 => "b", |
456 | | 999 => "c", |
457 | | 1111 => "d", |
458 | | }; |
459 | | let mut test_cbor = vec![ |
460 | | 0xa4, // map with 4 key value pairs: |
461 | | 0x01, // key : 1 |
462 | | 0x61, 0x61, // value : "a" |
463 | | 0x09, // key : 9 |
464 | | 0x61, 0x62, // value : "b" |
465 | | 0x19, 0x03, 0xE7, // key : 999 |
466 | | 0x61, 0x63, // value "c" |
467 | | 0x19, 0x04, 0x57, // key : 1111 |
468 | | 0x61, 0x64, // value : "d" |
469 | | ]; |
470 | | assert_eq!(read(&test_cbor), Ok(value_map)); |
471 | | test_cbor.push(0x01); |
472 | | assert_eq!(read(&test_cbor), Err(DecoderError::ExtraneousData)); |
473 | | } |
474 | | |
475 | | #[test] |
476 | | fn test_read_map_with_negative_keys() { |
477 | | let value_map = cbor_map! { |
478 | | -1 => 1, |
479 | | -2 => 2, |
480 | | -100 => 3, |
481 | | }; |
482 | | let mut test_cbor = vec![ |
483 | | 0xA3, // map with 3 key value pairs |
484 | | 0x20, // key : -1 |
485 | | 0x01, // value : 1 |
486 | | 0x21, // key : -2 |
487 | | 0x02, // value : 2 |
488 | | 0x38, 0x63, // key : -100 |
489 | | 0x03, // value : 3 |
490 | | ]; |
491 | | assert_eq!(read(&test_cbor), Ok(value_map)); |
492 | | test_cbor.push(0x01); |
493 | | assert_eq!(read(&test_cbor), Err(DecoderError::ExtraneousData)); |
494 | | } |
495 | | |
496 | | #[test] |
497 | | fn test_read_map_with_array() { |
498 | | let value_map = cbor_map! { |
499 | | "a" => 1, |
500 | | "b" => cbor_array![2, 3], |
501 | | }; |
502 | | let mut test_cbor = vec![ |
503 | | 0xa2, // map of 2 pairs |
504 | | 0x61, 0x61, // "a" |
505 | | 0x01, 0x61, 0x62, // "b" |
506 | | 0x82, // array with 2 elements |
507 | | 0x02, 0x03, |
508 | | ]; |
509 | | assert_eq!(read(&test_cbor), Ok(value_map)); |
510 | | test_cbor.push(0x01); |
511 | | assert_eq!(read(&test_cbor), Err(DecoderError::ExtraneousData)); |
512 | | } |
513 | | |
514 | | #[test] |
515 | | fn test_read_map_with_text_string_keys() { |
516 | | let value_map = cbor_map! { |
517 | | "k" => "v", |
518 | | "foo" => "bar", |
519 | | }; |
520 | | let mut test_cbor = vec![ |
521 | | 0xa2, // map of 2 pairs |
522 | | 0x61, b'k', // text string "k" |
523 | | 0x61, b'v', 0x63, b'f', b'o', b'o', // text string "foo" |
524 | | 0x63, b'b', b'a', b'r', |
525 | | ]; |
526 | | assert_eq!(read(&test_cbor), Ok(value_map)); |
527 | | test_cbor.push(0x01); |
528 | | assert_eq!(read(&test_cbor), Err(DecoderError::ExtraneousData)); |
529 | | } |
530 | | |
531 | | #[test] |
532 | | fn test_read_map_with_byte_string_keys() { |
533 | | let value_map = cbor_map! { |
534 | | b"k" => b"v", |
535 | | b"foo" => b"bar", |
536 | | }; |
537 | | let mut test_cbor = vec![ |
538 | | 0xa2, // map of 2 pairs |
539 | | 0x41, b'k', // text string "k" |
540 | | 0x41, b'v', 0x43, b'f', b'o', b'o', // text string "foo" |
541 | | 0x43, b'b', b'a', b'r', |
542 | | ]; |
543 | | assert_eq!(read(&test_cbor), Ok(value_map)); |
544 | | test_cbor.push(0x01); |
545 | | assert_eq!(read(&test_cbor), Err(DecoderError::ExtraneousData)); |
546 | | } |
547 | | |
548 | | #[test] |
549 | | fn test_read_nested_map() { |
550 | | let value_map = cbor_map! { |
551 | | "a" => 1, |
552 | | "b" => cbor_map! { |
553 | | "c" => 2, |
554 | | "d" => 3, |
555 | | }, |
556 | | }; |
557 | | let mut test_cbor = vec![ |
558 | | 0xa2, // map of 2 pairs |
559 | | 0x61, 0x61, 0x01, // "a" |
560 | | 0x61, 0x62, // "b" |
561 | | 0xa2, // map of 2 pairs |
562 | | 0x61, 0x63, 0x02, // "c" |
563 | | 0x61, 0x64, 0x03, // "d" |
564 | | ]; |
565 | | assert_eq!(read(&test_cbor), Ok(value_map)); |
566 | | test_cbor.push(0x01); |
567 | | assert_eq!(read(&test_cbor), Err(DecoderError::ExtraneousData)); |
568 | | } |
569 | | |
570 | | #[test] |
571 | | fn test_read_tagged() { |
572 | | let cases = vec![ |
573 | | (cbor_tagged!(6, cbor_int!(0x42)), vec![0xc6, 0x18, 0x42]), |
574 | | (cbor_tagged!(1, cbor_true!()), vec![0xc1, 0xf5]), |
575 | | ( |
576 | | cbor_tagged!( |
577 | | 1000, |
578 | | cbor_map! { |
579 | | "a" => 1, |
580 | | "b" => cbor_array![2, 3], |
581 | | } |
582 | | ), |
583 | | vec![ |
584 | | 0xd9, 0x03, 0xe8, 0xa2, // map of 2 pairs |
585 | | 0x61, 0x61, // "a" |
586 | | 0x01, 0x61, 0x62, // "b" |
587 | | 0x82, // array with 2 elements |
588 | | 0x02, 0x03, |
589 | | ], |
590 | | ), |
591 | | ]; |
592 | | for (value, mut cbor) in cases { |
593 | | assert_eq!(read(&cbor), Ok(value)); |
594 | | cbor.push(0x01); |
595 | | assert_eq!(read(&cbor), Err(DecoderError::ExtraneousData)); |
596 | | } |
597 | | } |
598 | | |
599 | | #[test] |
600 | | fn test_read_integer_out_of_range() { |
601 | | let cases = vec![ |
602 | | // The positive case is impossible since we support u64. |
603 | | // vec![0x1B, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00], |
604 | | vec![0x3B, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00], |
605 | | ]; |
606 | | for cbor in cases { |
607 | | assert_eq!(read(&cbor), Err(DecoderError::OutOfRangeIntegerValue)); |
608 | | } |
609 | | } |
610 | | |
611 | | #[test] |
612 | | fn test_read_simple_value() { |
613 | | let cases = vec![ |
614 | | (cbor_false!(), vec![0xF4]), |
615 | | (cbor_true!(), vec![0xF5]), |
616 | | (cbor_null!(), vec![0xF6]), |
617 | | (cbor_undefined!(), vec![0xF7]), |
618 | | ]; |
619 | | for (simple, mut cbor) in cases { |
620 | | assert_eq!(read(&cbor.clone()), Ok(simple)); |
621 | | cbor.push(0x01); |
622 | | assert_eq!(read(&cbor), Err(DecoderError::ExtraneousData)); |
623 | | } |
624 | | } |
625 | | |
626 | | #[test] |
627 | | fn test_read_unsupported_floating_point_numbers() { |
628 | | let cases = vec![ |
629 | | vec![0xF9, 0x10, 0x00], |
630 | | vec![0xFA, 0x10, 0x00, 0x00, 0x00], |
631 | | vec![0xFB, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00], |
632 | | ]; |
633 | | for cbor in cases { |
634 | | assert_eq!( |
635 | | read(&cbor), |
636 | | Err(DecoderError::UnsupportedFloatingPointValue) |
637 | | ); |
638 | | } |
639 | | } |
640 | | |
641 | | #[test] |
642 | | fn test_read_incomplete_cbor_data_error() { |
643 | | let cases = vec![ |
644 | | vec![0x19, 0x03], |
645 | | vec![0x44, 0x01, 0x02, 0x03], |
646 | | vec![0x65, 0x49, 0x45, 0x54, 0x46], |
647 | | vec![0x82, 0x02], |
648 | | vec![0xA2, 0x61, 0x61, 0x01], |
649 | | vec![0x18], |
650 | | vec![0x99], |
651 | | vec![0xBA], |
652 | | vec![0x5B], |
653 | | vec![0x3B], |
654 | | vec![0x99, 0x01], |
655 | | vec![0xBA, 0x01, 0x02, 0x03], |
656 | | vec![0x3B, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07], |
657 | | ]; |
658 | | for cbor in cases { |
659 | | assert_eq!(read(&cbor), Err(DecoderError::IncompleteCborData)); |
660 | | } |
661 | | } |
662 | | |
663 | | #[test] |
664 | | fn test_read_unknown_additional_info_error() { |
665 | | let cases = vec![ |
666 | | vec![0x7C, 0x49, 0x45, 0x54, 0x46], |
667 | | vec![0x7D, 0x22, 0x5C], |
668 | | vec![0x7E, 0xC3, 0xBC], |
669 | | vec![0x7F, 0xE6, 0xB0, 0xB4], |
670 | | vec![0xFC], |
671 | | vec![0xFD], |
672 | | vec![0xFE], |
673 | | vec![0xFF], |
674 | | ]; |
675 | | for cbor in cases { |
676 | | assert_eq!(read(&cbor), Err(DecoderError::UnknownAdditionalInfo)); |
677 | | } |
678 | | } |
679 | | |
680 | | #[test] |
681 | | fn test_read_too_much_nesting_error() { |
682 | | let cases = vec![ |
683 | | vec![0x18, 0x64], |
684 | | vec![0x44, 0x01, 0x02, 0x03, 0x04], |
685 | | vec![0x64, 0x49, 0x45, 0x54, 0x46], |
686 | | vec![0x80], |
687 | | vec![0xA0], |
688 | | ]; |
689 | | for cbor in cases { |
690 | | let mut reader = Reader::new(&cbor); |
691 | | assert!(reader.decode_complete_data_item(Some(0)).is_ok()); |
692 | | } |
693 | | let map_cbor = vec![ |
694 | | 0xa2, // map of 2 pairs |
695 | | 0x61, 0x61, // "a" |
696 | | 0x01, 0x61, 0x62, // "b" |
697 | | 0x82, // array with 2 elements |
698 | | 0x02, 0x03, |
699 | | ]; |
700 | | let mut reader = Reader::new(&map_cbor); |
701 | | assert_eq!( |
702 | | reader.decode_complete_data_item(Some(1)), |
703 | | Err(DecoderError::TooMuchNesting) |
704 | | ); |
705 | | reader = Reader::new(&map_cbor); |
706 | | assert!(reader.decode_complete_data_item(Some(2)).is_ok()); |
707 | | } |
708 | | |
709 | | #[test] |
710 | | fn test_read_out_of_order_key_error() { |
711 | | let cases = vec![ |
712 | | vec![ |
713 | | 0xa2, // map with 2 keys with same major type and length |
714 | | 0x61, 0x62, // key "b" |
715 | | 0x61, 0x42, // value "B" |
716 | | 0x61, 0x61, // key "a" (out of order byte-wise lexically) |
717 | | 0x61, 0x45, // value "E" |
718 | | ], |
719 | | vec![ |
720 | | 0xa2, // map with 2 keys with different major type |
721 | | 0x61, 0x62, // key "b" |
722 | | 0x02, // value 2 |
723 | | // key 1000 (out of order since lower major type sorts first) |
724 | | 0x19, 0x03, 0xe8, 0x61, 0x61, // value a |
725 | | ], |
726 | | vec![ |
727 | | 0xa2, // map with 2 keys with same major type |
728 | | 0x19, 0x03, 0xe8, // key 1000 (out of order due to longer length) |
729 | | 0x61, 0x61, //value "a" |
730 | | 0x0a, // key 10 |
731 | | 0x61, 0x62, // value "b" |
732 | | ], |
733 | | vec![ |
734 | | 0xa2, // map with 2 text string keys |
735 | | 0x62, b'a', b'a', // key text string "aa" |
736 | | // (out of order due to longer length) |
737 | | 0x02, 0x61, b'b', // key "b" |
738 | | 0x01, |
739 | | ], |
740 | | vec![ |
741 | | 0xa2, // map with 2 byte string keys |
742 | | 0x42, b'x', b'x', // key byte string "xx" |
743 | | // (out of order due to longer length) |
744 | | 0x02, 0x41, b'y', // key byte string "y" |
745 | | 0x01, |
746 | | ], |
747 | | ]; |
748 | | for cbor in cases { |
749 | | assert_eq!(read(&cbor), Err(DecoderError::OutOfOrderKey)); |
750 | | } |
751 | | } |
752 | | |
753 | | #[test] |
754 | | fn test_read_duplicate_key_error() { |
755 | | let map_with_duplicate_key = vec![ |
756 | | 0xa6, // map of 6 pairs: |
757 | | 0x60, // "" |
758 | | 0x61, 0x2e, // "." |
759 | | 0x61, 0x62, // "b" |
760 | | 0x61, 0x42, // "B" |
761 | | 0x61, 0x62, // "b" (Duplicate key) |
762 | | 0x61, 0x43, // "C" |
763 | | 0x61, 0x64, // "d" |
764 | | 0x61, 0x44, // "D" |
765 | | 0x61, 0x65, // "e" |
766 | | 0x61, 0x44, // "D" |
767 | | 0x62, 0x61, 0x61, // "aa" |
768 | | 0x62, 0x41, 0x41, // "AA" |
769 | | ]; |
770 | | assert_eq!( |
771 | | read(&map_with_duplicate_key), |
772 | | Err(DecoderError::OutOfOrderKey) |
773 | | ); |
774 | | } |
775 | | |
776 | | #[test] |
777 | | fn test_read_incorrect_string_encoding_error() { |
778 | | let cases = vec![ |
779 | | vec![0x63, 0xED, 0x9F, 0xBF], |
780 | | vec![0x63, 0xEE, 0x80, 0x80], |
781 | | vec![0x63, 0xEF, 0xBF, 0xBD], |
782 | | ]; |
783 | | for cbor in cases { |
784 | | assert!(read(&cbor).is_ok()); |
785 | | } |
786 | | let impossible_utf_byte = vec![0x64, 0xFE, 0xFE, 0xFF, 0xFF]; |
787 | | assert_eq!(read(&impossible_utf_byte), Err(DecoderError::InvalidUtf8)); |
788 | | } |
789 | | |
790 | | #[test] |
791 | | fn test_read_extraneous_cbor_data_error() { |
792 | | let cases = vec![ |
793 | | vec![0x19, 0x03, 0x05, 0x00], |
794 | | vec![0x44, 0x01, 0x02, 0x03, 0x04, 0x00], |
795 | | vec![0x64, 0x49, 0x45, 0x54, 0x46, 0x00], |
796 | | vec![0x82, 0x01, 0x02, 0x00], |
797 | | vec![0xa1, 0x61, 0x63, 0x02, 0x61, 0x64, 0x03], |
798 | | ]; |
799 | | for cbor in cases { |
800 | | assert_eq!(read(&cbor), Err(DecoderError::ExtraneousData)); |
801 | | } |
802 | | } |
803 | | |
804 | | #[test] |
805 | | fn test_read_unsupported_simple_type() { |
806 | | let cases = vec![ |
807 | | vec![0xE0], |
808 | | vec![0xF3], |
809 | | vec![0xF8, 0x18], |
810 | | vec![0xF8, 0x1C], |
811 | | vec![0xF8, 0x1D], |
812 | | vec![0xF8, 0x1E], |
813 | | vec![0xF8, 0x1F], |
814 | | vec![0xF8, 0x20], |
815 | | vec![0xF8, 0xFF], |
816 | | ]; |
817 | | for cbor in cases { |
818 | | assert_eq!(read(&cbor), Err(DecoderError::UnsupportedSimpleValue)); |
819 | | } |
820 | | } |
821 | | |
822 | | #[test] |
823 | | fn test_read_super_long_content_dont_crash() { |
824 | | let cases = vec![ |
825 | | vec![0x9B, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF], |
826 | | vec![0xBB, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF], |
827 | | ]; |
828 | | for cbor in cases { |
829 | | assert_eq!(read(&cbor), Err(DecoderError::IncompleteCborData)); |
830 | | } |
831 | | } |
832 | | } |