Skip to main content

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}