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 9110 parameters under `DuplicatePolicy::Refuse`: at most 64, [`param::MAX_CHECKED_PARAMS`](crate::param::MAX_CHECKED_PARAMS)) | 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 /// RFC 9110 parameters read under [`DuplicatePolicy::Refuse`] stop at
153 /// [`MAX_CHECKED_PARAMS`](crate::param::MAX_CHECKED_PARAMS) (64) whatever
154 /// this says: the repeat check keeps their names on the stack (D-072).
155 ///
156 /// # Examples
157 ///
158 /// ```
159 /// use parse_net::{param, ErrorKind, Limits};
160 ///
161 /// let one = Limits::DEFAULT.max_params(1);
162 /// assert_eq!(param::parse(b";a=1", &one)?.0.len(), 1);
163 /// assert_eq!(param::parse(b";a=1;b=2", &one).unwrap_err().kind(), ErrorKind::TooManyMembers);
164 /// # Ok::<(), parse_net::ParseError>(())
165 /// ```
166 #[must_use]
167 pub const fn max_params(self, n: u16) -> Self {
168 Self { params: n, ..self }
169 }
170
171 /// The most members a Structured Field dictionary may have (default 1024).
172 ///
173 /// # Examples
174 ///
175 /// ```
176 /// use parse_net::{sfv::Parser, ErrorKind, Limits};
177 ///
178 /// let p = Parser::new(Limits::DEFAULT.max_dictionary_members(1));
179 /// assert!(p.dictionary(b"a=1").is_ok());
180 /// assert_eq!(p.dictionary(b"a=1, b=2").unwrap_err().kind(), ErrorKind::TooManyMembers);
181 /// ```
182 #[must_use]
183 pub const fn max_dictionary_members(self, n: u16) -> Self {
184 Self {
185 dictionary_members: n,
186 ..self
187 }
188 }
189
190 /// The longest Structured Field key (default 256).
191 ///
192 /// # Examples
193 ///
194 /// ```
195 /// use parse_net::{sfv::Parser, ErrorKind, Limits};
196 ///
197 /// let p = Parser::new(Limits::DEFAULT.max_key_len(3));
198 /// assert!(p.dictionary(b"abc=1").is_ok());
199 /// assert_eq!(p.dictionary(b"abcd=1").unwrap_err().kind(), ErrorKind::TooLong);
200 /// ```
201 #[must_use]
202 pub const fn max_key_len(self, n: u16) -> Self {
203 Self { key_len: n, ..self }
204 }
205
206 /// The longest Structured Field string, decoded (default 1024).
207 ///
208 /// # Examples
209 ///
210 /// ```
211 /// use parse_net::{sfv::Parser, ErrorKind, Limits};
212 ///
213 /// let p = Parser::new(Limits::DEFAULT.max_string_len(3));
214 /// assert!(p.item(b"\"a\\\"b\"").is_ok());
215 /// assert_eq!(p.item(b"\"abcd\"").unwrap_err().kind(), ErrorKind::TooLong);
216 /// ```
217 #[must_use]
218 pub const fn max_string_len(self, n: u16) -> Self {
219 Self {
220 string_len: n,
221 ..self
222 }
223 }
224
225 /// The longest Structured Field token (default 512).
226 ///
227 /// # Examples
228 ///
229 /// ```
230 /// use parse_net::{sfv::Parser, ErrorKind, Limits};
231 ///
232 /// let p = Parser::new(Limits::DEFAULT.max_token_len(4));
233 /// assert!(p.item(b"gzip").is_ok());
234 /// assert_eq!(p.item(b"deflate").unwrap_err().kind(), ErrorKind::TooLong);
235 /// ```
236 #[must_use]
237 pub const fn max_token_len(self, n: u16) -> Self {
238 Self {
239 token_len: n,
240 ..self
241 }
242 }
243
244 /// The longest Structured Field byte sequence, decoded (default 16384).
245 ///
246 /// # Examples
247 ///
248 /// ```
249 /// use parse_net::{sfv::Parser, ErrorKind, Limits};
250 ///
251 /// let p = Parser::new(Limits::DEFAULT.max_byte_seq_len(3));
252 /// assert!(p.item(b":AQID:").is_ok());
253 /// assert_eq!(p.item(b":AQIDBA==:").unwrap_err().kind(), ErrorKind::TooLong);
254 /// ```
255 #[must_use]
256 pub const fn max_byte_seq_len(self, n: u32) -> Self {
257 Self {
258 byte_seq_len: n,
259 ..self
260 }
261 }
262
263 /// The most empty list elements accepted in one field (default 16).
264 ///
265 /// # Examples
266 ///
267 /// ```
268 /// use parse_net::{list, ErrorKind, Limits};
269 ///
270 /// let one = Limits::DEFAULT.max_empty_elements(1);
271 /// assert_eq!(list::parse(b"a, , b", &one)?.len(), 2);
272 /// assert_eq!(list::parse(b"a, , , b", &one).unwrap_err().kind(), ErrorKind::TooManyEmptyElements);
273 /// # Ok::<(), parse_net::ParseError>(())
274 /// ```
275 #[must_use]
276 pub const fn max_empty_elements(self, n: u16) -> Self {
277 Self {
278 empty_elements: n,
279 ..self
280 }
281 }
282
283 /// The deepest comment nesting accepted (default 8).
284 ///
285 /// # Examples
286 ///
287 /// ```
288 /// use parse_net::{text::parse_comment, ErrorKind, Limits};
289 ///
290 /// let flat = Limits::DEFAULT.max_comment_depth(1);
291 /// assert!(parse_comment(b"(a)", &flat).is_ok());
292 /// assert_eq!(parse_comment(b"(a(b))", &flat).unwrap_err().kind(), ErrorKind::CommentTooDeep);
293 /// ```
294 #[must_use]
295 pub const fn max_comment_depth(self, n: u8) -> Self {
296 Self {
297 comment_depth: n,
298 ..self
299 }
300 }
301
302 /// The most ranges a `Range` field may request (default 16).
303 ///
304 /// # Examples
305 ///
306 /// ```
307 /// use parse_net::{range, ByteRange, Limits, RangeOutcome};
308 ///
309 /// let h = range::parse(b"bytes=0-9, 20-29", &Limits::DEFAULT)?;
310 /// let mut out = [ByteRange { start: 0, end: 0 }; 4];
311 /// assert_eq!(range::resolve(&h, 100, false, &Limits::DEFAULT, &mut out), RangeOutcome::Ranges(2));
312 /// assert_eq!(range::resolve(&h, 100, false, &Limits::DEFAULT.max_ranges(1), &mut out), RangeOutcome::Ignore);
313 /// # Ok::<(), parse_net::ParseError>(())
314 /// ```
315 #[must_use]
316 pub const fn max_ranges(self, n: u16) -> Self {
317 Self { ranges: n, ..self }
318 }
319
320 /// The most RFC 2231 sections in one parameter (default 32). Values above
321 /// 32, the size of the reassembly array, are stored as 32.
322 ///
323 /// # Examples
324 ///
325 /// ```
326 /// use parse_net::{mail, ErrorKind, Limits};
327 ///
328 /// let two = Limits::DEFAULT.max_rfc2231_sections(2);
329 /// assert!(mail::parse_mime_params(b"; t*0=a; t*1=b", &two).is_ok());
330 /// let err = mail::parse_mime_params(b"; t*0=a; t*1=b; t*2=c", &two).unwrap_err();
331 /// assert_eq!(err.kind(), ErrorKind::TooManySections);
332 /// ```
333 #[must_use]
334 pub const fn max_rfc2231_sections(self, n: u8) -> Self {
335 let n = if n > MAX_RFC2231_SECTIONS {
336 MAX_RFC2231_SECTIONS
337 } else {
338 n
339 };
340 Self {
341 rfc2231_sections: n,
342 ..self
343 }
344 }
345
346 /// The most RFC 2047 encoded words in one field (default 64).
347 ///
348 /// # Examples
349 ///
350 /// ```
351 /// use parse_net::{mail, ErrorKind, Limits};
352 ///
353 /// let one = Limits::DEFAULT.max_encoded_words(1);
354 /// let mut buf = [0u8; 16];
355 /// assert_eq!(mail::decode_words(b"=?utf-8?q?a?=", &one, &mut buf)?, "a");
356 /// let err = mail::decode_words(b"=?utf-8?q?a?= =?utf-8?q?b?=", &one, &mut buf).unwrap_err();
357 /// assert_eq!(err.kind(), ErrorKind::TooManyMembers);
358 /// # Ok::<(), parse_net::ParseError>(())
359 /// ```
360 #[must_use]
361 pub const fn max_encoded_words(self, n: u16) -> Self {
362 Self {
363 encoded_words: n,
364 ..self
365 }
366 }
367
368 /// The most hops in a forwarded chain (default 16).
369 ///
370 /// # Examples
371 ///
372 /// ```
373 /// use parse_net::{forwarded, ErrorKind, Limits};
374 ///
375 /// let lines = [&b"192.0.2.1, 198.51.100.2"[..]];
376 /// assert!(forwarded::parse_x_forwarded_for(&lines, &Limits::DEFAULT).is_ok());
377 /// let err = forwarded::parse_x_forwarded_for(&lines, &Limits::DEFAULT.max_hops(1)).unwrap_err();
378 /// assert_eq!(err.kind(), ErrorKind::TooManyHops);
379 /// ```
380 #[must_use]
381 pub const fn max_hops(self, n: u8) -> Self {
382 Self { hops: n, ..self }
383 }
384
385 /// Whether HTTP-date accepts second `60` (read as 59). Off by default.
386 ///
387 /// # Examples
388 ///
389 /// ```
390 /// use parse_net::{HttpDate, Limits};
391 ///
392 /// let leap = b"Sun, 06 Nov 1994 08:49:60 GMT";
393 /// assert!(HttpDate::parse_at_with(leap, 0, &Limits::DEFAULT).is_err());
394 /// let d = HttpDate::parse_at_with(leap, 0, &Limits::DEFAULT.allow_leap_second(true))?;
395 /// assert_eq!(d, HttpDate::parse_imf_fixdate(b"Sun, 06 Nov 1994 08:49:59 GMT")?);
396 /// # Ok::<(), parse_net::ParseError>(())
397 /// ```
398 #[must_use]
399 pub const fn allow_leap_second(self, yes: bool) -> Self {
400 Self {
401 allow_leap_second: yes,
402 ..self
403 }
404 }
405
406 /// What parameter parsers do with a repeated name (default
407 /// [`DuplicatePolicy::Refuse`]).
408 ///
409 /// # Examples
410 ///
411 /// ```
412 /// use parse_net::{param, DuplicatePolicy, Limits};
413 ///
414 /// assert!(param::parse(b";a=1;a=2", &Limits::DEFAULT).is_err());
415 /// let last = Limits::DEFAULT.duplicate_params(DuplicatePolicy::Last);
416 /// let (p, _) = param::parse(b";a=1;a=2", &last)?;
417 /// assert!(p.get("a").is_some_and(|v| v.eq_bytes(b"2")));
418 /// # Ok::<(), parse_net::ParseError>(())
419 /// ```
420 #[must_use]
421 pub const fn duplicate_params(self, p: DuplicatePolicy) -> Self {
422 Self {
423 duplicate_params: p,
424 ..self
425 }
426 }
427}
428
429impl Default for Limits {
430 fn default() -> Self {
431 Self::DEFAULT
432 }
433}
434
435/// What a parameter parser does when a name repeats.
436///
437/// Names compare ASCII case-insensitively. [`Refuse`](Self::Refuse), the
438/// default, fails with [`ErrorKind::DuplicateParameter`](crate::ErrorKind::DuplicateParameter)
439/// at the repeated name: a field one component reads first-wins and another
440/// last-wins is a known attack. [`First`](Self::First) and
441/// [`Last`](Self::Last) exist for fields whose RFC states the rule.
442/// Structured Fields always use last-wins, as RFC 9651 requires.
443///
444/// # Examples
445///
446/// ```
447/// use parse_net::{param, DuplicatePolicy, Limits};
448///
449/// let limits = Limits::DEFAULT.duplicate_params(DuplicatePolicy::Last);
450/// let (p, _) = param::parse(b";a=1;a=2", &limits)?;
451/// assert!(p.get("a").is_some_and(|v| v.eq_bytes(b"2")));
452/// # Ok::<(), parse_net::ParseError>(())
453/// ```
454#[non_exhaustive]
455#[derive(Clone, Copy, Debug, PartialEq, Eq, Hash, Default)]
456pub enum DuplicatePolicy {
457 /// Refuse a repeated name.
458 #[default]
459 Refuse,
460 /// Keep the first occurrence for lookups.
461 First,
462 /// Keep the last occurrence for lookups.
463 Last,
464}
465
466#[cfg(test)]
467mod tests {
468 use super::*;
469
470 #[test]
471 fn test_limits_defaults_meet_rfc_minimums() {
472 let l = Limits::new();
473 assert_eq!(l, Limits::default());
474 assert!(l.list_members >= 1024);
475 assert!(l.inner_list_members >= 256);
476 assert!(l.params >= 256);
477 assert!(l.dictionary_members >= 1024);
478 assert!(l.key_len >= 64);
479 assert!(l.string_len >= 1024);
480 assert!(l.token_len >= 512);
481 assert!(l.byte_seq_len >= 16384);
482 assert!(!l.allow_leap_second);
483 assert_eq!(l.duplicate_params, DuplicatePolicy::Refuse);
484 }
485
486 #[test]
487 fn test_limits_setters_set_one_field() {
488 let l = Limits::DEFAULT
489 .max_list_members(1)
490 .max_inner_list_members(2)
491 .max_params(3)
492 .max_dictionary_members(4)
493 .max_key_len(5)
494 .max_string_len(6)
495 .max_token_len(7)
496 .max_byte_seq_len(8)
497 .max_empty_elements(9)
498 .max_comment_depth(10)
499 .max_ranges(11)
500 .max_rfc2231_sections(12)
501 .max_encoded_words(13)
502 .max_hops(14)
503 .allow_leap_second(true)
504 .duplicate_params(DuplicatePolicy::First);
505 assert_eq!(
506 (
507 l.list_members,
508 l.inner_list_members,
509 l.params,
510 l.dictionary_members
511 ),
512 (1, 2, 3, 4)
513 );
514 assert_eq!(
515 (l.key_len, l.string_len, l.token_len, l.byte_seq_len),
516 (5, 6, 7, 8)
517 );
518 assert_eq!((l.empty_elements, l.comment_depth, l.ranges), (9, 10, 11));
519 assert_eq!((l.rfc2231_sections, l.encoded_words, l.hops), (12, 13, 14));
520 assert!(l.allow_leap_second);
521 assert_eq!(l.duplicate_params, DuplicatePolicy::First);
522 }
523
524 #[test]
525 fn test_limits_rfc2231_sections_capped_at_32() {
526 assert_eq!(
527 Limits::DEFAULT.max_rfc2231_sections(200).rfc2231_sections,
528 32
529 );
530 }
531}