fix for OSS-Fuzz infra changes

Signed-off-by: AdamKorcz <adam@adalogics.com>
This commit is contained in:
AdamKorcz
2022-11-16 10:50:31 +00:00
parent 20cb9a9fd8
commit ed3a49c0e6
31 changed files with 463 additions and 98 deletions

View File

@@ -0,0 +1,195 @@
package testing
import (
"fmt"
fuzz "github.com/AdaLogics/go-fuzz-headers"
"reflect"
)
type F struct {
Data []byte
T *T
FuzzFunc func(*T, any)
}
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, "\n")
}
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 (c *F) TempDir() string {
panic("TempDir() is not supported")
}

View File

@@ -0,0 +1,109 @@
package testing
import (
"fmt"
"strings"
"time"
)
// T can be used to terminate the current fuzz iteration
// without terminating the whole fuzz run. To do so, simply
// panic with the text "GO-FUZZ-BUILD-PANIC" and the fuzzer
// will recover.
type T struct {
}
func unsupportedApi(name string) string {
plsOpenIss := "Please open an issue https://github.com/AdamKorcz/go-118-fuzz-build if you need this feature."
var b strings.Builder
b.WriteString(fmt.Sprintf("%s is not supported when fuzzing in libFuzzer mode\n.", name))
b.WriteString(plsOpenIss)
return b.String()
}
func (t *T) Cleanup(f func()) {
f()
}
func (t *T) Deadline() (deadline time.Time, ok bool) {
panic(unsupportedApi("t.Deadline()"))
}
func (t *T) Error(args ...any) {
fmt.Println(args...)
panic("error")
}
func (t *T) Errorf(format string, args ...any) {
fmt.Println(format)
fmt.Println(args...)
panic("errorf")
}
func (t *T) Fail() {
panic("Called T.Fail()")
}
func (t *T) FailNow() {
panic("Called T.Fail()")
panic(unsupportedApi("t.FailNow()"))
}
func (t *T) Failed() bool {
panic(unsupportedApi("t.Failed()"))
}
func (t *T) Fatal(args ...any) {
fmt.Println(args...)
panic("fatal")
}
func (t *T) Fatalf(format string, args ...any) {
fmt.Println(format, args)
panic("fatal")
}
func (t *T) Helper() {
panic(unsupportedApi("t.Failed()"))
}
func (t *T) Log(args ...any) {
fmt.Println(args...)
}
func (t *T) Logf(format string, args ...any) {
fmt.Println(format)
fmt.Println(args...)
}
func (t *T) Name() string {
return "libFuzzer"
}
func (t *T) Parallel() {
panic(unsupportedApi("t.Failed()"))
}
func (t *T) Run(name string, f func(t *T)) bool {
panic(unsupportedApi("t.Run()."))
}
func (t *T) Setenv(key, value string) {
}
func (t *T) Skip(args ...any) {
panic("GO-FUZZ-BUILD-PANIC")
}
func (t *T) SkipNow() {
panic("GO-FUZZ-BUILD-PANIC")
}
// Is not really supported. We just skip instead
// of printing any message. A log message can be
// added if need be.
func (t *T) Skipf(format string, args ...any) {
panic("GO-FUZZ-BUILD-PANIC")
}
func (t *T) Skipped() bool {
panic(unsupportedApi("t.Skipped()"))
}
func (t *T) TempDir() string {
panic(unsupportedApi("t.TempDir()"))
}

View File

@@ -0,0 +1,42 @@
package testing
import (
"testing"
)
func AllocsPerRun(runs int, f func()) (avg float64) {
panic(unsupportedApi("testing.AllocsPerRun"))
}
func CoverMode() string {
panic(unsupportedApi("testing.CoverMode"))
}
func Coverage() float64 {
panic(unsupportedApi("testing.Coverage"))
}
func Init() {
panic(unsupportedApi("testing.Init"))
}
func RegisterCover(c testing.Cover) {
panic(unsupportedApi("testing.RegisterCover"))
}
func RunExamples(matchString func(pat, str string) (bool, error), examples []testing.InternalExample) (ok bool) {
panic(unsupportedApi("testing.RunExamples"))
}
func RunTests(matchString func(pat, str string) (bool, error), tests []testing.InternalTest) (ok bool) {
panic(unsupportedApi("testing.RunTests"))
}
func Short() bool {
panic(unsupportedApi("testing.Short"))
}
func Verbose() bool {
panic(unsupportedApi("testing.Verbose"))
}
type M struct {}
func (m *M) Run() (code int) {
panic("testing.M is not support in libFuzzer Mode")
}