diff --git a/spec/src/run.rs b/spec/src/run.rs index e0781d3..22f36c6 100644 --- a/spec/src/run.rs +++ b/spec/src/run.rs @@ -23,7 +23,7 @@ pub fn spec(path: &str) { match kind { CommandKind::AssertMalformed { module, .. } => { match deserialize_buffer::(&module.into_vec()) { - Ok(_) => panic!("Expected invalid module definition, got some module!"), + Ok(_) => panic!("Expected invalid module definition, got some module! at line {}", line), Err(e) => println!("assert_invalid at line {} - success ({:?})", line, e), } } diff --git a/src/elements/func.rs b/src/elements/func.rs index 8c9c217..3ad9743 100644 --- a/src/elements/func.rs +++ b/src/elements/func.rs @@ -120,6 +120,14 @@ impl Deserialize for FuncBody { // todo: maybe use reader.take(section_length) let mut body_reader = SectionReader::new(reader)?; let locals: Vec = CountedList::::deserialize(&mut body_reader)?.into_inner(); + + // The specification obliges us to count the total number of local variables while + // decoding the binary format. + locals + .iter() + .try_fold(0u32, |acc, &Local { count, .. }| acc.checked_add(count)) + .ok_or_else(|| Error::TooManyLocals)?; + let instructions = Instructions::deserialize(&mut body_reader)?; body_reader.close()?; Ok(FuncBody { locals: locals, instructions: instructions }) diff --git a/src/elements/mod.rs b/src/elements/mod.rs index e05b03e..6f46306 100644 --- a/src/elements/mod.rs +++ b/src/elements/mod.rs @@ -145,6 +145,8 @@ pub enum Error { InconsistentCode, /// Only flags 0, 1, and 2 are accepted on segments InvalidSegmentFlags(u32), + /// Sum of counts of locals is greater than 2^32. + TooManyLocals, } impl fmt::Display for Error { @@ -181,6 +183,7 @@ impl fmt::Display for Error { Error::UnknownFunctionForm(ref form) => write!(f, "Unknown function form ({})", form), Error::InconsistentCode => write!(f, "Number of function body entries and signatures does not match"), Error::InvalidSegmentFlags(n) => write!(f, "Invalid segment flags: {}", n), + Error::TooManyLocals => write!(f, "Too many locals"), } } } @@ -218,6 +221,7 @@ impl ::std::error::Error for Error { Error::UnknownFunctionForm(_) => "Unknown function form", Error::InconsistentCode => "Number of function body entries and signatures does not match", Error::InvalidSegmentFlags(_) => "Invalid segment flags", + Error::TooManyLocals => "Too many locals", } } }