ifc_lite_landxml/
limits.rs

1/* This Source Code Form is subject to the terms of the Mozilla Public
2 * License, v. 2.0. If a copy of the MPL was not distributed with this
3 * file, You can obtain one at https://mozilla.org/MPL/2.0/. */
4
5use std::sync::atomic::{AtomicBool, Ordering};
6
7/// Cooperative cancellation hook for hosts that run ingestion off-thread.
8pub trait LandXmlCancellation: Send + Sync {
9    fn is_cancelled(&self) -> bool;
10}
11
12/// Share this flag with a native task and call [`Self::cancel`] from its host.
13#[derive(Default)]
14pub struct LandXmlCancellationFlag {
15    cancelled: AtomicBool,
16}
17
18impl LandXmlCancellationFlag {
19    pub const fn new() -> Self {
20        Self {
21            cancelled: AtomicBool::new(false),
22        }
23    }
24    pub fn cancel(&self) {
25        self.cancelled.store(true, Ordering::Release);
26    }
27    pub fn reset(&self) {
28        self.cancelled.store(false, Ordering::Release);
29    }
30}
31
32impl LandXmlCancellation for LandXmlCancellationFlag {
33    fn is_cancelled(&self) -> bool {
34        self.cancelled.load(Ordering::Acquire)
35    }
36}
37
38/// Hard limits applied before semantic allocations grow with untrusted input.
39#[derive(Clone, Debug)]
40pub struct LandXmlLimits {
41    pub max_bytes: usize,
42    pub max_depth: usize,
43    pub max_name_bytes: usize,
44    pub max_attributes: usize,
45    pub max_attribute_bytes: usize,
46    pub max_text_bytes: usize,
47    /// Maximum predefined or numeric XML character references after DTD refusal.
48    pub max_character_references: usize,
49    /// Maximum LandXML `Surface` records, including non-TIN surfaces we skip.
50    pub max_surfaces: usize,
51    /// Maximum LandXML `PipeNetwork` records, including refused networks.
52    pub max_pipe_networks: usize,
53    /// Maximum pipe-network `Struct` records across a document.
54    pub max_pipe_structures: usize,
55    /// Maximum pipe-network `Pipe` records across a document.
56    pub max_pipes: usize,
57    /// Maximum `Invert` records across a document.
58    pub max_pipe_inverts: usize,
59    /// Maximum `PipeFlow` and `StructFlow` records across a document.
60    pub max_pipe_flows: usize,
61    /// Maximum element-level semantic refusals retained for a document.
62    pub max_pipe_refusals: usize,
63    /// Maximum preserved roots from foreign XML namespaces.
64    pub max_extensions: usize,
65    /// Maximum coordinate records across the whole source document, including
66    /// Definition points, SourceData point lists and overlay vertices.
67    pub max_points: usize,
68    /// Maximum visible face records across the whole source document.
69    pub max_faces: usize,
70    pub max_references: usize,
71    /// Maximum source alignments retained for profile and section review.
72    pub max_alignments: usize,
73    /// Maximum `ProfAlign` and `ProfSurf` records across all alignments.
74    pub max_profiles: usize,
75    /// Maximum PVI and sampled grade-line points across all profiles.
76    pub max_profile_points: usize,
77    /// Maximum advertised vertical curves across all profiles.
78    pub max_vertical_curves: usize,
79    /// Maximum cross-sections across all alignments.
80    pub max_cross_sections: usize,
81    /// Maximum cross-section surfaces and their vertices.
82    pub max_cross_section_surfaces: usize,
83    pub max_cross_section_points: usize,
84    /// Maximum roadway association records.
85    pub max_roadways: usize,
86    /// Maximum bounded preserved-only corridor/stringline extension roots.
87    pub max_preserved_only_extensions: usize,
88    /// Maximum capability records retained while parsing incomplete source data.
89    pub max_capability_diagnostics: usize,
90    pub max_work: usize,
91    /// #5175: an explicit, caller-audited linear unit to assume when the
92    /// source declares no `LandXML/Units` element at all. `None` by default,
93    /// which keeps the LXML009 refusal in `parser::finalize` in force. This
94    /// is never inferred from the file; it is supplied by the host and
95    /// carried into the parsed document's units record with `assumed: true`
96    /// so nothing downstream can mistake it for a declared unit. A declared
97    /// `<Units>` element always wins over this field; see
98    /// `parser.rs`'s `Metric`/`Imperial` handler.
99    pub assumed_linear_unit: Option<String>,
100}
101
102impl Default for LandXmlLimits {
103    fn default() -> Self {
104        Self {
105            max_bytes: 64 * 1024 * 1024,
106            max_depth: 64,
107            max_name_bytes: 256,
108            max_attributes: 64,
109            max_attribute_bytes: 4096,
110            max_text_bytes: 1024 * 1024,
111            max_character_references: 100_000,
112            max_surfaces: 100_000,
113            max_pipe_networks: 100_000,
114            max_pipe_structures: 5_000_000,
115            max_pipes: 5_000_000,
116            max_pipe_inverts: 10_000_000,
117            max_pipe_flows: 10_000_000,
118            max_pipe_refusals: 1_000_000,
119            max_extensions: 100_000,
120            max_points: 5_000_000,
121            max_faces: 10_000_000,
122            max_references: 30_000_000,
123            max_alignments: 100_000,
124            max_profiles: 1_000_000,
125            max_profile_points: 10_000_000,
126            max_vertical_curves: 5_000_000,
127            max_cross_sections: 5_000_000,
128            max_cross_section_surfaces: 10_000_000,
129            max_cross_section_points: 20_000_000,
130            max_roadways: 100_000,
131            max_preserved_only_extensions: 1_000_000,
132            max_capability_diagnostics: 1_000_000,
133            max_work: 100_000_000,
134            assumed_linear_unit: None,
135        }
136    }
137}