Skip to content

Arithmetic operations choose arch-dependant type and overflow in 32bit #804

@diegommm

Description

@diegommm

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

No one assigned

    Labels

    Type

    No type

    Projects

    No projects

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions