From 41035c758907ce8a4bfaa10785e80fea4c013bd2 Mon Sep 17 00:00:00 2001 From: Jehan Date: Tue, 30 Sep 2025 19:57:59 +0200 Subject: [PATCH] plug-ins: fix memory management and handle multi-file zip. We should not call archive_entry_free() since man archive_read_next_header explicitly says that the returned entry is an internal object: > This is a convenience wrapper around archive_read_next_header2() that > reuses an internal struct archive_entry object for each request. The only reason why it was not crashing is that we were not properly freeing the archive itself so internal objects were hanging! The man archive_read says: > Once you have finished reading data from the archive, you should call > archive_read_close() to close the archive, then call archive_read_free() > to release all resources, including all memory allocated by the library. Therefore this code add archive_read_free() at the end and removes archive_entry_free(). Furthermore we now verify if the zip archive contains any other file. Unlike all other compression formats we were supporting until now, zip is a full multi-file container format and we are always only trying to read the first file listed in the archive. This likely means that this file was not meant to be opened this way. In any case, still try to load the first file as an image, yet raise a warning about the existence of more files in the archive. --- plug-ins/common/file-compressor.c | 12 +++++++++++- 1 file changed, 11 insertions(+), 1 deletion(-) diff --git a/plug-ins/common/file-compressor.c b/plug-ins/common/file-compressor.c index 763caeccdc..ede431a89a 100644 --- a/plug-ins/common/file-compressor.c +++ b/plug-ins/common/file-compressor.c @@ -1083,6 +1083,7 @@ zip_load (GFile *infile, if (r != ARCHIVE_OK) { archive_read_close (a); + archive_read_free (a); goto out; } @@ -1094,13 +1095,22 @@ zip_load (GFile *infile, if (r != ARCHIVE_OK) { archive_read_close (a); + archive_read_free (a); goto out; } - archive_entry_free (entry); ret = TRUE; + + if (archive_read_next_header (a, &entry) != ARCHIVE_EOF) + /* Leave a chance for the load to succeed (in case the first + * file happens to be an image file), yet still warns. This + * procedure expects that the archive contains a single + * file. + */ + g_message (_("This zip archive contains more than one file.")); } archive_read_close (a); + archive_read_free (a); } out: