aboutsummaryrefslogtreecommitdiff
path: root/engines/agi/op_test.cpp
diff options
context:
space:
mode:
authorMartin Kiewitz2017-02-23 23:54:45 +0100
committerMartin Kiewitz2017-02-23 23:54:45 +0100
commit9dd0cd51d5b243700ccbd154e1d91ddb84c307c2 (patch)
tree5fa0a22dc13b07840d5495d0fec99f3d1a38c0ee /engines/agi/op_test.cpp
parent5fa728371f9d01f9fb268596d961ad841825a456 (diff)
downloadscummvm-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.cpp16
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);
}
}