git/list[1] front-page[2] threads[3] people[4] search[5] about
 

[PATCH 4/4] archive-zip: move git_deflate() with Z_FINISH into the loop

From
Toon Claes <toon@iotcl.com>
Date
Aug 4, 2025, 16:56 UTC
Message-ID
<20250804-toon-archive-zip-fix-v1-4-ca89858e5eaa@iotcl.com>
In-Reply-To
<20250804-toon-archive-zip-fix-v1-0-ca89858e5eaa@iotcl.com>

Instead duplicating code to do the final deflate (with `flush` value Z_FINISH), bring this call inside the loop that's deflate parts of the input stream. This causes also this final deflate to be wrapped in a loop to ensure the whole input is taken care of.

This change makes crc32() to be called without checking if the `readlen` is greater than zero, but looking at the zlib manual[1] should be allowed.

This patch concluded some refactoring, making the code more similar to the example usage of the official zlib docs[2].

[1]: https://zlib.net/manual.html [2]: https://zlib.net/zlib_how.html

Co-authored-by: Justin Tobler <jltobler@gmail.com>
Signed-off-by: Toon Claes <toon@iotcl.com>
---
 archive-zip.c | 25 +++++++++----------------
 1 file changed, 9 insertions(+), 16 deletions(-)
diff --git a/archive-zip.c b/archive-zip.c
index 25a0224130..559ed267be 100644
--- a/archive-zip.c
+++ b/archive-zip.c
@@ -451,7 +451,7 @@ static int write_zip_entry(struct archiver_args *args,
 		unsigned char buf[STREAM_BUFFER_SIZE];
 		ssize_t readlen;
 		git_zstream zstream;
-		int result;
+		int result, flush;
 		size_t out_len;
 		unsigned char compressed[STREAM_BUFFER_SIZE * 2];
 
@@ -459,44 +459,37 @@ static int write_zip_entry(struct archiver_args *args,
 
 		compressed_size = 0;
 
-		for (;;) {
+		do {
 			readlen = read_istream(stream, buf, sizeof(buf));
-			if (readlen <= 0)
+			if (readlen < 0)
 				break;
 			crc = crc32(crc, buf, readlen);
-			if (is_binary == -1)
+			if ((is_binary == -1) && readlen)
 				is_binary = entry_is_binary(args->repo->index,
 							    path_without_prefix,
 							    buf, readlen);
 
+			flush = readlen ? Z_NO_FLUSH : Z_FINISH;
 			zstream.next_in = buf;
 			zstream.avail_in = readlen;
 			do {
 				zstream.next_out = compressed;
 				zstream.avail_out = sizeof(compressed);
-				result = git_deflate(&zstream, 0);
-				if (result != Z_OK)
+				result = git_deflate(&zstream, flush);
+				if ((result != Z_OK) && (result != Z_STREAM_END))
 					die(_("deflate error (%d)"), result);
 				out_len = zstream.next_out - compressed;
 
 				write_or_die(1, compressed, out_len);
 				compressed_size += out_len;
 			} while (zstream.avail_out == 0);
-		}
+		} while (flush != Z_FINISH);
+
 		close_istream(stream);
 		if (readlen)
 			return readlen;
 
-		zstream.next_in = buf;
-		zstream.avail_in = 0;
-		result = git_deflate(&zstream, Z_FINISH);
-		if (result != Z_STREAM_END)
-			die("deflate error (%d)", result);
-
 		git_deflate_end(&zstream);
-		out_len = zstream.next_out - compressed;
-		write_or_die(1, compressed, out_len);
-		compressed_size += out_len;
 		zip_offset += compressed_size;
 
 		write_zip_data_desc(size, compressed_size, crc);
-- 
2.50.1.327.g047016eb4a
Previous: René ScharfeNext: René Scharfe
Message 8 of 9 in “Fix archiving some corner-case files into zip”
  1. 0/4 Fix archiving some corner-case files into zipToon Claes, Aug 4, 2025
  2. 1/4 archive-zip: deduplicate code setting output buffer in write_zip_entry()Toon Claes, Aug 4, 2025
  3. René ScharfeAug 7, 2025
  4. 2/4 archive-zip: remove unneccesarry condition in write_zip_entry()Toon Claes, Aug 4, 2025
  5. René ScharfeAug 7, 2025
  6. 3/4 archive-zip: in write_zip_entry() call git_deflate() in a loopToon Claes, Aug 4, 2025
  7. René ScharfeAug 7, 2025
  8. 4/4 archive-zip: move git_deflate() with Z_FINISH into the loopToon Claes, Aug 4, 2025
  9. René ScharfeAug 7, 2025

Read the whole thread, see it on lore, or plain text.

$ cat FOOTERMessages come from the public archive at lore.kernel.org/git, fetched every hour. The front page is chosen and written each morning by an AI editor and can be wrong; the threads themselves are the record. About and API. For agents: an MCP server at https://gitlist.dev/mcp, and any thread, story or person page as Markdown by adding .md to its URL (or sending Accept: text/markdown). Details in /llms.txt.