type fuzzFuncMap … type Fuzzer … // New returns a new Fuzzer. Customize your Fuzzer further by calling Funcs, // RandSource, NilChance, or NumElements in any order. func New() *Fuzzer { … } func NewWithSeed(seed int64) *Fuzzer { … } // NewFromGoFuzz is a helper function that enables using gofuzz (this // project) with go-fuzz (https://github.com/dvyukov/go-fuzz) for continuous // fuzzing. Essentially, it enables translating the fuzzing bytes from // go-fuzz to any Go object using this library. // // This implementation promises a constant translation from a given slice of // bytes to the fuzzed objects. This promise will remain over future // versions of Go and of this library. // // Note: the returned Fuzzer should not be shared between multiple goroutines, // as its deterministic output will no longer be available. // // Example: use go-fuzz to test the function `MyFunc(int)` in the package // `mypackage`. Add the file: "mypacakge_fuzz.go" with the content: // // // +build gofuzz // package mypacakge // import fuzz "github.com/google/gofuzz" // func Fuzz(data []byte) int { // var i int // fuzz.NewFromGoFuzz(data).Fuzz(&i) // MyFunc(i) // return 0 // } func NewFromGoFuzz(data []byte) *Fuzzer { … } // Funcs adds each entry in fuzzFuncs as a custom fuzzing function. // // Each entry in fuzzFuncs must be a function taking two parameters. // The first parameter must be a pointer or map. It is the variable that // function will fill with random data. The second parameter must be a // fuzz.Continue, which will provide a source of randomness and a way // to automatically continue fuzzing smaller pieces of the first parameter. // // These functions are called sensibly, e.g., if you wanted custom string // fuzzing, the function `func(s *string, c fuzz.Continue)` would get // called and passed the address of strings. Maps and pointers will always // be made/new'd for you, ignoring the NilChange option. For slices, it // doesn't make much sense to pre-create them--Fuzzer doesn't know how // long you want your slice--so take a pointer to a slice, and make it // yourself. (If you don't want your map/pointer type pre-made, take a // pointer to it, and make it yourself.) See the examples for a range of // custom functions. func (f *Fuzzer) Funcs(fuzzFuncs ...interface{ … } // RandSource causes f to get values from the given source of randomness. // Use if you want deterministic fuzzing. func (f *Fuzzer) RandSource(s rand.Source) *Fuzzer { … } // NilChance sets the probability of creating a nil pointer, map, or slice to // 'p'. 'p' should be between 0 (no nils) and 1 (all nils), inclusive. func (f *Fuzzer) NilChance(p float64) *Fuzzer { … } // NumElements sets the minimum and maximum number of elements that will be // added to a non-nil map or slice. func (f *Fuzzer) NumElements(atLeast, atMost int) *Fuzzer { … } func (f *Fuzzer) genElementCount() int { … } func (f *Fuzzer) genShouldFill() bool { … } // MaxDepth sets the maximum number of recursive fuzz calls that will be made // before stopping. This includes struct members, pointers, and map and slice // elements. func (f *Fuzzer) MaxDepth(d int) *Fuzzer { … } // Skip fields which match the supplied pattern. Call this multiple times if needed // This is useful to skip XXX_ fields generated by protobuf func (f *Fuzzer) SkipFieldsWithPattern(pattern *regexp.Regexp) *Fuzzer { … } // Fuzz recursively fills all of obj's fields with something random. First // this tries to find a custom fuzz function (see Funcs). If there is no // custom function this tests whether the object implements fuzz.Interface and, // if so, calls Fuzz on it to fuzz itself. If that fails, this will see if // there is a default fuzz function provided by this package. If all of that // fails, this will generate random values for all primitive fields and then // recurse for all non-primitives. // // This is safe for cyclic or tree-like structs, up to a limit. Use the // MaxDepth method to adjust how deep you need it to recurse. // // obj must be a pointer. Only exported (public) fields can be set (thanks, // golang :/ ) Intended for tests, so will panic on bad input or unimplemented // fields. func (f *Fuzzer) Fuzz(obj interface{ … } // FuzzNoCustom is just like Fuzz, except that any custom fuzz function for // obj's type will not be called and obj will not be tested for fuzz.Interface // conformance. This applies only to obj and not other instances of obj's // type. // Not safe for cyclic or tree-like structs! // obj must be a pointer. Only exported (public) fields can be set (thanks, golang :/ ) // Intended for tests, so will panic on bad input or unimplemented fields. func (f *Fuzzer) FuzzNoCustom(obj interface{ … } const flagNoCustomFuzz … func (f *Fuzzer) fuzzWithContext(v reflect.Value, flags uint64) { … } type fuzzerContext … func (fc *fuzzerContext) doFuzz(v reflect.Value, flags uint64) { … } // tryCustom searches for custom handlers, and returns true iff it finds a match // and successfully randomizes v. func (fc *fuzzerContext) tryCustom(v reflect.Value) bool { … } type Interface … type Continue … // Fuzz continues fuzzing obj. obj must be a pointer. func (c Continue) Fuzz(obj interface{ … } // FuzzNoCustom continues fuzzing obj, except that any custom fuzz function for // obj's type will not be called and obj will not be tested for fuzz.Interface // conformance. This applies only to obj and not other instances of obj's // type. func (c Continue) FuzzNoCustom(obj interface{ … } // RandString makes a random string up to 20 characters long. The returned string // may include a variety of (valid) UTF-8 encodings. func (c Continue) RandString() string { … } // RandUint64 makes random 64 bit numbers. // Weirdly, rand doesn't have a function that gives you 64 random bits. func (c Continue) RandUint64() uint64 { … } // RandBool returns true or false randomly. func (c Continue) RandBool() bool { … } func fuzzInt(v reflect.Value, r *rand.Rand) { … } func fuzzUint(v reflect.Value, r *rand.Rand) { … } func fuzzTime(t *time.Time, c Continue) { … } var fillFuncMap … // randBool returns true or false randomly. func randBool(r *rand.Rand) bool { … } type int63nPicker … type UnicodeRange … type UnicodeRanges … // choose returns a random unicode character from the given range, using the // given randomness source. func (ur UnicodeRange) choose(r int63nPicker) rune { … } // CustomStringFuzzFunc constructs a FuzzFunc which produces random strings. // Each character is selected from the range ur. If there are no characters // in the range (cr.Last < cr.First), this will panic. func (ur UnicodeRange) CustomStringFuzzFunc() func(s *string, c Continue) { … } // check is a function that used to check whether the first of ur(UnicodeRange) // is greater than the last one. func (ur UnicodeRange) check() { … } // randString of UnicodeRange makes a random string up to 20 characters long. // Each character is selected form ur(UnicodeRange). func (ur UnicodeRange) randString(r *rand.Rand) string { … } var defaultUnicodeRanges … // CustomStringFuzzFunc constructs a FuzzFunc which produces random strings. // Each character is selected from one of the ranges of ur(UnicodeRanges). // Each range has an equal probability of being chosen. If there are no ranges, // or a selected range has no characters (.Last < .First), this will panic. // Do not modify any of the ranges in ur after calling this function. func (ur UnicodeRanges) CustomStringFuzzFunc() func(s *string, c Continue) { … } // randString of UnicodeRanges makes a random string up to 20 characters long. // Each character is selected form one of the ranges of ur(UnicodeRanges), // and each range has an equal probability of being chosen. func (ur UnicodeRanges) randString(r *rand.Rand) string { … } // randString makes a random string up to 20 characters long. The returned string // may include a variety of (valid) UTF-8 encodings. func randString(r *rand.Rand) string { … } // randUint64 makes random 64 bit numbers. // Weirdly, rand doesn't have a function that gives you 64 random bits. func randUint64(r *rand.Rand) uint64 { … }