aboutsummaryrefslogtreecommitdiff
path: root/src/testing/fuzz.go
diff options
context:
space:
mode:
authorKatie Hockman <katie@golang.org>2021-06-07 17:51:51 -0400
committerKatie Hockman <katie@golang.org>2021-06-15 19:32:21 +0000
commit413c125da38990720744c0d98ab65c0d5b1602da (patch)
tree0e8e9e63f364abc3c00380e092311c621b4a1ce7 /src/testing/fuzz.go
parent965b1147549ef28a407bd4e8f5efe5e7b7616f80 (diff)
downloadgo-413c125da38990720744c0d98ab65c0d5b1602da.tar.xz
[dev.fuzz] testing: convert seed corpus values where possible
The types provided in f.Fuzz will be viewed as the canonical types for fuzzing. If the type is different for a seed corpus entry, then the testing package will attempt to convert it. If it can't convert it, f.Fuzz will fail. Currently, this allows converting types that may result in precision loss or a semantically different value. For example, an int(-1) can be converted to uint even though the value could be math.MaxUint64. There is a TODO to consider improving this in the future. Updates golang/go#45593 Change-Id: I2e752119662f46b68445d42b1ffa46dd30e9faea Reviewed-on: https://go-review.googlesource.com/c/go/+/325702 Trust: Katie Hockman <katie@golang.org> Run-TryBot: Katie Hockman <katie@golang.org> TryBot-Result: Go Bot <gobot@golang.org> Reviewed-by: Roland Shoemaker <roland@golang.org>
Diffstat (limited to 'src/testing/fuzz.go')
-rw-r--r--src/testing/fuzz.go14
1 files changed, 13 insertions, 1 deletions
diff --git a/src/testing/fuzz.go b/src/testing/fuzz.go
index 9f0bb1ec50..b4c1ffcdd5 100644
--- a/src/testing/fuzz.go
+++ b/src/testing/fuzz.go
@@ -222,7 +222,7 @@ func (f *F) TempDir() string {
// Add will add the arguments to the seed corpus for the fuzz target. This will
// be a no-op if called after or within the Fuzz function. The args must match
-// those in the Fuzz function.
+// or be convertible to those in the Fuzz function.
func (f *F) Add(args ...interface{}) {
var values []interface{}
for i := range args {
@@ -291,6 +291,15 @@ func (f *F) Fuzz(ff interface{}) {
types = append(types, t)
}
+ // Check the corpus provided by f.Add
+ for _, c := range f.corpus {
+ if err := f.fuzzContext.checkCorpus(c.Values, types); err != nil {
+ // TODO: Is there a way to save which line number is associated
+ // with the f.Add call that failed?
+ f.Fatal(err)
+ }
+ }
+
// Load seed corpus
c, err := f.fuzzContext.readCorpus(filepath.Join(corpusDir, f.name), types)
if err != nil {
@@ -470,6 +479,7 @@ type fuzzContext struct {
coordinateFuzzing func(time.Duration, int64, time.Duration, int64, int, []corpusEntry, []reflect.Type, string, string) error
runFuzzWorker func(func(corpusEntry) error) error
readCorpus func(string, []reflect.Type) ([]corpusEntry, error)
+ checkCorpus func(vals []interface{}, types []reflect.Type) error
resetCoverage func()
snapshotCoverage func()
}
@@ -487,6 +497,7 @@ func runFuzzTargets(deps testDeps, fuzzTargets []InternalFuzzTarget) (ran, ok bo
fctx := &fuzzContext{
importPath: deps.ImportPath,
readCorpus: deps.ReadCorpus,
+ checkCorpus: deps.CheckCorpus,
resetCoverage: deps.ResetCoverage,
snapshotCoverage: deps.SnapshotCoverage,
}
@@ -543,6 +554,7 @@ func runFuzzing(deps testDeps, fuzzTargets []InternalFuzzTarget) (ran, ok bool)
fctx := &fuzzContext{
importPath: deps.ImportPath,
readCorpus: deps.ReadCorpus,
+ checkCorpus: deps.CheckCorpus,
resetCoverage: deps.ResetCoverage,
snapshotCoverage: deps.SnapshotCoverage,
}