From 456cdf6edbf0c14b75fd9048708e9abea43e6aa1 Mon Sep 17 00:00:00 2001 From: Linus Torvalds Date: Mon, 19 Mar 2007 22:49:53 -0700 Subject: [PATCH] Fix loose object uncompression check. The thing is, if the output buffer is empty, we should *still* actually use the zlib routines to *unpack* that empty output buffer. But we had a test that said "only unpack if we still expect more output". So we wouldn't use up all the zlib stream, because we felt that we didn't need it, because we already had all the bytes we wanted. And it was "true": we did have all the output data. We just needed to also eat all the input data! We've had this bug before - thinking that we don't need to inflate() anything because we already had it all.. Signed-off-by: Linus Torvalds Signed-off-by: Junio C Hamano --- sha1_file.c | 17 +++++++++++++++-- 1 file changed, 15 insertions(+), 2 deletions(-) diff --git a/sha1_file.c b/sha1_file.c index 9fe2bd69a1..c445a24718 100644 --- a/sha1_file.c +++ b/sha1_file.c @@ -1030,14 +1030,27 @@ static void *unpack_sha1_rest(z_stream *stream, void *buffer, unsigned long size n = size; memcpy(buf, (char *) buffer + bytes, n); bytes = n; - if (bytes < size) { + if (bytes <= size) { + /* + * The above condition must be (bytes <= size), not + * (bytes < size). In other words, even though we + * expect no more output and set avail_out to zer0, + * the input zlib stream may have bytes that express + * "this concludes the stream", and we *do* want to + * eat that input. + * + * Otherwise we would not be able to test that we + * consumed all the input to reach the expected size; + * we also want to check that zlib tells us that all + * went well with status == Z_STREAM_END at the end. + */ stream->next_out = buf + bytes; stream->avail_out = size - bytes; while (status == Z_OK) status = inflate(stream, Z_FINISH); } buf[size] = 0; - if ((status == Z_OK || status == Z_STREAM_END) && !stream->avail_in) { + if (status == Z_STREAM_END && !stream->avail_in) { inflateEnd(stream); return buf; } -- 2.11.4.GIT