aboutsummaryrefslogtreecommitdiff
path: root/internal/sexp/fuzz_test.go
blob: c64145a912b99da019adbe63e8add2c4c454d362 (plain) (blame)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
// SPDX-License-Identifier: GPL-3.0-or-later

package sexp

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.
func FuzzParse(f *testing.F) {
	for _, s := range []string{`(a "b" (c))`, `"\"`, `(((`, `)`, "; x\n(y)", `("ł" x)`, "\xff", `"\\"`} {
		f.Add([]byte(s))
	}
	f.Fuzz(func(t *testing.T, src []byte) {
		nodes, err := Parse("f", src)
		if err != nil {
			return
		}
		walk(nodes, func(n *Node) {
			if n.Pos.Offset < 0 || n.End.Offset > len(src) || n.Pos.Offset >= n.End.Offset {
				t.Fatalf("bad span %d..%d in %q", n.Pos.Offset, n.End.Offset, src)
			}
			if n.Kind == List && (src[n.Pos.Offset] != '(' || src[n.End.Offset-1] != ')') {
				t.Fatalf("list %d..%d does not span its parens in %q", n.Pos.Offset, n.End.Offset, src)
			}
		})
	})
}

// 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)
		}
	})
}