diff --git a/ethcore/evm/src/interpreter/memory.rs b/ethcore/evm/src/interpreter/memory.rs index a13c99a82..9aa9babc7 100644 --- a/ethcore/evm/src/interpreter/memory.rs +++ b/ethcore/evm/src/interpreter/memory.rs @@ -44,7 +44,7 @@ pub trait Memory { } /// Checks whether offset and size is valid memory range -fn is_valid_range(off: usize, size: usize) -> bool { +pub fn is_valid_range(off: usize, size: usize) -> bool { // When size is zero we haven't actually expanded the memory let overflow = off.overflowing_add(size).1; size > 0 && !overflow diff --git a/ethcore/evm/src/interpreter/mod.rs b/ethcore/evm/src/interpreter/mod.rs index 3069ab2fe..709ffe4d9 100644 --- a/ethcore/evm/src/interpreter/mod.rs +++ b/ethcore/evm/src/interpreter/mod.rs @@ -168,7 +168,12 @@ impl vm::Vm for Interpreter { } if do_trace { - ext.trace_executed(gasometer.current_gas.as_u256(), stack.peek_top(info.ret), mem_written.map(|(o, s)| (o, &(self.mem[o..(o + s)]))), store_written); + ext.trace_executed( + gasometer.current_gas.as_u256(), + stack.peek_top(info.ret), + mem_written.map(|(o, s)| (o, &(self.mem[o..o+s]))), + store_written, + ); } // Advance @@ -252,14 +257,20 @@ impl Interpreter { instruction: Instruction, stack: &Stack ) -> Option<(usize, usize)> { - match instruction { - instructions::MSTORE | instructions::MLOAD => Some((stack.peek(0).low_u64() as usize, 32)), - instructions::MSTORE8 => Some((stack.peek(0).low_u64() as usize, 1)), - instructions::CALLDATACOPY | instructions::CODECOPY | instructions::RETURNDATACOPY => Some((stack.peek(0).low_u64() as usize, stack.peek(2).low_u64() as usize)), - instructions::EXTCODECOPY => Some((stack.peek(1).low_u64() as usize, stack.peek(3).low_u64() as usize)), - instructions::CALL | instructions::CALLCODE => Some((stack.peek(5).low_u64() as usize, stack.peek(6).low_u64() as usize)), - instructions::DELEGATECALL => Some((stack.peek(4).low_u64() as usize, stack.peek(5).low_u64() as usize)), + let read = |pos| stack.peek(pos).low_u64() as usize; + let written = match instruction { + instructions::MSTORE | instructions::MLOAD => Some((read(0), 32)), + instructions::MSTORE8 => Some((read(0), 1)), + instructions::CALLDATACOPY | instructions::CODECOPY | instructions::RETURNDATACOPY => Some((read(0), read(2))), + instructions::EXTCODECOPY => Some((read(1), read(3))), + instructions::CALL | instructions::CALLCODE => Some((read(5), read(6))), + instructions::DELEGATECALL | instructions::STATICCALL => Some((read(4), read(5))), _ => None, + }; + + match written { + Some((offset, size)) if !memory::is_valid_range(offset, size) => None, + written => written, } }