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}