Skip to content

Commit

Permalink
[add] 更新evilpot,修复大数计算bug,以及加法计算错误
Browse files Browse the repository at this point in the history
  • Loading branch information
Jarcis-cy committed Jul 10, 2024
1 parent 9df959c commit e0e361a
Show file tree
Hide file tree
Showing 2 changed files with 208 additions and 9 deletions.
22 changes: 13 additions & 9 deletions tests/evilpot/evil/evil.go
Original file line number Diff line number Diff line change
Expand Up @@ -7,15 +7,14 @@ import (
"encoding/base64"
"encoding/hex"
"log"
"math/big"
"net/http"
"net/http/httputil"
"net/url"
"regexp"
"strconv"
"sync"
"time"

"github.com/dengsgo/math-engine/engine"
)

func ServeEvilServer(addr string, hard bool) error {
Expand Down Expand Up @@ -94,14 +93,19 @@ func NewEvilServeMux(hard bool) *http.ServeMux {
}
}
}

for _, expr := range mathRe.FindAllString(unescape, -1) {
r, err := engine.ParseAndExec(expr)
if err != nil {
log.Println(err)
continue
for _, match := range []string{string(data), unescape} {
for _, expr := range mathRe.FindAllString(match, -1) {
r, err := calculate(expr)
if err != nil {
r = big.NewFloat(0)
}
switch v := r.(type) {
case *big.Int:
GenEvilContent(buf, []byte(v.String()))
case *big.Float:
GenEvilContent(buf, []byte(v.Text('f', 10)))
}
}
GenEvilContent(buf, []byte(strconv.Itoa(int(r))))
}

_, _ = writer.Write(buf.Bytes())
Expand Down
195 changes: 195 additions & 0 deletions tests/evilpot/evil/util.go
Original file line number Diff line number Diff line change
@@ -1,5 +1,12 @@
package evil

import (
"math/big"
"strconv"
"strings"
"unicode"
)

var SepFunc = func(b byte) bool {
if 48 <= b && b <= 57 {
return false
Expand Down Expand Up @@ -42,3 +49,191 @@ func Split(data []byte, sep func(b byte) bool, handler func([]byte) bool) {
}
return
}

func calculate(expression string) (interface{}, error) {
// 去除多余空格
expression = strings.TrimSpace(expression)
expression = strings.ReplaceAll(expression, " ", "")

// 定义运算符优先级
precedence := map[rune]int{
'+': 1,
'-': 1,
'*': 2,
'/': 2,
}

// 定义两个栈,一个存操作数,一个存操作符
var numStack []interface{}
var opStack []rune

// 辅助函数,用于执行整数计算
applyOpInt := func(op rune, b, a *big.Int) *big.Int {
result := new(big.Int)
switch op {
case '+':
return result.Add(a, b)
case '-':
return result.Sub(a, b)
case '*':
return result.Mul(a, b)
case '/':
return result.Div(a, b)
default:
return big.NewInt(0)
}
}

// 辅助函数,用于执行浮点数计算
applyOpFloat := func(op rune, b, a *big.Float) *big.Float {
result := new(big.Float)
switch op {
case '+':
return result.Add(a, b)
case '-':
return result.Sub(a, b)
case '*':
return result.Mul(a, b)
case '/':
return result.Quo(a, b)
default:
return big.NewFloat(0)
}
}

// 判断字符串是否为整数
isInteger := func(s string) bool {
_, err := strconv.ParseInt(s, 10, 64)
return err == nil
}

// 将操作数转换为浮点数
toBigFloat := func(num interface{}) *big.Float {
switch v := num.(type) {
case *big.Int:
return new(big.Float).SetInt(v)
case *big.Float:
return v
default:
return big.NewFloat(0)
}
}

// 解析表达式并进行计算
i := 0
for i < len(expression) {
char := rune(expression[i])

if unicode.IsDigit(char) || char == '.' {
// 处理数字和小数点
j := i
for j < len(expression) && (unicode.IsDigit(rune(expression[j])) || rune(expression[j]) == '.') {
j++
}
numStr := expression[i:j]
if isInteger(numStr) {
num := new(big.Int)
num, ok := num.SetString(numStr, 10)
if !ok {
return big.NewFloat(0), nil
}
numStack = append(numStack, num)
} else {
num, ok := new(big.Float).SetString(numStr)
if !ok {
return big.NewFloat(0), nil
}
numStack = append(numStack, num)
}
i = j
} else if char == '(' {
// 处理左括号
opStack = append(opStack, char)
i++
} else if char == ')' {
// 处理右括号
for len(opStack) > 0 && opStack[len(opStack)-1] != '(' {
op := opStack[len(opStack)-1]
opStack = opStack[:len(opStack)-1]
b := numStack[len(numStack)-1]
numStack = numStack[:len(numStack)-1]
a := numStack[len(numStack)-1]
numStack = numStack[:len(numStack)-1]

if aInt, okA := a.(*big.Int); okA {
if bInt, okB := b.(*big.Int); okB {
result := applyOpInt(op, bInt, aInt)
numStack = append(numStack, result)
} else {
result := applyOpFloat(op, toBigFloat(b), toBigFloat(a))
numStack = append(numStack, result)
}
} else {
result := applyOpFloat(op, toBigFloat(b), toBigFloat(a))
numStack = append(numStack, result)
}
}
// 移除左括号
if len(opStack) > 0 {
opStack = opStack[:len(opStack)-1]
}
i++
} else if strings.ContainsRune("+-*/", char) {
// 处理运算符
for len(opStack) > 0 && precedence[char] <= precedence[opStack[len(opStack)-1]] {
op := opStack[len(opStack)-1]
opStack = opStack[:len(opStack)-1]
b := numStack[len(numStack)-1]
numStack = numStack[:len(numStack)-1]
a := numStack[len(numStack)-1]
numStack = numStack[:len(numStack)-1]

if aInt, okA := a.(*big.Int); okA {
if bInt, okB := b.(*big.Int); okB {
result := applyOpInt(op, bInt, aInt)
numStack = append(numStack, result)
} else {
result := applyOpFloat(op, toBigFloat(b), toBigFloat(a))
numStack = append(numStack, result)
}
} else {
result := applyOpFloat(op, toBigFloat(b), toBigFloat(a))
numStack = append(numStack, result)
}
}
opStack = append(opStack, char)
i++
} else {
return big.NewFloat(0), nil
}
}

// 处理剩余的运算符
for len(opStack) > 0 {
op := opStack[len(opStack)-1]
opStack = opStack[:len(opStack)-1]
b := numStack[len(numStack)-1]
numStack = numStack[:len(numStack)-1]
a := numStack[len(numStack)-1]
numStack = numStack[:len(numStack)-1]

if aInt, okA := a.(*big.Int); okA {
if bInt, okB := b.(*big.Int); okB {
result := applyOpInt(op, bInt, aInt)
numStack = append(numStack, result)
} else {
result := applyOpFloat(op, toBigFloat(b), toBigFloat(a))
numStack = append(numStack, result)
}
} else {
result := applyOpFloat(op, toBigFloat(b), toBigFloat(a))
numStack = append(numStack, result)
}
}

if len(numStack) != 1 {
return big.NewFloat(0), nil
}

return numStack[0], nil
}

0 comments on commit e0e361a

Please sign in to comment.