diff options
author | Colin Snover | 2017-01-31 19:03:33 -0600 |
---|---|---|
committer | Colin Snover | 2017-03-30 20:49:37 -0500 |
commit | ee644ec01b292c3308085170021f04f6f6917bc9 (patch) | |
tree | 8c36e03eadd759ecdb994d9bc211ac20cd57f942 /engines | |
parent | 3678390f3eac8d8373840c91646076154f49aed1 (diff) | |
download | scummvm-rg350-ee644ec01b292c3308085170021f04f6f6917bc9.tar.gz scummvm-rg350-ee644ec01b292c3308085170021f04f6f6917bc9.tar.bz2 scummvm-rg350-ee644ec01b292c3308085170021f04f6f6917bc9.zip |
SCI32: Check for game aborts in all kList iteration methods
This fixes a use-after-free in GK2 when restoring a second save
game, when the List reg_t is still considered valid but the List
has moved due to a partial game restore.
Diffstat (limited to 'engines')
-rw-r--r-- | engines/sci/engine/klists.cpp | 13 |
1 files changed, 13 insertions, 0 deletions
diff --git a/engines/sci/engine/klists.cpp b/engines/sci/engine/klists.cpp index 305d459ac1..2f66e51a6e 100644 --- a/engines/sci/engine/klists.cpp +++ b/engines/sci/engine/klists.cpp @@ -618,6 +618,7 @@ reg_t kListEachElementDo(EngineState *s, int argc, reg_t *argv) { } } else { invokeSelector(s, curObject, slc, argc, argv, argc - 2, argv + 2); + // Check if the call above leads to a game restore, in which case // the segment manager will be reset, and the original list will // be invalidated @@ -672,6 +673,12 @@ reg_t kListFirstTrue(EngineState *s, int argc, reg_t *argv) { } else { invokeSelector(s, curObject, slc, argc, argv, argc - 2, argv + 2); + // Check if the call above leads to a game restore, in which case + // the segment manager will be reset, and the original list will + // be invalidated + if (s->abortScriptProcessing == kAbortLoadGame) + return s->r_acc; + // Check if the result is true if (!s->r_acc.isNull()) { s->r_acc = curObject; @@ -721,6 +728,12 @@ reg_t kListAllTrue(EngineState *s, int argc, reg_t *argv) { s->r_acc = readSelector(s->_segMan, curObject, slc); } else { invokeSelector(s, curObject, slc, argc, argv, argc - 2, argv + 2); + + // Check if the call above leads to a game restore, in which case + // the segment manager will be reset, and the original list will + // be invalidated + if (s->abortScriptProcessing == kAbortLoadGame) + return s->r_acc; } // Check if the result isn't true |