reliakit_json/limits.rs
1//! Explicit resource limits for parsing untrusted JSON.
2
3/// Resource limits enforced while parsing.
4///
5/// Limits bound *logical* decoded data (counts and byte lengths), not exact
6/// allocator memory — real heap use also depends on `String`/`Vec` capacity and
7/// the platform. Parsing untrusted input should always go through limits;
8/// [`crate::parse`] applies [`JsonLimits::new`] by default.
9///
10/// Pick a profile with [`new`](Self::new), [`conservative`](Self::conservative),
11/// or [`permissive`](Self::permissive), adjust individual limits with the
12/// `with_*` builder methods, and read current values with the matching
13/// accessors.
14#[derive(Debug, Clone, Copy, PartialEq, Eq)]
15pub struct JsonLimits {
16 max_input_bytes: usize,
17 max_depth: usize,
18 max_string_bytes: usize,
19 max_key_bytes: usize,
20 max_number_bytes: usize,
21 max_array_items: usize,
22 max_object_members: usize,
23 max_total_nodes: usize,
24 max_total_decoded_string_bytes: usize,
25}
26
27impl JsonLimits {
28 /// The default limits: conservative values suitable for untrusted input.
29 ///
30 /// `1 MiB` input, depth `64`, `256 KiB` per string, `16 KiB` per key,
31 /// `256` bytes per number, `100_000` array items / object members,
32 /// `200_000` total nodes, `1 MiB` total decoded string bytes.
33 pub const fn new() -> Self {
34 Self {
35 max_input_bytes: 1 << 20,
36 max_depth: 64,
37 max_string_bytes: 256 << 10,
38 max_key_bytes: 16 << 10,
39 max_number_bytes: 256,
40 max_array_items: 100_000,
41 max_object_members: 100_000,
42 max_total_nodes: 200_000,
43 max_total_decoded_string_bytes: 1 << 20,
44 }
45 }
46
47 /// A tighter profile for small, low-trust payloads (e.g. tokens, webhooks).
48 ///
49 /// `64 KiB` input, depth `32`, `16 KiB` per string, `1 KiB` per key,
50 /// `64` bytes per number, `4_096` array items / object members,
51 /// `16_384` total nodes, `64 KiB` total decoded string bytes.
52 pub const fn conservative() -> Self {
53 Self {
54 max_input_bytes: 64 << 10,
55 max_depth: 32,
56 max_string_bytes: 16 << 10,
57 max_key_bytes: 1 << 10,
58 max_number_bytes: 64,
59 max_array_items: 4_096,
60 max_object_members: 4_096,
61 max_total_nodes: 16_384,
62 max_total_decoded_string_bytes: 64 << 10,
63 }
64 }
65
66 /// A looser profile for larger trusted documents. Still explicit and finite.
67 ///
68 /// `64 MiB` input, depth `128`, `16 MiB` per string, `256 KiB` per key,
69 /// `1_024` bytes per number, `5_000_000` array items / object members,
70 /// `10_000_000` total nodes, `64 MiB` total decoded string bytes.
71 pub const fn permissive() -> Self {
72 Self {
73 max_input_bytes: 64 << 20,
74 max_depth: 128,
75 max_string_bytes: 16 << 20,
76 max_key_bytes: 256 << 10,
77 max_number_bytes: 1_024,
78 max_array_items: 5_000_000,
79 max_object_members: 5_000_000,
80 max_total_nodes: 10_000_000,
81 max_total_decoded_string_bytes: 64 << 20,
82 }
83 }
84
85 /// Maximum size of the whole input, in bytes.
86 pub const fn max_input_bytes(&self) -> usize {
87 self.max_input_bytes
88 }
89
90 /// Maximum nesting depth of arrays and objects.
91 pub const fn max_depth(&self) -> usize {
92 self.max_depth
93 }
94
95 /// Maximum decoded size of a single string value, in bytes.
96 pub const fn max_string_bytes(&self) -> usize {
97 self.max_string_bytes
98 }
99
100 /// Maximum decoded size of a single object key, in bytes.
101 pub const fn max_key_bytes(&self) -> usize {
102 self.max_key_bytes
103 }
104
105 /// Maximum length of a single number token, in bytes.
106 pub const fn max_number_bytes(&self) -> usize {
107 self.max_number_bytes
108 }
109
110 /// Maximum number of items in a single array.
111 pub const fn max_array_items(&self) -> usize {
112 self.max_array_items
113 }
114
115 /// Maximum number of members in a single object.
116 pub const fn max_object_members(&self) -> usize {
117 self.max_object_members
118 }
119
120 /// Maximum total number of values (nodes) in the document.
121 pub const fn max_total_nodes(&self) -> usize {
122 self.max_total_nodes
123 }
124
125 /// Maximum total decoded string bytes across the whole document.
126 pub const fn max_total_decoded_string_bytes(&self) -> usize {
127 self.max_total_decoded_string_bytes
128 }
129
130 /// Sets [`max_input_bytes`](Self::max_input_bytes).
131 pub const fn with_max_input_bytes(mut self, value: usize) -> Self {
132 self.max_input_bytes = value;
133 self
134 }
135
136 /// Sets [`max_depth`](Self::max_depth).
137 pub const fn with_max_depth(mut self, value: usize) -> Self {
138 self.max_depth = value;
139 self
140 }
141
142 /// Sets [`max_string_bytes`](Self::max_string_bytes).
143 pub const fn with_max_string_bytes(mut self, value: usize) -> Self {
144 self.max_string_bytes = value;
145 self
146 }
147
148 /// Sets [`max_key_bytes`](Self::max_key_bytes).
149 pub const fn with_max_key_bytes(mut self, value: usize) -> Self {
150 self.max_key_bytes = value;
151 self
152 }
153
154 /// Sets [`max_number_bytes`](Self::max_number_bytes).
155 pub const fn with_max_number_bytes(mut self, value: usize) -> Self {
156 self.max_number_bytes = value;
157 self
158 }
159
160 /// Sets [`max_array_items`](Self::max_array_items).
161 pub const fn with_max_array_items(mut self, value: usize) -> Self {
162 self.max_array_items = value;
163 self
164 }
165
166 /// Sets [`max_object_members`](Self::max_object_members).
167 pub const fn with_max_object_members(mut self, value: usize) -> Self {
168 self.max_object_members = value;
169 self
170 }
171
172 /// Sets [`max_total_nodes`](Self::max_total_nodes).
173 pub const fn with_max_total_nodes(mut self, value: usize) -> Self {
174 self.max_total_nodes = value;
175 self
176 }
177
178 /// Sets [`max_total_decoded_string_bytes`](Self::max_total_decoded_string_bytes).
179 pub const fn with_max_total_decoded_string_bytes(mut self, value: usize) -> Self {
180 self.max_total_decoded_string_bytes = value;
181 self
182 }
183}
184
185impl Default for JsonLimits {
186 fn default() -> Self {
187 Self::new()
188 }
189}