Download raw body.
reuse deltas while packing
On Mon, Feb 07, 2022 at 08:26:38AM -0700, Todd C. Miller wrote:
> On Mon, 07 Feb 2022 15:32:10 +0100, Stefan Sperling wrote:
>
> > This patch fixes got-index-pack getting stuck.
> >
> > Unfortunately, zlib uses an unsigned int to represent the number of
> > input bytes available in its input buffer, instead of a size_t.
> >
> > Large mapped files can cause truncation during our assignment from
> > size_t to unsigned int when we update zlib's input length counter.
> > This results in z->avail_in being set to zero, even though plenty
> > of bytes are available for zlib to consume. We then loop forever
> > asking zlib to decompress another zero bytes during every iteration.
>
> Since the problem occurs when len - *consumed > UINT_MAX wouldn't
> something like this be a little better?
>
> const size_t avail = len - *consumed;
> z->avail_in = MIN(avail, UINT_MAX);
>
> That way the entire UINT_MAX is available. Or if you prefer the
> if() style:
>
> if (len - *consumed > UINT_MAX)
> z->avail_in = UINT_MAX;
> else
> z->avail_in = len - *consumed;
>
> There should be no need to cast UINT_MAX to size_t since it is
> explicitly unsigned and should be implicitly promoted to size_t for
> the comparison.
Indeed, thank you. The code is much clearer this way.
This new patch still fixes the issue for me.
diff 0cc5a39811be39e9f2b47098ec3a38e8817ba0bc /home/stsp/src/got
blob - 6a151f9c54a8c0f4fc4fea9a4c91ecc7dec71aed
file + lib/deflate.c
--- lib/deflate.c
+++ lib/deflate.c
@@ -153,7 +153,10 @@ got_deflate_read_mmap(struct got_deflate_buf *zb, uint
size_t last_total_in = z->total_in;
if (z->avail_in == 0) {
z->next_in = map + offset + *consumed;
- z->avail_in = len - *consumed;
+ if (len - *consumed > UINT_MAX)
+ z->avail_in = UINT_MAX;
+ else
+ z->avail_in = len - *consumed;
if (z->avail_in == 0) {
/* EOF */
ret = deflate(z, Z_FINISH);
blob - b0426141094227c79e5dd1d6e3cd0e5c2a0b28f0
file + lib/inflate.c
--- lib/inflate.c
+++ lib/inflate.c
@@ -249,7 +249,10 @@ got_inflate_read_mmap(struct got_inflate_buf *zb, uint
break;
}
z->next_in = map + offset + *consumed;
- z->avail_in = len - *consumed;
+ if (len - *consumed > UINT_MAX)
+ z->avail_in = UINT_MAX;
+ else
+ z->avail_in = len - *consumed;
}
if (zb->csum) {
csum_in = z->next_in;
@@ -322,7 +325,6 @@ got_inflate_to_mem(uint8_t **outbuf, size_t *outlen,
if (zb.flags & GOT_INFLATE_F_HAVE_MORE) {
if (outbuf == NULL)
continue;
- zb.outlen = (nbuf * GOT_INFLATE_BUFSIZE) - *outlen;
newbuf = reallocarray(*outbuf, ++nbuf,
GOT_INFLATE_BUFSIZE);
if (newbuf == NULL) {
@@ -334,6 +336,7 @@ got_inflate_to_mem(uint8_t **outbuf, size_t *outlen,
}
*outbuf = newbuf;
zb.outbuf = newbuf + *outlen;
+ zb.outlen = (nbuf * GOT_INFLATE_BUFSIZE) - *outlen;
}
} while (zb.flags & GOT_INFLATE_F_HAVE_MORE);
@@ -382,7 +385,6 @@ got_inflate_to_mem_fd(uint8_t **outbuf, size_t *outlen
if (zb.flags & GOT_INFLATE_F_HAVE_MORE) {
if (outbuf == NULL)
continue;
- zb.outlen = (nbuf * GOT_INFLATE_BUFSIZE) - *outlen;
newbuf = reallocarray(*outbuf, ++nbuf,
GOT_INFLATE_BUFSIZE);
if (newbuf == NULL) {
@@ -394,6 +396,7 @@ got_inflate_to_mem_fd(uint8_t **outbuf, size_t *outlen
}
*outbuf = newbuf;
zb.outbuf = newbuf + *outlen;
+ zb.outlen = (nbuf * GOT_INFLATE_BUFSIZE) - *outlen;
}
} while (zb.flags & GOT_INFLATE_F_HAVE_MORE);
reuse deltas while packing