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
This commit is contained in:
Ben Harris
2023-01-07 22:05:33 +00:00
parent a539f38efd
commit 1aded127eb

View File

@ -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 x = dir > 0 ? -1 : w;
int tx = x + dir; int tx = x + dir;
int n = w - 1; 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 { do {
x = tx; x = tx;
tx = (x + dir + w) % w; 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 y = dir > 0 ? -1 : h;
int ty = y + dir; int ty = y + dir;
int n = h - 1; 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 { do {
y = ty; y = ty;
ty = (y + dir + h) % h; 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') && if ((move[0] == 'C' || move[0] == 'R') &&
sscanf(move+1, "%d,%d", &c, &d) == 2 && 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'); col = (move[0] == 'C');
} else if (move[0] == 'S' && } else if (move[0] == 'S' &&
strlen(move) == from->width * from->height + 1) { strlen(move) == from->width * from->height + 1) {