Skip to content

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).

Merge request reports