From aa24cfb344b1b3eaef7217d996359023cd72ba28 Mon Sep 17 00:00:00 2001 From: Lukasz Kasprzak Date: Mon, 14 Sep 2026 20:10:01 +0200 Subject: plan 8: fuzz decoders; fold ẞ and invalid UTF-8 correctly, refuse non-UTF-8 paths in krino new MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- internal/plan/fuzz_test.go | 33 +++++++++++++++++++++++++++++++++ 1 file changed, 33 insertions(+) create mode 100644 internal/plan/fuzz_test.go (limited to 'internal/plan') diff --git a/internal/plan/fuzz_test.go b/internal/plan/fuzz_test.go new file mode 100644 index 0000000..fb68f94 --- /dev/null +++ b/internal/plan/fuzz_test.go @@ -0,0 +1,33 @@ +// SPDX-License-Identifier: GPL-3.0-or-later + +package plan + +import ( + "testing" + "time" +) + +// FuzzExpand: expanding any template against any file name never panics, +// gives the same answer twice, and never succeeds with a {N} beyond the +// capture groups there are - MaxIndex and Expand read placeholders alike. +func FuzzExpand(f *testing.F) { + for _, s := range []string{"{name}", "{stem}{ext}", "{mtime:%Y/%m}", "{1}_{2}", "{{literal}}", "{", "}", "{now:%", "{0}", "{9}", "{99999999999999999999}"} { + f.Add(s, "a.b.pdf") + } + f.Fuzz(func(t *testing.T, tmpl, name string) { + facts := Facts{ + Name: name, + Captures: []string{name, "x", ".."}, + ModTime: time.Date(2026, 8, 15, 12, 0, 0, 0, time.UTC), + Now: time.Date(2026, 9, 14, 0, 0, 0, 0, time.UTC), + } + a, errA := Expand(tmpl, facts) + b, errB := Expand(tmpl, facts) + if a != b || (errA == nil) != (errB == nil) { + t.Fatalf("Expand(%q) differs between two calls: %q/%v, %q/%v", tmpl, a, errA, b, errB) + } + if n, err := MaxIndex(tmpl); err == nil && n > 2 && errA == nil { + t.Fatalf("Expand(%q) = %q, though it uses {%d} and only 2 groups exist", tmpl, a, n) + } + }) +} -- cgit v1.3