use std::sync::Arc;
use tensor_wasm_core::error::TensorWasmError;
use tensor_wasm_core::types::TenantId;
use tensor_wasm_exec::engine::TensorWasmEngine;
use tensor_wasm_exec::executor::{SpawnConfig, TensorWasmExecutor};
const FORBIDDEN_SUBSTRINGS: &[&str] = &[
"0x", "/usr/", "\\\\?\\C:\\", "wasmtime/runtime", "__libc_", "cranelift", ];
fn trapping_wasm() -> Vec<u8> {
wat::parse_str(r#"(module (func (export "go") (unreachable)))"#).expect("trapping wat parses")
}
fn assert_no_leaks(label: &str, rendered: &str) {
let lower = rendered.to_ascii_lowercase();
for needle in FORBIDDEN_SUBSTRINGS {
let needle_lower = needle.to_ascii_lowercase();
assert!(
!lower.contains(&needle_lower),
"{label}: rendered error contains forbidden substring {needle:?}; \
full rendered text was:\n---\n{rendered}\n---",
);
}
}
#[tokio::test]
async fn trap_error_does_not_leak_host_paths_or_pointers() {
let engine = Arc::new(TensorWasmEngine::new().expect("engine"));
let exec = TensorWasmExecutor::new(engine);
let id = exec
.spawn_instance(SpawnConfig::for_tenant(TenantId(1)), &trapping_wasm())
.await
.expect("spawn trapping module");
let exec_err = exec
.call_export_with_args(id, "go", &[])
.await
.expect_err("unreachable must trap");
let public_err: TensorWasmError = exec_err.into();
let plain = format!("{public_err}");
let alt = format!("{public_err:#}");
assert!(
matches!(public_err, TensorWasmError::WasmTrap(_)),
"expected WasmTrap, got {public_err:?}",
);
assert_no_leaks("Display", &plain);
assert_no_leaks("Display (alt)", &alt);
exec.terminate(id).await.expect("terminate after trap");
}