diff --git a/examples/fuzzing/calculator_fuzz.go b/examples/fuzzing/calculator_fuzz.go deleted file mode 100644 index 2d7b33b..0000000 --- a/examples/fuzzing/calculator_fuzz.go +++ /dev/null @@ -1,79 +0,0 @@ -package main - -import ( - "errors" - "fmt" - "math/rand" - "strconv" - "strings" -) - -func Calculator(num1, num2 float64, operator string) (float64, error) { - var result float64 - - switch operator { - case "-": - result = num1 - num2 - - case "+": - result = num1 + num2 - - case "/": - if num2 == 0 || num1 == 0 { - return 0, errors.New("Division by 0") - } - case "*": - result = num1 * num2 - } - - return result, nil -} - -/* -The go-fuzz testing tools operates on raw binary data -Every input are in []bytes which are coverted to strings and -The string is then split into three parts (two numbers and an operator) using strings. -Split, and the numbers are parsed using strconv.ParseFloat. Finally, -the Calculator function is called with the parsed numbers and operator. -*/ -func Fuzz(data []byte) float64 { - //converts input data into string - inputs := strings.Split(string(data), ",") - //parse input numbers and operators - num1, err := strconv.ParseFloat(inputs[0], 64) - if err != nil { - return 0 - - } - num2, err := strconv.ParseFloat(inputs[1], 64) - if err != nil { - return 0 - } - operators := inputs[2] - _, err = Calculator(num1, num2, operators) - if err != nil { - if err.Error() != "Division by 0" { - return 0 - } - } - //returns a success - return 1 -} - -func main() { - // Seed the random number generator - rand.Seed(1234) - - // Generate random input data - data := make([]byte, 64) - rand.Read(data) - - result, err := Calculator(16, 18, "*") - if err != nil { - fmt.Println(err) - } - fmt.Println(result) - - // Fuzz the Calculator function with the generated input data - Fuzz(data) -} diff --git a/examples/fuzzing/calculator_test.go b/examples/fuzzing/calculator_test.go new file mode 100644 index 0000000..fa59c79 --- /dev/null +++ b/examples/fuzzing/calculator_test.go @@ -0,0 +1,79 @@ +package main + +/* Fuzz testing or fuzzing is an automated software testing method +that injects invalid, malformed, or unexpected inputs into a system +to reveal software defects and vulnerabilities. +A fuzzing tool injects these inputs into the system and then monitors for exceptions such as crashes or information leakage +*/ + +//A simple way of using fuzzing to test a program using a claculator instance +import ( + "errors" + "fmt" + "testing" +) + +/*A calculator for performing simple arithmetic operations*/ +func calculator(num1, num2 float64, operator string) (float64, error) { + var result float64 + + switch operator { + case "-": + result = num1 - num2 + + case "+": + result = num1 + num2 + + case "/": + if num2 == 0 || num1 == 0 { + return 0, errors.New("Division by 0") + } + case "*": + result = num1 * num2 + } + + return result, nil +} + +/*Accepts inputs, calls the calculator function and executes inputs and return results*/ +func InputCalculator(data float64) float64 { + inputcases := []struct { + input1 float64 + input2 float64 + operator string + output float64 + }{ + {1, 3, "+", 4}, + {4, 6, "-", -2}, + {0, 0, "/", 0}, + {9, 2, "*", 18}, + {1.2, 2.4, "*", 2.88}, + {2, 6, "+", 9}, + } + success := 1 + for _, input := range inputcases { + result, _ := calculator(input.input1, input.input2, input.operator) + if result != input.output { + fmt.Errorf("Calculator(%f,%f,%s)=%f; expected %f", input.input1, input.input2, + input.operator, result, input.output) + } + return result + } + return float64(success) + +} + +// testing the Calculator inputs function +func FuzzTestInput(f *testing.F) { + f.Fuzz(func(t *testing.T, data float64) { + _ = InputCalculator(data) + }) + +} + +// Tests the calculator function +func FuzzTestCalculator(f *testing.F) { + f.Fuzz(func(t *testing.T, num1, num2 float64, operator string) { + _, _ = calculator(num1, num2, operator) + }) +}