Skip to content

Instantly share code, notes, and snippets.

@eyJhb
Created May 10, 2020 13:30
Show Gist options
  • Save eyJhb/f0e913588803d3190e624682220eecf7 to your computer and use it in GitHub Desktop.
Save eyJhb/f0e913588803d3190e624682220eecf7 to your computer and use it in GitHub Desktop.
inequality
package memory
import (
"reflect"
"testing"
"gitlab.com/deviosec/octp/server/pkgs/store/models"
"golang.org/x/exp/errors/fmt"
)
func DeepInequal(a, b reflect.Value) []string {
fmt.Println("Called!")
var errors []string
if a.Type() != b.Type() || a.Kind() != b.Kind() {
errors = append(errors, "Types or kind do not match")
return errors
}
switch k := a.Kind(); {
case k == reflect.Struct:
for i := 0; i < a.NumField(); i++ {
errors = append(errors, DeepInequal(a.Field(i), b.Field(i))...)
}
case k == reflect.Slice:
if a.IsNil() == true || b.IsNil() == true {
errors = append(errors, "A slice is nil, cannot be")
return errors
}
if a.Len() != b.Len() || a.Cap() != b.Cap() {
errors = append(errors, "Slices not same length/cap")
return errors
}
for i := 0; i < a.Cap(); i++ {
errors = append(errors, DeepInequal(a.Index(i), b.Index(i))...)
}
case k == reflect.Map:
if a.IsNil() == true || b.IsNil() == true {
errors = append(errors, "A map is nil, cannot be")
return errors
}
if a.Len() != b.Len() {
errors = append(errors, "Maps not same length/cap")
return errors
}
for _, k := range a.MapKeys() {
errors = append(errors, DeepInequal(a.MapIndex(k), b.MapIndex(k))...)
}
case k >= reflect.Array && k <= reflect.Interface:
panic("Not imlemented for reflect.Array > k < reflect.Interface")
case (k >= reflect.Bool && k <= reflect.Complex128) || k == reflect.String:
fmt.Println(a.String(), b.String())
if a == b {
fmt.Println("Same")
errors = append(errors, fmt.Sprintf("Values of type %s match, '%v' and '%v'", a.Type(), a.String(), b.String()))
}
default:
panic("No clue what to do with this")
fmt.Println("No clue what to do with:", k)
}
return errors
}
func Fuzz2(v reflect.Value) reflect.Value {
if v.Kind() == reflect.Ptr {
v = v.Elem()
}
switch k := v.Kind(); {
case k == reflect.Struct:
newStruct := reflect.New(v.Type()).Elem()
for i := 0; i < v.NumField(); i++ {
fieldOriginal := v.Field(i)
fieldNew := newStruct.Field(i)
fieldNew.Set(Fuzz2(fieldOriginal))
}
v = newStruct
case k == reflect.Slice:
for i := 0; i < v.Cap(); i++ {
Fuzz2(v.Index(i))
}
case k == reflect.Map:
iter := v.MapRange()
for iter.Next() {
v.SetMapIndex(iter.Key(), Fuzz2(iter.Value()))
}
case k >= reflect.Array && k <= reflect.Interface:
panic("Not imlemented for reflect.Array > k < reflect.Interface")
case (k >= reflect.Bool && k <= reflect.Complex128) || k == reflect.String:
// this will only be the case for maps...
if !v.CanSet() {
vt := reflect.New(v.Type()).Elem()
vt.Set(v)
v = vt
}
if found, fieldValue := changeValue(v); found {
v.Set(fieldValue)
} else {
fmt.Println("Could not find vaule for", v.Kind())
}
default:
panic("No clue what to do with this")
fmt.Println("No clue what to do with:", k)
}
return v
}
func changeValue(v reflect.Value) (bool, reflect.Value) {
kind := v.Kind()
switch kind {
case reflect.Bool:
return true, reflect.ValueOf(!v.Interface().(bool))
case reflect.Int:
return true, reflect.ValueOf(v.Interface().(int) + 1)
case reflect.Int8:
return true, reflect.ValueOf(v.Interface().(int8) + 1)
case reflect.Int16:
return true, reflect.ValueOf(v.Interface().(int16) + 1)
case reflect.Int32:
return true, reflect.ValueOf(v.Interface().(int32) + 1)
case reflect.Int64:
return true, reflect.ValueOf(v.Interface().(int64) + 1)
case reflect.Uint:
return true, reflect.ValueOf(v.Interface().(uint) + 1)
case reflect.Uint8:
return true, reflect.ValueOf(v.Interface().(uint8) + 1)
case reflect.Uint16:
return true, reflect.ValueOf(v.Interface().(uint16) + 1)
case reflect.Uint32:
return true, reflect.ValueOf(v.Interface().(uint32) + 1)
case reflect.Uint64:
return true, reflect.ValueOf(v.Interface().(int64) + 1)
case reflect.Float32:
return true, reflect.ValueOf(v.Interface().(float32) + 1)
case reflect.Float64:
return true, reflect.ValueOf(v.Interface().(float64) + 1)
case reflect.Complex64:
return true, reflect.ValueOf(v.Interface().(complex64) + 1)
case reflect.Complex128:
return true, reflect.ValueOf(v.Interface().(complex128) + 1)
case reflect.String:
return true, reflect.ValueOf(v.Interface().(string) + "a")
}
return false, reflect.Value{}
}
func TestFuzz(t *testing.T) {
// struct we can use to test
type smallStruct struct {
FieldSimple string
FieldSlice []string
FieldMap map[string]string
}
copySmallStruct := func(c smallStruct) smallStruct {
cc := c
cc.FieldSlice = make([]string, len(c.FieldSlice))
copy(cc.FieldSlice, c.FieldSlice)
cc.FieldMap = make(map[string]string)
for k, v := range c.FieldMap {
cc.FieldMap[k] = v
}
return cc
}
type bigStruct struct {
FieldString string
FieldBool bool
FieldInt int
FieldSliceString []string
FieldSliceStruct []smallStruct
FieldMapString map[string]string
FieldMapStruct map[string]smallStruct
}
copyBigStruct := func(c bigStruct) bigStruct {
cc := c
cc.FieldSliceString = make([]string, len(c.FieldSliceString))
copy(cc.FieldSliceString, c.FieldSliceString)
cc.FieldSliceStruct = []smallStruct{}
for _, v := range c.FieldSliceStruct {
cc.FieldSliceStruct = append(cc.FieldSliceStruct, copySmallStruct(v))
}
cc.FieldMapString = make(map[string]string)
for k, v := range c.FieldMapString {
cc.FieldMapString[k] = v
}
cc.FieldMapStruct = make(map[string]smallStruct)
for k, v := range c.FieldMapStruct {
cc.FieldMapStruct[k] = copySmallStruct(v)
}
return cc
}
_ = copyBigStruct
// declare the struct
ts := bigStruct{
FieldString: "",
FieldBool: false,
FieldInt: 10,
FieldSliceString: []string{"element1"},
FieldSliceStruct: []smallStruct{
smallStruct{
FieldSimple: "",
FieldSlice: []string{"element1"},
FieldMap: map[string]string{
"key1": "value1",
},
},
},
FieldMapString: map[string]string{
"key1": "value1",
},
FieldMapStruct: map[string]smallStruct{
"key1": {
FieldSimple: "",
FieldSlice: []string{"element1"},
FieldMap: map[string]string{
"key1": "value1",
},
},
},
}
// copy it
// tsc := copyBigStruct(ts)
tsc := ts
// fuzz it
fmt.Println(ts)
Fuzz2(reflect.ValueOf(&tsc))
fmt.Println(ts)
fmt.Println(tsc)
}
func TestCopy(t *testing.T) {
c1 := models.Container{
Id: 120,
Image: "image",
Sha256: "sha256",
Envs: []string{"someenv"},
Ports: map[string]models.Port{
"PORTA": {
HostIP: "127.0.0.1",
Host: 8080,
Guest: 8008,
Protocol: "TCP",
},
},
Privileged: false,
Action: "NONE",
}
// test := 1
// changeInput(test)
// changeInput(c)
// c2 := copyContainer(c1)
c2 := c1
fmt.Println(c1)
Fuzz2(reflect.ValueOf(&c2))
fmt.Println(c1)
fmt.Println(c2)
fmt.Println(DeepInequal(reflect.ValueOf(c1), reflect.ValueOf(c2)))
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment