Files
Jeff King 3c7a31204f xdiff: use size_t for buffer sizes
An mmfile_t stores its size as a signed long, but the more natural type
for a buffer size is size_t. This not only limits the size of entry we
can hold, but also creates some possible integer overflow issues.

For example, read_mmfile() checks that the file size fits in a size_t
before allocating, but then assigns it to a long. Likewise,
read_mmblob() and fill_mmfile() copy sizes from other types without
checking that they fit.

On LP64 systems like Linux, this is mostly academic. You could wrap to a
negative long value, but you'd need an object that's 2^63 bytes, which
is impractical.

But on an LLP64 system like Windows, a 2^31+1-byte blob could perhaps
cause mischief. We do prevent large values from entering the xdiff code
due to MAX_XDIFF_SIZE (which is itself marked as unsigned, so we'd
convert any negative "long" back to a large unsigned value). But if you
ask for binary diffs, that negative long value could instead be
converted to a huge 64-bit size_t when passed to memcmp(), diff_delta(),
etc. So probably there are paths that can cause an out-of-bounds read,
given the right set of options, but I didn't really dig for them.

On a 32-bit system things are less clear. Because "long" and "size_t"
have the same width, any time we implicitly convert to size_t, we should
get back the original size (even if the intermediate "long" is itself
negative). Probably iterating using a long could be a problem, but most
of that happens inside xdiff, which is protected by MAX_XDIFF_SIZE
(which, again, compares in the unsigned space).

Let's just use the obvious size_t type for counting the bytes. I suspect
you could still find truncation problems on LLP64 systems due to the use
of "unsigned long" throughout the code, but that's a larger problem.
This should at least nudge us in the right direction.

Note that we have to update the printf format in emit_binary_diff_body()
to accommodate the new type. Curiously it was using "%lu", even though
the type was signed (I guess compiler printf-linting is happy enough if
just the width of the format and the type match).

Signed-off-by: Jeff King <peff@peff.net>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
2026-10-01 06:38:13 -07:00
..
2026-10-01 06:38:13 -07:00
2026-05-19 09:57:44 +09:00
2025-09-30 14:12:46 -07:00
…
…
2026-05-05 16:20:06 +09:00