#![no_main] //! Arbitrary bytes as a WAL file. Reading, and opening for append (which scans //! the chain and truncates an unverifiable tail), must never panic, hang, or //! allocate without bound — and after `open` repairs the file, everything //! `read_entries` returned before must still be returned. //! //! The deterministic counterpart that runs in ordinary CI is //! `tests/wal_properties.rs`; this target explores inputs it cannot reach. use std::io::Write as _; use clawhdf5_agent::wal::WalFile; use libfuzzer_sys::fuzz_target; fuzz_target!(|data: &[u8]| { let Ok(mut tmp) = tempfile::NamedTempFile::new() else { return; }; if tmp.write_all(data).and_then(|()| tmp.flush()).is_err() { return; } let before = WalFile::read_entries(tmp.path()).map(|e| e.len()); // Only the chained formats (header versions 3 and 4) are repaired in // place. `open` deliberately recreates a legacy-format file from scratch: // `HDF5Memory::open` has already replayed its entries by then. let chained = matches!(data.get(4), Some(3 | 4)); let opened = WalFile::open(tmp.path()); if !chained { return; } if let (Ok(before), Ok(wal)) = (before, opened) { drop(wal); let after = WalFile::read_entries(tmp.path()).map(|e| e.len()); assert_eq!(after.ok(), Some(before), "open() changed what is replayable"); } });