analyzer, cmd/capslock-git-diff: escape control characters in callpath filenames#300
Merged
Merged
Conversation
…h filenames token.Position.Filename can be set to an arbitrary string by //line and /*line ...*/ directives in analyzed Go source. capslock copies that string into terminal output unmodified, allowing crafted source files to emit ANSI escape sequences (CSI, OSC 8 hyperlinks, OSC 52 clipboard, cursor manipulation) when scanned. Apply strconv.Quote with surrounding quotes trimmed to filenames in the three terminal-oriented sinks (verbose output, default callpath rendering, capslock-git-diff output). Mirrors the existing sanitization pattern in cmd/capslock/capslock.go. JSON output via protojson is already safe. Adds analyzer/util_test.go covering the escape behavior.
jcd2
approved these changes
Apr 28, 2026
Collaborator
jcd2
left a comment
There was a problem hiding this comment.
Nicely done, thanks!
This will make path separators on Windows double-backslashes, but that's ok for now.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Fixes #299.
token.Position.Filenamecan be set to an arbitrary string by//lineand/*line ...*/directives in analyzed Go source. capslock copies that stringinto
cpb.Function_Site.Filename(afterpath.Base) and writes it to terminalsinks unchanged, so a directive containing ANSI escape bytes or tabs reaches
the user's terminal.
This change escapes control characters at the three terminal-output sinks:
analyzer/compare.goprintCallPath(-output=compare)analyzer/static/verbose.tmpl(-output=v/-output=verbose), via a newescapeentry intemplateFuncMapcmd/capslock-git-diff/main.goprintCallPathThe escape helper uses
strconv.Quotewith the surrounding"s trimmed off,matching the existing helper in
cmd/capslock/capslock.go(used since versionoutput was added). Legitimate Go source filenames pass through unchanged;
only non-printable bytes are escaped.
The JSON output path is not touched:
protojsonalready escapes controlbytes, and machine consumers should keep receiving raw filenames.
cmd/capslock-git-diffdoes not importanalyzer, so the helper isduplicated locally rather than exported from
analyzer.Test
analyzer/util_test.goadds a unit test forescapeControlCharscoveringplain filenames, filenames with spaces, ANSI CSI bytes, embedded tabs, and
BEL. It also asserts that no C0 byte or DEL remains in the output for any
case. Existing tests continue to pass.