Guess: Don't allow any moves once the game is solved

If the game is solved (either by a win or a loss), interpret_move()
can never return a move, but execute_move() should also reject any
moves in case we're loading a corrupt or malicious save file.
Otherwise a save file with more guesses than the maximum allowed can
cause a buffer overrun.

This save file demonstrates the problem when loaded into a build of
Puzzles with AddressSanitizer:

SAVEFILE:41:Simon Tatham's Portable Puzzle Collection
VERSION :1:1
GAME    :5:Guess
PARAMS  :9:c6p4g1Bm
CPARAMS :9:c6p4g1Bm
DESC    :8:b5f3faed
NSTATES :1:3
STATEPOS:1:3
MOVE    :8:G1,1,2,2
MOVE    :8:G4,3,1,1
This commit is contained in:
Ben Harris
2023-01-07 19:45:03 +00:00
parent 09b1629386
commit c84af670b5

View File

@ -942,6 +942,8 @@ static game_state *execute_move(const game_state *from, const char *move)
game_state *ret;
const char *p;
/* No moves are allowed once the game is solved. */
if (from->solved) return NULL;
if (!strcmp(move, "S")) {
ret = dup_game(from);
ret->solved = -1;