Deserialization Endianness Remediation
How to fix endianness mismatches in data deserialization.
Deserialization Endianness Remediation
Overview
Detector Reference: Deserialization Endianness
This guide explains how to fix endianness mismatches when deserializing multi-byte values from account data.
Recommended Fix
Use explicit endianness conversion functions instead of manual byte manipulation:
// For Solana-native data (Borsh, little-endian):
let value = u64::from_le_bytes(data[offset..offset + 8].try_into()?);
// For external data (big-endian/network byte order):
let value = u64::from_be_bytes(data[offset..offset + 8].try_into()?);
Alternative Mitigations
- Use Borsh consistently:
BorshDeserialize::try_from_slice()handles endianness uniformly. - Document data source endianness: comment the byte order of each external data source and use the matching conversion.
- Wrapper types: create newtype wrappers like
BigEndianU64that enforce correct conversion at the type level.
Common Mistakes
- Mixing endianness within a struct: some fields from Borsh (little-endian) and others from external sources (big-endian). Use consistent conversion for each source.
- Assuming native endianness: Solana’s BPF runtime is little-endian, but explicitly specifying endianness prevents bugs if the runtime changes.
- Manual byte extraction with shifts:
(value >> 24) & 0xFFextracts the most significant byte in memory, which differs between endianness. Useto_le_bytes()orto_be_bytes()instead.