Skip to content
This repository has been archived by the owner on Mar 19, 2021. It is now read-only.

Commit

Permalink
Merge pull request #20 from aqua/fuzz-1
Browse files Browse the repository at this point in the history
Fix a panic on history underflow, and add ClearHistory() to expose it
  • Loading branch information
alfredxing authored Aug 27, 2018
2 parents 41b6cd2 + 7547b3e commit 77daf57
Show file tree
Hide file tree
Showing 2 changed files with 43 additions and 3 deletions.
18 changes: 15 additions & 3 deletions compute/compute.go
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,11 @@ import (

var resHistory = []float64{}

// ClearHistory removes prior evaluation history used for @ references.
func ClearHistory() {
resHistory = []float64{}
}

func Evaluate(in string) (float64, error) {
floats := NewFloatStack()
ops := NewStringStack()
Expand All @@ -29,7 +34,11 @@ ScanLoop:
_, tok, lit := s.Scan()

if lit != "@" && back > -1 && len(resHistory) > 0 {
floats.Push(getHistory(back))
if hval, err := getHistory(back); err != nil {
return 0, err
} else {
floats.Push(hval)
}
if prev == token.RPAREN || constants.IsConstant(prev.String()) {
evalUnprecedenced("*", ops, floats)
}
Expand Down Expand Up @@ -184,8 +193,11 @@ func parseOperator(lit string) *operators.Operator {
return operators.FindOperatorFromString(lit)
}

func getHistory(back int) float64 {
return resHistory[back]
func getHistory(back int) (float64, error) {
if back >= len(resHistory) {
return 0, errors.New("History underflow")
}
return resHistory[back], nil
}

func pushHistory(res float64) {
Expand Down
28 changes: 28 additions & 0 deletions compute/compute_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -50,6 +50,34 @@ func TestEvaluate(t *testing.T) {
}
}

func TestEvaluateInvalid(t *testing.T) {
tests := [][]string{
{"/"},
{"1/"},
{"1("},
{")("},
{"(()"},
{"@"},
{"@@"},
{"0", "@@"},
{"0", "@@@"},
{"@@\xa6"},
}
for i, series := range tests {
ClearHistory()
var fail error
for _, expr := range series {
if _, err := Evaluate(expr); err != nil {
fail = err
break
}
}
if fail == nil {
t.Errorf("case %d: expected error, finished successfully", i)
}
}
}

func BenchmarkEvaluate(b *testing.B) {
tests := []string{
"π",
Expand Down

0 comments on commit 77daf57

Please sign in to comment.