Skip to main content

wasmer_types/
serialize.rs

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