For example, if I serialize usize::MAX on a 64-bit system and then deserialize it on a 32-bit system, what would happen? An overflow error, be truncated to a u32 and cause misaligned read for the remaining data, or it depends on how some certain data format is implemented? Would casting usize to u64 be overly defensive?
Serde unconditionally casts an usize/isize to u64/i64 before serializing:
primitive_impl!(isize, serialize_i64 as i64); // … primitive_impl!(usize, serialize_u64 as u64);
and when deserializing depending on the type visited (defaulting to u64 for non self describing formats) it uses an as-cast or TryFrom:
impl_deserialize_num! { usize, NonZeroUsize, deserialize_u64 num_as_self!(u8:visit_u8 u16:visit_u16); int_to_uint!(i8:visit_i8 i16:visit_i16 i32:visit_i32 i64:visit_i64); uint_to_self!(u32:visit_u32 u64:visit_u64); }
Where num_as_self uses an as-cast, int_to_uint checks for >= 0 and uses TryFrom and uint_to_self uses TryFrom
That means a bare usize causes an Err to be returned when it's deserialized from a value that's bigger than usize::MAX.
To achieve saturating semantics you can wrap your usize in Saturating.
Would casting usize to u64 be overly defensive?
For serializing yes, it would be. serde already does that.
For deserializing, it would allow any value up to u64::MAX on all platforms instead of just usize::MAX.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With