INT-06, INT-08, INT-10: WAL fuzz target, JNI Mutex wrapping, media sandboxing

INT-06 — Add WAL replay fuzz target (crates/clawhdf5-agent/fuzz/).
  Writes arbitrary bytes to a temp file and runs them through
  WalFile::read_entries, exercising the magic-byte check, version
  dispatch, CRC32 guard, length-prefix bounds, and EOF handling.
  No byte sequence should cause a panic or OOM.

INT-08 — Wrap Android JNI HDF5Memory handles in Mutex.
  Handle type changed from *mut HDF5Memory to *mut Mutex<HDF5Memory>.
  Every JNI entry point acquires the lock before calling into
  HDF5Memory, making concurrent calls from multiple Java/Kotlin threads
  safe without requiring the caller to synchronize externally.
  Added concurrent_count_active_is_safe test to exercise the path.

INT-10 — Add media reference sandboxing to MediaRef::validate().
  Path references are canonicalized and checked to stay within an
  optional sandbox directory (preventing ../ traversal).
  URL references must use a scheme from ALLOWED_URL_SCHEMES (https,
  http); file://, data:, and schemeless strings are rejected.
  Inline references are always accepted.
  Added 9 unit tests covering the acceptance and rejection paths.

Co-Authored-By: Claude Sonnet 4.6 <[email protected]>
This commit is contained in:
ClawHDF5 Planner
2026-08-12 11:46:59 +00:00
co-authored by Claude Sonnet 4.6
parent 5ca0b8092e
commit 4aee2fa610
4 changed files with 258 additions and 23 deletions
@@ -0,0 +1,21 @@
#![no_main]
use libfuzzer_sys::fuzz_target;
use std::io::Write as _;
fuzz_target!(|data: &[u8]| {
// Write the fuzz input to a temporary file, then run it through the WAL
// replay path. The goal: verify that no arbitrary byte sequence causes a
// panic, OOM, or other safety violation. CRC32 mismatches, truncated
// entries, bad magic bytes, and oversized length fields are all expected to
// return an error (not crash).
let Ok(mut tmp) = tempfile::NamedTempFile::new() else {
return;
};
if tmp.write_all(data).is_err() {
return;
}
// Flush so the reader sees the data.
let _ = tmp.flush();
let _ = clawhdf5_agent::wal::WalFile::read_entries(tmp.path());
});