fluxa-core/fuzz/fuzz_targets/engine_dispatch.rs
KhooLy 2439bb3ba6 test: add golden wire fixtures and a headless-engine dispatch fuzz target
Per the robustness plan's §8: a tests/wire/ directory holds one real
AppAction input per representative action family, each paired with a
checked-in golden DispatchResult captured from an actual dispatch (a
new #[cfg(test)] wire_fixtures_match_golden_dispatch_output test
compares against it, with UPDATE_WIRE_FIXTURES=1 to regenerate when a
change is intentional). Any future camelCase/field drift on the
dispatch/completeEffect wire now fails in this repo instead of surfacing
as a silent Android/desktop regression.

Also add fuzz/fuzz_targets/engine_dispatch.rs, feeding arbitrary bytes
into both headless_engine_dispatch_json and
headless_engine_complete_effect_json against one engine handle — this
is the one path in the crate that runs global engine-mutating logic
without a catch_unwind guard on the desktop call path, so it's the
highest-value fuzz target missing from fuzz/. Exposes the four
headless_engine entry points as `pub` (still unreachable outside the
crate except through the fuzzing-gated `fuzz_targets` re-export module)
following the same pattern already used for parse_manifest and the
content_identity helpers.
2026-07-07 14:28:48 +03:00

24 lines
807 B
Rust

#![no_main]
use fluxa_core::fuzz_targets::{
create_headless_engine, destroy_headless_engine, headless_engine_complete_effect_json,
headless_engine_dispatch_json,
};
use libfuzzer_sys::fuzz_target;
fuzz_target!(|data: &[u8]| {
let split = data.iter().position(|&b| b == b'\n').unwrap_or(data.len());
let (action_bytes, rest) = data.split_at(split);
let effect_bytes = rest.strip_prefix(b"\n").unwrap_or(rest);
let handle = create_headless_engine("{}");
if let Ok(action_json) = std::str::from_utf8(action_bytes) {
let _ = headless_engine_dispatch_json(handle, action_json);
}
if let Ok(effect_json) = std::str::from_utf8(effect_bytes) {
let _ = headless_engine_complete_effect_json(handle, effect_json);
}
destroy_headless_engine(handle);
});