From 439730a13bcb58ac76047e87cd3fb927b4385b49 Mon Sep 17 00:00:00 2001 From: Intubun <41478036+Intubun@users.noreply.github.com> Date: Thu, 21 May 2026 14:28:09 +0200 Subject: [PATCH] fix: sscanf length bound in TclmagicRegisterCommands; show output-tcl in CI Add explicit length limit to sscanf in TclmagicRegisterCommands: %92s instead of %s prevents a potential stack overwrite if a command name were ever longer than the buffer. Matches the available space (keyword[100] minus the 7-byte "magic::" prefix minus null). Extend the CI output-display step to also iterate over output-tcl/ so that TCL-variant test regressions are visible in the job log without downloading artifacts. --- .github/workflows/main-wasm.yml | 16 ++++++++++------ tcltk/tclmagic.c | 2 +- 2 files changed, 11 insertions(+), 7 deletions(-) diff --git a/.github/workflows/main-wasm.yml b/.github/workflows/main-wasm.yml index b2d6aa87..0b0ef86e 100644 --- a/.github/workflows/main-wasm.yml +++ b/.github/workflows/main-wasm.yml @@ -107,12 +107,16 @@ jobs: - name: Display example outputs run: | shopt -s nullglob - for f in npm/examples/output/*; do - name=$(basename "$f") - case "$f" in - *.gds) echo "===== $name (binary, $(wc -c < "$f") bytes — skipped) =====" ;; - *) echo "===== $name ====="; cat "$f" ;; - esac + for dir in npm/examples/output npm/examples/output-tcl; do + [ -d "$dir" ] || continue + echo "======== $dir ========" + for f in "$dir"/*; do + name=$(basename "$f") + case "$f" in + *.gds) echo "===== $name (binary, $(wc -c < "$f") bytes — skipped) =====" ;; + *) echo "===== $name ====="; cat "$f" ;; + esac + done done # The release gate. We publish a new npm version only when a tag of the diff --git a/tcltk/tclmagic.c b/tcltk/tclmagic.c index aeb097bc..710319ff 100644 --- a/tcltk/tclmagic.c +++ b/tcltk/tclmagic.c @@ -680,7 +680,7 @@ TclmagicRegisterCommands(Tcl_Interp *interp) commandTable = WindGetCommandTable(client); for (n = 0; commandTable[n] != NULL; n++) { - sscanf(commandTable[n], "%s ", kwptr); + sscanf(commandTable[n], "%92s", kwptr); Tcl_CreateCommand(interp, keyword, (Tcl_CmdProc *)_tcl_dispatch, (ClientData)NULL, (Tcl_CmdDeleteProc *)NULL); }