summaryrefslogtreecommitdiff
path: root/ext/zip/lib/zip_unchange.c
diff options
context:
space:
mode:
Diffstat (limited to 'ext/zip/lib/zip_unchange.c')
-rw-r--r--ext/zip/lib/zip_unchange.c32
1 files changed, 28 insertions, 4 deletions
diff --git a/ext/zip/lib/zip_unchange.c b/ext/zip/lib/zip_unchange.c
index 6c8a495c78..5ef5462127 100644
--- a/ext/zip/lib/zip_unchange.c
+++ b/ext/zip/lib/zip_unchange.c
@@ -1,6 +1,6 @@
/*
zip_unchange.c -- undo changes to file in zip archive
- Copyright (C) 1999-2014 Dieter Baron and Thomas Klausner
+ Copyright (C) 1999-2015 Dieter Baron and Thomas Klausner
This file is part of libzip, a library to manipulate ZIP archives.
The authors can be contacted at <libzip@nih.at>
@@ -48,6 +48,7 @@ int
_zip_unchange(zip_t *za, zip_uint64_t idx, int allow_duplicates)
{
zip_int64_t i;
+ const char *orig_name, *changed_name;
if (idx >= za->nentry) {
zip_error_set(&za->error, ZIP_ER_INVAL, 0);
@@ -55,9 +56,32 @@ _zip_unchange(zip_t *za, zip_uint64_t idx, int allow_duplicates)
}
if (!allow_duplicates && za->entry[idx].changes && (za->entry[idx].changes->changed & ZIP_DIRENT_FILENAME)) {
- i = _zip_name_locate(za, _zip_get_name(za, idx, ZIP_FL_UNCHANGED, NULL), 0, NULL);
- if (i >= 0 && (zip_uint64_t)i != idx) {
- zip_error_set(&za->error, ZIP_ER_EXISTS, 0);
+ if (za->entry[idx].orig != NULL) {
+ if ((orig_name=_zip_get_name(za, idx, ZIP_FL_UNCHANGED, &za->error)) == NULL) {
+ return -1;
+ }
+
+ i = _zip_name_locate(za, orig_name, 0, NULL);
+ if (i >= 0 && (zip_uint64_t)i != idx) {
+ zip_error_set(&za->error, ZIP_ER_EXISTS, 0);
+ return -1;
+ }
+ }
+ else {
+ orig_name = NULL;
+ }
+
+ if ((changed_name=_zip_get_name(za, idx, 0, &za->error)) == NULL) {
+ return -1;
+ }
+
+ if (orig_name) {
+ if (_zip_hash_add(za->names, (const zip_uint8_t *)orig_name, idx, 0, &za->error) == false) {
+ 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;
}
}