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    /// Admission cap on the output of a single `DEFLATE_REPLAY`.
16    ///
17    /// This is a **VOLE replay-profile policy limit**, not an RFC 1951 maximum.
18    /// RFC 1951 permits arbitrarily many empty non-final stored blocks, so it
19    /// gives no finite `f(decompressed_size)` bound on `compressed_size`; a
20    /// bitstream that inflates to zero bytes may be arbitrarily large. VOLE
21    /// therefore declines to replay a descriptor whose declared output exceeds
22    /// this policy cap (see ADR-0016).
23    pub max_replay_bytes: u64,
24    /// Maximum length of a single record payload.
25    pub max_record_len: u32,
26    /// Maximum number of records in a container.
27    pub max_record_count: u32,
28    /// Maximum number of distinct byte objects (`OBJECT` records).
29    pub max_object_count: u32,
30    /// Maximum number of DRA instructions in a reconstruction graph.
31    pub max_graph_ops: u32,
32    /// Maximum repeat count for a single `REPEAT_LAST` instruction.
33    pub max_repeat_count: u64,
34    /// Maximum number of symbols in a single entropy channel.
35    pub max_channel_symbols: u64,
36    /// Maximum number of distinct entropy models (`MODEL` records).
37    pub max_model_count: u32,
38    /// Maximum number of entropy channels (`ENTROPY_CHANNEL` records).
39    pub max_channel_count: u32,
40    /// Maximum encoded size of a single entropy model payload.
41    pub max_entropy_model_bytes: u32,
42    /// Maximum number of lexical spans produced for a PDF input.
43    pub max_pdf_spans: u32,
44    /// Maximum number of selectors in a single `OBSERVATION_INDEX` record.
45    ///
46    /// Bounds the admissions of the optional partial-decode index (Phase 7.3)
47    /// before allocation: an index whose selector table would exceed this is
48    /// rejected at parse and declined by the index builder. It mirrors the
49    /// object/graph scale so the table cannot dwarf the document it describes.
50    pub max_index_selectors: u32,
51}
52
53impl Limits {
54    /// The default archival limits: generous, but always finite.
55    pub const DEFAULT: Limits = Limits {
56        max_input_bytes: 1 << 40,  // 1 TiB
57        max_output_bytes: 1 << 40, // 1 TiB
58        max_replay_bytes: 1 << 34, // 16 GiB
59        max_record_len: 1 << 31,   // 2 GiB
60        max_record_count: 1 << 20, // ~1M records
61        max_object_count: 1 << 20,
62        max_graph_ops: 1 << 20,
63        max_repeat_count: 1 << 32,
64        max_channel_symbols: 1 << 40,
65        max_model_count: 1 << 16,
66        max_channel_count: 1 << 16,
67        max_entropy_model_bytes: 4096,
68        max_pdf_spans: 1 << 26,
69        max_index_selectors: 1 << 20,
70    };
71
72    /// Tight limits for hostile-input testing and fuzzing.
73    pub const STRICT: Limits = Limits {
74        max_input_bytes: 1 << 26,  // 64 MiB
75        max_output_bytes: 1 << 26, // 64 MiB
76        max_replay_bytes: 1 << 26, // 64 MiB
77        max_record_len: 1 << 24,   // 16 MiB
78        max_record_count: 1 << 16, // 65536
79        max_object_count: 1 << 16,
80        max_graph_ops: 1 << 16,
81        max_repeat_count: 1 << 24,
82        max_channel_symbols: 1 << 26,
83        max_model_count: 1 << 12,
84        max_channel_count: 1 << 12,
85        max_entropy_model_bytes: 4096,
86        max_pdf_spans: 1 << 16,
87        max_index_selectors: 1 << 16,
88    };
89}
90
91impl Default for Limits {
92    fn default() -> Self {
93        Limits::DEFAULT
94    }
95}