Restore old name in name hash table after unchanging delete.
Fixes problem reported in PR #285.
diff --git a/THANKS b/THANKS
index 2a6c58e..bca868e 100644
--- a/THANKS
+++ b/THANKS
@@ -66,6 +66,7 @@
Keith Jones <keith@keithjjones.com>
Khaled Mardam-Bey
Kohei Yoshida <kohei.yoshida@gmail.com>
+Krzesimir Nowak <qdlacz@gmail.com>
Leith Bade <leith@mapbox.com>
Lubomir I. Ivanov <neolit123@gmail.com>
Maël Nison
diff --git a/lib/zip_unchange.c b/lib/zip_unchange.c
index d80a6ad..6d29219 100644
--- a/lib/zip_unchange.c
+++ b/lib/zip_unchange.c
@@ -46,14 +46,18 @@
int
_zip_unchange(zip_t *za, zip_uint64_t idx, int allow_duplicates) {
zip_int64_t i;
- const char *orig_name, *changed_name;
+ bool renamed;
if (idx >= za->nentry) {
zip_error_set(&za->error, ZIP_ER_INVAL, 0);
return -1;
}
- if (!allow_duplicates && za->entry[idx].changes && (za->entry[idx].changes->changed & ZIP_DIRENT_FILENAME)) {
+ renamed = za->entry[idx].changes && (za->entry[idx].changes->changed & ZIP_DIRENT_FILENAME);
+ if (!allow_duplicates && (renamed || za->entry[idx].deleted)) {
+ const char *orig_name = NULL;
+ const char *changed_name = NULL;
+
if (za->entry[idx].orig != NULL) {
if ((orig_name = _zip_get_name(za, idx, ZIP_FL_UNCHANGED, &za->error)) == NULL) {
return -1;
@@ -65,12 +69,11 @@
return -1;
}
}
- else {
- orig_name = NULL;
- }
- if ((changed_name = _zip_get_name(za, idx, 0, &za->error)) == NULL) {
- return -1;
+ if (renamed) {
+ if ((changed_name = _zip_get_name(za, idx, 0, &za->error)) == NULL) {
+ return -1;
+ }
}
if (orig_name) {
@@ -78,9 +81,11 @@
return -1;
}
}
- if (_zip_hash_delete(za->names, (const zip_uint8_t *)changed_name, &za->error) == false) {
- _zip_hash_delete(za->names, (const zip_uint8_t *)orig_name, NULL);
- return -1;
+ if (changed_name) {
+ if (_zip_hash_delete(za->names, (const zip_uint8_t *)changed_name, &za->error) == false) {
+ _zip_hash_delete(za->names, (const zip_uint8_t *)orig_name, NULL);
+ return -1;
+ }
}
}
diff --git a/regress/unchange-delete-namelocate.test b/regress/unchange-delete-namelocate.test
new file mode 100644
index 0000000..96ce06f
--- /dev/null
+++ b/regress/unchange-delete-namelocate.test
@@ -0,0 +1,5 @@
+# namelocate after a file has been deleted and unchanged should succeed.
+args test2.zip delete 0 unchange 0 name_locate testfile.txt 0
+return 0
+file test2.zip test2.zip test2.zip
+stdout name 'testfile.txt' using flags '0' found at index 0