cmd/eofdump: regular- and fuzz-testing of eof parsing

This commit is contained in:
Martin Holst Swende 2024-09-06 11:45:55 +02:00 committed by Marius van der Wijden
parent ddb9907a7a
commit cdae48c452
5 changed files with 6242 additions and 0 deletions

131
cmd/eofdump/parse_test.go Normal file
View file

@ -0,0 +1,131 @@
package main
import (
"bufio"
"bytes"
"encoding/hex"
"fmt"
"os"
"strings"
"testing"
"github.com/ethereum/go-ethereum/common"
"github.com/ethereum/go-ethereum/core/vm"
)
func FuzzEofParsing(f *testing.F) {
// Seed with corpus from execution-spec-tests
for i := 0; ; i++ {
fname := fmt.Sprintf("testdata/eof_corpus_%d.txt", i)
corpus, err := os.Open(fname)
if err != nil {
break
}
f.Logf("Reading seed data from %v", fname)
scanner := bufio.NewScanner(corpus)
scanner.Buffer(make([]byte, 1024), 10*1024*1024)
for scanner.Scan() {
s := scanner.Text()
if len(s) >= 2 && strings.HasPrefix(s, "0x") {
s = s[2:]
}
b, err := hex.DecodeString(s)
if err != nil {
panic(err) // rotten corpus
}
f.Add(b)
}
corpus.Close()
if err := scanner.Err(); err != nil {
panic(err) // rotten corpus
}
}
// And do the fuzzing
f.Fuzz(func(t *testing.T, data []byte) {
var (
jt = vm.NewPragueEOFInstructionSetForTesting()
c vm.Container
)
cpy := common.CopyBytes(data)
if err := c.UnmarshalBinary(data, true); err == nil {
c.ValidateCode(&jt, true)
}
if err := c.UnmarshalBinary(data, false); err == nil {
c.ValidateCode(&jt, false)
}
if !bytes.Equal(cpy, data) {
panic("data modified during unmarshalling")
}
})
}
func TestEofParseInitcode(t *testing.T) {
testEofParse(t, true, "testdata/results.initcode.txt")
}
func TestEofParseRegular(t *testing.T) {
testEofParse(t, false, "testdata/results.regular.txt")
}
func testEofParse(t *testing.T, isInitCode bool, wantFile string) {
var wantFn func() string
{ // Configure the want-reader
wants, err := os.Open(wantFile)
if err != nil {
t.Fatal(err)
}
scanner := bufio.NewScanner(wants)
scanner.Buffer(make([]byte, 1024), 10*1024*1024)
wantFn = func() string {
if scanner.Scan() {
return scanner.Text()
}
return "end of file reached"
}
}
for i := 0; ; i++ {
fname := fmt.Sprintf("testdata/eof_corpus_%d.txt", i)
corpus, err := os.Open(fname)
if err != nil {
break
}
t.Logf("# Reading seed data from %v", fname)
scanner := bufio.NewScanner(corpus)
scanner.Buffer(make([]byte, 1024), 10*1024*1024)
for scanner.Scan() {
s := scanner.Text()
if len(s) >= 2 && strings.HasPrefix(s, "0x") {
s = s[2:]
}
b, err := hex.DecodeString(s)
if err != nil {
panic(err) // rotten corpus
}
have := parse(b, isInitCode)
want := wantFn()
if have != want {
t.Fatalf("input %x, isInit: %v \nhave: %q\nwant: %q\n",
b, isInitCode, have, want)
}
}
corpus.Close()
}
}
func parse(data []byte, isInitCode bool) string {
var (
jt = vm.NewPragueEOFInstructionSetForTesting()
c vm.Container
err = c.UnmarshalBinary(data, isInitCode)
)
if err == nil {
if err = c.ValidateCode(&jt, isInitCode); err == nil {
return "OK"
}
return fmt.Sprintf("ERR: %v", err)
}
return fmt.Sprintf("ERR: %v", err)
}

1814
cmd/eofdump/testdata/eof_corpus_0.txt vendored Normal file

File diff suppressed because one or more lines are too long

223
cmd/eofdump/testdata/eof_corpus_1.txt vendored Normal file

File diff suppressed because one or more lines are too long

2037
cmd/eofdump/testdata/results.initcode.txt vendored Normal file

File diff suppressed because one or more lines are too long

2037
cmd/eofdump/testdata/results.regular.txt vendored Normal file

File diff suppressed because one or more lines are too long