1 // SPDX-License-Identifier: Apache-2.0
2
3 //! This test validates that we don't get stack overflows.
4 //!
5 //! If container types cause recursion, then a long list of prefixes which
6 //! indicate nested container types could cause the stack to overflow. We
7 //! test each of these types here to ensure there is no stack overflow.
8
9 use ciborium::{
10 de::{from_reader, from_reader_with_recursion_limit, Error},
11 value::Value,
12 };
13
14 #[test]
array()15 fn array() {
16 let bytes = [0x9f; 128 * 1024];
17 match from_reader::<Value, _>(&bytes[..]).unwrap_err() {
18 Error::RecursionLimitExceeded => (),
19 e => panic!("incorrect error: {:?}", e),
20 }
21 }
22
23 #[test]
map()24 fn map() {
25 let bytes = [0xbf; 128 * 1024];
26 match from_reader::<Value, _>(&bytes[..]).unwrap_err() {
27 Error::RecursionLimitExceeded => (),
28 e => panic!("incorrect error: {:?}", e),
29 }
30 }
31
32 #[test]
bytes()33 fn bytes() {
34 let bytes = [0x5f; 128 * 1024];
35 match from_reader::<Value, _>(&bytes[..]).unwrap_err() {
36 Error::Io(..) => (),
37 e => panic!("incorrect error: {:?}", e),
38 }
39 }
40
41 #[test]
text()42 fn text() {
43 let bytes = [0x7f; 128 * 1024];
44 match from_reader::<Value, _>(&bytes[..]).unwrap_err() {
45 Error::Io(..) => (),
46 e => panic!("incorrect error: {:?}", e),
47 }
48 }
49
50 #[test]
array_limit()51 fn array_limit() {
52 let bytes = [0x9f; 128 * 1024];
53 for limit in 16..256 {
54 match from_reader_with_recursion_limit::<Value, _>(&bytes[..], limit).unwrap_err() {
55 Error::RecursionLimitExceeded => (),
56 e => panic!("incorrect error with limit {}: {:?}", limit, e),
57 }
58 // Data that is nested beyond the limit should fail with `RecursionLimitExceeded`
59 match from_reader_with_recursion_limit::<Value, _>(&bytes[..limit + 1], limit).unwrap_err()
60 {
61 Error::RecursionLimitExceeded => (),
62 e => panic!("incorrect error with limit {}: {:?}", limit, e),
63 }
64 // Data that is nested within the limit fails with a different error.
65 match from_reader_with_recursion_limit::<Value, _>(&bytes[..limit], limit).unwrap_err() {
66 Error::Io(..) => (),
67 e => panic!("incorrect error with limit {}: {:?}", limit, e),
68 }
69 }
70 }
71
72 #[test]
map_limit()73 fn map_limit() {
74 let bytes = [0xbf; 128 * 1024];
75 for limit in 16..256 {
76 match from_reader_with_recursion_limit::<Value, _>(&bytes[..], limit).unwrap_err() {
77 Error::RecursionLimitExceeded => (),
78 e => panic!("incorrect error with limit {}: {:?}", limit, e),
79 }
80 // Data that is nested beyond the limit should fail with `RecursionLimitExceeded`
81 match from_reader_with_recursion_limit::<Value, _>(&bytes[..limit + 1], limit).unwrap_err()
82 {
83 Error::RecursionLimitExceeded => (),
84 e => panic!("incorrect error with limit {}: {:?}", limit, e),
85 }
86 // Data that is nested within the limit fails with a different error.
87 match from_reader_with_recursion_limit::<Value, _>(&bytes[..limit], limit).unwrap_err() {
88 Error::Io(..) => (),
89 e => panic!("incorrect error with limit {}: {:?}", limit, e),
90 }
91 }
92 }
93