parse_net/limits.rs
1//! [`Limits`], the work and size bounds every parser enforces, and
2//! [`DuplicatePolicy`].
3
4/// The work and size bounds every parser enforces.
5///
6/// Every bound is checked before the work it governs, and none allocates:
7/// they bound loops. The defaults meet every minimum RFC 9651 section 3 sets
8/// for parsers, so a conforming sender is never refused by default.
9///
10/// | Bound | Default | Source |
11/// |---|---|---|
12/// | list members | 1024 | RFC 9651 section 3.1 minimum |
13/// | inner list members | 256 | RFC 9651 section 3.1.1 minimum |
14/// | parameters per item or field | 256 | RFC 9651 section 3.1.2 minimum |
15/// | dictionary members | 1024 | RFC 9651 section 3.2 minimum |
16/// | key length | 256 | RFC 9651 minimum is 64 |
17/// | string length (decoded) | 1024 | RFC 9651 section 3.3.3 minimum |
18/// | token length | 512 | RFC 9651 section 3.3.4 minimum |
19/// | byte sequence length (decoded) | 16384 | RFC 9651 section 3.3.5 minimum |
20/// | empty list elements | 16 | RFC 9110 section 5.6.1.2: "a reasonable number" |
21/// | comment depth | 8 | none in the RFC |
22/// | ranges | 16 | RFC 9110 section 14.2 permits refusal |
23/// | RFC 2231 sections | 32 | none in the RFC |
24/// | encoded words per field | 64 | none in the RFC |
25/// | forwarded hops | 16 | none in the RFC |
26///
27/// A setter may set a bound below the RFC minimum: that is the caller
28/// tightening deliberately, and it makes the parser non-conforming for that
29/// field.
30///
31/// # Examples
32///
33/// ```
34/// use parse_net::{list, ErrorKind, Limits};
35///
36/// const STRICT: Limits = Limits::DEFAULT.max_list_members(64).max_params(16);
37/// let err = list::parse(b"a, b, c", &Limits::DEFAULT.max_list_members(2)).unwrap_err();
38/// assert_eq!((err.kind(), err.offset()), (ErrorKind::TooManyMembers, 6));
39/// # let _ = STRICT;
40/// ```
41#[derive(Clone, Copy, Debug, PartialEq, Eq, Hash)]
42pub struct Limits {
43 pub(crate) list_members: u16,
44 pub(crate) inner_list_members: u16,
45 pub(crate) params: u16,
46 pub(crate) dictionary_members: u16,
47 pub(crate) key_len: u16,
48 pub(crate) string_len: u16,
49 pub(crate) token_len: u16,
50 pub(crate) byte_seq_len: u32,
51 pub(crate) empty_elements: u16,
52 pub(crate) comment_depth: u8,
53 pub(crate) ranges: u16,
54 pub(crate) rfc2231_sections: u8,
55 pub(crate) encoded_words: u16,
56 pub(crate) hops: u8,
57 pub(crate) allow_leap_second: bool,
58 pub(crate) duplicate_params: DuplicatePolicy,
59}
60
61/// The size of the stack array that reassembles RFC 2231 sections.
62pub(crate) const MAX_RFC2231_SECTIONS: u8 = 32;
63
64impl Limits {
65 /// The defaults in the table above.
66 ///
67 /// # Examples
68 ///
69 /// ```
70 /// use parse_net::Limits;
71 ///
72 /// assert_eq!(Limits::DEFAULT, Limits::default());
73 /// let l = parse_net::list::parse(b"a, b, c", &Limits::DEFAULT)?;
74 /// assert_eq!(l.len(), 3);
75 /// # Ok::<(), parse_net::ParseError>(())
76 /// ```
77 pub const DEFAULT: Self = Self {
78 list_members: 1024,
79 inner_list_members: 256,
80 params: 256,
81 dictionary_members: 1024,
82 key_len: 256,
83 string_len: 1024,
84 token_len: 512,
85 byte_seq_len: 16384,
86 empty_elements: 16,
87 comment_depth: 8,
88 ranges: 16,
89 rfc2231_sections: MAX_RFC2231_SECTIONS,
90 encoded_words: 64,
91 hops: 16,
92 allow_leap_second: false,
93 duplicate_params: DuplicatePolicy::Refuse,
94 };
95
96 /// The defaults; the same as [`Limits::DEFAULT`].
97 ///
98 /// # Examples
99 ///
100 /// ```
101 /// use parse_net::Limits;
102 ///
103 /// const LIMITS: Limits = Limits::new();
104 /// assert_eq!(LIMITS, Limits::DEFAULT);
105 /// ```
106 #[must_use]
107 pub const fn new() -> Self {
108 Self::DEFAULT
109 }
110
111 /// The most members a list may have (default 1024).
112 ///
113 /// # Examples
114 ///
115 /// ```
116 /// use parse_net::{list, ErrorKind, Limits};
117 ///
118 /// let two = Limits::DEFAULT.max_list_members(2);
119 /// assert_eq!(list::parse(b"a, b", &two)?.len(), 2);
120 /// assert_eq!(list::parse(b"a, b, c", &two).unwrap_err().kind(), ErrorKind::TooManyMembers);
121 /// # Ok::<(), parse_net::ParseError>(())
122 /// ```
123 #[must_use]
124 pub const fn max_list_members(self, n: u16) -> Self {
125 Self {
126 list_members: n,
127 ..self
128 }
129 }
130
131 /// The most members a Structured Field inner list may have (default 256).
132 ///
133 /// # Examples
134 ///
135 /// ```
136 /// use parse_net::{sfv::Parser, ErrorKind, Limits};
137 ///
138 /// let p = Parser::new(Limits::DEFAULT.max_inner_list_members(2));
139 /// assert!(p.list(b"(a b), c").is_ok());
140 /// assert_eq!(p.list(b"(a b c)").unwrap_err().kind(), ErrorKind::TooManyMembers);
141 /// ```
142 #[must_use]
143 pub const fn max_inner_list_members(self, n: u16) -> Self {
144 Self {
145 inner_list_members: n,
146 ..self
147 }
148 }
149
150 /// The most parameters an item or a field may have (default 256).
151 ///
152 /// # Examples
153 ///
154 /// ```
155 /// use parse_net::{param, ErrorKind, Limits};
156 ///
157 /// let one = Limits::DEFAULT.max_params(1);
158 /// assert_eq!(param::parse(b";a=1", &one)?.0.len(), 1);
159 /// assert_eq!(param::parse(b";a=1;b=2", &one).unwrap_err().kind(), ErrorKind::TooManyMembers);
160 /// # Ok::<(), parse_net::ParseError>(())
161 /// ```
162 #[must_use]
163 pub const fn max_params(self, n: u16) -> Self {
164 Self { params: n, ..self }
165 }
166
167 /// The most members a Structured Field dictionary may have (default 1024).
168 ///
169 /// # Examples
170 ///
171 /// ```
172 /// use parse_net::{sfv::Parser, ErrorKind, Limits};
173 ///
174 /// let p = Parser::new(Limits::DEFAULT.max_dictionary_members(1));
175 /// assert!(p.dictionary(b"a=1").is_ok());
176 /// assert_eq!(p.dictionary(b"a=1, b=2").unwrap_err().kind(), ErrorKind::TooManyMembers);
177 /// ```
178 #[must_use]
179 pub const fn max_dictionary_members(self, n: u16) -> Self {
180 Self {
181 dictionary_members: n,
182 ..self
183 }
184 }
185
186 /// The longest Structured Field key (default 256).
187 ///
188 /// # Examples
189 ///
190 /// ```
191 /// use parse_net::{sfv::Parser, ErrorKind, Limits};
192 ///
193 /// let p = Parser::new(Limits::DEFAULT.max_key_len(3));
194 /// assert!(p.dictionary(b"abc=1").is_ok());
195 /// assert_eq!(p.dictionary(b"abcd=1").unwrap_err().kind(), ErrorKind::TooLong);
196 /// ```
197 #[must_use]
198 pub const fn max_key_len(self, n: u16) -> Self {
199 Self { key_len: n, ..self }
200 }
201
202 /// The longest Structured Field string, decoded (default 1024).
203 ///
204 /// # Examples
205 ///
206 /// ```
207 /// use parse_net::{sfv::Parser, ErrorKind, Limits};
208 ///
209 /// let p = Parser::new(Limits::DEFAULT.max_string_len(3));
210 /// assert!(p.item(b"\"a\\\"b\"").is_ok());
211 /// assert_eq!(p.item(b"\"abcd\"").unwrap_err().kind(), ErrorKind::TooLong);
212 /// ```
213 #[must_use]
214 pub const fn max_string_len(self, n: u16) -> Self {
215 Self {
216 string_len: n,
217 ..self
218 }
219 }
220
221 /// The longest Structured Field token (default 512).
222 ///
223 /// # Examples
224 ///
225 /// ```
226 /// use parse_net::{sfv::Parser, ErrorKind, Limits};
227 ///
228 /// let p = Parser::new(Limits::DEFAULT.max_token_len(4));
229 /// assert!(p.item(b"gzip").is_ok());
230 /// assert_eq!(p.item(b"deflate").unwrap_err().kind(), ErrorKind::TooLong);
231 /// ```
232 #[must_use]
233 pub const fn max_token_len(self, n: u16) -> Self {
234 Self {
235 token_len: n,
236 ..self
237 }
238 }
239
240 /// The longest Structured Field byte sequence, decoded (default 16384).
241 ///
242 /// # Examples
243 ///
244 /// ```
245 /// use parse_net::{sfv::Parser, ErrorKind, Limits};
246 ///
247 /// let p = Parser::new(Limits::DEFAULT.max_byte_seq_len(3));
248 /// assert!(p.item(b":AQID:").is_ok());
249 /// assert_eq!(p.item(b":AQIDBA==:").unwrap_err().kind(), ErrorKind::TooLong);
250 /// ```
251 #[must_use]
252 pub const fn max_byte_seq_len(self, n: u32) -> Self {
253 Self {
254 byte_seq_len: n,
255 ..self
256 }
257 }
258
259 /// The most empty list elements accepted in one field (default 16).
260 ///
261 /// # Examples
262 ///
263 /// ```
264 /// use parse_net::{list, ErrorKind, Limits};
265 ///
266 /// let one = Limits::DEFAULT.max_empty_elements(1);
267 /// assert_eq!(list::parse(b"a, , b", &one)?.len(), 2);
268 /// assert_eq!(list::parse(b"a, , , b", &one).unwrap_err().kind(), ErrorKind::TooManyEmptyElements);
269 /// # Ok::<(), parse_net::ParseError>(())
270 /// ```
271 #[must_use]
272 pub const fn max_empty_elements(self, n: u16) -> Self {
273 Self {
274 empty_elements: n,
275 ..self
276 }
277 }
278
279 /// The deepest comment nesting accepted (default 8).
280 ///
281 /// # Examples
282 ///
283 /// ```
284 /// use parse_net::{text::parse_comment, ErrorKind, Limits};
285 ///
286 /// let flat = Limits::DEFAULT.max_comment_depth(1);
287 /// assert!(parse_comment(b"(a)", &flat).is_ok());
288 /// assert_eq!(parse_comment(b"(a(b))", &flat).unwrap_err().kind(), ErrorKind::CommentTooDeep);
289 /// ```
290 #[must_use]
291 pub const fn max_comment_depth(self, n: u8) -> Self {
292 Self {
293 comment_depth: n,
294 ..self
295 }
296 }
297
298 /// The most ranges a `Range` field may request (default 16).
299 ///
300 /// # Examples
301 ///
302 /// ```
303 /// use parse_net::{range, ByteRange, Limits, RangeOutcome};
304 ///
305 /// let h = range::parse(b"bytes=0-9, 20-29", &Limits::DEFAULT)?;
306 /// let mut out = [ByteRange { start: 0, end: 0 }; 4];
307 /// assert_eq!(range::resolve(&h, 100, false, &Limits::DEFAULT, &mut out), RangeOutcome::Ranges(2));
308 /// assert_eq!(range::resolve(&h, 100, false, &Limits::DEFAULT.max_ranges(1), &mut out), RangeOutcome::Ignore);
309 /// # Ok::<(), parse_net::ParseError>(())
310 /// ```
311 #[must_use]
312 pub const fn max_ranges(self, n: u16) -> Self {
313 Self { ranges: n, ..self }
314 }
315
316 /// The most RFC 2231 sections in one parameter (default 32). Values above
317 /// 32, the size of the reassembly array, are stored as 32.
318 ///
319 /// # Examples
320 ///
321 /// ```
322 /// use parse_net::{mail, ErrorKind, Limits};
323 ///
324 /// let two = Limits::DEFAULT.max_rfc2231_sections(2);
325 /// assert!(mail::parse_mime_params(b"; t*0=a; t*1=b", &two).is_ok());
326 /// let err = mail::parse_mime_params(b"; t*0=a; t*1=b; t*2=c", &two).unwrap_err();
327 /// assert_eq!(err.kind(), ErrorKind::TooManySections);
328 /// ```
329 #[must_use]
330 pub const fn max_rfc2231_sections(self, n: u8) -> Self {
331 let n = if n > MAX_RFC2231_SECTIONS {
332 MAX_RFC2231_SECTIONS
333 } else {
334 n
335 };
336 Self {
337 rfc2231_sections: n,
338 ..self
339 }
340 }
341
342 /// The most RFC 2047 encoded words in one field (default 64).
343 ///
344 /// # Examples
345 ///
346 /// ```
347 /// use parse_net::{mail, ErrorKind, Limits};
348 ///
349 /// let one = Limits::DEFAULT.max_encoded_words(1);
350 /// let mut buf = [0u8; 16];
351 /// assert_eq!(mail::decode_words(b"=?utf-8?q?a?=", &one, &mut buf)?, "a");
352 /// let err = mail::decode_words(b"=?utf-8?q?a?= =?utf-8?q?b?=", &one, &mut buf).unwrap_err();
353 /// assert_eq!(err.kind(), ErrorKind::TooManyMembers);
354 /// # Ok::<(), parse_net::ParseError>(())
355 /// ```
356 #[must_use]
357 pub const fn max_encoded_words(self, n: u16) -> Self {
358 Self {
359 encoded_words: n,
360 ..self
361 }
362 }
363
364 /// The most hops in a forwarded chain (default 16).
365 ///
366 /// # Examples
367 ///
368 /// ```
369 /// use parse_net::{forwarded, ErrorKind, Limits};
370 ///
371 /// let lines = [&b"192.0.2.1, 198.51.100.2"[..]];
372 /// assert!(forwarded::parse_x_forwarded_for(&lines, &Limits::DEFAULT).is_ok());
373 /// let err = forwarded::parse_x_forwarded_for(&lines, &Limits::DEFAULT.max_hops(1)).unwrap_err();
374 /// assert_eq!(err.kind(), ErrorKind::TooManyHops);
375 /// ```
376 #[must_use]
377 pub const fn max_hops(self, n: u8) -> Self {
378 Self { hops: n, ..self }
379 }
380
381 /// Whether HTTP-date accepts second `60` (read as 59). Off by default.
382 ///
383 /// # Examples
384 ///
385 /// ```
386 /// use parse_net::{HttpDate, Limits};
387 ///
388 /// let leap = b"Sun, 06 Nov 1994 08:49:60 GMT";
389 /// assert!(HttpDate::parse_at_with(leap, 0, &Limits::DEFAULT).is_err());
390 /// let d = HttpDate::parse_at_with(leap, 0, &Limits::DEFAULT.allow_leap_second(true))?;
391 /// assert_eq!(d, HttpDate::parse_imf_fixdate(b"Sun, 06 Nov 1994 08:49:59 GMT")?);
392 /// # Ok::<(), parse_net::ParseError>(())
393 /// ```
394 #[must_use]
395 pub const fn allow_leap_second(self, yes: bool) -> Self {
396 Self {
397 allow_leap_second: yes,
398 ..self
399 }
400 }
401
402 /// What parameter parsers do with a repeated name (default
403 /// [`DuplicatePolicy::Refuse`]).
404 ///
405 /// # Examples
406 ///
407 /// ```
408 /// use parse_net::{param, DuplicatePolicy, Limits};
409 ///
410 /// assert!(param::parse(b";a=1;a=2", &Limits::DEFAULT).is_err());
411 /// let last = Limits::DEFAULT.duplicate_params(DuplicatePolicy::Last);
412 /// let (p, _) = param::parse(b";a=1;a=2", &last)?;
413 /// assert!(p.get("a").is_some_and(|v| v.eq_bytes(b"2")));
414 /// # Ok::<(), parse_net::ParseError>(())
415 /// ```
416 #[must_use]
417 pub const fn duplicate_params(self, p: DuplicatePolicy) -> Self {
418 Self {
419 duplicate_params: p,
420 ..self
421 }
422 }
423}
424
425impl Default for Limits {
426 fn default() -> Self {
427 Self::DEFAULT
428 }
429}
430
431/// What a parameter parser does when a name repeats.
432///
433/// Names compare ASCII case-insensitively. [`Refuse`](Self::Refuse), the
434/// default, fails with [`ErrorKind::DuplicateParameter`](crate::ErrorKind::DuplicateParameter)
435/// at the repeated name: a field one component reads first-wins and another
436/// last-wins is a known attack. [`First`](Self::First) and
437/// [`Last`](Self::Last) exist for fields whose RFC states the rule.
438/// Structured Fields always use last-wins, as RFC 9651 requires.
439///
440/// # Examples
441///
442/// ```
443/// use parse_net::{param, DuplicatePolicy, Limits};
444///
445/// let limits = Limits::DEFAULT.duplicate_params(DuplicatePolicy::Last);
446/// let (p, _) = param::parse(b";a=1;a=2", &limits)?;
447/// assert!(p.get("a").is_some_and(|v| v.eq_bytes(b"2")));
448/// # Ok::<(), parse_net::ParseError>(())
449/// ```
450#[non_exhaustive]
451#[derive(Clone, Copy, Debug, PartialEq, Eq, Hash, Default)]
452pub enum DuplicatePolicy {
453 /// Refuse a repeated name.
454 #[default]
455 Refuse,
456 /// Keep the first occurrence for lookups.
457 First,
458 /// Keep the last occurrence for lookups.
459 Last,
460}
461
462#[cfg(test)]
463mod tests {
464 use super::*;
465
466 #[test]
467 fn test_limits_defaults_meet_rfc_minimums() {
468 let l = Limits::new();
469 assert_eq!(l, Limits::default());
470 assert!(l.list_members >= 1024);
471 assert!(l.inner_list_members >= 256);
472 assert!(l.params >= 256);
473 assert!(l.dictionary_members >= 1024);
474 assert!(l.key_len >= 64);
475 assert!(l.string_len >= 1024);
476 assert!(l.token_len >= 512);
477 assert!(l.byte_seq_len >= 16384);
478 assert!(!l.allow_leap_second);
479 assert_eq!(l.duplicate_params, DuplicatePolicy::Refuse);
480 }
481
482 #[test]
483 fn test_limits_setters_set_one_field() {
484 let l = Limits::DEFAULT
485 .max_list_members(1)
486 .max_inner_list_members(2)
487 .max_params(3)
488 .max_dictionary_members(4)
489 .max_key_len(5)
490 .max_string_len(6)
491 .max_token_len(7)
492 .max_byte_seq_len(8)
493 .max_empty_elements(9)
494 .max_comment_depth(10)
495 .max_ranges(11)
496 .max_rfc2231_sections(12)
497 .max_encoded_words(13)
498 .max_hops(14)
499 .allow_leap_second(true)
500 .duplicate_params(DuplicatePolicy::First);
501 assert_eq!(
502 (
503 l.list_members,
504 l.inner_list_members,
505 l.params,
506 l.dictionary_members
507 ),
508 (1, 2, 3, 4)
509 );
510 assert_eq!(
511 (l.key_len, l.string_len, l.token_len, l.byte_seq_len),
512 (5, 6, 7, 8)
513 );
514 assert_eq!((l.empty_elements, l.comment_depth, l.ranges), (9, 10, 11));
515 assert_eq!((l.rfc2231_sections, l.encoded_words, l.hops), (12, 13, 14));
516 assert!(l.allow_leap_second);
517 assert_eq!(l.duplicate_params, DuplicatePolicy::First);
518 }
519
520 #[test]
521 fn test_limits_rfc2231_sections_capped_at_32() {
522 assert_eq!(
523 Limits::DEFAULT.max_rfc2231_sections(200).rfc2231_sections,
524 32
525 );
526 }
527}