vole_document/limits.rs
1//! Centralized resource bounds.
2//!
3//! Every decode and encode path takes a [`Limits`]. Untrusted descriptors must
4//! be rejected *before* catastrophic work is performed, so all arithmetic on
5//! declared lengths and offsets is checked against these bounds and uses
6//! checked integer operations.
7
8/// Hard upper bounds applied while parsing and materializing a descriptor.
9#[derive(Debug, Clone, Copy, PartialEq, Eq)]
10pub struct Limits {
11 /// Maximum accepted source/descriptor input size.
12 pub max_input_bytes: u64,
13 /// Maximum reconstructed output size for a single materialization.
14 pub max_output_bytes: u64,
15 /// Maximum length of a single record payload.
16 pub max_record_len: u32,
17 /// Maximum number of records in a container.
18 pub max_record_count: u32,
19 /// Maximum number of distinct byte objects (`OBJECT` records).
20 pub max_object_count: u32,
21 /// Maximum number of DRA instructions in a reconstruction graph.
22 pub max_graph_ops: u32,
23 /// Maximum repeat count for a single `REPEAT_LAST` instruction.
24 pub max_repeat_count: u64,
25}
26
27impl Limits {
28 /// The default archival limits: generous, but always finite.
29 pub const DEFAULT: Limits = Limits {
30 max_input_bytes: 1 << 40, // 1 TiB
31 max_output_bytes: 1 << 40, // 1 TiB
32 max_record_len: 1 << 31, // 2 GiB
33 max_record_count: 1 << 20, // ~1M records
34 max_object_count: 1 << 20,
35 max_graph_ops: 1 << 20,
36 max_repeat_count: 1 << 32,
37 };
38
39 /// Tight limits for hostile-input testing and fuzzing.
40 pub const STRICT: Limits = Limits {
41 max_input_bytes: 1 << 26, // 64 MiB
42 max_output_bytes: 1 << 26, // 64 MiB
43 max_record_len: 1 << 24, // 16 MiB
44 max_record_count: 1 << 16, // 65536
45 max_object_count: 1 << 16,
46 max_graph_ops: 1 << 16,
47 max_repeat_count: 1 << 24,
48 };
49}
50
51impl Default for Limits {
52 fn default() -> Self {
53 Limits::DEFAULT
54 }
55}