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:
@@ -19,6 +19,7 @@ use alloc::{vec, vec::Vec};
|
||||
|
||||
use core::ops::Range;
|
||||
|
||||
use crate::addr::to_usize;
|
||||
use crate::error::FormatError;
|
||||
|
||||
/// A selection describing which elements of a dataset to access.
|
||||
@@ -562,7 +563,7 @@ fn decode_hyperslab(r: &mut SelReader, version: u64) -> Result<SerializedSelecti
|
||||
if !matches!(enc_size, 2 | 4 | 8) {
|
||||
return Err(sel_err("unsupported hyperslab coordinate encoding size"));
|
||||
}
|
||||
let rank = r.uint(4)? as usize;
|
||||
let rank = to_usize(r.uint(4)?)?;
|
||||
// HDF5 caps dataspace rank at 32 (H5S_MAX_RANK). Reject anything else so a
|
||||
// corrupt rank can't drive a huge allocation or read loop.
|
||||
if rank == 0 || rank > 32 {
|
||||
@@ -625,11 +626,11 @@ fn decode_hyperslab(r: &mut SelReader, version: u64) -> Result<SerializedSelecti
|
||||
return Err(FormatError::UnexpectedEof {
|
||||
expected: r
|
||||
.pos
|
||||
.saturating_add(nblocks.saturating_mul(per_block) as usize),
|
||||
.saturating_add(to_usize(nblocks.saturating_mul(per_block))?),
|
||||
available: r.data.len(),
|
||||
});
|
||||
}
|
||||
let n = nblocks as usize * rank;
|
||||
let n = to_usize(nblocks)? * rank;
|
||||
let (mut starts, mut ends) = (Vec::with_capacity(n), Vec::with_capacity(n));
|
||||
for _ in 0..nblocks {
|
||||
for _ in 0..rank {
|
||||
@@ -662,7 +663,7 @@ fn blocks_union_coords(
|
||||
.filter(|&t| t <= MAX_EXPANDED_POINTS)
|
||||
.ok_or_else(|| sel_err("irregular hyperslab selection is too large to expand"))?;
|
||||
}
|
||||
let mut out = Vec::with_capacity(total as usize);
|
||||
let mut out = Vec::with_capacity(to_usize(total)?);
|
||||
for (s, e) in starts.chunks_exact(rank).zip(ends.chunks_exact(rank)) {
|
||||
let mut cur = s.to_vec();
|
||||
'block: loop {
|
||||
|
||||
Reference in New Issue
Block a user