libhdf5 follows any number of continuation chunks, and a header that is full gains one per message added (each new chunk holding the next continuation message), so a version-1 header with a few dozen attributes added one at a time is a chain dozens of chunks long. The reader recursed once per chunk and refused a chain deeper than 32 (NestingDepthExceeded): h5py read such files, we did not. Version-2 headers stopped at 256 continuation chunks. Version-1 chunks are now followed with an explicit stack (the same depth-first message order as before), version-2 ones as before; both refuse a chunk address seen twice (a cycle, what the limits guarded against) and more than 65 536 chunks. Regression: long_v1_continuation_chains_are_read (a 200-chunk chain), v1_continuation_cycles_are_refused; the dense-attribute interop test's 'earliest' case produces such a chain. Co-Authored-By: Claude Opus 5.5 (1M context) <[email protected]>
clawhdf5-format
Pure-Rust HDF5 binary format parsing and writing — no C dependencies.
Features
- Zero-copy superblock, object header, and B-tree parsing
- Chunked dataset read/write with filter pipelines
no_stdsupport (disablestdfeature)- Optional parallel reads via Rayon
- SHA-256 provenance tracking
Usage
use clawhdf5_format::Superblock;
let data = std::fs::read("data.h5").unwrap();
let sb = Superblock::from_bytes(&data).unwrap();
println!("HDF5 version {}.{}", sb.version_major(), sb.version_minor());
License
MIT