diff --git a/examples/fuzzing/calculator_test.go b/examples/fuzzing/calculator_test.go index fa59c79..5f9a401 100644 --- a/examples/fuzzing/calculator_test.go +++ b/examples/fuzzing/calculator_test.go @@ -1,79 +1,88 @@ 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 ( + "bytes" "errors" - "fmt" + "math/rand" + "strconv" "testing" ) /*A calculator for performing simple arithmetic operations*/ -func calculator(num1, num2 float64, operator string) (float64, error) { - var result float64 +/* +[]byte was used as its parameters in the Calculator() cause fuzz test requires []bytes as + it parameters when testing a function + then the []bytes are coverted to []float for performing arithmetic operations +*/ + +func Calculator(numbers []byte) (float64, error) { + bytesList := bytes.Split(numbers, []byte(",")) + + //convert to float + var floatList []float64 + for _, b := range bytesList { + f, err := strconv.ParseFloat(string(b), 64) + if err != nil { + return 0, err + } + floatList = append(floatList, f) + } + + var result float64 + var operator string + + //performing calculations based on the indices of the values in FloatList switch operator { case "-": - result = num1 - num2 + if floatList[0] > floatList[1] || floatList[0] < floatList[1] { + result = floatList[0] - floatList[1] + return result, nil + } else if floatList[1] > floatList[0] || floatList[1] < floatList[0] { + result = floatList[1] - floatList[0] + return result, nil + } case "+": - result = num1 + num2 + if floatList[0] > floatList[1] || floatList[0] < floatList[1] { + result = floatList[0] + floatList[1] + return result, nil + } else if floatList[1] > floatList[0] || floatList[1] < floatList[0] { + result = floatList[1] + floatList[0] + return result, nil + } case "/": - if num2 == 0 || num1 == 0 { + if floatList[0] == 0 || floatList[1] == 0 { return 0, errors.New("Division by 0") } + result = floatList[0] / floatList[1] + case "*": - result = num1 * num2 + result = floatList[0] * floatList[1] } 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}, +func FuzzCalculator(f *testing.F) { + //generate random numbers btwn 0-100 + testcases := []float64{rand.Float64() * 100, rand.Float64() * 100} + + //convert to bytes + var b []byte + for _, n := range testcases { + b = strconv.AppendFloat(b, n, 'f', -1, 64) + b = append(b, ',') } - 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) + f.Add(b) //seed corpus inputs performed + + //Runs the fuzz function for testing + f.Fuzz(func(t *testing.T, numbers []byte) { + _, err := Calculator(numbers) + if err != nil { + return } - 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) + t.Log("Calculations Test Passed") }) }