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 /// Maximum number of symbols in a single entropy channel.
26 pub max_channel_symbols: u64,
27 /// Maximum number of distinct entropy models (`MODEL` records).
28 pub max_model_count: u32,
29 /// Maximum number of entropy channels (`ENTROPY_CHANNEL` records).
30 pub max_channel_count: u32,
31 /// Maximum encoded size of a single entropy model payload.
32 pub max_entropy_model_bytes: u32,
33}
34
35impl Limits {
36 /// The default archival limits: generous, but always finite.
37 pub const DEFAULT: Limits = Limits {
38 max_input_bytes: 1 << 40, // 1 TiB
39 max_output_bytes: 1 << 40, // 1 TiB
40 max_record_len: 1 << 31, // 2 GiB
41 max_record_count: 1 << 20, // ~1M records
42 max_object_count: 1 << 20,
43 max_graph_ops: 1 << 20,
44 max_repeat_count: 1 << 32,
45 max_channel_symbols: 1 << 40,
46 max_model_count: 1 << 16,
47 max_channel_count: 1 << 16,
48 max_entropy_model_bytes: 4096,
49 };
50
51 /// Tight limits for hostile-input testing and fuzzing.
52 pub const STRICT: Limits = Limits {
53 max_input_bytes: 1 << 26, // 64 MiB
54 max_output_bytes: 1 << 26, // 64 MiB
55 max_record_len: 1 << 24, // 16 MiB
56 max_record_count: 1 << 16, // 65536
57 max_object_count: 1 << 16,
58 max_graph_ops: 1 << 16,
59 max_repeat_count: 1 << 24,
60 max_channel_symbols: 1 << 26,
61 max_model_count: 1 << 12,
62 max_channel_count: 1 << 12,
63 max_entropy_model_bytes: 4096,
64 };
65}
66
67impl Default for Limits {
68 fn default() -> Self {
69 Limits::DEFAULT
70 }
71}