From e51f988cc593b699d1acef61521810faaabbbb59 Mon Sep 17 00:00:00 2001 From: sergeyfedorov02 Date: Fri, 19 Apr 2024 16:00:23 +0300 Subject: [PATCH 1/3] implement string, float, complex --- generator.go | 124 +++++++++++++++++++++++++++++++++++++++++++++++++++ main.go | 14 ++++++ 2 files changed, 138 insertions(+) diff --git a/generator.go b/generator.go index 61832fa..5f7d344 100644 --- a/generator.go +++ b/generator.go @@ -2,6 +2,7 @@ package main import ( "errors" + "math" "reflect" ) @@ -42,6 +43,49 @@ func (g *Generator) fillAny(any reflect.Value) error { return err } + case reflect.String: + str, err := g.GenerateString() + if err != nil { + return err + } + any.SetString(str) + + case reflect.Float32: + newFloat, err := g.GenerateFloat32() + if err != nil { + return err + } + any.SetFloat(float64(newFloat)) + + case reflect.Float64: + newFloat, err := g.GenerateFloat64() + if err != nil { + return err + } + any.SetFloat(float64(newFloat)) + + case reflect.Complex64: + newFloatReal, err := g.GenerateFloat32() + if err != nil { + return err + } + newFloatImag, err := g.GenerateFloat32() + if err != nil { + return err + } + any.SetComplex(complex(float64(newFloatReal), float64(newFloatImag))) + + case reflect.Complex128: + newFloatReal, err := g.GenerateFloat64() + if err != nil { + return err + } + newFloatImag, err := g.GenerateFloat64() + if err != nil { + return err + } + any.SetComplex(complex(newFloatReal, newFloatImag)) + default: panic("unhandled default case") } @@ -61,3 +105,83 @@ func (g *Generator) GenerateInt() (int, error) { g.position++ return result, nil } + +func (g *Generator) GenerateUInt32() (uint32, error) { + if g.position+3 >= g.dataSize { + return 0, errors.New("the data bytes are over") + } + result := uint32(0) + for i := 0; i < 4; i++ { + result = result<<8 | uint32(g.data[g.position]) + g.position++ + } + return result, nil +} + +func (g *Generator) GenerateString() (string, error) { + maxStrLength := uint32(2000000) + + if g.position >= g.dataSize { + return "nil", errors.New("the data bytes are over") + } + + length, err := g.GenerateUInt32() + if err != nil { + return "nil", errors.New("the data bytes are over") + } + + if g.position > maxStrLength { + return "nil", errors.New("the string length too large") + } + + startBytePos := g.position + if startBytePos >= g.dataSize { + return "nil", errors.New("the data bytes are over") + } + + if startBytePos+length > g.dataSize { + return "nil", errors.New("the data bytes are over") + } + + if startBytePos > startBytePos+length { + return "nil", errors.New("overflow") + } + + g.position = startBytePos + length + result := string(g.data[startBytePos:g.position]) + + return result, nil +} + +func (g *Generator) GenerateFloat32() (float32, error) { + if g.position+3 >= g.dataSize { + return 0, errors.New("the data bytes are over") + } + + bits := uint32(0) + for i := 0; i < 4; i++ { + bits = bits<<8 | uint32(g.data[g.position]) + g.position++ + } + + floatBits := uint32(math.Float32bits(math.Float32frombits(bits))) + result := math.Float32frombits(floatBits) + + return result, nil +} + +func (g *Generator) GenerateFloat64() (float64, error) { + if g.position+7 >= g.dataSize { + return 0, errors.New("the data bytes are over") + } + + bits := uint64(0) + for i := 0; i < 8; i++ { + bits = bits<<8 | uint64(g.data[g.position]) + g.position++ + } + + result := math.Float64frombits(bits) + + return result, nil +} \ No newline at end of file diff --git a/main.go b/main.go index 81897f8..4372c43 100644 --- a/main.go +++ b/main.go @@ -13,6 +13,20 @@ type Struct2 struct { Field2 Struct1 } +type Struct3 struct { + Field1 string + Field2 float32 + Field3 float64 + Field4 complex64 + Field5 complex128 +} + +type Struct4 struct { + Field1 [5]int + Field2 map[string]int + Field3 func() +} + func main() { } -- 2.45.2 From c447f7f9b5c1495493925cd7885f73a847c00568 Mon Sep 17 00:00:00 2001 From: sergeyfedorov02 Date: Wed, 24 Apr 2024 22:09:23 +0300 Subject: [PATCH 2/3] implement map, array --- generator.go | 38 +++++++++++++++++++++++++++++++++++--- 1 file changed, 35 insertions(+), 3 deletions(-) diff --git a/generator.go b/generator.go index 5f7d344..1bd3824 100644 --- a/generator.go +++ b/generator.go @@ -7,9 +7,11 @@ import ( ) type Generator struct { - data []byte - dataSize uint32 - position uint32 + data []byte + dataSize uint32 + position uint32 + mapStruct map[string]interface{} + arrayStruct []interface{} } func NewGenerator(fuzzData []byte) *Generator { @@ -86,6 +88,36 @@ func (g *Generator) fillAny(any reflect.Value) error { } any.SetComplex(complex(newFloatReal, newFloatImag)) + case reflect.Map: + any.Set(reflect.MakeMap(any.Type())) + + mapLen, err := g.GenerateUInt32() + if err != nil { + return err + } + + for i := uint32(0); i < mapLen; i++ { + key := fmt.Sprintf("key%d", i) + mapValue := reflect.New(any.Type().Elem()) + err := g.fillAny(mapValue.Elem()) + if err != nil { + return err + } + any.SetMapIndex(reflect.ValueOf(key), mapValue.Elem()) + } + + case reflect.Array: + any.Set(reflect.New(any.Type()).Elem()) + arrayLen := any.Len() + for i := 0; i < arrayLen; i++ { + arrayValue := reflect.New(any.Type().Elem()) + err := g.fillAny(arrayValue.Elem()) + if err != nil { + return err + } + any.Index(i).Set(arrayValue.Elem()) + } + default: panic("unhandled default case") } -- 2.45.2 From 43872e055d141a9159852892ca77477057c4e6bc Mon Sep 17 00:00:00 2001 From: sergeyfedorov02 Date: Tue, 7 May 2024 13:38:18 +0300 Subject: [PATCH 3/3] fix import --- generator.go | 1 + main.go | 1 - 2 files changed, 1 insertion(+), 1 deletion(-) diff --git a/generator.go b/generator.go index 1bd3824..2f1066a 100644 --- a/generator.go +++ b/generator.go @@ -2,6 +2,7 @@ package main import ( "errors" + "fmt" "math" "reflect" ) diff --git a/main.go b/main.go index 4372c43..55bf77d 100644 --- a/main.go +++ b/main.go @@ -24,7 +24,6 @@ type Struct3 struct { type Struct4 struct { Field1 [5]int Field2 map[string]int - Field3 func() } func main() { -- 2.45.2