In src/protocol/bittorrent/bencoding.c, parse_bencoding_integer does: off_t integer = 0; ... for (; pos < length && isdigit(string[pos]); pos++) { if (integer > (off_t) integer * 10) return 0; integer = (off_t) integer * 10 + string[pos] - '0'; }
The check (integer > (off_t) integer * 10) does not detect all overflows. Examples with 32-bit off_t: integer = 0x1C71C71D (0x100000000/9 rounded up) integer * 10 = 0x11C71C722, wraps to 0x1C71C722 which is > integer integer = 0x73333333 integer * 10 = 0x47FFFFFFE, wraps to 0x7FFFFFFE which is > integer Examples with 64-bit off_t: integer = 0x1C71C71C71C71C72 (0x10000000000000000/9 rounded up) integer * 10 = 0x11C71C71C71C71C74, wraps to 0x1C71C71C71C71C74 which is > integer integer = 0x7333333333333333 integer * 10 = 0x47FFFFFFFFFFFFFFE, wraps to 0x7FFFFFFFFFFFFFFE which is > integer So if the overflow check is necessary, it should be corrected. If overflows can be assumed to wrap (C does not guarantee that), then I think the following is correct and the simplest solution: for (; pos < length && isdigit(string[pos]); pos++) { off_t newint = integer * 10 + string[pos] - '0'; if (newint / 10 != integer) return 0; /* overflow */ integer = newint; } OTOH, if overflows instead trap or saturate, then this won't work.
pgp2hLRG6qLjj.pgp
Description: PGP signature
_______________________________________________ elinks-dev mailing list elinks-dev@linuxfromscratch.org http://linuxfromscratch.org/mailman/listinfo/elinks-dev