Commit 01745181c for clamav.net

commit 01745181c7f6c712d015abc78fe4b756e094bc39
Author: Val S. <valsnyde@cisco.com>
Date:   Fri Aug 7 13:46:28 2026 -0400

    Libclamav: fix ZIP catalogue invalid free (#68)

    The ZIP local-header indexing path merges records from the central
    directory with records found by scanning local file headers. The merge used
    shallow struct copies, so the combined catalogue and source catalogues could
    share the same original_filename pointer.

    If overlap detection failed after the merge copied entries, cleanup could
    free the source catalogue names and then free the same pointers again from
    the combined catalogue.

    Add a small zip_record_move() helper and use it for the merge so ownership
    of original_filename transfers to the combined catalogue before any later
    cleanup.

    CLAM-3003

diff --git a/libclamav/unzip.c b/libclamav/unzip.c
index 07d118824..3c6938ffa 100644
--- a/libclamav/unzip.c
+++ b/libclamav/unzip.c
@@ -85,6 +85,15 @@ struct zip_record {
     char *original_filename;
 };

+/**
+ * @brief Move a zip record and its owned resources to another record.
+ */
+static void zip_record_move(struct zip_record *dst, struct zip_record *src)
+{
+    *dst = *src;
+    src->original_filename = NULL;
+}
+
 static int wrap_inflateinit2(void *a, int b)
 {
     return inflateInit2(a, b);
@@ -1561,11 +1570,15 @@ cl_error_t index_local_file_headers(
                 (temp_catalogue_offset < local_file_headers_count &&
                  temp_catalogue[temp_catalogue_offset].local_header_offset < (*catalogue)[catalogue_offset].local_header_offset)) {
                 // add entry from temp_catalogue into the list
-                combined_catalogue[i] = temp_catalogue[temp_catalogue_offset];
+                zip_record_move(
+                    &combined_catalogue[i],
+                    &temp_catalogue[temp_catalogue_offset]);
                 temp_catalogue_offset++;
             } else {
                 // add entry from the catalogue into the list
-                combined_catalogue[i] = (*catalogue)[catalogue_offset];
+                zip_record_move(
+                    &combined_catalogue[i],
+                    &((*catalogue)[catalogue_offset]));
                 catalogue_offset++;
             }