1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
// This Source Code Form is subject to the terms of the Mozilla Public
// License, v. 2.0. If a copy of the MPL was not distributed with this
// file, You can obtain one at https://mozilla.org/MPL/2.0/.
//! Regression for #3641: subtracting three `IfcVoidingFeature` voids from a
//! single host in a sequential CSG chain traps the WASM instance with
//! "memory access out of bounds". Reported as reproducing only when all
//! three voids are present together (each void alone, and every pair, is
//! fine) — pointing at a degenerating intermediate result in the sequential
//! subtraction chain, not any single boolean op.
//!
//! This test drives the NATIVE (non-WASM) pipeline with the reporter's
//! minimal fixture to check whether the same underlying defect (a
//! degenerate/non-manifold intermediate feeding an out-of-range index) is
//! reachable without WASM at all, or whether it is WASM-memory-specific.
use ifc_lite_processing::process_geometry;
const FIXTURE: &str = "tests/fixtures/issue_3641_voiding_trap.ifc";
fn fixture_path() -> std::path::PathBuf {
std::path::PathBuf::from(env!("CARGO_MANIFEST_DIR")).join(FIXTURE)
}
#[test]
fn three_void_sequential_chain_does_not_panic_or_corrupt_native() {
let path = fixture_path();
let content = std::fs::read_to_string(&path).expect("fixture must be checked in");
// Must not panic. If the underlying defect is an OOB Rust index (not
// WASM-memory-specific), this either panics natively (bounds-checked
// Vec/slice indexing) or produces meshes with an out-of-range index
// value, both of which are checked below.
let result = process_geometry(content.as_str());
eprintln!(
"processed: {} meshes, {} CSG failures logged",
result.meshes.len(),
result.stats.total_csg_failures
);
for m in &result.meshes {
let vertex_count = m.positions.len() / 3;
for (i, &idx) in m.indices.iter().enumerate() {
assert!(
(idx as usize) < vertex_count,
"mesh #{}: index[{i}] = {idx} is out of range for {vertex_count} vertices \
(positions.len() = {})",
m.express_id,
m.positions.len()
);
}
}
}