Remember wether we cloned a struct zip_dirent, and use this information to correctly free it.
diff --git a/lib/zip_dirent.c b/lib/zip_dirent.c index 3c2f907..f4f2deb 100644 --- a/lib/zip_dirent.c +++ b/lib/zip_dirent.c
@@ -221,6 +221,7 @@ _zip_dirent_init(tde); tde->changed = 0; + tde->cloned = 1; return tde; } @@ -230,11 +231,11 @@ void _zip_dirent_finalize(struct zip_dirent *zde) { - if (zde->changed & ZIP_DIRENT_FILENAME) + if (!zde->cloned || zde->changed & ZIP_DIRENT_FILENAME) _zip_string_free(zde->filename); - if (zde->changed & ZIP_DIRENT_EXTRA_FIELD) + if (!zde->cloned || zde->changed & ZIP_DIRENT_EXTRA_FIELD) _zip_ef_free(zde->extra_fields); - if (zde->changed & ZIP_DIRENT_COMMENT) + if (!zde->cloned || zde->changed & ZIP_DIRENT_COMMENT) _zip_string_free(zde->comment); } @@ -257,6 +258,7 @@ { de->changed = 0; de->local_extra_fields_read = 0; + de->cloned = 0; de->version_madeby = 20; de->version_needed = 20; /* 2.0 */
diff --git a/lib/zipint.h b/lib/zipint.h index ca907d0..fa98b30 100644 --- a/lib/zipint.h +++ b/lib/zipint.h
@@ -295,6 +295,7 @@ struct zip_dirent { zip_uint32_t changed; int local_extra_fields_read; /* whether we already read in local header extra fields */ + int cloned; /* wether this instance is cloned, and thus shares non-changed strings */ zip_uint16_t version_madeby; /* (c) version of creator */ zip_uint16_t version_needed; /* (cl) version needed to extract */