107 lines
2.3 KiB
Go
107 lines
2.3 KiB
Go
// Fuzz tests for use with the Go 1.18 fuzzer.
|
|
|
|
//go: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)
|
|
}
|
|
})
|
|
}
|
|
})
|
|
}
|