[dev.fuzz] testing,internal/fuzz: support structured inputs

This change makes several refactors to start supporting
structured fuzzing. The mutator can still only mutate
byte slices, and future changes will be made to support
mutating other types. However, it does now support
fuzzing more than one []byte.

This change also makes it so that corpus entries are
encoded in the new file format when being written to
testdata or GOCACHE. Any existing GOCACHE data should
be deleted from your local workstation to allow tests
to pass locally.

Change-Id: Iab8fe01a5dc870f0c53010b9d5b0b479bbdb310d
Reviewed-on: https://go-review.googlesource.com/c/go/+/293810
Trust: Katie Hockman <katie@golang.org>
Run-TryBot: Katie Hockman <katie@golang.org>
TryBot-Result: Go Bot <gobot@golang.org>
Reviewed-by: Jay Conrod <jayconrod@google.com>
This commit is contained in:
Katie Hockman 2021-02-18 15:42:05 -05:00
parent 5aacd47c00
commit 621a81aba0
10 changed files with 298 additions and 72 deletions

View file

@ -20,14 +20,14 @@ var encVersion1 = "go test fuzz v1"
// corpus.
func marshalCorpusFile(vals ...interface{}) []byte {
if len(vals) == 0 {
panic("must have at least one value to encode")
panic("must have at least one value to marshal")
}
b := bytes.NewBuffer([]byte(encVersion1))
// TODO(katiehockman): keep uint8 and int32 encoding where applicable,
// instead of changing to byte and rune respectively.
for _, val := range vals {
switch t := val.(type) {
case int, int8, int16, int64, uint, uint16, uint32, uint64, uintptr, float32, float64, bool:
case int, int8, int16, int64, uint, uint16, uint32, uint64, float32, float64, bool:
fmt.Fprintf(b, "\n%T(%v)", t, t)
case string:
fmt.Fprintf(b, "\nstring(%q)", t)
@ -47,7 +47,7 @@ func marshalCorpusFile(vals ...interface{}) []byte {
// unmarshalCorpusFile decodes corpus bytes into their respective values.
func unmarshalCorpusFile(b []byte) ([]interface{}, error) {
if len(b) == 0 {
return nil, fmt.Errorf("cannot decode empty string")
return nil, fmt.Errorf("cannot unmarshal empty string")
}
lines := bytes.Split(b, []byte("\n"))
if len(lines) < 2 {