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