Subject: Re: [PATCH] wrapper: properly handle MAX_IO_SIZE in `write_in_full()`

From: Jeff King <[email-masked]>
Date: Thu, 9 Apr 2026 16:59:28 -0400

On Thu, Apr 09, 2026 at 01:40:36PM -0700, Junio C Hamano wrote:

> >> As the width of ssize_t in bits can be a lot smaller than size_t,
> >> the above "unsigned_add_overflows() triggers way too late for the
> >> check to matter, no?
> >
> > I think it is correct as-is.
> >
> > The real check against ssize_t is later, when we compare total_length to
> > MAX_IO_SIZE (which is clamped to SSIZE_MAX). So this is just making sure
> > we do not overflow size_t when counting up the total (and if we do, we
> > _know_ we are going to overflow ssize_t, which must be smaller).
> 
> But then what happens after it breaks out of the loop?  We cannot be
> at i==0, so let's say we have a reasonably small iov[0] and iov[1]
> that is so large and makes size_t wraparound.  We break out here,
> and then send the iov[0] with writev().  But have we checked if
> iov[0] is under MAX_IO_SIZE in that case before calling writev()?

I think so. Either:

  - We completed the first iteration of the loop successfully (and i >=
    1), in which case we added iov[0].iov_len to total_length, and then
    compared total_length against MAX_IO_SIZE, but did not break out of
    the loop. So we know iov[0] is within the limits.

  - We bailed at i==0 either because of addition overflow, or because of
    the MAX_IO_SIZE check. Either way, we will bail to xwrite() because
    i is 0.

-Peff