1use alloc::vec::Vec;
2
3use crate::de::{Layer, LayerEvent, Next};
4use crate::error::{Error, ErrorKind};
5use crate::event::{Atom, Event};
6
7#[derive(Debug, Clone, Copy, Default, PartialEq, Eq)]
39pub struct Limits {
40 max_depth: Option<usize>,
41 max_events: Option<usize>,
42 max_items: Option<usize>,
43 max_len: Option<usize>,
44}
45
46impl Limits {
47 pub const fn new() -> Limits {
49 Limits {
50 max_depth: None,
51 max_events: None,
52 max_items: None,
53 max_len: None,
54 }
55 }
56
57 pub const fn builder() -> LimitsBuilder {
59 LimitsBuilder::new()
60 }
61
62 pub const fn into_builder(self) -> LimitsBuilder {
64 LimitsBuilder { value: self }
65 }
66
67 pub const fn set_max_depth(&mut self, depth: usize) {
72 self.max_depth = Some(depth);
73 }
74
75 pub const fn max_depth(&self) -> Option<usize> {
77 self.max_depth
78 }
79
80 pub const fn set_max_events(&mut self, events: usize) {
84 self.max_events = Some(events);
85 }
86
87 pub const fn max_events(&self) -> Option<usize> {
89 self.max_events
90 }
91
92 pub const fn set_max_items(&mut self, items: usize) {
94 self.max_items = Some(items);
95 }
96
97 pub const fn max_items(&self) -> Option<usize> {
100 self.max_items
101 }
102
103 pub const fn set_max_len(&mut self, len: usize) {
105 self.max_len = Some(len);
106 }
107
108 pub const fn max_len(&self) -> Option<usize> {
110 self.max_len
111 }
112
113 pub(crate) const fn is_unlimited(&self) -> bool {
115 self.max_depth.is_none()
116 && self.max_events.is_none()
117 && self.max_items.is_none()
118 && self.max_len.is_none()
119 }
120}
121
122#[derive(Debug, Clone)]
126#[must_use]
127pub struct LimitsBuilder {
128 value: Limits,
129}
130
131impl LimitsBuilder {
132 pub const fn new() -> LimitsBuilder {
134 LimitsBuilder {
135 value: Limits::new(),
136 }
137 }
138
139 pub const fn max_depth(mut self, depth: usize) -> LimitsBuilder {
143 self.value.set_max_depth(depth);
144 self
145 }
146
147 pub const fn max_events(mut self, events: usize) -> LimitsBuilder {
151 self.value.set_max_events(events);
152 self
153 }
154
155 pub const fn max_items(mut self, items: usize) -> LimitsBuilder {
159 self.value.set_max_items(items);
160 self
161 }
162
163 pub const fn max_len(mut self, len: usize) -> LimitsBuilder {
167 self.value.set_max_len(len);
168 self
169 }
170
171 pub const fn build(self) -> Limits {
173 self.value
174 }
175}
176
177impl Default for LimitsBuilder {
178 fn default() -> LimitsBuilder {
179 LimitsBuilder::new()
180 }
181}
182
183pub(crate) struct LimitsLayer {
185 limits: Limits,
186 events: usize,
187 items: Vec<(bool, usize)>,
189}
190
191impl LimitsLayer {
192 pub(crate) fn new(limits: Limits) -> LimitsLayer {
193 LimitsLayer {
194 limits,
195 events: 0,
196 items: Vec::new(),
197 }
198 }
199
200 fn count_item(&mut self, is_map_key: bool) -> Result<(), Error> {
202 if let (Some(max), Some((is_map, count))) = (self.limits.max_items, self.items.last_mut())
203 && (!*is_map || is_map_key)
204 {
205 *count += 1;
206 if *count > max {
207 return Err(limit_error("too many items"));
208 }
209 }
210 Ok(())
211 }
212}
213
214#[cold]
215fn limit_error(msg: &'static str) -> Error {
216 Error::new(ErrorKind::LimitExceeded, msg)
217}
218
219impl Layer for LimitsLayer {
220 fn event<'de>(
221 &mut self,
222 event: LayerEvent<'_, 'de>,
223 next: &mut Next<'_, 'de>,
224 ) -> Result<(), Error> {
225 if let Some(max) = self.limits.max_events {
226 self.events += 1;
227 if self.events > max {
228 return Err(limit_error("too many events"));
229 }
230 }
231 let is_map_key = next.state().is_map_key();
232 match event.event() {
233 Event::MapStart(_) | Event::SeqStart(_) => {
234 if self
235 .limits
236 .max_depth
237 .is_some_and(|max| next.state().depth() >= max)
238 {
239 return Err(limit_error("recursion limit exceeded"));
240 }
241 self.count_item(is_map_key)?;
242 if self.limits.max_items.is_some() {
243 self.items
244 .push((matches!(event.event(), Event::MapStart(_)), 0));
245 }
246 }
247 Event::MapEnd | Event::SeqEnd => {
248 self.items.pop();
249 }
250 Event::Atom(atom) => {
251 if let Some(max) = self.limits.max_len {
252 let len = match atom {
253 Atom::Str(s) | Atom::Lexical(s) => s.len(),
254 Atom::Bytes(b) => b.len(),
255 _ => 0,
256 };
257 if len > max {
258 return Err(limit_error("string or bytes too long"));
259 }
260 }
261 self.count_item(is_map_key)?;
262 }
263 }
264 next.emit(event)
265 }
266}