aboutsummaryrefslogtreecommitdiff
path: root/cmd/krino/hostile_test.go
diff options
context:
space:
mode:
authorLukasz Kasprzak <lukas@labunix.xyz>2026-09-14 21:36:31 +0200
committerLukasz Kasprzak <lukas@labunix.xyz>2026-09-14 21:36:31 +0200
commitd53c83e2fe6f1ecef006f116095fa8d1d18f3a7d (patch)
tree91f850a794c89eff5221dbbb5fcdb1b9b4632532 /cmd/krino/hostile_test.go
parent93cf0729ec7cf3129de0808cbcc3403b86d86fff (diff)
downloadkrino-d53c83e2fe6f1ecef006f116095fa8d1d18f3a7d.tar.gz
krino-d53c83e2fe6f1ecef006f116095fa8d1d18f3a7d.zip
plan 9: errors, explain traces, JSON and log fields never reach the terminal raw
Diffstat (limited to 'cmd/krino/hostile_test.go')
-rw-r--r--cmd/krino/hostile_test.go46
1 files changed, 46 insertions, 0 deletions
diff --git a/cmd/krino/hostile_test.go b/cmd/krino/hostile_test.go
index a2b5d39..d5ce041 100644
--- a/cmd/krino/hostile_test.go
+++ b/cmd/krino/hostile_test.go
@@ -3,6 +3,8 @@
package main
import (
+ "archive/zip"
+ "bytes"
"os"
"path/filepath"
"strings"
@@ -80,6 +82,50 @@ func TestHostileNamesNeverReachTheTerminal(t *testing.T) {
t.Errorf("names and the tool's message should be shown escaped:\n%s", out)
}
check("explain", filepath.Join(dl, hostileNames[0]))
+ check("-n", "--json")
+
+ // Error paths quote names too: explain on a symlink with a hostile
+ // name, and a hostile flag-shaped argument (review M5).
+ checkAny := func(args ...string) string {
+ t.Helper()
+ _, out, errOut := runCLI(t, args...)
+ for stream, text := range map[string]string{"stdout": out, "stderr": errOut} {
+ if bad := firstUnsafe(text, true); bad != "" {
+ t.Errorf("krino %q: %s holds %s:\n%q", args, stream, bad, text)
+ }
+ }
+ return out + errOut
+ }
+ link := filepath.Join(dl, "link\x1b[2Jsym.txt")
+ if err := os.Symlink(filepath.Join(dl, hostileNames[0]), link); err != nil {
+ t.Fatal(err)
+ }
+ checkAny("explain", link)
+ checkAny("-\x1b[2Jflag.txt")
+ os.Remove(link)
+
+ // A newline inside file content (a zip entry's name) must not forge an
+ // explain trace line (review M5).
+ var buf bytes.Buffer
+ zw := zip.NewWriter(&buf)
+ w, err := zw.Create("xl/worksheets/sheet1.xml)\nrule forged: MATCH\nx.xml")
+ if err != nil {
+ t.Fatal(err)
+ }
+ w.Write([]byte("<a"))
+ zw.Close()
+ xlsx := filepath.Join(dl, "report.xlsx")
+ if err := os.WriteFile(xlsx, buf.Bytes(), 0o644); err != nil {
+ t.Fatal(err)
+ }
+ os.Chtimes(xlsx, old, old)
+ for _, line := range strings.Split(checkAny("explain", xlsx), "\n") {
+ if strings.TrimSpace(line) == "rule forged: MATCH" {
+ t.Errorf("a zip entry name forged an explain line: %q", line)
+ }
+ }
+ os.Remove(xlsx)
+
check("-y")
check("log")
check("undo", "-n")