diff options
author | Martin Kiewitz | 2017-02-23 23:54:45 +0100 |
---|---|---|
committer | Martin Kiewitz | 2017-02-23 23:54:45 +0100 |
commit | 9dd0cd51d5b243700ccbd154e1d91ddb84c307c2 (patch) | |
tree | 5fa0a22dc13b07840d5495d0fec99f3d1a38c0ee /engines/agi/op_test.cpp | |
parent | 5fa728371f9d01f9fb268596d961ad841825a456 (diff) | |
download | scummvm-rg350-9dd0cd51d5b243700ccbd154e1d91ddb84c307c2.tar.gz scummvm-rg350-9dd0cd51d5b243700ccbd154e1d91ddb84c307c2.tar.bz2 scummvm-rg350-9dd0cd51d5b243700ccbd154e1d91ddb84c307c2.zip |
AGI: Clean up VM opcode handling
so that invalid opcodes won't crash ScummVM anymore
Diffstat (limited to 'engines/agi/op_test.cpp')
-rw-r--r-- | engines/agi/op_test.cpp | 16 |
1 files changed, 13 insertions, 3 deletions
diff --git a/engines/agi/op_test.cpp b/engines/agi/op_test.cpp index 4505668fd1..b4bf38b8a2 100644 --- a/engines/agi/op_test.cpp +++ b/engines/agi/op_test.cpp @@ -418,7 +418,7 @@ int AgiEngine::testIfCode(int lognum) { default: // Evaluate the command and skip the rest of the instruction - _agiCondCommands[op](state, this, p); + _opCodesCond[op].functionPtr(state, this, p); skipInstruction(op); // NOT mode is enabled only for one instruction @@ -469,16 +469,26 @@ void AgiEngine::skipInstruction(byte op) { return; if (op == 0x0E && state->_vm->getVersion() >= 0x2000) // said ip += *(code + ip) * 2 + 1; - else - ip += logicNamesTest[op].argumentsLength(); + else { + ip += _opCodesCond[op].parameterSize; + } } void AgiEngine::skipInstructionsUntil(byte v) { AgiGame *state = &_game; + int originalIP = state->_curLogic->cIP; + while (1) { byte op = *(code + ip++); if (op == v) return; + + if (op < 0xFC) { + if (!_opCodesCond[op].functionPtr) { + // security-check + error("illegal opcode %x during skipinstructions in script %d at %d (triggered at %d)", op, state->curLogicNr, ip, originalIP); + } + } skipInstruction(op); } } |