File: fuzz_test.go

package info (click to toggle)
goawk 1.29.0-1
  • links: PTS, VCS
  • area: main
  • in suites: forky, sid, trixie
  • size: 10,560 kB
  • sloc: awk: 3,060; yacc: 198; fortran: 189; python: 131; sh: 58; makefile: 12
file content (107 lines) | stat: -rw-r--r-- 2,394 bytes parent folder | download
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
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
// Fuzz tests for use with the Go 1.18 fuzzer.

//go:build go1.18
// +build go1.18

package interp_test

import (
	"context"
	"fmt"
	"io"
	"strings"
	"testing"
	"time"

	"github.com/benhoyt/goawk/interp"
	"github.com/benhoyt/goawk/parser"
)

func isFuzzTest(test interpTest) bool {
	return test.err == "" && test.awkErr == "" && !strings.Contains(test.src, "!fuzz")
}

func FuzzSource(f *testing.F) {
	for _, test := range interpTests {
		if isFuzzTest(test) {
			f.Add(test.src)
		}
	}

	f.Fuzz(func(t *testing.T, src string) {
		prog, err := parser.ParseProgram([]byte(src), nil)
		if err != nil {
			return
		}
		interpreter, err := interp.New(prog)
		if err != nil {
			t.Fatalf("interp.New error: %v", err)
		}
		config := interp.Config{
			Stdin:        strings.NewReader("foo bar\nbazz\n"),
			Output:       io.Discard,
			Error:        io.Discard,
			NoExec:       true,
			NoFileWrites: true,
			NoFileReads:  true,
			Environ:      []string{},
		}
		ctx, cancel := context.WithTimeout(context.Background(), 500*time.Millisecond)
		defer cancel()
		_, _ = interpreter.ExecuteContext(ctx, &config)
	})
}

func FuzzInput(f *testing.F) {
	f.Add("")
	added := make(map[string]bool)
	for _, test := range interpTests {
		if test.in != "" && !added[test.in] {
			f.Add(test.in)
			added[test.in] = true
		}
	}

	prog, err := parser.ParseProgram([]byte(`{ print $0, $3, $1, $10 }`), nil)
	if err != nil {
		f.Fatalf("parse error: %v", err)
	}

	interpreter, err := interp.New(prog)
	if err != nil {
		f.Fatalf("interp.New error: %v", err)
	}

	var vars = [][]string{
		{"FS", " ", "RS", "\n"},
		{"FS", ",", "RS", "\n"},
		{"FS", "\t", "RS", "\n"},
		{"FS", "@+", "RS", "\n"},
		{"FS", "\n", "RS", ""},
		{"FS", " ", "RS", "X+"},
	}

	f.Fuzz(func(t *testing.T, in string) {
		for _, v := range vars {
			t.Run(fmt.Sprintf("Vars=%q", v), func(t *testing.T) {
				interpreter.ResetVars()
				config := interp.Config{
					Stdin:        strings.NewReader(in),
					Output:       io.Discard,
					Error:        io.Discard,
					Vars:         v,
					NoExec:       true,
					NoFileWrites: true,
					NoFileReads:  true,
					Environ:      []string{},
				}
				ctx, cancel := context.WithTimeout(context.Background(), 500*time.Millisecond)
				defer cancel()
				_, err := interpreter.ExecuteContext(ctx, &config)
				if err != nil {
					t.Fatalf("execute error: %v", err)
				}
			})
		}
	})
}