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/sexp/fuzz_test.go | 28 +++++++++++++++++++++++++++- 1 file changed, 27 insertions(+), 1 deletion(-) (limited to 'internal/sexp') diff --git a/internal/sexp/fuzz_test.go b/internal/sexp/fuzz_test.go index 01d436b..c64145a 100644 --- a/internal/sexp/fuzz_test.go +++ b/internal/sexp/fuzz_test.go @@ -2,7 +2,10 @@ package sexp -import "testing" +import ( + "testing" + "unicode/utf8" +) // FuzzParse checks that Parse never panics and that every node it returns // spans valid bytes, with lists pointing at their own parentheses. @@ -25,3 +28,26 @@ func FuzzParse(f *testing.F) { }) }) } + +// FuzzQuoteRoundTrip: Quote gives one string atom that parses back to +// exactly the text quoted, for any valid UTF-8 - quotes, backslashes and +// newlines included. krino new writes a directory's path into its config +// with Quote; config files are UTF-8 text, so krino new refuses a path that +// is not, and invalid UTF-8 is out of this property's scope. +func FuzzQuoteRoundTrip(f *testing.F) { + for _, s := range []string{"plain", `with "quotes"`, `back\slash`, "new\nline", "zażółć", "", "\xff", `\bacme\b`} { + f.Add(s) + } + f.Fuzz(func(t *testing.T, s string) { + if !utf8.ValidString(s) { + return + } + nodes, err := Parse("f", []byte(Quote(s))) + if err != nil { + t.Fatalf("Quote(%q) = %s does not parse: %v", s, Quote(s), err) + } + if len(nodes) != 1 || nodes[0].Kind != String || nodes[0].Text != s { + t.Fatalf("Quote(%q) = %s reads back as %+v", s, Quote(s), nodes) + } + }) +} -- cgit v1.3