diff options
| author | Scott Gasch <[email protected]> | 2026-10-15 16:26:43 -0700 |
|---|---|---|
| committer | Scott Gasch <[email protected]> | 2026-10-15 16:26:43 -0700 |
| commit | c179ae5ad9f1a0efb68904033621705fd060aea4 (patch) | |
| tree | 2f0639b4699a7825b6983f27518497d388eb0e2d /src/gamelist.c | |
| parent | 1ea81bae240912efb8cebabae35fe58bc5d12afb (diff) | |
Fix overlapping-buffer sprintf/snprintf bugs in fen.c and gamelist.c
Both FenFromPosition and the status-line builder in gamelist.c were
reading and writing the same buffer within a single sprintf/snprintf
call (e.g. sprintf(pHeap, "%s...", pHeap, ...)) -- undefined behavior
per the C standard since the source and destination overlap, caught
by valgrind as uninitialised-value reads even though no DEBUG ASSERT
ever tripped. Fixed by building each piece into a separate buffer (or
appending via snprintf/strncat into the already-terminated prefix)
instead of re-reading the destination as a source argument.
debug_smoke_test.sh: added a valgrind pass over the same sampled
smoke-test positions, since this class of bug produces no ASSERT
failure and was otherwise invisible to the existing smoke test.
Co-Authored-By: Claude Sonnet 5 <[email protected]>
Diffstat (limited to 'src/gamelist.c')
| -rw-r--r-- | src/gamelist.c | 19 |
1 files changed, 11 insertions, 8 deletions
diff --git a/src/gamelist.c b/src/gamelist.c index a409f07..0a0bdd1 100644 --- a/src/gamelist.c +++ b/src/gamelist.c @@ -1099,23 +1099,26 @@ Return value: char buf[SMALL_STRING_LEN_CHAR]; ASSERT(IS_VALID_COLOR(g_uToMove)); - if (g_Options.fStatusLine) + if (g_Options.fStatusLine) { strcpy(buf, "_\0"); - if (!g_Options.fRunningUnderXboard) + if (!g_Options.fRunningUnderXboard) { if ((TRUE == g_Options.fPondering) && (g_Options.mvPonder.uMove != 0)) { snprintf(buf, SMALL_STRING_LEN_CHAR - 1, - "_[pondering %s] ", + "_[pondering %s] ", MoveToSan(g_Options.mvPonder, &g_RootPosition)); } - snprintf(buf, SMALL_STRING_LEN_CHAR - strlen(buf), - "%s%s(move %u)_", - buf, - (g_uToMove == WHITE) ? "white" : "black", - g_uMoveNumber[g_uToMove]); + { + char bufTail[SMALL_STRING_LEN_CHAR]; + snprintf(bufTail, sizeof(bufTail), + "%s(move %u)_", + (g_uToMove == WHITE) ? "white" : "black", + g_uMoveNumber[g_uToMove]); + strncat(buf, bufTail, SMALL_STRING_LEN_CHAR - strlen(buf) - 1); + } Trace("%s\n", buf); } } |
