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:
@@ -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.
|
||||
|
||||
Reference in New Issue
Block a user