diff --git a/lib/exceptions.js b/lib/exceptions.js index d4bd91fd76..3f478d5ff1 100644 --- a/lib/exceptions.js +++ b/lib/exceptions.js @@ -5,7 +5,8 @@ const ERROR = { INVALID_JUMP: 'invalid JUMP', INVALID_OPCODE: 'invalid opcode', REVERT: 'revert', - STATIC_STATE_CHANGE: 'static state change' + STATIC_STATE_CHANGE: 'static state change', + INTERNAL_ERROR: 'internal error' } function VmError (error) { diff --git a/lib/runCode.js b/lib/runCode.js index d3e1d2d999..7d64efe4e8 100644 --- a/lib/runCode.js +++ b/lib/runCode.js @@ -165,11 +165,14 @@ module.exports = function (opts, cb) { cb(new VmError(ERROR.OUT_OF_GAS)) return } + // advance program counter runState.programCounter++ var argsNum = opInfo.in + var retNum = opInfo.out // pop the stack - var args = argsNum ? runState.stack.splice(-opInfo.in) : [] + var args = argsNum ? runState.stack.splice(-argsNum) : [] + args.reverse() args.push(runState) // create a callback for async opFunc @@ -178,11 +181,20 @@ module.exports = function (opts, cb) { if (err) return cb(err) // save result to the stack - if (result) { + if (result !== undefined) { + if (retNum !== 1) { + // opcode post-stack mismatch + return cb(new VmError(ERROR.INTERNAL_ERROR)) + } // NOTE: Ensure that every stack item is padded to 256 bits. // This should be done at every opcode in the future. result = utils.setLengthLeft(result, 32) runState.stack.push(result) + } else { + if (retNum !== 0) { + // opcode post-stack mismatch + return cb(new VmError(ERROR.INTERNAL_ERROR)) + } } cb() @@ -198,11 +210,20 @@ module.exports = function (opts, cb) { } // save result to the stack - if (result) { + if (result !== undefined) { + if (retNum !== 1) { + // opcode post-stack mismatch + return cb(VmError(ERROR.INTERNAL_ERROR)) + } // NOTE: Ensure that every stack item is padded to 256 bits. // This should be done at every opcode in the future. result = utils.setLengthLeft(result, 32) runState.stack.push(result) + } else { + if (!opInfo.async && retNum !== 0) { + // opcode post-stack mismatch + return cb(VmError(ERROR.INTERNAL_ERROR)) + } } // call the callback if opFn was sync