You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
{{ message }}
Repository navigation
Arithmetic operations choose arch-dependant type and overflow in 32bit #804
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.
I apologize for not clarifying my expectations. I would have expected the sum to not overflow. The issue is that there is no int64 builtin sum operation when running in 32bit architectures because if I sum two int64 values then they get converted to int, which in 32bit architectures is an int32, so it unnecessarily overflows.
I think the following example is more illustrative:
package main // run this in 32bit, you can use the docker commands from the descriptionimport (
"fmt""math""testing""github.com/expr-lang/expr"
)
funcTestOverflows32bit(t*testing.T) {
p, err:=expr.Compile("maxInt32AsInt64 + oneAsInt64") // int64 + int64 overflows in 32bitiferr!=nil {
t.Fatalf("compile error: %v", err)
}
val, err:=expr.Run(p, map[string]any{
"maxInt32AsInt64": int64(math.MaxInt32),
"oneAsInt64": int64(1),
})
iferr!=nil {
t.Fatalf("run error: %v", err)
}
str:=fmt.Sprint(val)
ifstr!="2147483648" { // succeeds in 64bit, overflows in 32bit, producing -2147483648t.Fatalf("expected %v, got %v", "2147483648", val)
}
}
Activity
antonmedv commentedon Jun 24, 2025
I don’t get, what results do you expect?
diegommm commentedon Jun 24, 2025
I apologize for not clarifying my expectations. I would have expected the sum to not overflow. The issue is that there is no
int64builtin sum operation when running in 32bit architectures because if I sum twoint64values then they get converted toint, which in 32bit architectures is anint32, so it unnecessarily overflows.I think the following example is more illustrative:
diegommm commentedon Jun 24, 2025
In the code for
Addin vm/runtime/helpers[generated].go it shows (roughly):The same happens for other arithmetic and comparison operations.
antonmedv commentedon Jun 25, 2025
Let be get it right:
So we do in Expr:
On 32 word arch this is:
But what you want is:
Right?
Question: why you don't convert int64 to int32 on env creation?
diegommm commentedon Jun 27, 2025
The goal is that I can have 64bit arithmetic on 32bit systems. It doesn't make sense to convert to int32 because then I can't use 64bit arithmetic.
antonmedv commentedon Sep 18, 2025
So this is kind of of a bug. I think we can address this one in upcoming v1.18.
fix(vm): preserve int64/uint64 precision in arithmetic operations on …
fix(vm): preserve int64/uint64 precision in arithmetic operations on …