diff options
| author | Ben Harris <bjh21@bjh21.me.uk> | 2023-01-07 22:05:33 +0000 |
|---|---|---|
| committer | Ben Harris <bjh21@bjh21.me.uk> | 2023-01-15 16:21:37 +0000 |
| commit | 1aded127eb3fb7194a1752d96bfba95a5b7fa4dc (patch) | |
| tree | a16465d74d685ea890f23f45d6a917c17d8908d5 | |
| parent | a539f38efd0d821c8325846fc879a3e46d6412bf (diff) | |
| download | puzzles-1aded127eb3fb7194a1752d96bfba95a5b7fa4dc.zip puzzles-1aded127eb3fb7194a1752d96bfba95a5b7fa4dc.tar.gz puzzles-1aded127eb3fb7194a1752d96bfba95a5b7fa4dc.tar.bz2 puzzles-1aded127eb3fb7194a1752d96bfba95a5b7fa4dc.tar.xz | |
Netslide: Reject moves wider than the grid
Also add a corresponding assertion to the underlying move primitive.
Without this limit, long moves cause a buffer overrun.
To demonstrate the problem, build Netslide with AddressSanitizer and
load this save file:
SAVEFILE:41:Simon Tatham's Portable Puzzle Collection
VERSION :1:1
GAME :8:Netslide
PARAMS :3:4x4
CPARAMS :3:4x4
DESC :16:49b59aca247714b4
NSTATES :1:2
STATEPOS:1:2
MOVE :5:R3,51
| -rw-r--r-- | netslide.c | 12 |
1 files changed, 9 insertions, 3 deletions
@@ -1004,7 +1004,9 @@ static void slide_row_int(int w, int h, unsigned char *tiles, int dir, int row) int x = dir > 0 ? -1 : w; int tx = x + dir; int n = w - 1; - unsigned char endtile = tiles[row * w + tx]; + unsigned char endtile; + assert(0 <= tx && tx < w); + endtile = tiles[row * w + tx]; do { x = tx; tx = (x + dir + w) % w; @@ -1018,7 +1020,9 @@ static void slide_col_int(int w, int h, unsigned char *tiles, int dir, int col) int y = dir > 0 ? -1 : h; int ty = y + dir; int n = h - 1; - unsigned char endtile = tiles[ty * w + col]; + unsigned char endtile; + assert(0 <= ty && ty < h); + endtile = tiles[ty * w + col]; do { y = ty; ty = (y + dir + h) % h; @@ -1139,7 +1143,9 @@ static game_state *execute_move(const game_state *from, const char *move) if ((move[0] == 'C' || move[0] == 'R') && sscanf(move+1, "%d,%d", &c, &d) == 2 && - c >= 0 && c < (move[0] == 'C' ? from->width : from->height)) { + c >= 0 && c < (move[0] == 'C' ? from->width : from->height) && + d <= (move[0] == 'C' ? from->width : from->height) && + d >= -(move[0] == 'C' ? from->width : from->height) && d != 0) { col = (move[0] == 'C'); } else if (move[0] == 'S' && strlen(move) == from->width * from->height + 1) { |