use super::ParseError;
use std::fmt;
use wasmparser::{Parser, Validator};
#[derive(Debug)]
pub enum ValidationError {
LimitExceeded {
actual: usize,
limit: usize,
},
UnsupportedEncoding,
Invalid(ParseError),
}
impl fmt::Display for ValidationError {
fn fmt(&self, formatter: &mut fmt::Formatter<'_>) -> fmt::Result {
match self {
Self::LimitExceeded { actual, limit } => {
write!(formatter, "Wasm module has {actual} bytes, limit {limit}")
}
Self::UnsupportedEncoding => {
formatter.write_str("expected a core Wasm module, received a component")
}
Self::Invalid(source) => write!(formatter, "invalid Wasm module: {source}"),
}
}
}
impl std::error::Error for ValidationError {
fn source(&self) -> Option<&(dyn std::error::Error + 'static)> {
match self {
Self::Invalid(source) => Some(source),
Self::LimitExceeded { .. } | Self::UnsupportedEncoding => None,
}
}
}
pub fn validate(bytes: &[u8], max_bytes: usize) -> Result<(), ValidationError> {
if bytes.len() > max_bytes {
return Err(ValidationError::LimitExceeded {
actual: bytes.len(),
limit: max_bytes,
});
}
if Parser::is_component(bytes) {
return Err(ValidationError::UnsupportedEncoding);
}
Validator::new()
.validate_all(bytes)
.map(|_| ())
.map_err(|source| ValidationError::Invalid(ParseError { source }))
}
#[cfg(test)]
mod tests;