Better error handling in fuzzing; skip on unsupported features
This commit is contained in:
parent
88bcc3d906
commit
26e7c7a3af
|
@ -1,12 +1,28 @@
|
|||
#![no_main]
|
||||
use libfuzzer_sys::fuzz_target;
|
||||
|
||||
use waffle::Module;
|
||||
use waffle::{FrontendError, Module};
|
||||
|
||||
fuzz_target!(|module: wasm_smith::Module| {
|
||||
let _ = env_logger::try_init();
|
||||
log::debug!("original module: {:?}", module);
|
||||
let orig_bytes = module.to_bytes();
|
||||
let parsed_module = Module::from_wasm_bytes(&orig_bytes[..]).unwrap();
|
||||
let parsed_module = match Module::from_wasm_bytes(&orig_bytes[..]) {
|
||||
Ok(m) => m,
|
||||
Err(e) => {
|
||||
match e.downcast::<FrontendError>() {
|
||||
Ok(FrontendError::UnsupportedFeature(_)) => {
|
||||
// Just skip this case.
|
||||
return;
|
||||
}
|
||||
Ok(e) => {
|
||||
panic!("Frontend error: {:?}", e);
|
||||
}
|
||||
Err(e) => {
|
||||
panic!("Other error when parsing module: {:?}", e);
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
let _ = parsed_module.to_wasm_bytes();
|
||||
});
|
||||
|
|
15
src/errors.rs
Normal file
15
src/errors.rs
Normal file
|
@ -0,0 +1,15 @@
|
|||
//! Error types.
|
||||
|
||||
#[derive(Clone, Debug)]
|
||||
pub enum FrontendError {
|
||||
UnsupportedFeature(String),
|
||||
Internal(String),
|
||||
}
|
||||
|
||||
impl std::fmt::Display for FrontendError {
|
||||
fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result {
|
||||
std::fmt::Debug::fmt(self, f)
|
||||
}
|
||||
}
|
||||
|
||||
impl std::error::Error for FrontendError {}
|
|
@ -3,6 +3,7 @@
|
|||
#![allow(dead_code)]
|
||||
|
||||
use crate::entity::EntityRef;
|
||||
use crate::errors::FrontendError;
|
||||
use crate::ir::*;
|
||||
use crate::op_traits::{op_inputs, op_outputs};
|
||||
use crate::ops::Operator;
|
||||
|
@ -33,17 +34,20 @@ fn parse_init_expr<'a>(init_expr: &wasmparser::ConstExpr<'a>) -> Result<Option<u
|
|||
return Ok(None);
|
||||
}
|
||||
if operators.len() != 2 || !matches!(&operators[1], &wasmparser::Operator::End) {
|
||||
anyhow::bail!(
|
||||
bail!(FrontendError::UnsupportedFeature(format!(
|
||||
"Unsupported operator seq in base-address expr: {:?}",
|
||||
operators
|
||||
);
|
||||
)));
|
||||
}
|
||||
Ok(match &operators[0] {
|
||||
&wasmparser::Operator::I32Const { value } => Some(value as u64),
|
||||
&wasmparser::Operator::I64Const { value } => Some(value as u64),
|
||||
&wasmparser::Operator::F32Const { value } => Some(value.bits() as u64),
|
||||
&wasmparser::Operator::F64Const { value } => Some(value.bits()),
|
||||
op => anyhow::bail!("Unsupported data segment base-address operator: {:?}", op),
|
||||
op => anyhow::bail!(FrontendError::UnsupportedFeature(format!(
|
||||
"Unsupported data segment base-address operator: {:?}",
|
||||
op
|
||||
))),
|
||||
})
|
||||
}
|
||||
|
||||
|
@ -186,7 +190,10 @@ fn handle_payload<'a>(
|
|||
for element in reader {
|
||||
let element = element?;
|
||||
if element.ty != wasmparser::ValType::FuncRef {
|
||||
anyhow::bail!("Unsupported table type: {:?}", element.ty);
|
||||
bail!(FrontendError::UnsupportedFeature(format!(
|
||||
"Unsupported table type: {:?}",
|
||||
element.ty
|
||||
)));
|
||||
}
|
||||
match &element.kind {
|
||||
wasmparser::ElementKind::Passive => {}
|
||||
|
@ -206,7 +213,10 @@ fn handle_payload<'a>(
|
|||
for item in items {
|
||||
let func = match item {
|
||||
wasmparser::ElementItem::Func(func_idx) => Func::from(func_idx),
|
||||
_ => anyhow::bail!("Unsupported element item: {:?}", item),
|
||||
_ => bail!(FrontendError::UnsupportedFeature(format!(
|
||||
"Unsupported element item: {:?}",
|
||||
item
|
||||
))),
|
||||
};
|
||||
funcs.push(func);
|
||||
}
|
||||
|
@ -1099,7 +1109,9 @@ impl<'a, 'b> FunctionBodyBuilder<'a, 'b> {
|
|||
self.cur_block = Some(el);
|
||||
self.locals.start_block(el);
|
||||
} else {
|
||||
bail!("Else without If on top of frame stack");
|
||||
bail!(FrontendError::Internal(format!(
|
||||
"Else without If on top of frame stack"
|
||||
)));
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1163,7 +1175,10 @@ impl<'a, 'b> FunctionBodyBuilder<'a, 'b> {
|
|||
self.emit_ret(&retvals[..]);
|
||||
}
|
||||
|
||||
_ => bail!("Unsupported operator: {:?}", op),
|
||||
_ => bail!(FrontendError::UnsupportedFeature(format!(
|
||||
"Unsupported operator: {:?}",
|
||||
op
|
||||
))),
|
||||
}
|
||||
|
||||
Ok(())
|
||||
|
|
|
@ -14,6 +14,8 @@ mod op_traits;
|
|||
mod ops;
|
||||
pub mod passes;
|
||||
mod scoped_map;
|
||||
mod errors;
|
||||
|
||||
pub use ir::*;
|
||||
pub use ops::{Ieee32, Ieee64, Operator};
|
||||
pub use errors::*;
|
||||
|
|
Loading…
Reference in a new issue