diff --git a/gnovm/pkg/transpiler/fuzz_test.go b/gnovm/pkg/transpiler/fuzz_test.go new file mode 100644 index 00000000000..68414c21e9a --- /dev/null +++ b/gnovm/pkg/transpiler/fuzz_test.go @@ -0,0 +1,80 @@ +package transpiler + +import ( + "fmt" + "io" + "io/fs" + "os" + "path/filepath" + "runtime" + "strings" + "testing" + "time" +) + +func FuzzTranspiling(f *testing.F) { + if testing.Short() { + f.Skip("Running in -short mode") + } + + // 1. Derive the seeds from our seedGnoFiles. + breakRoot := filepath.Join("gnolang", "gno") + pc, thisFile, _, _ := runtime.Caller(0) + index := strings.Index(thisFile, breakRoot) + _ = pc // to silence the pedantic golangci linter. + rootPath := thisFile[:index+len(breakRoot)] + examplesDir := filepath.Join(rootPath, "examples") + ffs := os.DirFS(examplesDir) + fs.WalkDir(ffs, ".", func(path string, d fs.DirEntry, err error) error { + if err != nil { + panic(err) + } + if !strings.HasSuffix(path, ".gno") { + return nil + } + file, err := ffs.Open(path) + if err != nil { + panic(err) + } + blob, err := io.ReadAll(file) + file.Close() + if err != nil { + panic(err) + } + f.Add(blob) + return nil + }) + + // 2. Run the fuzzers. + f.Fuzz(func(t *testing.T, gnoSourceCode []byte) { + // 3. Add timings to ensure that if transpiling takes a long time + // to run, that we report this as problematic. + doneCh := make(chan bool, 1) + readyCh := make(chan bool) + go func() { + defer func() { + r := recover() + if r == nil { + return + } + + sr := fmt.Sprintf("%s", r) + if !strings.Contains(sr, "invalid line number ") { + panic(r) + } + }() + close(readyCh) + defer close(doneCh) + _, _ = Transpile(string(gnoSourceCode), "gno", "in.gno") + doneCh <- true + }() + + <-readyCh + + select { + case <-time.After(2 * time.Second): + t.Fatalf("took more than 2 seconds to transpile\n\n%s", gnoSourceCode) + case <-doneCh: + } + }) +} diff --git a/gnovm/pkg/transpiler/testdata/fuzz/FuzzTranspiling/26ec2c0a22e242fc b/gnovm/pkg/transpiler/testdata/fuzz/FuzzTranspiling/26ec2c0a22e242fc new file mode 100644 index 00000000000..d82acb3eaa5 --- /dev/null +++ b/gnovm/pkg/transpiler/testdata/fuzz/FuzzTranspiling/26ec2c0a22e242fc @@ -0,0 +1,2 @@ +go test fuzz v1 +[]byte("package\tA\nimport(\"\"//\"\n\"\"/***/)") diff --git a/gnovm/pkg/transpiler/testdata/fuzz/FuzzTranspiling/54f7287f473abfa5 b/gnovm/pkg/transpiler/testdata/fuzz/FuzzTranspiling/54f7287f473abfa5 new file mode 100644 index 00000000000..a3accb3dd8e --- /dev/null +++ b/gnovm/pkg/transpiler/testdata/fuzz/FuzzTranspiling/54f7287f473abfa5 @@ -0,0 +1,2 @@ +go test fuzz v1 +[]byte("package A\nimport(\"\"//\"\n\"\"/***/)") diff --git a/gnovm/pkg/transpiler/testdata/fuzz/FuzzTranspiling/703a1cacabb84c6d b/gnovm/pkg/transpiler/testdata/fuzz/FuzzTranspiling/703a1cacabb84c6d new file mode 100644 index 00000000000..c08c7cfe904 --- /dev/null +++ b/gnovm/pkg/transpiler/testdata/fuzz/FuzzTranspiling/703a1cacabb84c6d @@ -0,0 +1,2 @@ +go test fuzz v1 +[]byte("package A\ncon\x12\n\xec|b\x80\xddQst(\n/*\n\n\n\n\n\n\nka\n*/A)") diff --git a/gnovm/pkg/transpiler/testdata/fuzz/FuzzTranspiling/bcd60839c81ca478 b/gnovm/pkg/transpiler/testdata/fuzz/FuzzTranspiling/bcd60839c81ca478 new file mode 100644 index 00000000000..df9d3b1b5b9 --- /dev/null +++ b/gnovm/pkg/transpiler/testdata/fuzz/FuzzTranspiling/bcd60839c81ca478 @@ -0,0 +1,2 @@ +go test fuzz v1 +[]byte("//\"\npackage\tA\nimport(\"\"//\"\n\"\"/***/)") diff --git a/gnovm/pkg/transpiler/testdata/fuzz/FuzzTranspiling/bf4f7515b25bf71b b/gnovm/pkg/transpiler/testdata/fuzz/FuzzTranspiling/bf4f7515b25bf71b new file mode 100644 index 00000000000..cbc2bd9be5b --- /dev/null +++ b/gnovm/pkg/transpiler/testdata/fuzz/FuzzTranspiling/bf4f7515b25bf71b @@ -0,0 +1,2 @@ +go test fuzz v1 +[]byte("//0000\x170000000000:0\npackage A")