diff --git a/src/lib.rs b/src/lib.rs index 054236f..b14a184 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -109,6 +109,7 @@ use std::collections::HashMap; #[derive(Debug)] pub enum Trap { Unreachable, + MemoryAccessOutOfBounds, } /// Internal interpreter error. diff --git a/src/runner.rs b/src/runner.rs index d1fb3af..ad92799 100644 --- a/src/runner.rs +++ b/src/runner.rs @@ -534,7 +534,12 @@ impl<'a, E: Externals> Interpreter<'a, E> { fn run_load(&mut self, context: &mut FunctionContext, _align: u32, offset: u32) -> Result where RuntimeValue: From, T: LittleEndianConvert { - let address = effective_address(offset, context.value_stack_mut().pop_as()?)?; + let address = + effective_address( + offset, + context.value_stack_mut().pop_as()? + ) + .map_err(Error::Trap)?; let m = context.module() .memory_by_index(DEFAULT_MEMORY_INDEX) .expect("Due to validation memory should exists"); @@ -546,7 +551,12 @@ impl<'a, E: Externals> Interpreter<'a, E> { fn run_load_extend(&mut self, context: &mut FunctionContext, _align: u32, offset: u32) -> Result where T: ExtendInto, RuntimeValue: From, T: LittleEndianConvert { - let address = effective_address(offset, context.value_stack_mut().pop_as()?)?; + let address = + effective_address( + offset, + context.value_stack_mut().pop_as()? + ) + .map_err(Error::Trap)?; let m = context.module() .memory_by_index(DEFAULT_MEMORY_INDEX) .expect("Due to validation memory should exists"); @@ -566,7 +576,12 @@ impl<'a, E: Externals> Interpreter<'a, E> { .value_stack_mut() .pop_as::() .map(|n| n.into_little_endian())?; - let address = effective_address(offset, context.value_stack_mut().pop_as::()?)?; + let address = + effective_address( + offset, + context.value_stack_mut().pop_as::()? + ) + .map_err(Error::Trap)?; let m = context.module() .memory_by_index(DEFAULT_MEMORY_INDEX) @@ -592,7 +607,12 @@ impl<'a, E: Externals> Interpreter<'a, E> { .map_err(Into::into) .and_then(|v| v.try_into())?; let stack_value = stack_value.wrap_into().into_little_endian(); - let address = effective_address(offset, context.value_stack_mut().pop_as::()?)?; + let address = + effective_address( + offset, + context.value_stack_mut().pop_as::()? + ) + .map_err(Error::Trap)?; let m = context.module() .memory_by_index(DEFAULT_MEMORY_INDEX) .expect("Due to validation memory should exists"); @@ -1147,9 +1167,9 @@ impl fmt::Debug for FunctionContext { } } -fn effective_address(address: u32, offset: u32) -> Result { +fn effective_address(address: u32, offset: u32) -> Result { match offset.checked_add(address) { - None => Err(Error::Memory(format!("invalid memory access: {} + {}", offset, address))), + None => Err(Trap::MemoryAccessOutOfBounds), Some(address) => Ok(address), } }