VeraCrypt
aboutsummaryrefslogtreecommitdiff
path: root/src/Common/libzip/zip_close.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/Common/libzip/zip_close.c')
-rw-r--r--src/Common/libzip/zip_close.c90
1 files changed, 58 insertions, 32 deletions
diff --git a/src/Common/libzip/zip_close.c b/src/Common/libzip/zip_close.c
index 8d1a2aa8..6b33cbf5 100644
--- a/src/Common/libzip/zip_close.c
+++ b/src/Common/libzip/zip_close.c
@@ -45,6 +45,7 @@
static int add_data(zip_t *, zip_source_t *, zip_dirent_t *, zip_uint32_t);
static int copy_data(zip_t *, zip_uint64_t);
static int copy_source(zip_t *, zip_source_t *, zip_int64_t);
+static int torrentzip_compare_names(const void *a, const void *b);
static int write_cdir(zip_t *, const zip_filelist_t *, zip_uint64_t);
static int write_data_descriptor(zip_t *za, const zip_dirent_t *dirent, int is_zip64);
@@ -61,12 +62,12 @@ zip_close(zip_t *za) {
changed = _zip_changed(za, &survivors);
- /* don't create zip files with no entries */
- if (survivors == 0) {
+ if (survivors == 0 && !(za->ch_flags & ZIP_AFL_CREATE_OR_KEEP_FILE_FOR_EMPTY_ARCHIVE)) {
+ /* don't create zip files with no entries */
if ((za->open_flags & ZIP_TRUNCATE) || changed) {
if (zip_source_remove(za->src) < 0) {
if (!((zip_error_code_zip(zip_source_error(za->src)) == ZIP_ER_REMOVE) && (zip_error_code_system(zip_source_error(za->src)) == ENOENT))) {
- _zip_error_set_from_source(&za->error, za->src);
+ zip_error_set_from_source(&za->error, za->src);
return -1;
}
}
@@ -75,7 +76,8 @@ zip_close(zip_t *za) {
return 0;
}
- if (!changed) {
+ /* Always write empty archive if we are told to keep it, otherwise it wouldn't be created if the file doesn't already exist. */
+ if (!changed && survivors > 0) {
zip_discard(za);
return 0;
}
@@ -105,6 +107,7 @@ zip_close(zip_t *za) {
}
filelist[j].idx = i;
+ filelist[j].name = zip_get_name(za, i, 0);
j++;
}
if (j < survivors) {
@@ -113,7 +116,11 @@ zip_close(zip_t *za) {
return -1;
}
- if ((zip_source_supports(za->src) & ZIP_SOURCE_MAKE_COMMAND_BITMASK(ZIP_SOURCE_BEGIN_WRITE_CLONING)) == 0) {
+ if (ZIP_WANT_TORRENTZIP(za)) {
+ qsort(filelist, (size_t)survivors, sizeof(filelist[0]), torrentzip_compare_names);
+ }
+
+ if (ZIP_WANT_TORRENTZIP(za) || (zip_source_supports(za->src) & ZIP_SOURCE_MAKE_COMMAND_BITMASK(ZIP_SOURCE_BEGIN_WRITE_CLONING)) == 0) {
unchanged_offset = 0;
}
else {
@@ -146,7 +153,7 @@ zip_close(zip_t *za) {
}
if (unchanged_offset == 0) {
if (zip_source_begin_write(za->src) < 0) {
- _zip_error_set_from_source(&za->error, za->src);
+ zip_error_set_from_source(&za->error, za->src);
free(filelist);
return -1;
}
@@ -178,7 +185,7 @@ zip_close(zip_t *za) {
continue;
}
- new_data = (ZIP_ENTRY_DATA_CHANGED(entry) || ZIP_ENTRY_CHANGED(entry, ZIP_DIRENT_COMP_METHOD) || ZIP_ENTRY_CHANGED(entry, ZIP_DIRENT_ENCRYPTION_METHOD));
+ new_data = (ZIP_ENTRY_DATA_CHANGED(entry) || ZIP_ENTRY_CHANGED(entry, ZIP_DIRENT_COMP_METHOD) || ZIP_ENTRY_CHANGED(entry, ZIP_DIRENT_ENCRYPTION_METHOD)) || (ZIP_WANT_TORRENTZIP(za) && !ZIP_IS_TORRENTZIP(za));
/* create new local directory entry */
if (entry->changes == NULL) {
@@ -195,8 +202,12 @@ zip_close(zip_t *za) {
break;
}
+ if (ZIP_WANT_TORRENTZIP(za)) {
+ zip_dirent_torrentzip_normalize(entry->changes);
+ }
+
if ((off = zip_source_tell_write(za->src)) < 0) {
- _zip_error_set_from_source(&za->error, za->src);
+ zip_error_set_from_source(&za->error, za->src);
error = 1;
break;
}
@@ -207,7 +218,7 @@ zip_close(zip_t *za) {
zs = NULL;
if (!ZIP_ENTRY_DATA_CHANGED(entry)) {
- if ((zs = _zip_source_zip_new(za, i, ZIP_FL_UNCHANGED, 0, 0, NULL, &za->error)) == NULL) {
+ if ((zs = zip_source_zip_file_create(za, i, ZIP_FL_UNCHANGED, 0, -1, NULL, &za->error)) == NULL) {
error = 1;
break;
}
@@ -240,7 +251,7 @@ zip_close(zip_t *za) {
break;
}
if (zip_source_seek(za->src, (zip_int64_t)offset, SEEK_SET) < 0) {
- _zip_error_set_from_source(&za->error, za->src);
+ zip_error_set_from_source(&za->error, za->src);
error = 1;
break;
}
@@ -267,7 +278,7 @@ zip_close(zip_t *za) {
if (!error) {
if (zip_source_commit_write(za->src) != 0) {
- _zip_error_set_from_source(&za->error, za->src);
+ zip_error_set_from_source(&za->error, za->src);
error = 1;
}
_zip_progress_end(za->progress);
@@ -296,7 +307,7 @@ add_data(zip_t *za, zip_source_t *src, zip_dirent_t *de, zip_uint32_t changed) {
bool needs_recompress, needs_decompress, needs_crc, needs_compress, needs_reencrypt, needs_decrypt, needs_encrypt;
if (zip_source_stat(src, &st) < 0) {
- _zip_error_set_from_source(&za->error, src);
+ zip_error_set_from_source(&za->error, src);
return -1;
}
@@ -324,6 +335,7 @@ add_data(zip_t *za, zip_source_t *src, zip_dirent_t *de, zip_uint32_t changed) {
flags = ZIP_EF_LOCAL;
if ((st.valid & ZIP_STAT_SIZE) == 0) {
+ /* TODO: not valid for torrentzip */
flags |= ZIP_FL_FORCE_ZIP64;
data_length = -1;
}
@@ -350,6 +362,7 @@ add_data(zip_t *za, zip_source_t *src, zip_dirent_t *de, zip_uint32_t changed) {
}
if (max_compressed_size > 0xffffffffu) {
+ /* TODO: not valid for torrentzip */
flags |= ZIP_FL_FORCE_ZIP64;
}
}
@@ -360,7 +373,7 @@ add_data(zip_t *za, zip_source_t *src, zip_dirent_t *de, zip_uint32_t changed) {
}
if ((offstart = zip_source_tell_write(za->src)) < 0) {
- _zip_error_set_from_source(&za->error, za->src);
+ zip_error_set_from_source(&za->error, za->src);
return -1;
}
@@ -370,7 +383,7 @@ add_data(zip_t *za, zip_source_t *src, zip_dirent_t *de, zip_uint32_t changed) {
return -1;
}
- needs_recompress = st.comp_method != ZIP_CM_ACTUAL(de->comp_method);
+ needs_recompress = ZIP_WANT_TORRENTZIP(za) || st.comp_method != ZIP_CM_ACTUAL(de->comp_method);
needs_decompress = needs_recompress && (st.comp_method != ZIP_CM_STORE);
/* in these cases we can compute the CRC ourselves, so we do */
needs_crc = (st.comp_method == ZIP_CM_STORE) || needs_decompress;
@@ -397,7 +410,6 @@ add_data(zip_t *za, zip_source_t *src, zip_dirent_t *de, zip_uint32_t changed) {
return -1;
}
- zip_source_free(src_final);
src_final = src_tmp;
}
@@ -407,7 +419,6 @@ add_data(zip_t *za, zip_source_t *src, zip_dirent_t *de, zip_uint32_t changed) {
return -1;
}
- zip_source_free(src_final);
src_final = src_tmp;
}
@@ -417,7 +428,6 @@ add_data(zip_t *za, zip_source_t *src, zip_dirent_t *de, zip_uint32_t changed) {
return -1;
}
- zip_source_free(src_final);
src_final = src_tmp;
}
@@ -427,7 +437,6 @@ add_data(zip_t *za, zip_source_t *src, zip_dirent_t *de, zip_uint32_t changed) {
return -1;
}
- zip_source_free(src_final);
src_final = src_tmp;
}
@@ -458,11 +467,10 @@ add_data(zip_t *za, zip_source_t *src, zip_dirent_t *de, zip_uint32_t changed) {
zip_stat_init(&st_mtime);
st_mtime.valid = ZIP_STAT_MTIME;
st_mtime.mtime = de->last_mod;
- if ((src_tmp = _zip_source_window_new(src_final, 0, -1, &st_mtime, NULL, NULL, 0, &za->error)) == NULL) {
+ if ((src_tmp = _zip_source_window_new(src_final, 0, -1, &st_mtime, 0, NULL, NULL, 0, true, &za->error)) == NULL) {
zip_source_free(src_final);
return -1;
}
- zip_source_free(src_final);
src_final = src_tmp;
}
}
@@ -473,25 +481,24 @@ add_data(zip_t *za, zip_source_t *src, zip_dirent_t *de, zip_uint32_t changed) {
return -1;
}
- zip_source_free(src_final);
src_final = src_tmp;
}
if ((offdata = zip_source_tell_write(za->src)) < 0) {
- _zip_error_set_from_source(&za->error, za->src);
+ zip_error_set_from_source(&za->error, za->src);
return -1;
}
ret = copy_source(za, src_final, data_length);
if (zip_source_stat(src_final, &st) < 0) {
- _zip_error_set_from_source(&za->error, src_final);
+ zip_error_set_from_source(&za->error, src_final);
ret = -1;
}
if (zip_source_get_file_attributes(src_final, &attributes) != 0) {
- _zip_error_set_from_source(&za->error, src_final);
+ zip_error_set_from_source(&za->error, src_final);
ret = -1;
}
@@ -502,12 +509,12 @@ add_data(zip_t *za, zip_source_t *src, zip_dirent_t *de, zip_uint32_t changed) {
}
if ((offend = zip_source_tell_write(za->src)) < 0) {
- _zip_error_set_from_source(&za->error, za->src);
+ zip_error_set_from_source(&za->error, za->src);
return -1;
}
if (zip_source_seek_write(za->src, offstart, SEEK_SET) < 0) {
- _zip_error_set_from_source(&za->error, za->src);
+ zip_error_set_from_source(&za->error, za->src);
return -1;
}
@@ -528,6 +535,10 @@ add_data(zip_t *za, zip_source_t *src, zip_dirent_t *de, zip_uint32_t changed) {
de->comp_size = (zip_uint64_t)(offend - offdata);
_zip_dirent_apply_attributes(de, &attributes, (flags & ZIP_FL_FORCE_ZIP64) != 0, changed);
+ if (ZIP_WANT_TORRENTZIP(za)) {
+ zip_dirent_torrentzip_normalize(de);
+ }
+
if ((ret = _zip_dirent_write(za, de, flags)) < 0)
return -1;
@@ -538,7 +549,7 @@ add_data(zip_t *za, zip_source_t *src, zip_dirent_t *de, zip_uint32_t changed) {
}
if (zip_source_seek_write(za->src, offend, SEEK_SET) < 0) {
- _zip_error_set_from_source(&za->error, za->src);
+ zip_error_set_from_source(&za->error, za->src);
return -1;
}
@@ -555,7 +566,6 @@ add_data(zip_t *za, zip_source_t *src, zip_dirent_t *de, zip_uint32_t changed) {
static int
copy_data(zip_t *za, zip_uint64_t len) {
DEFINE_BYTE_ARRAY(buf, BUFSIZE);
- size_t n;
double total = (double)len;
if (!byte_array_init(buf, BUFSIZE)) {
@@ -564,7 +574,8 @@ copy_data(zip_t *za, zip_uint64_t len) {
}
while (len > 0) {
- n = len > BUFSIZE ? BUFSIZE : len;
+ zip_uint64_t n = ZIP_MIN(len, BUFSIZE);
+
if (_zip_read(za->src, buf, n, &za->error) < 0) {
byte_array_fini(buf);
return -1;
@@ -595,7 +606,7 @@ copy_source(zip_t *za, zip_source_t *src, zip_int64_t data_length) {
int ret;
if (zip_source_open(src) < 0) {
- _zip_error_set_from_source(&za->error, src);
+ zip_error_set_from_source(&za->error, src);
return -1;
}
@@ -622,7 +633,7 @@ copy_source(zip_t *za, zip_source_t *src, zip_int64_t data_length) {
}
if (n < 0) {
- _zip_error_set_from_source(&za->error, src);
+ zip_error_set_from_source(&za->error, src);
ret = -1;
}
@@ -659,7 +670,7 @@ _zip_changed(const zip_t *za, zip_uint64_t *survivorsp) {
changed = 0;
survivors = 0;
- if (za->comment_changed || za->ch_flags != za->flags) {
+ if (za->comment_changed || (ZIP_WANT_TORRENTZIP(za) && !ZIP_IS_TORRENTZIP(za))) {
changed = 1;
}
@@ -712,3 +723,18 @@ write_data_descriptor(zip_t *za, const zip_dirent_t *de, int is_zip64) {
return ret;
}
+
+
+static int torrentzip_compare_names(const void *a, const void *b) {
+ const char *aname = ((const zip_filelist_t *)a)->name;
+ const char *bname = ((const zip_filelist_t *)b)->name;
+
+ if (aname == NULL) {
+ return (bname != NULL) * -1;
+ }
+ else if (bname == NULL) {
+ return 1;
+ }
+
+ return strcasecmp(aname, bname);
+} \ No newline at end of file