Goal
Add focused tests for Sanitize in internal/display/sanitize.go.
Why
// Sanitize removes terminal controls and bidi overrides from untrusted labels.
func Sanitize(value string) string {
var output strings.Builder
for _, char := range value {
if unicode.IsControl(char) || unicode.Is(unicode.Cf, char) || unicode.Is(unicode.Zl, char) || unicode.Is(unicode.Zp, char) {
output.WriteRune('?')
continue
}
output.WriteRune(char)
}
return output.String()
}
This is the one place the runtime neutralizes text it did not write. display.Sanitize appears on 296 lines across 20 files, among them the human renderer (internal/cli/render.go), the MCP tool surface (internal/mcp/tools.go), and the carrier decoder (internal/carrier/decode.go). The strings handed to it are pack ids, decision ids, reasons, fact pointers, and diagnostic text — authored elsewhere, so untrusted whenever someone runs jpack against a pack they did not write.
It has one test, and Sanitize sits at 100% statement coverage. Those two facts are not in tension. internal/display/sanitize_test.go is twenty lines and holds a single case that feeds one string and then re-checks the same four Unicode predicates the function itself uses; full coverage of a line says the line ran, not that anything about it is held in place. What that test pins is the class of character removed, and nothing else around it:
- ESC (U+001B), the introducer of an ANSI escape sequence and the most common terminal-injection vector, does not appear anywhere in the test file — nor in any test file in the repository;
- nothing pins what a removed character becomes — only that it is no longer a control, so replacing
'?' with anything, or with nothing, still passes;
- nothing pins one-rune-in-one-rune-out, so a change that dropped characters instead of substituting them would pass;
- U+2029 (Zp) appears nowhere, so that predicate can be deleted from the
if with the whole suite still green;
- nothing pins the far side of the boundary. The existing case does show the ASCII runs
safe and text surviving, but nothing shows that an ordinary space, or a non-breaking space (U+00A0, category Zs), survives unchanged — which is what keeps a sanitized label readable rather than mangled.
Behaviour today, for the cases worth pinning:
"\x1b[31mred" -> "?[31mred" // the introducer goes; the rest is inert text
"a\tb\nc" -> "a?b?c" // a label cannot open a new line
"\x7f" -> "?" // DEL
"a b" -> "a b" // an ordinary space survives
"a b" -> "a b" // a non-breaking space survives — Zs, not Cf
"\U0001F600" -> "\U0001F600" // a multi-byte rune survives
Scope
- Change
internal/display/sanitize_test.go only.
- Table-driven,
t.Run per case, asserting the exact output string rather than a property of it. Cover at least: ESC and a full ANSI colour sequence; tab, newline and carriage return; DEL (U+007F); a C1 control (U+009B); a bidi override (U+202E, Cf); a line separator (U+2028, Zl); a paragraph separator (U+2029, Zp); plain ASCII; a string containing an ordinary space; a non-breaking space (U+00A0); a multi-byte character and an emoji; the empty string.
- Add one case pinning that the output has the same rune count as the input.
- Add one case pinning idempotency:
Sanitize(Sanitize(s)) == Sanitize(s).
- Do not change
Sanitize, and do not change any caller. If the substitution character or the predicate list looks wrong, open a separate issue rather than editing it here.
Acceptance criteria
Contributor learning
Why a tool that prints text it did not author routes all of it through one sanitizer instead of trusting call sites; how to pin a transformation by its output instead of restating its implementation in the assertion; and why 100% statement coverage said nothing about either.
Goal
Add focused tests for
Sanitizeininternal/display/sanitize.go.Why
This is the one place the runtime neutralizes text it did not write.
display.Sanitizeappears on 296 lines across 20 files, among them the human renderer (internal/cli/render.go), the MCP tool surface (internal/mcp/tools.go), and the carrier decoder (internal/carrier/decode.go). The strings handed to it are pack ids, decision ids, reasons, fact pointers, and diagnostic text — authored elsewhere, so untrusted whenever someone runsjpackagainst a pack they did not write.It has one test, and
Sanitizesits at 100% statement coverage. Those two facts are not in tension.internal/display/sanitize_test.gois twenty lines and holds a single case that feeds one string and then re-checks the same four Unicode predicates the function itself uses; full coverage of a line says the line ran, not that anything about it is held in place. What that test pins is the class of character removed, and nothing else around it:'?'with anything, or with nothing, still passes;ifwith the whole suite still green;safeandtextsurviving, but nothing shows that an ordinary space, or a non-breaking space (U+00A0, category Zs), survives unchanged — which is what keeps a sanitized label readable rather than mangled.Behaviour today, for the cases worth pinning:
Scope
internal/display/sanitize_test.goonly.t.Runper case, asserting the exact output string rather than a property of it. Cover at least: ESC and a full ANSI colour sequence; tab, newline and carriage return; DEL (U+007F); a C1 control (U+009B); a bidi override (U+202E, Cf); a line separator (U+2028, Zl); a paragraph separator (U+2029, Zp); plain ASCII; a string containing an ordinary space; a non-breaking space (U+00A0); a multi-byte character and an emoji; the empty string.Sanitize(Sanitize(s)) == Sanitize(s).Sanitize, and do not change any caller. If the substitution character or the predicate list looks wrong, open a separate issue rather than editing it here.Acceptance criteria
'?'to another rune fails a case in your new file, and deleting any one of the four predicates from theiffails a case in your new file. Both of those pass the whole suite as it stands today — and deleting theunicode.Zppredicate is caught by nothing at all — so a criterion met only by the existing test does not count.env GO111MODULE=on go test ./internal/displayandenv GO111MODULE=on go test ./...pass;gofmt -l .prints nothing;env GO111MODULE=on go vet ./...is clean.git commit -s.Contributor learning
Why a tool that prints text it did not author routes all of it through one sanitizer instead of trusting call sites; how to pin a transformation by its output instead of restating its implementation in the assertion; and why 100% statement coverage said nothing about either.