summaryrefslogtreecommitdiff
path: root/src/pack.c
diff options
context:
space:
mode:
authorEdward Thomson <ethomson@edwardthomson.com>2020-08-05 09:42:52 +0100
committerEdward Thomson <ethomson@edwardthomson.com>2020-08-05 09:42:52 +0100
commit9bb61bad9ea1503362557e30e16b83ad2bd290eb (patch)
tree33af328ee5bb4837d42e968c20363c88b77a9140 /src/pack.c
parentc71321a099373753c22055921c8f538afed5ebb6 (diff)
downloadlibgit2-9bb61bad9ea1503362557e30e16b83ad2bd290eb.tar.gz
zstream: handle Z_BUF_ERROR appropriately in get_output_chunk
Our processing loop in git_zstream_get_output_chunk does not handle `Z_BUF_ERROR` appropriately at the end of a compressed window. From the zlib manual, inflate will return: > Z_BUF_ERROR if no progress was possible or if there was not enough > room in the output buffer when Z_FINISH is used. Note that Z_BUF_ERROR > is not fatal, and inflate() can be called again with more input and > more output space to continue decompressing. In our loop, we were waiting until we got the expected size, then ensuring that we were at `Z_STREAM_END`. We are not guaranteed to be, since zlib may be in the `Z_BUF_ERROR` state where it has consumed a full window's worth of data, but it doesn't know that it's really at the end of the stream. There _could_ be more compressed data, but it doesn't _know_ that there's not until we make a subsequent call. We can change the loop to look for the end of stream instead of our expected size. This allows us to call inflate one last time when we are at the end of a window (and in the `Z_BUF_ERROR` state), allowing it to recognize the end of the stream, and move from the `Z_BUF_ERROR` state to the `Z_STREAM_END` state. If we do this, we need another exit condition: when `bytes == 0`, then no progress could be made and we should stop trying to inflate. This will be an error case, caught by the size and/or end-of-stream test.
Diffstat (limited to 'src/pack.c')
-rw-r--r--src/pack.c5
1 files changed, 4 insertions, 1 deletions
diff --git a/src/pack.c b/src/pack.c
index 4294a6e32..d9e8bf2d5 100644
--- a/src/pack.c
+++ b/src/pack.c
@@ -854,9 +854,12 @@ static int packfile_unpack_compressed(
git_mwindow_close(mwindow);
+ if (!bytes)
+ break;
+
*position += window_len - zstream.in_len;
total += bytes;
- } while (total < size);
+ } while (!git_zstream_eos(&zstream));
if (total != size || !git_zstream_eos(&zstream)) {
git_error_set(GIT_ERROR_ZLIB, "error inflating zlib stream");