Fix VariantWriter overflow on 64-bit int
Created by: akien-mga
Integers in Godot are signed 64-bit ints (int64_t), but var2str used int behind the scenes and would thus overflow after 2^31.
Also properly documented the actual bounds of int and the behaviour when overflowing them.
Before this fix, this would overflow:
var foo = 2147483648 # 2^31, so out of bounds for 32-bit unsigned int [-2^31,-2^31-1]
print(foo) # 2147483648
print(var2str(foo)) # -2147483648, wraps around
Now it works fine:
var foo = 2147483648 # 2^31, so out of bounds for 32-bit unsigned int [-2^31,-2^31-1]
print(foo) # 2147483648
print(var2str(foo)) # 2147483648
var bar = 9223372036854775807 # 2^63-1, upper bound for signed 64-bit int
print(bar) # 9223372036854775807
print(var2str(bar)) # 9223372036854775807
print(str2var(var2str(bar))) # 9223372036854775807
print(bar + 1) # -9223372036854775808, wraps around
print(var2str(bar + 1)) # -9223372036854775808, wraps around
print(str2var(var2str(bar + 1))) # -9223372036854775808, wraps around
This was particularly problematic when serializing the output of randi()
, which gives an unsigned 32-bit int, so [0, 2^32-1], which could thus overflow VariantWriter
. (Thanks @Keetz for the report on IRC.)
Edit: Commit 5585420 fixes #26116 (closed) and fixes #22004 (closed).