summaryrefslogtreecommitdiff
path: root/src/gamelist.c
diff options
context:
space:
mode:
authorScott Gasch <[email protected]>2026-10-15 16:26:43 -0700
committerScott Gasch <[email protected]>2026-10-15 16:26:43 -0700
commitc179ae5ad9f1a0efb68904033621705fd060aea4 (patch)
tree2f0639b4699a7825b6983f27518497d388eb0e2d /src/gamelist.c
parent1ea81bae240912efb8cebabae35fe58bc5d12afb (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.c19
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);
}
}