Skip to content

Commit

Permalink
Split Artifact::deserialize into two functions to prevent panics
Browse files Browse the repository at this point in the history
  • Loading branch information
fschutt committed Aug 23, 2022
1 parent ec95964 commit c0672d2
Showing 1 changed file with 23 additions and 10 deletions.
33 changes: 23 additions & 10 deletions lib/compiler/src/engine/artifact.rs
Original file line number Diff line number Diff line change
Expand Up @@ -96,14 +96,33 @@ impl Artifact {
))
}


/// Deserialize a ArtifactBuild
///
/// # Safety
///
/// This function is unsafe because rkyv reads directly without validating
/// the data.
pub unsafe fn deserialize(engine: &Engine, bytes: &[u8]) -> Result<Self, DeserializeError> {
/// the data. This function does not check whether the `Artifact` is an object file
/// (use [`deserialize`] instead)
pub unsafe fn deserialize_unchecked(engine: &Engine, bytes: &[u8]) -> Result<Self, DeserializeError> {
let bytes = &bytes[ArtifactBuild::MAGIC_HEADER.len()..];
let metadata_len = MetadataHeader::parse(bytes)?;
let metadata_slice: &[u8] = &bytes[MetadataHeader::LEN..][..metadata_len];
let serializable = SerializableModule::deserialize(metadata_slice)?;
let artifact = ArtifactBuild::from_serializable(serializable);
let mut inner_engine = engine.inner_mut();
Self::from_parts(&mut inner_engine, artifact).map_err(DeserializeError::Compiler)
}

/// Deserialize a ArtifactBuild
///
/// # Error
///
/// Returns an error if the bytes are not deserializable. If you don't
/// want this behaviour, use [`deserialize_unchecked`]
pub fn deserialize(engine: &Engine, bytes: &[u8]) -> Result<Self, DeserializeError> {
if !ArtifactBuild::is_deserializable(bytes) {
let static_artifact = Self::deserialize_object(engine, bytes);
let static_artifact = unsafe { Self::deserialize_object(engine, bytes) };
match static_artifact {
Ok(v) => {
return Ok(v);
Expand All @@ -116,13 +135,7 @@ impl Artifact {
"The provided bytes are not wasmer-universal".to_string(),
));
}
let bytes = &bytes[ArtifactBuild::MAGIC_HEADER.len()..];
let metadata_len = MetadataHeader::parse(bytes)?;
let metadata_slice: &[u8] = &bytes[MetadataHeader::LEN..][..metadata_len];
let serializable = SerializableModule::deserialize(metadata_slice)?;
let artifact = ArtifactBuild::from_serializable(serializable);
let mut inner_engine = engine.inner_mut();
Self::from_parts(&mut inner_engine, artifact).map_err(DeserializeError::Compiler)
unsafe { Self::deserialize_unchecked(engine, bytes) }
}

/// Construct a `ArtifactBuild` from component parts.
Expand Down

0 comments on commit c0672d2

Please sign in to comment.