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.
This commit is contained in:
Colin Snover 2017-01-31 19:03:33 -06:00
parent 3678390f3e
commit ee644ec01b

View File

@ -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