Open
Description
Hi, thank you for your work and for reading. I found that arithmetic operations choose architecture-dependant types in some circumstances and can cause overflows in 32bit architectures.
Example
Given a value a
of type int64
and a value b
of any integer type, if we run the expression a+b
then we will get int(a)+int(b)
, which can overflow in 32bit architectures.
Reproduction steps
First, save the following file as 32bit_test.go
:
package main
import (
"fmt"
"math"
"testing"
"github.com/expr-lang/expr"
)
func TestOverflows32bit(t *testing.T) {
p, err := expr.Compile("val64 + 0")
if err != nil {
t.Fatalf("compile error: %v", err)
}
val, err := expr.Run(p, map[string]any{
"val64": int64(math.MaxInt32 + 1),
})
if err != nil {
t.Fatalf("run error: %v", err)
}
str := fmt.Sprint(val)
if str != "2147483648" {
t.Fatalf("expected %v, got %v", "2147483648", val)
}
}
Second, run it in a 32bit architecture docker container:
docker run --name go32 --rm -dit --platform linux/386 i386/golang:latest bash
docker exec go32 mkdir -p /go/src/test
docker cp 32bit_test.go go32:/go/src/test/main_test.go
docker exec -it go32 bash
> cd /go/src/test/
> go mod init
> go get github.com/expr-lang/expr
> go test
--- FAIL: TestOverflows32bit (0.01s)
main_test.go:24: expected 2147483648, got -2147483648
FAIL
exit status 1
FAIL test 0.043s
Metadata
Metadata
Assignees
Labels
No labels