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:
@@ -9,6 +9,7 @@ use alloc::{collections::BTreeMap, format, string::String, vec, vec::Vec};
|
||||
#[cfg(feature = "std")]
|
||||
use std::collections::BTreeMap;
|
||||
|
||||
use crate::addr::to_usize;
|
||||
use crate::error::FormatError;
|
||||
use crate::global_heap::{GlobalHeapCollection, GlobalHeapIndex};
|
||||
|
||||
@@ -55,7 +56,7 @@ pub fn parse_vl_references(
|
||||
) -> Result<Vec<VlElement>, FormatError> {
|
||||
let elem_size = 4 + offset_size as usize + 4; // length + address + index
|
||||
let total =
|
||||
(num_elements as usize)
|
||||
to_usize(num_elements)?
|
||||
.checked_mul(elem_size)
|
||||
.ok_or(FormatError::UnexpectedEof {
|
||||
expected: usize::MAX,
|
||||
@@ -68,7 +69,7 @@ pub fn parse_vl_references(
|
||||
});
|
||||
}
|
||||
|
||||
let mut elements = Vec::with_capacity(num_elements as usize);
|
||||
let mut elements = Vec::with_capacity(to_usize(num_elements)?);
|
||||
let mut pos = 0;
|
||||
|
||||
for _ in 0..num_elements {
|
||||
@@ -406,7 +407,7 @@ impl<'a> VlResolver<'a> {
|
||||
let index =
|
||||
GlobalHeapCollection::parse_index(self.file_data, offset, self.length_size)?;
|
||||
// parse_index checked that the collection lies in the file.
|
||||
let end = offset + index.collection_size as usize;
|
||||
let end = offset + to_usize(index.collection_size)?;
|
||||
self.check_overlap(offset, end)?;
|
||||
let coll = CachedCollection::new(index);
|
||||
if self.cached_bytes.saturating_add(coll.cost()) > self.budget {
|
||||
|
||||
Reference in New Issue
Block a user