Fix too many locals problem.

This commit is contained in:
Sergey Pepyakin 2018-11-07 14:54:22 +01:00
parent 256b7f934d
commit 84ea83f40e
3 changed files with 13 additions and 1 deletions

View File

@ -23,7 +23,7 @@ pub fn spec(path: &str) {
match kind {
CommandKind::AssertMalformed { module, .. } => {
match deserialize_buffer::<Module>(&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),
}
}

View File

@ -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<Local> = CountedList::<Local>::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 })

View File

@ -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",
}
}
}