You cannot select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
208 lines
5.0 KiB
Go
208 lines
5.0 KiB
Go
package testing
|
|
|
|
import (
|
|
"fmt"
|
|
fuzz "github.com/AdaLogics/go-fuzz-headers"
|
|
"os"
|
|
"reflect"
|
|
)
|
|
|
|
type F struct {
|
|
Data []byte
|
|
T *T
|
|
FuzzFunc func(*T, any)
|
|
}
|
|
|
|
func (f *F) CleanupTempDirs() {
|
|
f.T.CleanupTempDirs()
|
|
}
|
|
|
|
func (f *F) Add(args ...any) {}
|
|
func (c *F) Cleanup(f func()) {}
|
|
func (c *F) Error(args ...any) {}
|
|
func (c *F) Errorf(format string, args ...any) {}
|
|
func (f *F) Fail() {}
|
|
func (c *F) FailNow() {}
|
|
func (c *F) Failed() bool { return false }
|
|
func (c *F) Fatal(args ...any) {}
|
|
func (c *F) Fatalf(format string, args ...any) {}
|
|
func (f *F) Fuzz(ff any) {
|
|
// we are assuming that ff is a func.
|
|
// TODO: Add a check for UX purposes
|
|
|
|
fn := reflect.ValueOf(ff)
|
|
fnType := fn.Type()
|
|
var types []reflect.Type
|
|
for i := 1; i < fnType.NumIn(); i++ {
|
|
t := fnType.In(i)
|
|
|
|
types = append(types, t)
|
|
}
|
|
args := []reflect.Value{reflect.ValueOf(f.T)}
|
|
fuzzConsumer := fuzz.NewConsumer(f.Data)
|
|
for _, v := range types {
|
|
switch v.String() {
|
|
case "[]uint8":
|
|
b, err := fuzzConsumer.GetBytes()
|
|
if err != nil {
|
|
return
|
|
}
|
|
newBytes := reflect.New(v)
|
|
newBytes.Elem().SetBytes(b)
|
|
args = append(args, newBytes.Elem())
|
|
case "string":
|
|
s, err := fuzzConsumer.GetString()
|
|
if err != nil {
|
|
return
|
|
}
|
|
newString := reflect.New(v)
|
|
newString.Elem().SetString(s)
|
|
args = append(args, newString.Elem())
|
|
case "int":
|
|
randInt, err := fuzzConsumer.GetInt()
|
|
if err != nil {
|
|
return
|
|
}
|
|
newInt := reflect.New(v)
|
|
newInt.Elem().SetInt(int64(randInt))
|
|
args = append(args, newInt.Elem())
|
|
case "int8":
|
|
randInt, err := fuzzConsumer.GetInt()
|
|
if err != nil {
|
|
return
|
|
}
|
|
newInt := reflect.New(v)
|
|
newInt.Elem().SetInt(int64(randInt))
|
|
args = append(args, newInt.Elem())
|
|
case "int16":
|
|
randInt, err := fuzzConsumer.GetInt()
|
|
if err != nil {
|
|
return
|
|
}
|
|
newInt := reflect.New(v)
|
|
newInt.Elem().SetInt(int64(randInt))
|
|
args = append(args, newInt.Elem())
|
|
case "int32":
|
|
randInt, err := fuzzConsumer.GetInt()
|
|
if err != nil {
|
|
return
|
|
}
|
|
newInt := reflect.New(v)
|
|
newInt.Elem().SetInt(int64(randInt))
|
|
args = append(args, newInt.Elem())
|
|
case "int64":
|
|
randInt, err := fuzzConsumer.GetInt()
|
|
if err != nil {
|
|
return
|
|
}
|
|
newInt := reflect.New(v)
|
|
newInt.Elem().SetInt(int64(randInt))
|
|
args = append(args, newInt.Elem())
|
|
case "uint":
|
|
randInt, err := fuzzConsumer.GetInt()
|
|
if err != nil {
|
|
return
|
|
}
|
|
newUint := reflect.New(v)
|
|
newUint.Elem().SetUint(uint64(randInt))
|
|
args = append(args, newUint.Elem())
|
|
case "uint8":
|
|
randInt, err := fuzzConsumer.GetInt()
|
|
if err != nil {
|
|
return
|
|
}
|
|
newUint := reflect.New(v)
|
|
newUint.Elem().SetUint(uint64(randInt))
|
|
args = append(args, newUint.Elem())
|
|
case "uint16":
|
|
randInt, err := fuzzConsumer.GetUint16()
|
|
if err != nil {
|
|
return
|
|
}
|
|
newUint16 := reflect.New(v)
|
|
newUint16.Elem().SetUint(uint64(randInt))
|
|
args = append(args, newUint16.Elem())
|
|
case "uint32":
|
|
randInt, err := fuzzConsumer.GetUint32()
|
|
if err != nil {
|
|
return
|
|
}
|
|
newUint32 := reflect.New(v)
|
|
newUint32.Elem().SetUint(uint64(randInt))
|
|
args = append(args, newUint32.Elem())
|
|
case "uint64":
|
|
randInt, err := fuzzConsumer.GetUint64()
|
|
if err != nil {
|
|
return
|
|
}
|
|
newUint64 := reflect.New(v)
|
|
newUint64.Elem().SetUint(uint64(randInt))
|
|
args = append(args, newUint64.Elem())
|
|
case "rune":
|
|
randRune, err := fuzzConsumer.GetRune()
|
|
if err != nil {
|
|
return
|
|
}
|
|
newRune := reflect.New(v)
|
|
newRune.Elem().Set(reflect.ValueOf(randRune))
|
|
args = append(args, newRune.Elem())
|
|
case "float32":
|
|
randFloat, err := fuzzConsumer.GetFloat32()
|
|
if err != nil {
|
|
return
|
|
}
|
|
newFloat := reflect.New(v)
|
|
newFloat.Elem().Set(reflect.ValueOf(randFloat))
|
|
args = append(args, newFloat.Elem())
|
|
case "float64":
|
|
randFloat, err := fuzzConsumer.GetFloat64()
|
|
if err != nil {
|
|
return
|
|
}
|
|
newFloat := reflect.New(v)
|
|
newFloat.Elem().Set(reflect.ValueOf(randFloat))
|
|
args = append(args, newFloat.Elem())
|
|
case "bool":
|
|
randBool, err := fuzzConsumer.GetBool()
|
|
if err != nil {
|
|
return
|
|
}
|
|
newBool := reflect.New(v)
|
|
newBool.Elem().Set(reflect.ValueOf(randBool))
|
|
args = append(args, newBool.Elem())
|
|
default:
|
|
fmt.Println(v.String())
|
|
}
|
|
}
|
|
fn.Call(args)
|
|
}
|
|
func (f *F) Helper() {}
|
|
func (c *F) Log(args ...any) {
|
|
fmt.Println(args...)
|
|
}
|
|
func (c *F) Logf(format string, args ...any) {
|
|
fmt.Println(format, args)
|
|
}
|
|
func (c *F) Name() string { return "libFuzzer" }
|
|
func (c *F) Setenv(key, value string) {}
|
|
func (c *F) Skip(args ...any) {
|
|
panic("GO-FUZZ-BUILD-PANIC")
|
|
}
|
|
func (c *F) SkipNow() {
|
|
panic("GO-FUZZ-BUILD-PANIC")
|
|
}
|
|
func (c *F) Skipf(format string, args ...any) {
|
|
panic("GO-FUZZ-BUILD-PANIC")
|
|
}
|
|
func (f *F) Skipped() bool { return false }
|
|
|
|
func (f *F) TempDir() string {
|
|
dir, err := os.MkdirTemp("", "fuzzdir-")
|
|
if err != nil {
|
|
panic(err)
|
|
}
|
|
f.T.TempDirs = append(f.T.TempDirs, dir)
|
|
|
|
return dir
|
|
}
|