wasmer_types/
serialize.rs

1use crate::{lib::std::mem, DeserializeError};
2
3/// Metadata header which holds an ABI version and the length of the remaining
4/// metadata.
5#[repr(C)]
6#[derive(Clone, Copy)]
7pub struct MetadataHeader {
8    magic: [u8; 8],
9    version: u32,
10    len: u32,
11}
12
13impl MetadataHeader {
14    /// Current ABI version. Increment this any time breaking changes are made
15    /// to the format of the serialized data.
16    pub const CURRENT_VERSION: u32 = 8;
17
18    /// Magic number to identify wasmer metadata.
19    const MAGIC: [u8; 8] = *b"WASMER\0\0";
20
21    /// Length of the metadata header.
22    pub const LEN: usize = 16;
23
24    /// Alignment of the metadata.
25    pub const ALIGN: usize = 16;
26
27    /// Creates a new header for metadata of the given length.
28    pub fn new(len: usize) -> Self {
29        Self {
30            magic: Self::MAGIC,
31            version: Self::CURRENT_VERSION,
32            len: len.try_into().expect("metadata exceeds maximum length"),
33        }
34    }
35
36    /// Convert the header into its bytes representation.
37    pub fn into_bytes(self) -> [u8; 16] {
38        unsafe { mem::transmute(self) }
39    }
40
41    /// Parses the header and returns the length of the metadata following it.
42    pub fn parse(bytes: &[u8]) -> Result<usize, DeserializeError> {
43        if bytes.as_ptr() as usize % 8 != 0 {
44            return Err(DeserializeError::CorruptedBinary(
45                "misaligned metadata".to_string(),
46            ));
47        }
48        let bytes: [u8; 16] = bytes
49            .get(..16)
50            .ok_or_else(|| {
51                DeserializeError::CorruptedBinary("invalid metadata header".to_string())
52            })?
53            .try_into()
54            .unwrap();
55        let header: Self = unsafe { mem::transmute(bytes) };
56        if header.magic != Self::MAGIC {
57            return Err(DeserializeError::Incompatible(
58                "The provided bytes were not serialized by Wasmer".to_string(),
59            ));
60        }
61        if header.version != Self::CURRENT_VERSION {
62            return Err(DeserializeError::Incompatible(
63                "The provided bytes were serialized by an incompatible version of Wasmer"
64                    .to_string(),
65            ));
66        }
67        Ok(header.len as usize)
68    }
69}