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/ignore/fuzz_test.go | 44 ++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 44 insertions(+) create mode 100644 internal/ignore/fuzz_test.go (limited to 'internal/ignore') diff --git a/internal/ignore/fuzz_test.go b/internal/ignore/fuzz_test.go new file mode 100644 index 0000000..0e9f0a3 --- /dev/null +++ b/internal/ignore/fuzz_test.go @@ -0,0 +1,44 @@ +// SPDX-License-Identifier: GPL-3.0-or-later + +package ignore + +import ( + "strings" + "testing" +) + +// FuzzMatch: any pattern either fails to compile or matches any walked +// path without panicking, and gives the same answer twice. The oracle test +// checks answers against git; this checks everything else. +func FuzzMatch(f *testing.F) { + for _, p := range []string{"*.log", "/a.txt", "build/", "**/readme.md", "[!a]*.txt", "[[:digit:]]*", `\`, "[", "a[/]b", "!", "**/**/**", "*a*a*a*b"} { + f.Add(p, "dir/sub/a.txt") + } + f.Fuzz(func(t *testing.T, pattern, rel string) { + m, err := New([]string{pattern}) + if err != nil { + return + } + rel = walkedRel(rel) + if rel == "" { + return + } + if m.Match(rel, false) != m.Match(rel, false) { + t.Fatalf("Match(%q) under %q is not deterministic", rel, pattern) + } + m.Match(rel, true) + }) +} + +// walkedRel turns any string into a path of the shape Match accepts, as a +// directory walk produces it: slash-separated, with no empty, "." or ".." +// components. +func walkedRel(s string) string { + var parts []string + for _, p := range strings.Split(s, "/") { + if p != "" && p != "." && p != ".." { + parts = append(parts, p) + } + } + return strings.Join(parts, "/") +} -- cgit v1.3