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 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    pub const DEFAULT: Self = Self {
67        list_members: 1024,
68        inner_list_members: 256,
69        params: 256,
70        dictionary_members: 1024,
71        key_len: 256,
72        string_len: 1024,
73        token_len: 512,
74        byte_seq_len: 16384,
75        empty_elements: 16,
76        comment_depth: 8,
77        ranges: 16,
78        rfc2231_sections: MAX_RFC2231_SECTIONS,
79        encoded_words: 64,
80        hops: 16,
81        allow_leap_second: false,
82        duplicate_params: DuplicatePolicy::Refuse,
83    };
84
85    /// The defaults; the same as [`Limits::DEFAULT`].
86    #[must_use]
87    pub const fn new() -> Self {
88        Self::DEFAULT
89    }
90
91    /// The most members a list may have (default 1024).
92    #[must_use]
93    pub const fn max_list_members(self, n: u16) -> Self {
94        Self {
95            list_members: n,
96            ..self
97        }
98    }
99
100    /// The most members a Structured Field inner list may have (default 256).
101    #[must_use]
102    pub const fn max_inner_list_members(self, n: u16) -> Self {
103        Self {
104            inner_list_members: n,
105            ..self
106        }
107    }
108
109    /// The most parameters an item or a field may have (default 256).
110    #[must_use]
111    pub const fn max_params(self, n: u16) -> Self {
112        Self { params: n, ..self }
113    }
114
115    /// The most members a Structured Field dictionary may have (default 1024).
116    #[must_use]
117    pub const fn max_dictionary_members(self, n: u16) -> Self {
118        Self {
119            dictionary_members: n,
120            ..self
121        }
122    }
123
124    /// The longest Structured Field key (default 256).
125    #[must_use]
126    pub const fn max_key_len(self, n: u16) -> Self {
127        Self { key_len: n, ..self }
128    }
129
130    /// The longest Structured Field string, decoded (default 1024).
131    #[must_use]
132    pub const fn max_string_len(self, n: u16) -> Self {
133        Self {
134            string_len: n,
135            ..self
136        }
137    }
138
139    /// The longest Structured Field token (default 512).
140    #[must_use]
141    pub const fn max_token_len(self, n: u16) -> Self {
142        Self {
143            token_len: n,
144            ..self
145        }
146    }
147
148    /// The longest Structured Field byte sequence, decoded (default 16384).
149    #[must_use]
150    pub const fn max_byte_seq_len(self, n: u32) -> Self {
151        Self {
152            byte_seq_len: n,
153            ..self
154        }
155    }
156
157    /// The most empty list elements accepted in one field (default 16).
158    #[must_use]
159    pub const fn max_empty_elements(self, n: u16) -> Self {
160        Self {
161            empty_elements: n,
162            ..self
163        }
164    }
165
166    /// The deepest comment nesting accepted (default 8).
167    #[must_use]
168    pub const fn max_comment_depth(self, n: u8) -> Self {
169        Self {
170            comment_depth: n,
171            ..self
172        }
173    }
174
175    /// The most ranges a `Range` field may request (default 16).
176    #[must_use]
177    pub const fn max_ranges(self, n: u16) -> Self {
178        Self { ranges: n, ..self }
179    }
180
181    /// The most RFC 2231 sections in one parameter (default 32). Values above
182    /// 32, the size of the reassembly array, are stored as 32.
183    #[must_use]
184    pub const fn max_rfc2231_sections(self, n: u8) -> Self {
185        let n = if n > MAX_RFC2231_SECTIONS {
186            MAX_RFC2231_SECTIONS
187        } else {
188            n
189        };
190        Self {
191            rfc2231_sections: n,
192            ..self
193        }
194    }
195
196    /// The most RFC 2047 encoded words in one field (default 64).
197    #[must_use]
198    pub const fn max_encoded_words(self, n: u16) -> Self {
199        Self {
200            encoded_words: n,
201            ..self
202        }
203    }
204
205    /// The most hops in a forwarded chain (default 16).
206    #[must_use]
207    pub const fn max_hops(self, n: u8) -> Self {
208        Self { hops: n, ..self }
209    }
210
211    /// Whether HTTP-date accepts second `60` (read as 59). Off by default.
212    #[must_use]
213    pub const fn allow_leap_second(self, yes: bool) -> Self {
214        Self {
215            allow_leap_second: yes,
216            ..self
217        }
218    }
219
220    /// What parameter parsers do with a repeated name (default
221    /// [`DuplicatePolicy::Refuse`]).
222    #[must_use]
223    pub const fn duplicate_params(self, p: DuplicatePolicy) -> Self {
224        Self {
225            duplicate_params: p,
226            ..self
227        }
228    }
229}
230
231impl Default for Limits {
232    fn default() -> Self {
233        Self::DEFAULT
234    }
235}
236
237/// What a parameter parser does when a name repeats.
238///
239/// Names compare ASCII case-insensitively. [`Refuse`](Self::Refuse), the
240/// default, fails with [`ErrorKind::DuplicateParameter`](crate::ErrorKind::DuplicateParameter)
241/// at the repeated name: a field one component reads first-wins and another
242/// last-wins is a known attack. [`First`](Self::First) and
243/// [`Last`](Self::Last) exist for fields whose RFC states the rule.
244/// Structured Fields always use last-wins, as RFC 9651 requires.
245///
246/// # Examples
247///
248/// ```
249/// use parse_net::{param, DuplicatePolicy, Limits};
250///
251/// let limits = Limits::DEFAULT.duplicate_params(DuplicatePolicy::Last);
252/// let (p, _) = param::parse(b";a=1;a=2", &limits)?;
253/// assert!(p.get("a").is_some_and(|v| v.eq_bytes(b"2")));
254/// # Ok::<(), parse_net::ParseError>(())
255/// ```
256#[non_exhaustive]
257#[derive(Clone, Copy, Debug, PartialEq, Eq, Hash, Default)]
258pub enum DuplicatePolicy {
259    /// Refuse a repeated name.
260    #[default]
261    Refuse,
262    /// Keep the first occurrence for lookups.
263    First,
264    /// Keep the last occurrence for lookups.
265    Last,
266}
267
268#[cfg(test)]
269mod tests {
270    use super::*;
271
272    #[test]
273    fn test_limits_defaults_meet_rfc_minimums() {
274        let l = Limits::new();
275        assert_eq!(l, Limits::default());
276        assert!(l.list_members >= 1024);
277        assert!(l.inner_list_members >= 256);
278        assert!(l.params >= 256);
279        assert!(l.dictionary_members >= 1024);
280        assert!(l.key_len >= 64);
281        assert!(l.string_len >= 1024);
282        assert!(l.token_len >= 512);
283        assert!(l.byte_seq_len >= 16384);
284        assert!(!l.allow_leap_second);
285        assert_eq!(l.duplicate_params, DuplicatePolicy::Refuse);
286    }
287
288    #[test]
289    fn test_limits_setters_set_one_field() {
290        let l = Limits::DEFAULT
291            .max_list_members(1)
292            .max_inner_list_members(2)
293            .max_params(3)
294            .max_dictionary_members(4)
295            .max_key_len(5)
296            .max_string_len(6)
297            .max_token_len(7)
298            .max_byte_seq_len(8)
299            .max_empty_elements(9)
300            .max_comment_depth(10)
301            .max_ranges(11)
302            .max_rfc2231_sections(12)
303            .max_encoded_words(13)
304            .max_hops(14)
305            .allow_leap_second(true)
306            .duplicate_params(DuplicatePolicy::First);
307        assert_eq!(
308            (
309                l.list_members,
310                l.inner_list_members,
311                l.params,
312                l.dictionary_members
313            ),
314            (1, 2, 3, 4)
315        );
316        assert_eq!(
317            (l.key_len, l.string_len, l.token_len, l.byte_seq_len),
318            (5, 6, 7, 8)
319        );
320        assert_eq!((l.empty_elements, l.comment_depth, l.ranges), (9, 10, 11));
321        assert_eq!((l.rfc2231_sections, l.encoded_words, l.hops), (12, 13, 14));
322        assert!(l.allow_leap_second);
323        assert_eq!(l.duplicate_params, DuplicatePolicy::First);
324    }
325
326    #[test]
327    fn test_limits_rfc2231_sections_capped_at_32() {
328        assert_eq!(
329            Limits::DEFAULT.max_rfc2231_sections(200).rfc2231_sections,
330            32
331        );
332    }
333}