Fix silent wrong data and libhdf5 interop found by the HDF5 audit #11
Binary file not shown.
@@ -312,3 +312,49 @@ fn provenance_mismatch_on_corruption() {
|
||||
"corrupted data should produce hash mismatch"
|
||||
);
|
||||
}
|
||||
|
||||
// ---------------------------------------------------------------------------
|
||||
// Fuzzer finds, kept as regression tests
|
||||
// ---------------------------------------------------------------------------
|
||||
|
||||
/// `fuzz_btree_v2` crash input from 2026-09-20 (82 bytes): a B-tree v2 header
|
||||
/// followed by internal nodes that point back into themselves. It predates the
|
||||
/// depth cap and record budget added to B-tree v2 traversal that day and no
|
||||
/// longer crashes; this replays the fuzz target's exact code path on it so a
|
||||
/// regression fails CI rather than waiting for a fuzz run.
|
||||
#[test]
|
||||
fn fuzz_btree_v2_crash_f98c19dc_is_a_clean_result() {
|
||||
use clawhdf5_format::btree_v2::{BTreeV2Header, collect_btree_v2_records};
|
||||
let data: &[u8] = &[
|
||||
0x42, 0x54, 0x48, 0x44, 0x00, 0x06, 0x00, 0xed, 0xef, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00,
|
||||
0x00, 0x03, 0x40, 0x14, 0x93, 0x42, 0x54, 0x49, 0x4e, 0x42, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x42, 0x54, 0x48, 0x44, 0x00, 0x00, 0x00, 0x13, 0x05, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x80, 0x00, 0x00, 0x00, 0x40, 0x14, 0x93, 0x42, 0x54, 0x00, 0x49,
|
||||
0x00, 0x01, 0x4e, 0x42, 0x42, 0x54, 0xbe,
|
||||
];
|
||||
assert_eq!(data.len(), 82);
|
||||
for offset_size in [4u8, 8] {
|
||||
for length_size in [4u8, 8] {
|
||||
if let Ok(header) = BTreeV2Header::parse(data, 0, offset_size, length_size) {
|
||||
let _ = collect_btree_v2_records(data, &header, offset_size, length_size);
|
||||
}
|
||||
}
|
||||
}
|
||||
let (fields, file) = data.split_first_chunk::<20>().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);
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user