mirror of
git://git.tartarus.org/simon/puzzles.git
synced 2025-04-20 23:51:29 -07:00
Palisade: forbid moves that remove grid edges
Without this check, a corrupt save file can include a move that removes an edge of the grid, and then is_solved() walks off the edge of the grid causing a buffer over- or under-run. To demonstrate the bug, load this save file in a build with AddressSanitizer: SAVEFILE:41:Simon Tatham's Portable Puzzle Collection VERSION :1:1 GAME :8:Palisade PARAMS :5:5x5n5 CPARAMS :5:5x5n5 DESC :0: NSTATES :1:2 STATEPOS:1:2 MOVE :6:F0,0,1
This commit is contained in:
12
palisade.c
12
palisade.c
@ -1010,10 +1010,9 @@ static game_state *execute_move(const game_state *state, const char *move)
|
||||
{
|
||||
int w = state->shared->params.w, h = state->shared->params.h, wh = w * h;
|
||||
game_state *ret = dup_game(state);
|
||||
int nchars, x, y, flag;
|
||||
int nchars, x, y, flag, i;
|
||||
|
||||
if (*move == 'S') {
|
||||
int i;
|
||||
++move;
|
||||
for (i = 0; i < wh && move[i]; ++i)
|
||||
ret->borders[i] =
|
||||
@ -1026,6 +1025,11 @@ static game_state *execute_move(const game_state *state, const char *move)
|
||||
while (sscanf(move, "F%d,%d,%d%n", &x, &y, &flag, &nchars) == 3 &&
|
||||
!OUT_OF_BOUNDS(x, y, w, h)) {
|
||||
move += nchars;
|
||||
for (i = 0; i < 4; i++)
|
||||
if ((flag & BORDER(i)) &&
|
||||
OUT_OF_BOUNDS(x+dx[i], y+dy[i], w, h))
|
||||
/* No toggling the borders of the grid! */
|
||||
goto badmove;
|
||||
ret->borders[y*w + x] ^= flag;
|
||||
}
|
||||
|
||||
@ -1036,6 +1040,10 @@ static game_state *execute_move(const game_state *state, const char *move)
|
||||
ret->borders);
|
||||
|
||||
return ret;
|
||||
|
||||
badmove:
|
||||
sfree(ret);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/* --- Drawing routines --------------------------------------------- */
|
||||
|
Reference in New Issue
Block a user