sf/base-type-impl #1
2 changed files with 174 additions and 16 deletions
169
generator.go
169
generator.go
|
@ -2,6 +2,8 @@ package main
|
|||
|
||||
import (
|
||||
"errors"
|
||||
"fmt"
|
||||
"math"
|
||||
"reflect"
|
||||
"unsafe"
|
||||
)
|
||||
|
@ -10,6 +12,8 @@ type Generator struct {
|
|||
data []byte
|
||||
dataSize uint32
|
||||
position uint32
|
||||
mapStruct map[string]interface{}
|
||||
arrayStruct []interface{}
|
||||
}
|
||||
|
||||
func NewGenerator(fuzzData []byte) *Generator {
|
||||
|
@ -43,6 +47,79 @@ 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))
|
||||
|
||||
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())
|
||||
}
|
||||
|
||||
case reflect.Bool:
|
||||
newBool, err := g.GenerateBool()
|
||||
if err != nil {
|
||||
|
@ -135,6 +212,86 @@ func (g *Generator) GenerateInt() (int, error) {
|
|||
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
|
||||
}
|
||||
|
||||
func (g *Generator) GenerateBool() (bool, error) {
|
||||
if g.position >= g.dataSize {
|
||||
return false, errors.New("the data bytes are over")
|
||||
|
@ -165,18 +322,6 @@ func (g *Generator) GenerateUInt16() (uint16, error) {
|
|||
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) GenerateUInt64() (uint64, error) {
|
||||
if g.position+7 >= g.dataSize {
|
||||
return 0, errors.New("the data bytes are over")
|
||||
|
|
13
main.go
13
main.go
|
@ -13,6 +13,19 @@ 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
|
||||
}
|
||||
ebukreev
commented
функции же не поддержаны функции же не поддержаны
|
||||
|
||||
func main() {
|
||||
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue
fmt не импортирован