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:
@@ -5,6 +5,7 @@ use alloc::vec::Vec;
|
||||
|
||||
use byteorder::{ByteOrder, LittleEndian};
|
||||
|
||||
use crate::addr::to_usize;
|
||||
use crate::error::FormatError;
|
||||
use crate::message_type::MessageType;
|
||||
|
||||
@@ -264,8 +265,8 @@ impl ObjectHeader {
|
||||
// Follow continuations (v1 continuation chunks are just raw
|
||||
// messages, no signature); check_message has checked the body.
|
||||
if msg_type == MessageType::ObjectHeaderContinuation {
|
||||
let cont_offset = read_offset(body, 0, offset_size)? as usize;
|
||||
let cont_length = read_offset(body, offset_size as usize, length_size)? as usize;
|
||||
let cont_offset = to_usize(read_offset(body, 0, offset_size)?)?;
|
||||
let cont_length = to_usize(read_offset(body, offset_size as usize, length_size)?)?;
|
||||
Self::parse_v1_chunk(
|
||||
data,
|
||||
cont_offset,
|
||||
@@ -339,7 +340,7 @@ impl ObjectHeader {
|
||||
_ => unreachable!(),
|
||||
};
|
||||
ensure_len(data, pos, chunk_size_width as usize)?;
|
||||
let chunk0_size = read_offset(data, pos, chunk_size_width)? as usize;
|
||||
let chunk0_size = to_usize(read_offset(data, pos, chunk_size_width)?)?;
|
||||
pos += chunk_size_width as usize;
|
||||
// Bit 2: attribute creation order tracked → messages include creation order field
|
||||
let has_creation_order = flags & 0x04 != 0;
|
||||
@@ -472,8 +473,8 @@ impl ObjectHeader {
|
||||
let msg_type = MessageType::from_u16(msg_type_raw);
|
||||
if msg_type == MessageType::ObjectHeaderContinuation {
|
||||
// check_message has checked the body holds both fields.
|
||||
let cont_off = read_offset(body, 0, offset_size)? as usize;
|
||||
let cont_len = read_offset(body, offset_size as usize, length_size)? as usize;
|
||||
let cont_off = to_usize(read_offset(body, 0, offset_size)?)?;
|
||||
let cont_len = to_usize(read_offset(body, offset_size as usize, length_size)?)?;
|
||||
continuations.push((cont_off, cont_len));
|
||||
} else if msg_type == MessageType::Nil {
|
||||
null_count += 1;
|
||||
|
||||
Reference in New Issue
Block a user