Skip to main content

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}