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 */