go.mod: github.com/AdaLogics/go-fuzz-headers v0.0.0-20221118232415-3345c89a7c72
full diff: 443f56ff4b...3345c89a7c
Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
			
			
This commit is contained in:
		
							
								
								
									
										430
									
								
								vendor/github.com/AdaLogics/go-fuzz-headers/consumer.go
									
									
									
										generated
									
									
										vendored
									
									
								
							
							
						
						
									
										430
									
								
								vendor/github.com/AdaLogics/go-fuzz-headers/consumer.go
									
									
									
										generated
									
									
										vendored
									
									
								
							| @@ -18,9 +18,7 @@ import ( | ||||
| 	securejoin "github.com/cyphar/filepath-securejoin" | ||||
| ) | ||||
|  | ||||
| var ( | ||||
| 	MaxTotalLen = uint32(2000000) | ||||
| ) | ||||
| var MaxTotalLen uint32 = 2000000 | ||||
|  | ||||
| func SetMaxTotalLen(newLen uint32) { | ||||
| 	MaxTotalLen = newLen | ||||
| @@ -28,6 +26,7 @@ func SetMaxTotalLen(newLen uint32) { | ||||
|  | ||||
| type ConsumeFuzzer struct { | ||||
| 	data                 []byte | ||||
| 	dataTotal            uint32 | ||||
| 	CommandPart          []byte | ||||
| 	RestOfArray          []byte | ||||
| 	NumberOfCalls        int | ||||
| @@ -41,22 +40,23 @@ func IsDivisibleBy(n int, divisibleby int) bool { | ||||
| } | ||||
|  | ||||
| func NewConsumer(fuzzData []byte) *ConsumeFuzzer { | ||||
| 	fuzzMap := make(map[reflect.Type]reflect.Value) | ||||
| 	f := &ConsumeFuzzer{data: fuzzData, position: 0, Funcs: fuzzMap} | ||||
| 	return f | ||||
| 	return &ConsumeFuzzer{ | ||||
| 		data:      fuzzData, | ||||
| 		dataTotal: uint32(len(fuzzData)), | ||||
| 		Funcs:     make(map[reflect.Type]reflect.Value), | ||||
| 	} | ||||
| } | ||||
|  | ||||
| func (f *ConsumeFuzzer) Split(minCalls, maxCalls int) error { | ||||
| 	if len(f.data) == 0 { | ||||
| 		return errors.New("Could not split") | ||||
| 	if f.dataTotal == 0 { | ||||
| 		return errors.New("could not split") | ||||
| 	} | ||||
| 	numberOfCalls := int(f.data[0]) | ||||
| 	if numberOfCalls < minCalls || numberOfCalls > maxCalls { | ||||
| 		return errors.New("Bad number of calls") | ||||
|  | ||||
| 		return errors.New("bad number of calls") | ||||
| 	} | ||||
| 	if len(f.data) < numberOfCalls+numberOfCalls+1 { | ||||
| 		return errors.New("Length of data does not match required parameters") | ||||
| 	if int(f.dataTotal) < numberOfCalls+numberOfCalls+1 { | ||||
| 		return errors.New("length of data does not match required parameters") | ||||
| 	} | ||||
|  | ||||
| 	// Define part 2 and 3 of the data array | ||||
| @@ -65,12 +65,12 @@ func (f *ConsumeFuzzer) Split(minCalls, maxCalls int) error { | ||||
|  | ||||
| 	// Just a small check. It is necessary | ||||
| 	if len(commandPart) != numberOfCalls { | ||||
| 		return errors.New("Length of commandPart does not match number of calls") | ||||
| 		return errors.New("length of commandPart does not match number of calls") | ||||
| 	} | ||||
|  | ||||
| 	// Check if restOfArray is divisible by numberOfCalls | ||||
| 	if !IsDivisibleBy(len(restOfArray), numberOfCalls) { | ||||
| 		return errors.New("Length of commandPart does not match number of calls") | ||||
| 		return errors.New("length of commandPart does not match number of calls") | ||||
| 	} | ||||
| 	f.CommandPart = commandPart | ||||
| 	f.RestOfArray = restOfArray | ||||
| @@ -87,75 +87,53 @@ func (f *ConsumeFuzzer) DisallowUnexportedFields() { | ||||
| } | ||||
|  | ||||
| func (f *ConsumeFuzzer) GenerateStruct(targetStruct interface{}) error { | ||||
| 	v := reflect.ValueOf(targetStruct) | ||||
| 	/*if !v.CanSet() { | ||||
| 		return errors.New("This interface cannot be set") | ||||
| 	}*/ | ||||
| 	e := v.Elem() | ||||
| 	err := f.fuzzStruct(e, false) | ||||
| 	if err != nil { | ||||
| 		return err | ||||
| 	} | ||||
| 	return nil | ||||
| 	e := reflect.ValueOf(targetStruct).Elem() | ||||
| 	return f.fuzzStruct(e, false) | ||||
| } | ||||
|  | ||||
| func (f *ConsumeFuzzer) setCustom(v reflect.Value) error { | ||||
| 	// First: see if we have a fuzz function for it. | ||||
| 	doCustom, ok := f.Funcs[v.Type()] | ||||
| 	if !ok { | ||||
| 		return fmt.Errorf("Could not find a custom function") | ||||
| 		return fmt.Errorf("could not find a custom function") | ||||
| 	} | ||||
|  | ||||
| 	switch v.Kind() { | ||||
| 	case reflect.Ptr: | ||||
| 		if v.IsNil() { | ||||
| 			if !v.CanSet() { | ||||
| 				return fmt.Errorf("Could not use a custom function") | ||||
| 				return fmt.Errorf("could not use a custom function") | ||||
| 			} | ||||
| 			v.Set(reflect.New(v.Type().Elem())) | ||||
| 		} | ||||
| 	case reflect.Map: | ||||
| 		if v.IsNil() { | ||||
| 			if !v.CanSet() { | ||||
| 				return fmt.Errorf("Could not use a custom function") | ||||
| 				return fmt.Errorf("could not use a custom function") | ||||
| 			} | ||||
| 			v.Set(reflect.MakeMap(v.Type())) | ||||
| 		} | ||||
| 	default: | ||||
| 		return fmt.Errorf("Could not use a custom function") | ||||
| 		return fmt.Errorf("could not use a custom function") | ||||
| 	} | ||||
|  | ||||
| 	verr := doCustom.Call([]reflect.Value{v, reflect.ValueOf(Continue{ | ||||
| 		F: f, | ||||
| 	})}) | ||||
|  | ||||
| 	// check if we return an error | ||||
| 	if verr[0].IsNil() { | ||||
| 		return nil | ||||
| 	} | ||||
| 	return fmt.Errorf("Could not use a custom function") | ||||
| 	return fmt.Errorf("could not use a custom function") | ||||
| } | ||||
|  | ||||
| func (f *ConsumeFuzzer) fuzzStruct(e reflect.Value, customFunctions bool) error { | ||||
|  | ||||
| 	// We check if we should check for custom functions | ||||
| 	if customFunctions { | ||||
| 		if e.IsValid() { | ||||
| 			if e.CanAddr() { | ||||
| 				err := f.setCustom(e.Addr()) | ||||
| 				if err == nil { | ||||
| 					return nil | ||||
| 				} | ||||
| 			} | ||||
| 			/*	return f.setCustom(e) | ||||
| 				_, ok := f.Funcs[e.Type()] | ||||
| 				if ok { | ||||
| 					if e.CanAddr() { | ||||
| 						err := f.setCustom(e.Addr()) | ||||
| 						if err == nil { | ||||
| 							return nil | ||||
| 						} | ||||
| 					}*/ | ||||
| 			//return f.setCustom(e) | ||||
| 	if customFunctions && e.IsValid() && e.CanAddr() { | ||||
| 		err := f.setCustom(e.Addr()) | ||||
| 		if err == nil { | ||||
| 			return nil | ||||
| 		} | ||||
| 	} | ||||
|  | ||||
| @@ -167,24 +145,14 @@ func (f *ConsumeFuzzer) fuzzStruct(e reflect.Value, customFunctions bool) error | ||||
| 				if f.fuzzUnexportedFields { | ||||
| 					v = reflect.NewAt(e.Field(i).Type(), unsafe.Pointer(e.Field(i).UnsafeAddr())).Elem() | ||||
| 				} | ||||
| 				err := f.fuzzStruct(v, customFunctions) | ||||
| 				if err != nil { | ||||
| 				if err := f.fuzzStruct(v, customFunctions); err != nil { | ||||
| 					return err | ||||
| 				} | ||||
| 			} else { | ||||
| 				/*if e.Field(i).Kind() == reflect.Struct { | ||||
| 					//e = reflect.NewAt(e.Type(), unsafe.Pointer(e.UnsafeAddr())).Elem() | ||||
| 					//e.Field(i).Set(reflect.New(e.Field(i).Type())) | ||||
| 				}*/ | ||||
| 				v = e.Field(i) | ||||
| 				//v = reflect.New(e.Field(i).Type()) | ||||
| 				err := f.fuzzStruct(v, customFunctions) | ||||
| 				if err != nil { | ||||
| 				if err := f.fuzzStruct(v, customFunctions); err != nil { | ||||
| 					return err | ||||
| 				} | ||||
| 				/*if e.Field(i).CanSet() { | ||||
| 					e.Field(i).Set(v.Elem()) | ||||
| 				}*/ | ||||
| 			} | ||||
| 		} | ||||
| 	case reflect.String: | ||||
| @@ -208,18 +176,16 @@ func (f *ConsumeFuzzer) fuzzStruct(e reflect.Value, customFunctions bool) error | ||||
| 		if err != nil { | ||||
| 			return err | ||||
| 		} | ||||
| 		var numOfElements uint32 | ||||
| 		numOfElements = randQty % maxElements | ||||
| 		if (uint32(len(f.data)) - f.position) < numOfElements { | ||||
| 			numOfElements = uint32(len(f.data)) - f.position | ||||
| 		numOfElements := randQty % maxElements | ||||
| 		if (f.dataTotal - f.position) < numOfElements { | ||||
| 			numOfElements = f.dataTotal - f.position | ||||
| 		} | ||||
|  | ||||
| 		uu := reflect.MakeSlice(e.Type(), int(numOfElements), int(numOfElements)) | ||||
|  | ||||
| 		for i := 0; i < int(numOfElements); i++ { | ||||
| 			err := f.fuzzStruct(uu.Index(i), customFunctions) | ||||
| 			// If we have more than 10, then we can proceed with that. | ||||
| 			if err != nil { | ||||
| 			if err := f.fuzzStruct(uu.Index(i), customFunctions); err != nil { | ||||
| 				if i >= 10 { | ||||
| 					if e.CanSet() { | ||||
| 						e.Set(uu) | ||||
| @@ -284,7 +250,7 @@ func (f *ConsumeFuzzer) fuzzStruct(e reflect.Value, customFunctions bool) error | ||||
| 	case reflect.Map: | ||||
| 		if e.CanSet() { | ||||
| 			e.Set(reflect.MakeMap(e.Type())) | ||||
| 			maxElements := 50 | ||||
| 			const maxElements = 50 | ||||
| 			randQty, err := f.GetInt() | ||||
| 			if err != nil { | ||||
| 				return err | ||||
| @@ -292,13 +258,11 @@ func (f *ConsumeFuzzer) fuzzStruct(e reflect.Value, customFunctions bool) error | ||||
| 			numOfElements := randQty % maxElements | ||||
| 			for i := 0; i < numOfElements; i++ { | ||||
| 				key := reflect.New(e.Type().Key()).Elem() | ||||
| 				err := f.fuzzStruct(key, customFunctions) | ||||
| 				if err != nil { | ||||
| 				if err := f.fuzzStruct(key, customFunctions); err != nil { | ||||
| 					return err | ||||
| 				} | ||||
| 				val := reflect.New(e.Type().Elem()).Elem() | ||||
| 				err = f.fuzzStruct(val, customFunctions) | ||||
| 				if err != nil { | ||||
| 				if err = f.fuzzStruct(val, customFunctions); err != nil { | ||||
| 					return err | ||||
| 				} | ||||
| 				e.SetMapIndex(key, val) | ||||
| @@ -307,8 +271,7 @@ func (f *ConsumeFuzzer) fuzzStruct(e reflect.Value, customFunctions bool) error | ||||
| 	case reflect.Ptr: | ||||
| 		if e.CanSet() { | ||||
| 			e.Set(reflect.New(e.Type().Elem())) | ||||
| 			err := f.fuzzStruct(e.Elem(), customFunctions) | ||||
| 			if err != nil { | ||||
| 			if err := f.fuzzStruct(e.Elem(), customFunctions); err != nil { | ||||
| 				return err | ||||
| 			} | ||||
| 			return nil | ||||
| @@ -321,43 +284,39 @@ func (f *ConsumeFuzzer) fuzzStruct(e reflect.Value, customFunctions bool) error | ||||
| 		if e.CanSet() { | ||||
| 			e.SetUint(uint64(b)) | ||||
| 		} | ||||
| 	default: | ||||
| 		return nil | ||||
| 	} | ||||
| 	return nil | ||||
| } | ||||
|  | ||||
| func (f *ConsumeFuzzer) GetStringArray() (reflect.Value, error) { | ||||
| 	// The max size of the array: | ||||
| 	max := uint32(20) | ||||
| 	const max uint32 = 20 | ||||
|  | ||||
| 	arraySize := f.position | ||||
| 	if arraySize > max { | ||||
| 		arraySize = max | ||||
| 	} | ||||
| 	elemType := reflect.TypeOf("string") | ||||
| 	stringArray := reflect.MakeSlice(reflect.SliceOf(elemType), int(arraySize), int(arraySize)) | ||||
| 	if f.position+arraySize >= uint32(len(f.data)) { | ||||
| 		return stringArray, errors.New("Could not make string array") | ||||
| 	stringArray := reflect.MakeSlice(reflect.SliceOf(reflect.TypeOf("string")), int(arraySize), int(arraySize)) | ||||
| 	if f.position+arraySize >= f.dataTotal { | ||||
| 		return stringArray, errors.New("could not make string array") | ||||
| 	} | ||||
|  | ||||
| 	for i := 0; i < int(arraySize); i++ { | ||||
| 		stringSize := uint32(f.data[f.position]) | ||||
|  | ||||
| 		if f.position+stringSize >= uint32(len(f.data)) { | ||||
| 		if f.position+stringSize >= f.dataTotal { | ||||
| 			return stringArray, nil | ||||
| 		} | ||||
| 		stringToAppend := string(f.data[f.position : f.position+stringSize]) | ||||
| 		strVal := reflect.ValueOf(stringToAppend) | ||||
| 		stringArray = reflect.Append(stringArray, strVal) | ||||
| 		f.position = f.position + stringSize | ||||
| 		f.position += stringSize | ||||
| 	} | ||||
| 	return stringArray, nil | ||||
| } | ||||
|  | ||||
| func (f *ConsumeFuzzer) GetInt() (int, error) { | ||||
| 	if f.position >= uint32(len(f.data)) { | ||||
| 		return 0, errors.New("Not enough bytes to create int") | ||||
| 	if f.position >= f.dataTotal { | ||||
| 		return 0, errors.New("not enough bytes to create int") | ||||
| 	} | ||||
| 	returnInt := int(f.data[f.position]) | ||||
| 	f.position++ | ||||
| @@ -365,29 +324,23 @@ func (f *ConsumeFuzzer) GetInt() (int, error) { | ||||
| } | ||||
|  | ||||
| func (f *ConsumeFuzzer) GetByte() (byte, error) { | ||||
| 	if len(f.data) == 0 { | ||||
| 		return 0x00, errors.New("Not enough bytes to get byte") | ||||
| 	} | ||||
| 	if f.position >= uint32(len(f.data)) { | ||||
| 		return 0x00, errors.New("Not enough bytes to get byte") | ||||
| 	if f.position >= f.dataTotal { | ||||
| 		return 0x00, errors.New("not enough bytes to get byte") | ||||
| 	} | ||||
| 	returnByte := f.data[f.position] | ||||
| 	f.position += 1 | ||||
| 	f.position++ | ||||
| 	return returnByte, nil | ||||
| } | ||||
|  | ||||
| func (f *ConsumeFuzzer) GetNBytes(numberOfBytes int) ([]byte, error) { | ||||
| 	returnBytes := make([]byte, 0) | ||||
| 	if len(f.data) == 0 { | ||||
| 		return returnBytes, errors.New("Not enough bytes to get byte") | ||||
| 	} | ||||
| 	if f.position >= uint32(len(f.data)) { | ||||
| 		return returnBytes, errors.New("Not enough bytes to get byte") | ||||
| 	if f.position >= f.dataTotal { | ||||
| 		return nil, errors.New("not enough bytes to get byte") | ||||
| 	} | ||||
| 	returnBytes := make([]byte, 0, numberOfBytes) | ||||
| 	for i := 0; i < numberOfBytes; i++ { | ||||
| 		newByte, err := f.GetByte() | ||||
| 		if err != nil { | ||||
| 			return returnBytes, err | ||||
| 			return nil, err | ||||
| 		} | ||||
| 		returnBytes = append(returnBytes, newByte) | ||||
| 	} | ||||
| @@ -397,112 +350,104 @@ func (f *ConsumeFuzzer) GetNBytes(numberOfBytes int) ([]byte, error) { | ||||
| func (f *ConsumeFuzzer) GetUint16() (uint16, error) { | ||||
| 	u16, err := f.GetNBytes(2) | ||||
| 	if err != nil { | ||||
| 		return uint16(0), err | ||||
| 		return 0, err | ||||
| 	} | ||||
| 	littleEndian, err := f.GetBool() | ||||
| 	if err != nil { | ||||
| 		return uint16(0), err | ||||
| 		return 0, err | ||||
| 	} | ||||
| 	if littleEndian { | ||||
| 		u16LE := binary.LittleEndian.Uint16(u16) | ||||
| 		return u16LE, nil | ||||
| 		return binary.LittleEndian.Uint16(u16), nil | ||||
| 	} | ||||
| 	u16BE := binary.BigEndian.Uint16(u16) | ||||
| 	return u16BE, nil | ||||
| 	return binary.BigEndian.Uint16(u16), nil | ||||
| } | ||||
|  | ||||
| func (f *ConsumeFuzzer) GetUint32() (uint32, error) { | ||||
| 	u32, err := f.GetNBytes(4) | ||||
| 	if err != nil { | ||||
| 		return uint32(0), err | ||||
| 		return 0, err | ||||
| 	} | ||||
| 	littleEndian, err := f.GetBool() | ||||
| 	if err != nil { | ||||
| 		return uint32(0), err | ||||
| 		return 0, err | ||||
| 	} | ||||
| 	if littleEndian { | ||||
| 		u32LE := binary.LittleEndian.Uint32(u32) | ||||
| 		return u32LE, nil | ||||
| 		return binary.LittleEndian.Uint32(u32), nil | ||||
| 	} | ||||
| 	u32BE := binary.BigEndian.Uint32(u32) | ||||
| 	return u32BE, nil | ||||
| 	return binary.BigEndian.Uint32(u32), nil | ||||
| } | ||||
|  | ||||
| func (f *ConsumeFuzzer) GetUint64() (uint64, error) { | ||||
| 	u64, err := f.GetNBytes(8) | ||||
| 	if err != nil { | ||||
| 		return uint64(0), err | ||||
| 		return 0, err | ||||
| 	} | ||||
| 	littleEndian, err := f.GetBool() | ||||
| 	if err != nil { | ||||
| 		return uint64(0), err | ||||
| 		return 0, err | ||||
| 	} | ||||
| 	if littleEndian { | ||||
| 		u64LE := binary.LittleEndian.Uint64(u64) | ||||
| 		return u64LE, nil | ||||
| 		return binary.LittleEndian.Uint64(u64), nil | ||||
| 	} | ||||
| 	u64BE := binary.BigEndian.Uint64(u64) | ||||
| 	return u64BE, nil | ||||
| 	return binary.BigEndian.Uint64(u64), nil | ||||
| } | ||||
|  | ||||
| func (f *ConsumeFuzzer) GetBytes() ([]byte, error) { | ||||
| 	if len(f.data) == 0 || f.position >= uint32(len(f.data)) { | ||||
| 		return nil, errors.New("Not enough bytes to create byte array") | ||||
| 	if f.position >= f.dataTotal { | ||||
| 		return nil, errors.New("not enough bytes to create byte array") | ||||
| 	} | ||||
| 	length, err := f.GetUint32() | ||||
| 	if err != nil { | ||||
| 		return nil, errors.New("Not enough bytes to create byte array") | ||||
| 		return nil, errors.New("not enough bytes to create byte array") | ||||
| 	} | ||||
| 	if f.position+length > MaxTotalLen { | ||||
| 		return nil, errors.New("Created too large a string") | ||||
| 		return nil, errors.New("created too large a string") | ||||
| 	} | ||||
| 	byteBegin := f.position - 1 | ||||
| 	if byteBegin >= uint32(len(f.data)) { | ||||
| 		return nil, errors.New("Not enough bytes to create byte array") | ||||
| 	if byteBegin >= f.dataTotal { | ||||
| 		return nil, errors.New("not enough bytes to create byte array") | ||||
| 	} | ||||
| 	if length == 0 { | ||||
| 		return nil, errors.New("Zero-length is not supported") | ||||
| 		return nil, errors.New("zero-length is not supported") | ||||
| 	} | ||||
| 	if byteBegin+length >= uint32(len(f.data)) { | ||||
| 		return nil, errors.New("Not enough bytes to create byte array") | ||||
| 	if byteBegin+length >= f.dataTotal { | ||||
| 		return nil, errors.New("not enough bytes to create byte array") | ||||
| 	} | ||||
| 	if byteBegin+length < byteBegin { | ||||
| 		return nil, errors.New("Nunmbers overflow. Returning") | ||||
| 		return nil, errors.New("numbers overflow") | ||||
| 	} | ||||
| 	b := f.data[byteBegin : byteBegin+length] | ||||
| 	f.position = byteBegin + length | ||||
| 	return b, nil | ||||
| 	return f.data[byteBegin:f.position], nil | ||||
| } | ||||
|  | ||||
| func (f *ConsumeFuzzer) GetString() (string, error) { | ||||
| 	if f.position >= uint32(len(f.data)) { | ||||
| 		return "nil", errors.New("Not enough bytes to create string") | ||||
| 	if f.position >= f.dataTotal { | ||||
| 		return "nil", errors.New("not enough bytes to create string") | ||||
| 	} | ||||
| 	length, err := f.GetUint32() | ||||
| 	if err != nil { | ||||
| 		return "nil", errors.New("Not enough bytes to create string") | ||||
| 		return "nil", errors.New("not enough bytes to create string") | ||||
| 	} | ||||
| 	if f.position > MaxTotalLen { | ||||
| 		return "nil", errors.New("Created too large a string") | ||||
| 		return "nil", errors.New("created too large a string") | ||||
| 	} | ||||
| 	byteBegin := f.position - 1 | ||||
| 	if byteBegin >= uint32(len(f.data)) { | ||||
| 		return "nil", errors.New("Not enough bytes to create string") | ||||
| 	if byteBegin >= f.dataTotal { | ||||
| 		return "nil", errors.New("not enough bytes to create string") | ||||
| 	} | ||||
| 	if byteBegin+length > uint32(len(f.data)) { | ||||
| 		return "nil", errors.New("Not enough bytes to create string") | ||||
| 	if byteBegin+length > f.dataTotal { | ||||
| 		return "nil", errors.New("not enough bytes to create string") | ||||
| 	} | ||||
| 	if byteBegin > byteBegin+length { | ||||
| 		return "nil", errors.New("Numbers overflow. Returning") | ||||
| 		return "nil", errors.New("numbers overflow") | ||||
| 	} | ||||
| 	str := string(f.data[byteBegin : byteBegin+length]) | ||||
| 	f.position = byteBegin + length | ||||
| 	return str, nil | ||||
| 	return string(f.data[byteBegin:f.position]), nil | ||||
| } | ||||
|  | ||||
| func (f *ConsumeFuzzer) GetBool() (bool, error) { | ||||
| 	if f.position >= uint32(len(f.data)) { | ||||
| 		return false, errors.New("Not enough bytes to create bool") | ||||
| 	if f.position >= f.dataTotal { | ||||
| 		return false, errors.New("not enough bytes to create bool") | ||||
| 	} | ||||
| 	if IsDivisibleBy(int(f.data[f.position]), 2) { | ||||
| 		f.position++ | ||||
| @@ -514,20 +459,13 @@ func (f *ConsumeFuzzer) GetBool() (bool, error) { | ||||
| } | ||||
|  | ||||
| func (f *ConsumeFuzzer) FuzzMap(m interface{}) error { | ||||
| 	err := f.GenerateStruct(m) | ||||
| 	if err != nil { | ||||
| 		return err | ||||
| 	} | ||||
| 	return nil | ||||
| 	return f.GenerateStruct(m) | ||||
| } | ||||
|  | ||||
| func returnTarBytes(buf []byte) ([]byte, error) { | ||||
| 	reader := bytes.NewReader(buf) | ||||
| 	tr := tar.NewReader(reader) | ||||
|  | ||||
| 	// Count files | ||||
| 	var fileCounter int | ||||
| 	fileCounter = 0 | ||||
| 	tr := tar.NewReader(bytes.NewReader(buf)) | ||||
| 	for { | ||||
| 		_, err := tr.Next() | ||||
| 		if err == io.EOF { | ||||
| @@ -541,7 +479,7 @@ func returnTarBytes(buf []byte) ([]byte, error) { | ||||
| 	if fileCounter > 4 { | ||||
| 		return buf, nil | ||||
| 	} | ||||
| 	return nil, fmt.Errorf("Not enough files were created\n") | ||||
| 	return nil, fmt.Errorf("not enough files were created\n") | ||||
| } | ||||
|  | ||||
| func setTarHeaderFormat(hdr *tar.Header, f *ConsumeFuzzer) error { | ||||
| @@ -609,94 +547,77 @@ func setTarHeaderTypeflag(hdr *tar.Header, f *ConsumeFuzzer) error { | ||||
| } | ||||
|  | ||||
| func (f *ConsumeFuzzer) createTarFileBody() ([]byte, error) { | ||||
| 	if len(f.data) == 0 || f.position >= uint32(len(f.data)) { | ||||
| 		return nil, errors.New("Not enough bytes to create byte array") | ||||
| 	} | ||||
| 	length, err := f.GetUint32() | ||||
| 	if err != nil { | ||||
| 		return nil, errors.New("Not enough bytes to create byte array") | ||||
| 		return nil, errors.New("not enough bytes to create byte array") | ||||
| 	} | ||||
|  | ||||
| 	// A bit of optimization to attempt to create a file body | ||||
| 	// when we don't have as many bytes left as "length" | ||||
| 	remainingBytes := (uint32(len(f.data)) - f.position) | ||||
| 	totalDataLen := uint32(len(f.data)) | ||||
| 	if uint32(len(f.data))-f.position < 50 { | ||||
| 		if remainingBytes == 0 { | ||||
| 			return nil, errors.New("Created too large a string") | ||||
| 		} | ||||
| 	remainingBytes := f.dataTotal - f.position | ||||
| 	if remainingBytes == 0 { | ||||
| 		return nil, errors.New("created too large a string") | ||||
| 	} | ||||
| 	if remainingBytes < 50 { | ||||
| 		length = length % remainingBytes | ||||
| 	} else if len(f.data) < 500 { | ||||
| 		if totalDataLen == 0 { | ||||
| 			return nil, errors.New("Created too large a string") | ||||
| 		} | ||||
| 		length = length % totalDataLen | ||||
| 	} else if f.dataTotal < 500 { | ||||
| 		length = length % f.dataTotal | ||||
| 	} | ||||
| 	if f.position+length > MaxTotalLen { | ||||
| 		return nil, errors.New("Created too large a string") | ||||
| 		return nil, errors.New("created too large a string") | ||||
| 	} | ||||
| 	byteBegin := f.position - 1 | ||||
| 	if byteBegin >= uint32(len(f.data)) { | ||||
| 		return nil, errors.New("Not enough bytes to create byte array") | ||||
| 	if byteBegin >= f.dataTotal { | ||||
| 		return nil, errors.New("not enough bytes to create byte array") | ||||
| 	} | ||||
| 	if length == 0 { | ||||
| 		return nil, errors.New("Zero-length is not supported") | ||||
| 		return nil, errors.New("zero-length is not supported") | ||||
| 	} | ||||
| 	if byteBegin+length >= uint32(len(f.data)) { | ||||
| 		return nil, errors.New("Not enough bytes to create byte array") | ||||
| 	if byteBegin+length >= f.dataTotal { | ||||
| 		return nil, errors.New("not enough bytes to create byte array") | ||||
| 	} | ||||
| 	if byteBegin+length < byteBegin { | ||||
| 		return nil, errors.New("Nunmbers overflow. Returning") | ||||
| 		return nil, errors.New("numbers overflow") | ||||
| 	} | ||||
| 	filebody := f.data[byteBegin : byteBegin+length] | ||||
| 	f.position = byteBegin + length | ||||
| 	return filebody, nil | ||||
|  | ||||
| 	return f.data[byteBegin:f.position], nil | ||||
| } | ||||
|  | ||||
| // Is similar to GetString(), but creates string based on the length | ||||
| // of the length of f.data to increase the likelihood of not overflowing | ||||
| // f.data | ||||
| // getTarFileName is similar to GetString(), but creates string based | ||||
| // on the length of f.data to reduce the likelihood of overflowing | ||||
| // f.data. | ||||
| func (f *ConsumeFuzzer) getTarFilename() (string, error) { | ||||
| 	if f.position >= uint32(len(f.data)) { | ||||
| 		return "nil", errors.New("Not enough bytes to create string") | ||||
| 	} | ||||
| 	length, err := f.GetUint32() | ||||
| 	if err != nil { | ||||
| 		return "nil", errors.New("Not enough bytes to create string") | ||||
| 		return "nil", errors.New("not enough bytes to create string") | ||||
| 	} | ||||
|  | ||||
| 	// A bit of optimization to attempt to create a file name | ||||
| 	// when we don't have as many bytes left as "length" | ||||
| 	remainingBytes := (uint32(len(f.data)) - f.position) | ||||
| 	totalDataLen := uint32(len(f.data)) | ||||
| 	if uint32(len(f.data))-f.position < 50 { | ||||
| 		if remainingBytes == 0 { | ||||
| 			return "nil", errors.New("Created too large a string") | ||||
| 		} | ||||
| 	remainingBytes := f.dataTotal - f.position | ||||
| 	if remainingBytes == 0 { | ||||
| 		return "nil", errors.New("created too large a string") | ||||
| 	} | ||||
| 	if remainingBytes < 50 { | ||||
| 		length = length % remainingBytes | ||||
| 	} else if len(f.data) < 500 { | ||||
| 		if totalDataLen == 0 { | ||||
| 			return "nil", errors.New("Created too large a string") | ||||
| 		} | ||||
| 		length = length % totalDataLen | ||||
| 	} else if f.dataTotal < 500 { | ||||
| 		length = length % f.dataTotal | ||||
| 	} | ||||
| 	if f.position > MaxTotalLen { | ||||
| 		return "nil", errors.New("Created too large a string") | ||||
| 		return "nil", errors.New("created too large a string") | ||||
| 	} | ||||
| 	byteBegin := f.position - 1 | ||||
| 	if byteBegin >= uint32(len(f.data)) { | ||||
| 		return "nil", errors.New("Not enough bytes to create string") | ||||
| 	if byteBegin >= f.dataTotal { | ||||
| 		return "nil", errors.New("not enough bytes to create string") | ||||
| 	} | ||||
| 	if byteBegin+length > uint32(len(f.data)) { | ||||
| 		return "nil", errors.New("Not enough bytes to create string") | ||||
| 	if byteBegin+length > f.dataTotal { | ||||
| 		return "nil", errors.New("not enough bytes to create string") | ||||
| 	} | ||||
| 	if byteBegin > byteBegin+length { | ||||
| 		return "nil", errors.New("Numbers overflow. Returning") | ||||
| 		return "nil", errors.New("numbers overflow") | ||||
| 	} | ||||
| 	str := string(f.data[byteBegin : byteBegin+length]) | ||||
| 	f.position = byteBegin + length | ||||
| 	return str, nil | ||||
| 	return string(f.data[byteBegin:f.position]), nil | ||||
| } | ||||
|  | ||||
| // TarBytes returns valid bytes for a tar archive | ||||
| @@ -710,7 +631,7 @@ func (f *ConsumeFuzzer) TarBytes() ([]byte, error) { | ||||
| 	tw := tar.NewWriter(&buf) | ||||
| 	defer tw.Close() | ||||
|  | ||||
| 	maxNoOfFiles := 1000 | ||||
| 	const maxNoOfFiles = 1000 | ||||
| 	for i := 0; i < numberOfFiles%maxNoOfFiles; i++ { | ||||
| 		filename, err := f.getTarFilename() | ||||
| 		if err != nil { | ||||
| @@ -720,34 +641,27 @@ func (f *ConsumeFuzzer) TarBytes() ([]byte, error) { | ||||
| 		if err != nil { | ||||
| 			return returnTarBytes(buf.Bytes()) | ||||
| 		} | ||||
| 		hdr := &tar.Header{} | ||||
|  | ||||
| 		err = setTarHeaderTypeflag(hdr, f) | ||||
| 		if err != nil { | ||||
| 			return returnTarBytes(buf.Bytes()) | ||||
| 		} | ||||
|  | ||||
| 		sec, err := f.GetInt() | ||||
| 		if err != nil { | ||||
| 			return returnTarBytes(buf.Bytes()) | ||||
| 		} | ||||
|  | ||||
| 		nsec, err := f.GetInt() | ||||
| 		if err != nil { | ||||
| 			return returnTarBytes(buf.Bytes()) | ||||
| 		} | ||||
|  | ||||
| 		hdr.ModTime = time.Unix(int64(sec), int64(nsec)) | ||||
|  | ||||
| 		hdr.Name = filename | ||||
| 		hdr.Size = int64(len(filebody)) | ||||
| 		hdr.Mode = 0600 | ||||
|  | ||||
| 		err = setTarHeaderFormat(hdr, f) | ||||
| 		if err != nil { | ||||
| 		hdr := &tar.Header{ | ||||
| 			Name:    filename, | ||||
| 			Size:    int64(len(filebody)), | ||||
| 			Mode:    0o600, | ||||
| 			ModTime: time.Unix(int64(sec), int64(nsec)), | ||||
| 		} | ||||
| 		if err := setTarHeaderTypeflag(hdr, f); err != nil { | ||||
| 			return returnTarBytes(buf.Bytes()) | ||||
| 		} | ||||
| 		if err := setTarHeaderFormat(hdr, f); err != nil { | ||||
| 			return returnTarBytes(buf.Bytes()) | ||||
| 		} | ||||
|  | ||||
| 		if err := tw.WriteHeader(hdr); err != nil { | ||||
| 			return returnTarBytes(buf.Bytes()) | ||||
| 		} | ||||
| @@ -758,13 +672,11 @@ func (f *ConsumeFuzzer) TarBytes() ([]byte, error) { | ||||
| 	return returnTarBytes(buf.Bytes()) | ||||
| } | ||||
|  | ||||
| // Creates pseudo-random files in rootDir. | ||||
| // Will create subdirs and place the files there. | ||||
| // CreateFiles creates pseudo-random files in rootDir. | ||||
| // It creates subdirs and places the files there. | ||||
| // It is the callers responsibility to ensure that | ||||
| // rootDir exists. | ||||
| func (f *ConsumeFuzzer) CreateFiles(rootDir string) error { | ||||
| 	var noOfCreatedFiles int | ||||
| 	noOfCreatedFiles = 0 | ||||
| 	numberOfFiles, err := f.GetInt() | ||||
| 	if err != nil { | ||||
| 		return err | ||||
| @@ -774,40 +686,35 @@ func (f *ConsumeFuzzer) CreateFiles(rootDir string) error { | ||||
| 		return errors.New("maxNumberOfFiles is nil") | ||||
| 	} | ||||
|  | ||||
| 	var noOfCreatedFiles int | ||||
| 	for i := 0; i < maxNumberOfFiles; i++ { | ||||
| 		// The file to create: | ||||
| 		fileName, err := f.GetString() | ||||
| 		if err != nil { | ||||
| 			if noOfCreatedFiles > 0 { | ||||
| 				// If files have been created, we don't return | ||||
| 				// an error | ||||
| 				// If files have been created, we don't return an error. | ||||
| 				break | ||||
| 			} else { | ||||
| 				return errors.New("Could not get fileName") | ||||
| 				return errors.New("could not get fileName") | ||||
| 			} | ||||
| 		} | ||||
| 		var fullFilePath string | ||||
| 		fullFilePath, err = securejoin.SecureJoin(rootDir, fileName) | ||||
| 		fullFilePath, err := securejoin.SecureJoin(rootDir, fileName) | ||||
| 		if err != nil { | ||||
| 			return err | ||||
| 		} | ||||
|  | ||||
| 		// Find the subdirectory of the file | ||||
| 		subDir := filepath.Dir(fileName) | ||||
| 		if subDir != "" && subDir != "." { | ||||
| 			// create the dir first | ||||
|  | ||||
| 			// Avoid going outside the root dir | ||||
| 		if subDir := filepath.Dir(fileName); subDir != "" && subDir != "." { | ||||
| 			// create the dir first; avoid going outside the root dir | ||||
| 			if strings.Contains(subDir, "../") || (len(subDir) > 0 && subDir[0] == 47) || strings.Contains(subDir, "\\") { | ||||
| 				continue | ||||
| 			} | ||||
| 			dirPath := filepath.Join(rootDir, subDir) | ||||
| 			dirPath, err := securejoin.SecureJoin(rootDir, subDir) | ||||
| 			if err != nil { | ||||
| 				continue | ||||
| 			} | ||||
| 			if _, err := os.Stat(dirPath); os.IsNotExist(err) { | ||||
| 				err2 := os.MkdirAll(dirPath, 0777) | ||||
| 				err2 := os.MkdirAll(dirPath, 0o777) | ||||
| 				if err2 != nil { | ||||
| 					continue | ||||
| 				} | ||||
| @@ -823,7 +730,7 @@ func (f *ConsumeFuzzer) CreateFiles(rootDir string) error { | ||||
| 				if noOfCreatedFiles > 0 { | ||||
| 					break | ||||
| 				} else { | ||||
| 					return errors.New("Could not create the symlink") | ||||
| 					return errors.New("could not create the symlink") | ||||
| 				} | ||||
| 			} | ||||
| 			if createSymlink { | ||||
| @@ -831,7 +738,10 @@ func (f *ConsumeFuzzer) CreateFiles(rootDir string) error { | ||||
| 				if err != nil { | ||||
| 					return err | ||||
| 				} | ||||
| 				os.Symlink(symlinkTarget, fullFilePath) | ||||
| 				err = os.Symlink(symlinkTarget, fullFilePath) | ||||
| 				if err != nil { | ||||
| 					return err | ||||
| 				} | ||||
| 				// stop loop here, since a symlink needs no further action | ||||
| 				noOfCreatedFiles++ | ||||
| 				continue | ||||
| @@ -842,43 +752,35 @@ func (f *ConsumeFuzzer) CreateFiles(rootDir string) error { | ||||
| 				if noOfCreatedFiles > 0 { | ||||
| 					break | ||||
| 				} else { | ||||
| 					return errors.New("Could not create the file") | ||||
| 					return errors.New("could not create the file") | ||||
| 				} | ||||
| 			} | ||||
| 			createdFile, err := os.Create(fullFilePath) | ||||
| 			err = os.WriteFile(fullFilePath, fileContents, 0o666) | ||||
| 			if err != nil { | ||||
| 				createdFile.Close() | ||||
| 				continue | ||||
| 			} | ||||
| 			_, err = createdFile.Write(fileContents) | ||||
| 			if err != nil { | ||||
| 				createdFile.Close() | ||||
| 				continue | ||||
| 			} | ||||
| 			createdFile.Close() | ||||
| 			noOfCreatedFiles++ | ||||
| 		} | ||||
| 	} | ||||
| 	return nil | ||||
| } | ||||
|  | ||||
| // Returns a string that can only consists of characters that are | ||||
| // included in possibleChars. Will return an error if the created | ||||
| // string does not have the specified length | ||||
| // GetStringFrom returns a string that can only consist of characters | ||||
| // included in possibleChars. It returns an error if the created string | ||||
| // does not have the specified length. | ||||
| func (f *ConsumeFuzzer) GetStringFrom(possibleChars string, length int) (string, error) { | ||||
| 	returnString := "" | ||||
| 	if (uint32(len(f.data)) - f.position) < uint32(length) { | ||||
| 		return returnString, errors.New("Not enough bytes to create a string") | ||||
| 	if (f.dataTotal - f.position) < uint32(length) { | ||||
| 		return "", errors.New("not enough bytes to create a string") | ||||
| 	} | ||||
| 	output := make([]byte, 0, length) | ||||
| 	for i := 0; i < length; i++ { | ||||
| 		charIndex, err := f.GetInt() | ||||
| 		if err != nil { | ||||
| 			return returnString, err | ||||
| 			return string(output), err | ||||
| 		} | ||||
| 		charToAdd := string(possibleChars[charIndex%len(possibleChars)]) | ||||
| 		returnString = fmt.Sprintf(returnString + charToAdd) | ||||
| 		output = append(output, possibleChars[charIndex%len(possibleChars)]) | ||||
| 	} | ||||
| 	return returnString, nil | ||||
| 	return string(output), nil | ||||
| } | ||||
|  | ||||
| func (f *ConsumeFuzzer) GetRune() ([]rune, error) { | ||||
| @@ -892,11 +794,11 @@ func (f *ConsumeFuzzer) GetRune() ([]rune, error) { | ||||
| func (f *ConsumeFuzzer) GetFloat32() (float32, error) { | ||||
| 	u32, err := f.GetNBytes(4) | ||||
| 	if err != nil { | ||||
| 		return float32(0.0), err | ||||
| 		return 0, err | ||||
| 	} | ||||
| 	littleEndian, err := f.GetBool() | ||||
| 	if err != nil { | ||||
| 		return float32(0.0), err | ||||
| 		return 0, err | ||||
| 	} | ||||
| 	if littleEndian { | ||||
| 		u32LE := binary.LittleEndian.Uint32(u32) | ||||
| @@ -909,11 +811,11 @@ func (f *ConsumeFuzzer) GetFloat32() (float32, error) { | ||||
| func (f *ConsumeFuzzer) GetFloat64() (float64, error) { | ||||
| 	u64, err := f.GetNBytes(8) | ||||
| 	if err != nil { | ||||
| 		return float64(0.0), err | ||||
| 		return 0, err | ||||
| 	} | ||||
| 	littleEndian, err := f.GetBool() | ||||
| 	if err != nil { | ||||
| 		return float64(0.0), err | ||||
| 		return 0, err | ||||
| 	} | ||||
| 	if littleEndian { | ||||
| 		u64LE := binary.LittleEndian.Uint64(u64) | ||||
| @@ -924,9 +826,5 @@ func (f *ConsumeFuzzer) GetFloat64() (float64, error) { | ||||
| } | ||||
|  | ||||
| func (f *ConsumeFuzzer) CreateSlice(targetSlice interface{}) error { | ||||
| 	err := f.GenerateStruct(targetSlice) | ||||
| 	if err != nil { | ||||
| 		return err | ||||
| 	} | ||||
| 	return nil | ||||
| 	return f.GenerateStruct(targetSlice) | ||||
| } | ||||
|   | ||||
		Reference in New Issue
	
	Block a user
	 Sebastiaan van Stijn
					Sebastiaan van Stijn