aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorKatie Hockman <katie@golang.org>2021-09-10 15:25:30 -0400
committerKatie Hockman <katie@golang.org>2021-09-10 20:17:28 +0000
commit17f62c0ac3de14c3dbff77b706f86dfb7dc820c7 (patch)
tree76b42ebff5f4c4ee0675a202b5cba9167c685a36 /src
parentd106089fa6aa69cc1b547c68ca19d84f28062c71 (diff)
downloadgo-17f62c0ac3de14c3dbff77b706f86dfb7dc820c7.tar.xz
[dev.fuzz] internal/fuzz: fix bug for -fuzzminimizetime of zero
Updates golang/go#48321 Change-Id: Ib35388f17580f1244a6eae4e5879f8329b6b44ce Reviewed-on: https://go-review.googlesource.com/c/go/+/349090 Trust: Katie Hockman <katie@golang.org> Run-TryBot: Katie Hockman <katie@golang.org> Reviewed-by: Jay Conrod <jayconrod@google.com>
Diffstat (limited to 'src')
-rw-r--r--src/cmd/go/testdata/script/test_fuzz_minimize.txt42
-rw-r--r--src/internal/fuzz/fuzz.go32
2 files changed, 49 insertions, 25 deletions
diff --git a/src/cmd/go/testdata/script/test_fuzz_minimize.txt b/src/cmd/go/testdata/script/test_fuzz_minimize.txt
index dac11231ef..c180890a9b 100644
--- a/src/cmd/go/testdata/script/test_fuzz_minimize.txt
+++ b/src/cmd/go/testdata/script/test_fuzz_minimize.txt
@@ -6,18 +6,6 @@
# We clean the fuzz cache during this test. Don't clean the user's cache.
env GOCACHE=$WORK/gocache
-# Test that fuzzminimizetime can be zero seconds
-! go test -fuzz=FuzzMinimizerRecoverable -run=FuzzMinimizerRecoverable -fuzztime=10000x -fuzzminimizetime=0s minimizer_test.go
-! stdout '^ok'
-stdout 'contains a non-zero byte'
-stdout FAIL
-
-# Test that fuzzminimizetime can be zero times
-! go test -fuzz=FuzzMinimizerRecoverable -run=FuzzMinimizerRecoverable -fuzztime=10000x -fuzzminimizetime=0x minimizer_test.go
-! stdout '^ok'
-stdout 'contains a non-zero byte'
-stdout FAIL
-
# Test that fuzzminimizetime cannot be negative seconds
! go test -fuzz=FuzzMinimizerRecoverable -run=FuzzMinimizerRecoverable -fuzztime=10000x -fuzzminimizetime=-1ms minimizer_test.go
! stdout '^ok'
@@ -32,6 +20,20 @@ stdout FAIL
stdout 'invalid count'
stdout FAIL
+# Test that fuzzminimizetime can be zero seconds, and minimization is disabled
+! go test -fuzz=FuzzMinimizeZeroDurationSet -run=FuzzMinimizeZeroDurationSet -fuzztime=10000x -fuzzminimizetime=0s minimizer_test.go
+! stdout '^ok'
+! stdout 'found a crash, minimizing...'
+stdout 'there was an Error'
+stdout FAIL
+
+# Test that fuzzminimizetime can be zero times, and minimization is disabled
+! go test -fuzz=FuzzMinimizeZeroLimitSet -run=FuzzMinimizeZeroLimitSet -fuzztime=10000x -fuzzminimizetime=0x minimizer_test.go
+! stdout '^ok'
+! stdout 'found a crash, minimizing...'
+stdout 'there was an Error'
+stdout FAIL
+
# Test that minimization is working for recoverable errors.
! go test -fuzz=FuzzMinimizerRecoverable -run=FuzzMinimizerRecoverable -fuzztime=10000x minimizer_test.go
! stdout '^ok'
@@ -87,6 +89,22 @@ import (
"testing"
)
+func FuzzMinimizeZeroDurationSet(f *testing.F) {
+ f.Fuzz(func(t *testing.T, b []byte) {
+ if len(b) > 5 {
+ t.Errorf("there was an Error")
+ }
+ })
+}
+
+func FuzzMinimizeZeroLimitSet(f *testing.F) {
+ f.Fuzz(func(t *testing.T, b []byte) {
+ if len(b) > 5 {
+ t.Errorf("there was an Error")
+ }
+ })
+}
+
func FuzzMinimizerRecoverable(f *testing.F) {
f.Add(make([]byte, 100))
f.Fuzz(func(t *testing.T, b []byte) {
diff --git a/src/internal/fuzz/fuzz.go b/src/internal/fuzz/fuzz.go
index 6c07da2dbe..c19ea35f23 100644
--- a/src/internal/fuzz/fuzz.go
+++ b/src/internal/fuzz/fuzz.go
@@ -40,13 +40,16 @@ type CoordinateFuzzingOpts struct {
Limit int64
// MinimizeTimeout is the amount of wall clock time to spend minimizing
- // after discovering a crasher. If zero, there will be no time limit.
+ // after discovering a crasher. If zero, there will be no time limit. If
+ // MinimizeTimeout and MinimizeLimit are both zero, then minimization will
+ // be disabled.
MinimizeTimeout time.Duration
// MinimizeLimit is the maximum number of calls to the fuzz function to be
- // made while minimizing after finding a crash. If zero, there will be
- // no limit. Calls to the fuzz function made when minimizing also count
- // toward Limit.
+ // made while minimizing after finding a crash. If zero, there will be no
+ // limit. Calls to the fuzz function made when minimizing also count toward
+ // Limit. If MinimizeTimeout and MinimizeLimit are both zero, then
+ // minimization will be disabled.
MinimizeLimit int64
// parallel is the number of worker processes to run in parallel. If zero,
@@ -552,9 +555,10 @@ type coordinator struct {
// generated values that workers reported as interesting.
corpus corpus
- // typesAreMinimizable is true if one or more of the types of fuzz function's
- // parameters can be minimized.
- typesAreMinimizable bool
+ // minimizationAllowed is true if one or more of the types of fuzz
+ // function's parameters can be minimized, and either the limit or duration
+ // for minimization is non-zero.
+ minimizationAllowed bool
// inputQueue is a queue of inputs that workers should try fuzzing. This is
// initially populated from the seed corpus and cached inputs. More inputs
@@ -604,10 +608,12 @@ func newCoordinator(opts CoordinateFuzzingOpts) (*coordinator, error) {
resultC: make(chan fuzzResult),
corpus: corpus,
}
- for _, t := range opts.Types {
- if isMinimizable(t) {
- c.typesAreMinimizable = true
- break
+ if opts.MinimizeLimit > 0 || opts.MinimizeTimeout > 0 {
+ for _, t := range opts.Types {
+ if isMinimizable(t) {
+ c.minimizationAllowed = true
+ break
+ }
}
}
@@ -736,7 +742,7 @@ func (c *coordinator) queueForMinimization(result fuzzResult, keepCoverage []byt
// peekMinimizeInput returns the next input that should be sent to workers for
// minimization.
func (c *coordinator) peekMinimizeInput() (fuzzMinimizeInput, bool) {
- if c.opts.Limit > 0 && c.count+c.countWaiting >= c.opts.Limit {
+ if !c.canMinimize() {
// Already making the maximum number of calls to the fuzz function.
// Don't send more inputs right now.
return fuzzMinimizeInput{}, false
@@ -810,7 +816,7 @@ func (c *coordinator) updateCoverage(newCoverage []byte) int {
// canMinimize returns whether the coordinator should attempt to find smaller
// inputs that reproduce a crash or new coverage.
func (c *coordinator) canMinimize() bool {
- return c.typesAreMinimizable &&
+ return c.minimizationAllowed &&
(c.opts.Limit == 0 || c.count+c.countWaiting < c.opts.Limit)
}