format: no truncating u64 -> usize casts

Every `u64 as usize` cast in clawhdf5-format (115 on wasm32) now goes
through addr::to_usize for values read from the file — addresses, lengths,
counts, dimensions: FormatError::Overflow where the value does not fit
instead of wrapping onto another part of the file on a 32-bit target — or
addr::saturating_usize for counts bounded by something in memory (codec
progress counters, writer sizes), which fail a bounds check or allocation
rather than wrap. A chunk whose offset does not fit lies outside the
dataset and is skipped; partial reads treat such an offset as out of the
buffers. On 64-bit targets nothing changes.

scripts/check-32bit-casts.sh (run by ci-test.sh) lints the wasm32 build
with clippy's cast_possible_truncation and fails on any u64 -> usize
finding; before this commit it listed 115.

Co-Authored-By: Claude Opus 5.5 (1M context) <[email protected]>
This commit is contained in:
osobh
2026-09-26 13:33:24 -05:00
co-authored by Claude Opus 5.5
parent 02e89c1d2d
commit b41583113a
27 changed files with 236 additions and 99 deletions
+12 -3
View File
@@ -203,7 +203,12 @@ fn copy_overlap(
};
let (src_strides, out_strides) = (strides(src_shape), strides(box_extent));
let last = rank - 1;
let run = ((hi[last] - lo[last]) as usize) * elem_size;
// Byte offsets into the in-memory buffers; one that does not fit `usize`
// (a 32-bit target) is out of both buffers, like one past their ends.
let bytes = |elements: u64| usize::try_from(elements).ok()?.checked_mul(elem_size);
let Some(run) = bytes(hi[last] - lo[last]) else {
return;
};
let mut idx = lo.clone();
loop {
@@ -213,8 +218,12 @@ fn copy_overlap(
let out_at: u64 = (0..rank)
.map(|d| (idx[d] - box_start[d]) * out_strides[d])
.sum();
let (s, o) = (src_at as usize * elem_size, out_at as usize * elem_size);
if let (Some(from), Some(to)) = (src.get(s..s + run), out.get_mut(o..o + run)) {
if let (Some(s), Some(o)) = (bytes(src_at), bytes(out_at))
&& let (Some(from), Some(to)) = (
src.get(s..s.saturating_add(run)),
out.get_mut(o..o.saturating_add(run)),
)
{
to.copy_from_slice(from);
}
// Advance over every dimension but the last.