From 182b3d9e27981c03df07cc86d8f794ad218dc350 Mon Sep 17 00:00:00 2001 From: Simon Tatham Date: Fri, 27 Sep 2024 22:28:57 +0100 Subject: [PATCH] Pattern: fix three bugs in game_text_format. A user reported that, on the default square board size, the clues were printed in the right places, but the grid contents were accidentally transposed by swapping the x and y coordinates. Oops! Trying to reproduce this, my dev build was running under ASan, which pointed out two further buffer handling bugs. The initial sprintf put the terminating NUL one char too early in the buffer, so that it was overwritten by the bottom right corner of the grid and no NUL ended up in the buffer at all; also, the separate buffer for formatting numeric clues in the left margin was sized one char too short, because the NUL at the end of it hadn't been counted. Apparently in a non-ASan environment both of those could work anyway by chance. --- pattern.c | 12 +++++++----- 1 file changed, 7 insertions(+), 5 deletions(-) diff --git a/pattern.c b/pattern.c index b370a3d..b7bde77 100644 --- a/pattern.c +++ b/pattern.c @@ -1180,7 +1180,8 @@ static char *game_text_format(const game_state *state) topleft = lw * top_gap + left_gap; board = snewn(len + 1, char); - sprintf(board, "%*s\n", len - 2, ""); + memset(board, ' ', len); + board[len] = '\0'; for (i = 0; i < lh; ++i) { board[lw - 1 + i*lw] = '\n'; @@ -1197,7 +1198,7 @@ static char *game_text_format(const game_state *state) } } - buf = snewn(left_gap, char); + buf = snewn(left_gap + 1, char); for (i = 0; i < h; ++i) { char *p = buf, *start = board + top_gap*lw + left_gap + (i*ch+1)*lw; for (j = 0; j < state->common->rowlen[i+w]; ++j) { @@ -1207,9 +1208,9 @@ static char *game_text_format(const game_state *state) memcpy(start - (p - buf), buf, p - buf); } - for (i = 0; i < w; ++i) { - for (j = 0; j < h; ++j) { - int cell = topleft + i*cw + j*ch*lw; + for (i = 0; i < h; ++i) { + for (j = 0; j < w; ++j) { + int cell = topleft + j*cw + i*ch*lw; int center = cell + cw/2 + (ch/2)*lw; int dx, dy; board[cell] = false ? center : '+'; @@ -1227,6 +1228,7 @@ static char *game_text_format(const game_state *state) sfree(buf); + assert(board[len] == '\0' && "Overwrote the NUL"); return board; }