Skip to main content

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}