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:
@@ -15,6 +15,7 @@
|
||||
#[cfg(not(feature = "std"))]
|
||||
use alloc::{format, string::String, vec, vec::Vec};
|
||||
|
||||
use crate::addr::to_usize;
|
||||
use crate::data_layout::{DataLayout, VdsMapping, parse_vds_mappings};
|
||||
use crate::dataspace::Dataspace;
|
||||
use crate::datatype::Datatype;
|
||||
@@ -208,7 +209,7 @@ fn load_mappings(
|
||||
return Ok(Vec::new());
|
||||
};
|
||||
let coll =
|
||||
crate::global_heap::GlobalHeapCollection::parse(file_data, addr as usize, length_size)?;
|
||||
crate::global_heap::GlobalHeapCollection::parse(file_data, to_usize(addr)?, length_size)?;
|
||||
let index = u16::try_from(*global_heap_index)
|
||||
.map_err(|_| vds_err("VDS mapping heap index out of range"))?;
|
||||
let obj = coll
|
||||
@@ -611,12 +612,12 @@ fn scatter(
|
||||
return Err(vds_err("virtual/source selection element counts differ"));
|
||||
}
|
||||
for (&v, &s) in vidx.iter().zip(sidx) {
|
||||
let (vo, so) = (v as usize * elem_size, s as usize * elem_size);
|
||||
let (vo, so) = (to_usize(v)? * elem_size, to_usize(s)? * elem_size);
|
||||
if vo + elem_size > out.len() || so + elem_size > src.len() {
|
||||
return Err(vds_err("virtual dataset selection out of bounds"));
|
||||
}
|
||||
out[vo..vo + elem_size].copy_from_slice(&src[so..so + elem_size]);
|
||||
mapped[v as usize] = true;
|
||||
mapped[to_usize(v)?] = true;
|
||||
}
|
||||
Ok(())
|
||||
}
|
||||
@@ -747,7 +748,7 @@ fn selection_indices(
|
||||
return Err(vds_err("VDS selection blocks overlap"));
|
||||
}
|
||||
}
|
||||
let mut out = Vec::with_capacity(volume as usize);
|
||||
let mut out = Vec::with_capacity(to_usize(volume)?);
|
||||
for (s, e) in starts.chunks_exact(rank).zip(ends.chunks_exact(rank)) {
|
||||
let mut cur = s.to_vec();
|
||||
'block: loop {
|
||||
@@ -868,7 +869,7 @@ fn load_source_file(whole: &mut [u8]) -> Result<(), FormatError> {
|
||||
// read as before, up to its length.
|
||||
let end = sb
|
||||
.data_end(base as u64, whole.len() as u64)
|
||||
.map_or(whole.len(), |e| base + e as usize);
|
||||
.map_or(Ok(whole.len()), |e| to_usize(e).map(|e| base + e))?;
|
||||
crate::superblock_ext::apply_cache_image_in_place(&mut whole[base..end], &sb)
|
||||
}
|
||||
|
||||
@@ -921,7 +922,7 @@ fn open_source(file_data: &[u8], path: &str) -> Result<Option<OpenSource>, Forma
|
||||
Err(FormatError::PathNotFound(_)) => return Ok(None),
|
||||
Err(e) => return Err(e),
|
||||
};
|
||||
let header = crate::object_header::ObjectHeader::parse(file_data, addr as usize, os, ls)?;
|
||||
let header = crate::object_header::ObjectHeader::parse(file_data, to_usize(addr)?, os, ls)?;
|
||||
let mut src = OpenSource {
|
||||
offset_size: os,
|
||||
length_size: ls,
|
||||
|
||||
Reference in New Issue
Block a user