From 46203ea7612a1a2766ee80ecd79c16ed0d5f0ee3 Mon Sep 17 00:00:00 2001 From: osobh Date: Fri, 25 Sep 2026 20:38:29 -0500 Subject: [PATCH] test(format): keep the 2026-09-20 B-tree v2 fuzz crash as a regression An 82-byte fuzz_btree_v2 crash input from 2026-09-20 was left untracked in fuzz/artifacts. Replayed today it runs cleanly: the depth cap and record budget added to B-tree v2 traversal that day fixed it. It is now in the committed fuzz corpus, and a robustness test replays the fuzz target's exact code path on it so a regression fails CI rather than waiting for someone to run the fuzzer. Co-Authored-By: Claude Opus 5.5 (1M context) --- .../fuzz_btree_v2/regression-crash-f98c19dc | Bin 0 -> 82 bytes .../clawhdf5-format/tests/robustness_tests.rs | 46 ++++++++++++++++++ 2 files changed, 46 insertions(+) create mode 100644 crates/clawhdf5-format/fuzz/corpus/fuzz_btree_v2/regression-crash-f98c19dc diff --git a/crates/clawhdf5-format/fuzz/corpus/fuzz_btree_v2/regression-crash-f98c19dc b/crates/clawhdf5-format/fuzz/corpus/fuzz_btree_v2/regression-crash-f98c19dc new file mode 100644 index 0000000000000000000000000000000000000000..afb7da7203eb9efd8600a7c9abefcce35057c8b8 GIT binary patch literal 82 zcmZSICOd_A`Z().unwrap(); + let header = BTreeV2Header { + tree_type: fields[0], + node_size: u32::from_le_bytes([fields[1], fields[2], fields[3], fields[4]]), + record_size: u16::from_le_bytes([fields[5], fields[6]]), + depth: u16::from_le_bytes([fields[7], fields[8]]), + root_node_address: u64::from(u32::from_le_bytes([ + fields[9], fields[10], fields[11], fields[12], + ])), + num_records_in_root: u16::from_le_bytes([fields[13], fields[14]]), + total_records: u64::from(u32::from_le_bytes([ + fields[15], fields[16], fields[17], fields[18], + ])), + }; + let offset_size = if fields[19] & 1 == 0 { 4 } else { 8 }; + let _ = collect_btree_v2_records(file, &header, offset_size, 8); +}