Range-check record lengths when deserialising games

"1999999999999999999999999999999999999999999999999999" as a record
length should lead to an error, not a buffer overrun.

(fun fact that was less obvious to me than it should have been: very
large powers of ten are multiples of large powers of two, so that number
is -1 mod 2^32)

This bug can be demonstrated by building any puzzle with
AddressSanitizer and then loading this save file:

SAVEFILE:41:Simon Tatham's Portable Puzzle Collection
VERSION :1999999999999999999999999999999999999999999999999999:1
This commit is contained in:
Ben Harris
2023-01-08 11:31:36 +00:00
parent 942d883d9b
commit e5717d1ba2

View File

@ -2310,7 +2310,7 @@ static const char *midend_deserialise_internal(
if (c == ':') {
break;
} else if (c >= '0' && c <= '9') {
} else if (c >= '0' && c <= '9' && len < (INT_MAX - 10) / 10) {
len = (len * 10) + (c - '0');
} else {
if (started)
@ -2704,7 +2704,7 @@ const char *identify_game(char **name,
if (c == ':') {
break;
} else if (c >= '0' && c <= '9') {
} else if (c >= '0' && c <= '9' && len < (INT_MAX - 10) / 10) {
len = (len * 10) + (c - '0');
} else {
if (started)