mirror of
https://github.com/mii443/wasmer.git
synced 2025-12-10 06:38:22 +00:00
feat: Implement safe, checked module artifact deserialization
Enable rkyv validation of serialized module artifacts. Required additions: * derive the required CheckBytes trait for all types * Add `_checked` variants of all the deserialization functions Also enables the `strict` feature of rkyv by default. This will ensure consistent archive binary layout across architectures and Rust compiler versions.
This commit is contained in:
committed by
Christoph Herzog
parent
9cb4bf32c9
commit
47cc5bbf99
@@ -238,6 +238,18 @@ impl Module {
|
||||
return Err(DeserializeError::Generic("You need to enable the `js-serializable-module` feature flag to deserialize a `Module`".to_string()));
|
||||
}
|
||||
|
||||
pub fn deserialize_checked(
|
||||
_engine: &impl AsEngineRef,
|
||||
_bytes: impl IntoBytes,
|
||||
) -> Result<Self, DeserializeError> {
|
||||
#[cfg(feature = "js-serializable-module")]
|
||||
return Self::from_binary(_engine, &_bytes.into_bytes())
|
||||
.map_err(|e| DeserializeError::Compiler(e));
|
||||
|
||||
#[cfg(not(feature = "js-serializable-module"))]
|
||||
return Err(DeserializeError::Generic("You need to enable the `js-serializable-module` feature flag to deserialize a `Module`".to_string()));
|
||||
}
|
||||
|
||||
pub unsafe fn deserialize_from_file(
|
||||
engine: &impl AsEngineRef,
|
||||
path: impl AsRef<Path>,
|
||||
@@ -246,6 +258,14 @@ impl Module {
|
||||
Self::deserialize(engine, bytes)
|
||||
}
|
||||
|
||||
pub fn deserialize_from_file_checked(
|
||||
engine: &impl AsEngineRef,
|
||||
path: impl AsRef<Path>,
|
||||
) -> Result<Self, DeserializeError> {
|
||||
let bytes = std::fs::read(path.as_ref())?;
|
||||
Self::deserialize_checked(engine, bytes)
|
||||
}
|
||||
|
||||
pub fn set_name(&mut self, name: &str) -> bool {
|
||||
self.name = Some(name.to_string());
|
||||
true
|
||||
|
||||
@@ -219,6 +219,8 @@ impl Module {
|
||||
|
||||
/// Deserializes a serialized Module binary into a `Module`.
|
||||
///
|
||||
/// Note: You should usually prefer the safe [`Module::deserialize_checked`].
|
||||
///
|
||||
/// # Important
|
||||
///
|
||||
/// This function only accepts a custom binary format, which will be different
|
||||
@@ -253,6 +255,56 @@ impl Module {
|
||||
Ok(Self(module_imp::Module::deserialize(engine, bytes)?))
|
||||
}
|
||||
|
||||
/// Deserializes a serialized Module binary into a `Module`.
|
||||
///
|
||||
/// # Important
|
||||
///
|
||||
/// This function only accepts a custom binary format, which will be different
|
||||
/// than the `wasm` binary format and may change among Wasmer versions.
|
||||
/// (it should be the result of the serialization of a Module via the
|
||||
/// `Module::serialize` method.).
|
||||
///
|
||||
/// # Usage
|
||||
///
|
||||
/// ```ignore
|
||||
/// # use wasmer::*;
|
||||
/// # fn main() -> anyhow::Result<()> {
|
||||
/// # let mut store = Store::default();
|
||||
/// let module = Module::deserialize_checked(&store, serialized_data)?;
|
||||
/// # Ok(())
|
||||
/// # }
|
||||
/// ```
|
||||
pub fn deserialize_checked(
|
||||
engine: &impl AsEngineRef,
|
||||
bytes: impl IntoBytes,
|
||||
) -> Result<Self, DeserializeError> {
|
||||
Ok(Self(module_imp::Module::deserialize_checked(
|
||||
engine, bytes,
|
||||
)?))
|
||||
}
|
||||
|
||||
/// Deserializes a a serialized Module located in a `Path` into a `Module`.
|
||||
/// > Note: the module has to be serialized before with the `serialize` method.
|
||||
///
|
||||
/// # Usage
|
||||
///
|
||||
/// ```ignore
|
||||
/// # use wasmer::*;
|
||||
/// # let mut store = Store::default();
|
||||
/// # fn main() -> anyhow::Result<()> {
|
||||
/// let module = Module::deserialize_from_file(&store, path)?;
|
||||
/// # Ok(())
|
||||
/// # }
|
||||
/// ```
|
||||
pub fn deserialize_from_file_checked(
|
||||
engine: &impl AsEngineRef,
|
||||
path: impl AsRef<Path>,
|
||||
) -> Result<Self, DeserializeError> {
|
||||
Ok(Self(module_imp::Module::deserialize_from_file_checked(
|
||||
engine, path,
|
||||
)?))
|
||||
}
|
||||
|
||||
/// Deserializes a a serialized Module located in a `Path` into a `Module`.
|
||||
/// > Note: the module has to be serialized before with the `serialize` method.
|
||||
///
|
||||
|
||||
@@ -78,6 +78,19 @@ impl Module {
|
||||
Ok(Self::from_artifact(artifact))
|
||||
}
|
||||
|
||||
pub fn deserialize_checked(
|
||||
engine: &impl AsEngineRef,
|
||||
bytes: impl IntoBytes,
|
||||
) -> Result<Self, DeserializeError> {
|
||||
let bytes = bytes.into_bytes();
|
||||
let artifact = engine
|
||||
.as_engine_ref()
|
||||
.engine()
|
||||
.0
|
||||
.deserialize_checked(&bytes)?;
|
||||
Ok(Self::from_artifact(artifact))
|
||||
}
|
||||
|
||||
pub unsafe fn deserialize_from_file(
|
||||
engine: &impl AsEngineRef,
|
||||
path: impl AsRef<Path>,
|
||||
@@ -90,6 +103,18 @@ impl Module {
|
||||
Ok(Self::from_artifact(artifact))
|
||||
}
|
||||
|
||||
pub fn deserialize_from_file_checked(
|
||||
engine: &impl AsEngineRef,
|
||||
path: impl AsRef<Path>,
|
||||
) -> Result<Self, DeserializeError> {
|
||||
let artifact = engine
|
||||
.as_engine_ref()
|
||||
.engine()
|
||||
.0
|
||||
.deserialize_from_file_checked(path.as_ref())?;
|
||||
Ok(Self::from_artifact(artifact))
|
||||
}
|
||||
|
||||
fn from_artifact(artifact: Arc<Artifact>) -> Self {
|
||||
Self { artifact }
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user