File size: 5,901 Bytes
e36aeda | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 | [!fuzz] skip
[short] skip
# We clean the fuzz cache during this test. Don't clean the user's cache.
env GOCACHE=$WORK/gocache
# Test that fuzzminimizetime cannot be negative seconds
! go test -fuzz=FuzzMinimizerRecoverable -run=FuzzMinimizerRecoverable -fuzztime=10000x -fuzzminimizetime=-1ms .
! stdout '^ok'
! stdout 'contains a non-zero byte'
stdout 'invalid duration'
stdout FAIL
# Test that fuzzminimizetime cannot be negative times
! go test -fuzz=FuzzMinimizerRecoverable -run=FuzzMinimizerRecoverable -fuzztime=10000x -fuzzminimizetime=-1x .
! stdout '^ok'
! stdout 'contains a non-zero byte'
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 .
! stdout '^ok'
! stdout '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 .
! stdout '^ok'
! stdout 'minimizing'
stdout -count=1 'there was an Error'
stdout FAIL
# Test that minimization is working for recoverable errors.
! go test -fuzz=FuzzMinimizerRecoverable -run=FuzzMinimizerRecoverable -fuzztime=10000x .
! stdout '^ok'
stdout 'got the minimum size!'
# The error message that was printed should be for the one written to testdata.
stdout 'contains a non-zero byte of length 50'
stdout FAIL
# Check that the bytes written to testdata are of length 50 (the minimum size)
go run ./check_testdata FuzzMinimizerRecoverable 50
# Test that re-running the minimized value causes a crash.
! go test -run=FuzzMinimizerRecoverable .
rm testdata
# Test that minimization is working for recoverable errors. Run it with -v this
# time to ensure the command line output still looks right.
! go test -v -fuzz=FuzzMinimizerRecoverable -run=FuzzMinimizerRecoverable -fuzztime=10000x .
! stdout '^ok'
stdout 'got the minimum size!'
# The error message that was printed should be for the one written to testdata.
stdout 'contains a non-zero byte of length 50'
stdout FAIL
# Check that the bytes written to testdata are of length 50 (the minimum size)
go run ./check_testdata FuzzMinimizerRecoverable 50
# Test that re-running the minimized value causes a crash.
! go test -run=FuzzMinimizerRecoverable .
rm testdata
# Test that minimization doesn't run for non-recoverable errors.
! go test -fuzz=FuzzMinimizerNonrecoverable -run=FuzzMinimizerNonrecoverable -fuzztime=10000x .
! stdout '^ok'
! stdout 'minimizing'
stdout -count=1 '^\s+fuzzing process hung or terminated unexpectedly: exit status 99'
stdout FAIL
# Check that re-running the value causes a crash.
! go test -run=FuzzMinimizerNonrecoverable .
rm testdata
# Clear the fuzzing cache. There may already be minimized inputs that would
# interfere with the next stage of the test.
go clean -fuzzcache
# Test that minimization can be cancelled by fuzzminimizetime and the latest
# crash will still be logged and written to testdata.
! go test -fuzz=FuzzMinimizerRecoverable -run=FuzzMinimizerRecoverable -fuzztime=100x -fuzzminimizetime=1x .
! stdout '^ok'
stdout 'testdata[/\\]fuzz[/\\]FuzzMinimizerRecoverable[/\\]'
! stdout 'got the minimum size!' # it shouldn't have had enough time to minimize it
stdout FAIL
# Test that re-running the unminimized value causes a crash.
! go test -run=FuzzMinimizerRecoverable .
# TODO(jayconrod,katiehockman): add a test which verifies that the right bytes
# are written to testdata in the case of an interrupt during minimization.
-- go.mod --
module example.com/y
go 1.16
-- y_test.go --
package y
import (
"os"
"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) {
if len(b) < 50 {
// Make sure that b is large enough that it can be minimized
return
}
// Given the randomness of the mutations, this should allow the
// minimizer to trim down the value a bit.
for _, n := range b {
if n != 0 {
if len(b) == 50 {
t.Log("got the minimum size!")
}
t.Fatalf("contains a non-zero byte of length %d", len(b))
}
}
})
}
func FuzzMinimizerNonrecoverable(f *testing.F) {
f.Fuzz(func(t *testing.T, b []byte) {
os.Exit(99)
})
}
-- empty/empty.go --
package empty
-- check_testdata/check_testdata.go --
package main
import (
"bytes"
"fmt"
"io/ioutil"
"os"
"path/filepath"
"strconv"
)
func main() {
target := os.Args[1]
numBytes, err := strconv.Atoi(os.Args[2])
if err != nil {
fmt.Fprintln(os.Stderr, err)
os.Exit(1)
}
// Open the file in testdata (there should only be one)
dir := fmt.Sprintf("testdata/fuzz/%s", target)
files, err := ioutil.ReadDir(dir)
if err != nil {
fmt.Fprintln(os.Stderr, err)
os.Exit(1)
}
if len(files) != 1 {
fmt.Fprintf(os.Stderr, "expected one file, got %d", len(files))
os.Exit(1)
}
got, err := ioutil.ReadFile(filepath.Join(dir, files[0].Name()))
if err != nil {
fmt.Fprintln(os.Stderr, err)
os.Exit(1)
}
// Trim the newline at the end of the file
got = bytes.TrimSpace(got)
// Make sure that there were exactly 100 bytes written to the corpus entry
prefix := []byte("[]byte(")
i := bytes.Index(got, prefix)
gotBytes := got[i+len(prefix) : len(got)-1]
s, err := strconv.Unquote(string(gotBytes))
if err != nil {
fmt.Fprintln(os.Stderr, err)
os.Exit(1)
}
if want, got := numBytes, len(s); want != got {
fmt.Fprintf(os.Stderr, "want %d bytes, got %d\n", want, got)
os.Exit(1)
}
}
|