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}