diff options
author | Filippos Karapetis | 2011-11-28 22:35:10 +0200 |
---|---|---|
committer | Filippos Karapetis | 2011-11-28 22:36:58 +0200 |
commit | 381e92a576ef05de60c1a90d534785ebd7a112c2 (patch) | |
tree | 903d7c95b2d96d82a3d1faabb5cf0ae3b7191597 /engines/sci/engine | |
parent | 29fb48b74b64752b712c2b0b2a15f6ff7dd33716 (diff) | |
download | scummvm-rg350-381e92a576ef05de60c1a90d534785ebd7a112c2.tar.gz scummvm-rg350-381e92a576ef05de60c1a90d534785ebd7a112c2.tar.bz2 scummvm-rg350-381e92a576ef05de60c1a90d534785ebd7a112c2.zip |
SCI: Added handling of invalid jump offsets (e.g. QFG2, script 260)
Diffstat (limited to 'engines/sci/engine')
-rw-r--r-- | engines/sci/engine/scriptdebug.cpp | 10 | ||||
-rw-r--r-- | engines/sci/engine/vm.cpp | 12 |
2 files changed, 20 insertions, 2 deletions
diff --git a/engines/sci/engine/scriptdebug.cpp b/engines/sci/engine/scriptdebug.cpp index ad3f4fb788..3faa13183c 100644 --- a/engines/sci/engine/scriptdebug.cpp +++ b/engines/sci/engine/scriptdebug.cpp @@ -296,7 +296,7 @@ bool isJumpOpcode(EngineState *s, reg_t pos, reg_t& jumpTarget) { Script *script_entity = (Script *)mobj; const byte *scr = script_entity->getBuf(); - int scr_size = script_entity->getBufSize(); + int scr_size = script_entity->getScriptSize(); if (pos.offset >= scr_size) return false; @@ -310,7 +310,13 @@ bool isJumpOpcode(EngineState *s, reg_t pos, reg_t& jumpTarget) { case op_bt: case op_bnt: case op_jmp: - jumpTarget = pos + bytecount + opparams[0]; + { + reg_t jmpTarget = pos + bytecount + opparams[0]; + // QFG2 has invalid jumps outside the script buffer in script 260 + if (jmpTarget.offset >= scr_size) + return false; + jumpTarget = jmpTarget; + } return true; default: return false; diff --git a/engines/sci/engine/vm.cpp b/engines/sci/engine/vm.cpp index 6b3a3198ea..226a73b139 100644 --- a/engines/sci/engine/vm.cpp +++ b/engines/sci/engine/vm.cpp @@ -764,16 +764,28 @@ void run_vm(EngineState *s) { // Branch relative if true if (s->r_acc.offset || s->r_acc.segment) s->xs->addr.pc.offset += opparams[0]; + + if (s->xs->addr.pc.offset >= local_script->getScriptSize()) + error("[VM] op_bt: request to jump past the end of script %d (offset %d, script is %d bytes)", + local_script->getScriptNumber(), s->xs->addr.pc.offset, local_script->getScriptSize()); break; case op_bnt: // 0x18 (24) // Branch relative if not true if (!(s->r_acc.offset || s->r_acc.segment)) s->xs->addr.pc.offset += opparams[0]; + + if (s->xs->addr.pc.offset >= local_script->getScriptSize()) + error("[VM] op_bnt: request to jump past the end of script %d (offset %d, script is %d bytes)", + local_script->getScriptNumber(), s->xs->addr.pc.offset, local_script->getScriptSize()); break; case op_jmp: // 0x19 (25) s->xs->addr.pc.offset += opparams[0]; + + if (s->xs->addr.pc.offset >= local_script->getScriptSize()) + error("[VM] op_jmp: request to jump past the end of script %d (offset %d, script is %d bytes)", + local_script->getScriptNumber(), s->xs->addr.pc.offset, local_script->getScriptSize()); break; case op_ldi: // 0x1a (26) |