Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Is (de)serializing `usize` with Serde platform-dependent?

Tags:

rust

serde

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?

like image 767
Lingxuan Ye Avatar asked Nov 17 '25 10:11

Lingxuan Ye


1 Answers

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.

like image 98
cafce25 Avatar answered Nov 19 '25 10:11

cafce25