Commit b7d36ef4a644c69c37e64c7c813546a68264b924

Edward Thomson 2017-12-12T12:24:11

zstream: treat `Z_BUF_ERROR` as non-fatal zlib will return `Z_BUF_ERROR` whenever there is more input to inflate or deflate than there is output to store the result. This is normal for us as we iterate through the input, particularly with very large input buffers.

diff --git a/src/zstream.c b/src/zstream.c
index 4895bdb..1c9d506 100644
--- a/src/zstream.c
+++ b/src/zstream.c
@@ -14,17 +14,22 @@
 #define ZSTREAM_BUFFER_SIZE (1024 * 1024)
 #define ZSTREAM_BUFFER_MIN_EXTRA 8
 
-static int zstream_seterr(git_zstream *zs)
+GIT_INLINE(int) zstream_seterr(git_zstream *zs)
 {
-	if (zs->zerr == Z_OK || zs->zerr == Z_STREAM_END)
+	switch (zs->zerr) {
+	case Z_OK:
+	case Z_STREAM_END:
+	case Z_BUF_ERROR: /* not fatal; we retry with a larger buffer */
 		return 0;
-
-	if (zs->zerr == Z_MEM_ERROR)
+	case Z_MEM_ERROR:
 		giterr_set_oom();
-	else if (zs->z.msg)
-		giterr_set_str(GITERR_ZLIB, zs->z.msg);
-	else
-		giterr_set(GITERR_ZLIB, "unknown compression error");
+		break;
+	default:
+		if (zs->z.msg)
+			giterr_set_str(GITERR_ZLIB, zs->z.msg);
+		else
+			giterr_set(GITERR_ZLIB, "unknown compression error");
+	}
 
 	return -1;
 }
@@ -119,8 +124,8 @@ int git_zstream_get_output(void *out, size_t *out_len, git_zstream *zstream)
 		else
 			zstream->zerr = deflate(&zstream->z, zflush);
 
-		if (zstream->zerr == Z_STREAM_ERROR)
-			return zstream_seterr(zstream);
+		if (zstream_seterr(zstream))
+			return -1;
 
 		out_used = (out_queued - zstream->z.avail_out);
 		out_remain -= out_used;