diff options
Diffstat (limited to 'src/Common/libzip/zip_close.c')
-rw-r--r-- | src/Common/libzip/zip_close.c | 743 |
1 files changed, 377 insertions, 366 deletions
diff --git a/src/Common/libzip/zip_close.c b/src/Common/libzip/zip_close.c index 816fcefa..8d1a2aa8 100644 --- a/src/Common/libzip/zip_close.c +++ b/src/Common/libzip/zip_close.c @@ -1,9 +1,9 @@ /* zip_close.c -- close zip archive and update changes - Copyright (C) 1999-2020 Dieter Baron and Thomas Klausner + Copyright (C) 1999-2022 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> + The authors can be contacted at <info@libzip.org> Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions @@ -57,225 +57,225 @@ zip_close(zip_t *za) { int changed; if (za == NULL) - return -1; + return -1; changed = _zip_changed(za, &survivors); /* don't create zip files with no entries */ if (survivors == 0) { - 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); - return -1; - } - } - } - zip_discard(za); - return 0; + 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); + return -1; + } + } + } + zip_discard(za); + return 0; } if (!changed) { - zip_discard(za); - return 0; + zip_discard(za); + return 0; } if (survivors > za->nentry) { - zip_error_set(&za->error, ZIP_ER_INTERNAL, 0); - return -1; + zip_error_set(&za->error, ZIP_ER_INTERNAL, 0); + return -1; } if ((filelist = (zip_filelist_t *)malloc(sizeof(filelist[0]) * (size_t)survivors)) == NULL) - return -1; + return -1; unchanged_offset = ZIP_UINT64_MAX; /* create list of files with index into original archive */ for (i = j = 0; i < za->nentry; i++) { - if (za->entry[i].orig != NULL && ZIP_ENTRY_HAS_CHANGES(&za->entry[i])) { - unchanged_offset = ZIP_MIN(unchanged_offset, za->entry[i].orig->offset); - } - if (za->entry[i].deleted) { - continue; - } - - if (j >= survivors) { - free(filelist); - zip_error_set(&za->error, ZIP_ER_INTERNAL, 0); - return -1; - } - - filelist[j].idx = i; - j++; + if (za->entry[i].orig != NULL && ZIP_ENTRY_HAS_CHANGES(&za->entry[i])) { + unchanged_offset = ZIP_MIN(unchanged_offset, za->entry[i].orig->offset); + } + if (za->entry[i].deleted) { + continue; + } + + if (j >= survivors) { + free(filelist); + zip_error_set(&za->error, ZIP_ER_INTERNAL, 0); + return -1; + } + + filelist[j].idx = i; + j++; } if (j < survivors) { - free(filelist); - zip_error_set(&za->error, ZIP_ER_INTERNAL, 0); - return -1; + free(filelist); + zip_error_set(&za->error, ZIP_ER_INTERNAL, 0); + return -1; } if ((zip_source_supports(za->src) & ZIP_SOURCE_MAKE_COMMAND_BITMASK(ZIP_SOURCE_BEGIN_WRITE_CLONING)) == 0) { - unchanged_offset = 0; + unchanged_offset = 0; } else { - if (unchanged_offset == ZIP_UINT64_MAX) { - /* we're keeping all file data, find the end of the last one */ - zip_uint64_t last_index = ZIP_UINT64_MAX; - unchanged_offset = 0; - - for (i = 0; i < za->nentry; i++) { - if (za->entry[i].orig != NULL) { - if (za->entry[i].orig->offset >= unchanged_offset) { - unchanged_offset = za->entry[i].orig->offset; - last_index = i; - } - } - } - if (last_index != ZIP_UINT64_MAX) { - if ((unchanged_offset = _zip_file_get_end(za, last_index, &za->error)) == 0) { - free(filelist); - return -1; - } - } - } - if (unchanged_offset > 0) { - if (zip_source_begin_write_cloning(za->src, unchanged_offset) < 0) { - /* cloning not supported, need to copy everything */ - unchanged_offset = 0; - } - } + if (unchanged_offset == ZIP_UINT64_MAX) { + /* we're keeping all file data, find the end of the last one */ + zip_uint64_t last_index = ZIP_UINT64_MAX; + unchanged_offset = 0; + + for (i = 0; i < za->nentry; i++) { + if (za->entry[i].orig != NULL) { + if (za->entry[i].orig->offset >= unchanged_offset) { + unchanged_offset = za->entry[i].orig->offset; + last_index = i; + } + } + } + if (last_index != ZIP_UINT64_MAX) { + if ((unchanged_offset = _zip_file_get_end(za, last_index, &za->error)) == 0) { + free(filelist); + return -1; + } + } + } + if (unchanged_offset > 0) { + if (zip_source_begin_write_cloning(za->src, unchanged_offset) < 0) { + /* cloning not supported, need to copy everything */ + unchanged_offset = 0; + } + } } if (unchanged_offset == 0) { - if (zip_source_begin_write(za->src) < 0) { - _zip_error_set_from_source(&za->error, za->src); - free(filelist); - return -1; - } + if (zip_source_begin_write(za->src) < 0) { + _zip_error_set_from_source(&za->error, za->src); + free(filelist); + return -1; + } } if (_zip_progress_start(za->progress) != 0) { - zip_error_set(&za->error, ZIP_ER_CANCELLED, 0); - zip_source_rollback_write(za->src); - free(filelist); - return -1; + zip_error_set(&za->error, ZIP_ER_CANCELLED, 0); + zip_source_rollback_write(za->src); + free(filelist); + return -1; } error = 0; for (j = 0; j < survivors; j++) { - int new_data; - zip_entry_t *entry; - zip_dirent_t *de; - - if (_zip_progress_subrange(za->progress, (double)j / (double)survivors, (double)(j + 1) / (double)survivors) != 0) { - zip_error_set(&za->error, ZIP_ER_CANCELLED, 0); - error = 1; - break; - } - - i = filelist[j].idx; - entry = za->entry + i; - - if (entry->orig != NULL && entry->orig->offset < unchanged_offset) { - /* already implicitly copied by cloning */ - continue; - } - - new_data = (ZIP_ENTRY_DATA_CHANGED(entry) || ZIP_ENTRY_CHANGED(entry, ZIP_DIRENT_COMP_METHOD) || ZIP_ENTRY_CHANGED(entry, ZIP_DIRENT_ENCRYPTION_METHOD)); - - /* create new local directory entry */ - if (entry->changes == NULL) { - if ((entry->changes = _zip_dirent_clone(entry->orig)) == NULL) { - zip_error_set(&za->error, ZIP_ER_MEMORY, 0); - error = 1; - break; - } - } - de = entry->changes; - - if (_zip_read_local_ef(za, i) < 0) { - error = 1; - break; - } - - if ((off = zip_source_tell_write(za->src)) < 0) { + int new_data; + zip_entry_t *entry; + zip_dirent_t *de; + + if (_zip_progress_subrange(za->progress, (double)j / (double)survivors, (double)(j + 1) / (double)survivors) != 0) { + zip_error_set(&za->error, ZIP_ER_CANCELLED, 0); + error = 1; + break; + } + + i = filelist[j].idx; + entry = za->entry + i; + + if (entry->orig != NULL && entry->orig->offset < unchanged_offset) { + /* already implicitly copied by cloning */ + continue; + } + + new_data = (ZIP_ENTRY_DATA_CHANGED(entry) || ZIP_ENTRY_CHANGED(entry, ZIP_DIRENT_COMP_METHOD) || ZIP_ENTRY_CHANGED(entry, ZIP_DIRENT_ENCRYPTION_METHOD)); + + /* create new local directory entry */ + if (entry->changes == NULL) { + if ((entry->changes = _zip_dirent_clone(entry->orig)) == NULL) { + zip_error_set(&za->error, ZIP_ER_MEMORY, 0); + error = 1; + break; + } + } + de = entry->changes; + + if (_zip_read_local_ef(za, i) < 0) { + error = 1; + break; + } + + if ((off = zip_source_tell_write(za->src)) < 0) { _zip_error_set_from_source(&za->error, za->src); - error = 1; - break; - } - de->offset = (zip_uint64_t)off; - - if (new_data) { - zip_source_t *zs; - - zs = NULL; - if (!ZIP_ENTRY_DATA_CHANGED(entry)) { - if ((zs = _zip_source_zip_new(za, za, i, ZIP_FL_UNCHANGED, 0, 0, NULL)) == NULL) { - error = 1; - break; - } - } - - /* add_data writes dirent */ - if (add_data(za, zs ? zs : entry->source, de, entry->changes ? entry->changes->changed : 0) < 0) { - error = 1; - if (zs) - zip_source_free(zs); - break; - } - if (zs) - zip_source_free(zs); - } - else { - zip_uint64_t offset; - - if (de->encryption_method != ZIP_EM_TRAD_PKWARE) { - /* when copying data, all sizes are known -> no data descriptor needed */ - /* except for PKWare encryption, where removing the data descriptor breaks password validation */ - de->bitflags &= (zip_uint16_t)~ZIP_GPBF_DATA_DESCRIPTOR; - } - if (_zip_dirent_write(za, de, ZIP_FL_LOCAL) < 0) { - error = 1; - break; - } - if ((offset = _zip_file_get_offset(za, i, &za->error)) == 0) { - error = 1; - break; - } - if (zip_source_seek(za->src, (zip_int64_t)offset, SEEK_SET) < 0) { - _zip_error_set_from_source(&za->error, za->src); + error = 1; + break; + } + de->offset = (zip_uint64_t)off; + + if (new_data) { + zip_source_t *zs; + + 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) { + error = 1; + break; + } + } + + /* add_data writes dirent */ + if (add_data(za, zs ? zs : entry->source, de, entry->changes ? entry->changes->changed : 0) < 0) { + error = 1; + if (zs) + zip_source_free(zs); + break; + } + if (zs) + zip_source_free(zs); + } + else { + zip_uint64_t offset; + + if (de->encryption_method != ZIP_EM_TRAD_PKWARE) { + /* when copying data, all sizes are known -> no data descriptor needed */ + /* except for PKWare encryption, where removing the data descriptor breaks password validation */ + de->bitflags &= (zip_uint16_t)~ZIP_GPBF_DATA_DESCRIPTOR; + } + if (_zip_dirent_write(za, de, ZIP_FL_LOCAL) < 0) { error = 1; - break; - } - if (copy_data(za, de->comp_size) < 0) { - error = 1; - break; - } - - if (de->bitflags & ZIP_GPBF_DATA_DESCRIPTOR) { - if (write_data_descriptor(za, de, _zip_dirent_needs_zip64(de, 0)) < 0) { - error = 1; - break; - } - } - } + break; + } + if ((offset = _zip_file_get_offset(za, i, &za->error)) == 0) { + error = 1; + break; + } + if (zip_source_seek(za->src, (zip_int64_t)offset, SEEK_SET) < 0) { + _zip_error_set_from_source(&za->error, za->src); + error = 1; + break; + } + if (copy_data(za, de->comp_size) < 0) { + error = 1; + break; + } + + if (de->bitflags & ZIP_GPBF_DATA_DESCRIPTOR) { + if (write_data_descriptor(za, de, _zip_dirent_needs_zip64(de, 0)) < 0) { + error = 1; + break; + } + } + } } if (!error) { - if (write_cdir(za, filelist, survivors) < 0) - error = 1; + if (write_cdir(za, filelist, survivors) < 0) + error = 1; } free(filelist); if (!error) { - if (zip_source_commit_write(za->src) != 0) { - _zip_error_set_from_source(&za->error, za->src); - error = 1; - } - _zip_progress_end(za->progress); + if (zip_source_commit_write(za->src) != 0) { + _zip_error_set_from_source(&za->error, za->src); + error = 1; + } + _zip_progress_end(za->progress); } if (error) { - zip_source_rollback_write(za->src); - return -1; + zip_source_rollback_write(za->src); + return -1; } zip_discard(za); @@ -296,86 +296,83 @@ 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); - return -1; + _zip_error_set_from_source(&za->error, src); + return -1; } if ((st.valid & ZIP_STAT_COMP_METHOD) == 0) { - st.valid |= ZIP_STAT_COMP_METHOD; - st.comp_method = ZIP_CM_STORE; + st.valid |= ZIP_STAT_COMP_METHOD; + st.comp_method = ZIP_CM_STORE; } if (ZIP_CM_IS_DEFAULT(de->comp_method) && st.comp_method != ZIP_CM_STORE) - de->comp_method = st.comp_method; + de->comp_method = st.comp_method; else if (de->comp_method == ZIP_CM_STORE && (st.valid & ZIP_STAT_SIZE)) { - st.valid |= ZIP_STAT_COMP_SIZE; - st.comp_size = st.size; + st.valid |= ZIP_STAT_COMP_SIZE; + st.comp_size = st.size; } else { - /* we'll recompress */ - st.valid &= ~ZIP_STAT_COMP_SIZE; + /* we'll recompress */ + st.valid &= ~ZIP_STAT_COMP_SIZE; } if ((st.valid & ZIP_STAT_ENCRYPTION_METHOD) == 0) { - st.valid |= ZIP_STAT_ENCRYPTION_METHOD; - st.encryption_method = ZIP_EM_NONE; + st.valid |= ZIP_STAT_ENCRYPTION_METHOD; + st.encryption_method = ZIP_EM_NONE; } flags = ZIP_EF_LOCAL; if ((st.valid & ZIP_STAT_SIZE) == 0) { - flags |= ZIP_FL_FORCE_ZIP64; - data_length = -1; + flags |= ZIP_FL_FORCE_ZIP64; + data_length = -1; } else { - de->uncomp_size = st.size; - /* this is technically incorrect (copy_source counts compressed data), but it's the best we have */ - data_length = (zip_int64_t)st.size; - - if ((st.valid & ZIP_STAT_COMP_SIZE) == 0) { - zip_uint64_t max_size; - - switch (ZIP_CM_ACTUAL(de->comp_method)) { - case ZIP_CM_BZIP2: - /* computed by looking at increase of 10 random files of size 1MB when - * compressed with bzip2, rounded up: 1.006 */ - max_size = 4269351188u; - break; - - case ZIP_CM_DEFLATE: - /* max deflate size increase: size + ceil(size/16k)*5+6 */ - max_size = 4293656963u; - break; - - case ZIP_CM_STORE: - max_size = 0xffffffffu; - break; - - default: - max_size = 0; - } - - if (st.size > max_size) { - flags |= ZIP_FL_FORCE_ZIP64; - } - } - else - de->comp_size = st.comp_size; + de->uncomp_size = st.size; + /* this is technically incorrect (copy_source counts compressed data), but it's the best we have */ + data_length = (zip_int64_t)st.size; + + if ((st.valid & ZIP_STAT_COMP_SIZE) == 0) { + zip_uint64_t max_compressed_size; + zip_uint16_t compression_method = ZIP_CM_ACTUAL(de->comp_method); + + if (compression_method == ZIP_CM_STORE) { + max_compressed_size = st.size; + } + else { + zip_compression_algorithm_t *algorithm = _zip_get_compression_algorithm(compression_method, true); + if (algorithm == NULL) { + max_compressed_size = ZIP_UINT64_MAX; + } + else { + max_compressed_size = algorithm->maximum_compressed_size(st.size); + } + } + + if (max_compressed_size > 0xffffffffu) { + flags |= ZIP_FL_FORCE_ZIP64; + } + } + else { + de->comp_size = st.comp_size; + data_length = (zip_int64_t)st.comp_size; + } } if ((offstart = zip_source_tell_write(za->src)) < 0) { - _zip_error_set_from_source(&za->error, za->src); - return -1; + _zip_error_set_from_source(&za->error, za->src); + return -1; } /* as long as we don't support non-seekable output, clear data descriptor bit */ de->bitflags &= (zip_uint16_t)~ZIP_GPBF_DATA_DESCRIPTOR; if ((is_zip64 = _zip_dirent_write(za, de, flags)) < 0) { - return -1; + return -1; } needs_recompress = 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; needs_compress = needs_recompress && (de->comp_method != ZIP_CM_STORE); @@ -387,127 +384,143 @@ add_data(zip_t *za, zip_source_t *src, zip_dirent_t *de, zip_uint32_t changed) { zip_source_keep(src_final); if (needs_decrypt) { - zip_encryption_implementation impl; + zip_encryption_implementation impl; - if ((impl = _zip_get_encryption_implementation(st.encryption_method, ZIP_CODEC_DECODE)) == NULL) { - zip_error_set(&za->error, ZIP_ER_ENCRNOTSUPP, 0); - zip_source_free(src_final); - return -1; - } - if ((src_tmp = impl(za, src_final, st.encryption_method, ZIP_CODEC_DECODE, za->default_password)) == NULL) { - /* error set by impl */ - zip_source_free(src_final); - return -1; - } + if ((impl = _zip_get_encryption_implementation(st.encryption_method, ZIP_CODEC_DECODE)) == NULL) { + zip_error_set(&za->error, ZIP_ER_ENCRNOTSUPP, 0); + zip_source_free(src_final); + return -1; + } + if ((src_tmp = impl(za, src_final, st.encryption_method, ZIP_CODEC_DECODE, za->default_password)) == NULL) { + /* error set by impl */ + zip_source_free(src_final); + return -1; + } - zip_source_free(src_final); - src_final = src_tmp; + zip_source_free(src_final); + src_final = src_tmp; } if (needs_decompress) { - if ((src_tmp = zip_source_decompress(za, src_final, st.comp_method)) == NULL) { - zip_source_free(src_final); - return -1; - } + if ((src_tmp = zip_source_decompress(za, src_final, st.comp_method)) == NULL) { + zip_source_free(src_final); + return -1; + } - zip_source_free(src_final); - src_final = src_tmp; + zip_source_free(src_final); + src_final = src_tmp; } if (needs_crc) { - if ((src_tmp = zip_source_crc(za, src_final, 0)) == NULL) { - zip_source_free(src_final); - return -1; - } + if ((src_tmp = zip_source_crc_create(src_final, 0, &za->error)) == NULL) { + zip_source_free(src_final); + return -1; + } - zip_source_free(src_final); - src_final = src_tmp; + zip_source_free(src_final); + src_final = src_tmp; } if (needs_compress) { - if ((src_tmp = zip_source_compress(za, src_final, de->comp_method, de->compression_level)) == NULL) { - zip_source_free(src_final); - return -1; - } + if ((src_tmp = zip_source_compress(za, src_final, de->comp_method, de->compression_level)) == NULL) { + zip_source_free(src_final); + return -1; + } - zip_source_free(src_final); - src_final = src_tmp; + zip_source_free(src_final); + src_final = src_tmp; } if (needs_encrypt) { - zip_encryption_implementation impl; - const char *password = NULL; - - if (de->password) { - password = de->password; - } - else if (za->default_password) { - password = za->default_password; - } - - if ((impl = _zip_get_encryption_implementation(de->encryption_method, ZIP_CODEC_ENCODE)) == NULL) { - zip_error_set(&za->error, ZIP_ER_ENCRNOTSUPP, 0); - zip_source_free(src_final); - return -1; - } - if ((src_tmp = impl(za, src_final, de->encryption_method, ZIP_CODEC_ENCODE, password)) == NULL) { - /* error set by impl */ - zip_source_free(src_final); - return -1; - } - if (de->encryption_method == ZIP_EM_TRAD_PKWARE) { - de->bitflags |= ZIP_GPBF_DATA_DESCRIPTOR; - } - - zip_source_free(src_final); - src_final = src_tmp; + zip_encryption_implementation impl; + const char *password = NULL; + + if (de->password) { + password = de->password; + } + else if (za->default_password) { + password = za->default_password; + } + + if ((impl = _zip_get_encryption_implementation(de->encryption_method, ZIP_CODEC_ENCODE)) == NULL) { + zip_error_set(&za->error, ZIP_ER_ENCRNOTSUPP, 0); + zip_source_free(src_final); + return -1; + } + + if (de->encryption_method == ZIP_EM_TRAD_PKWARE) { + de->bitflags |= ZIP_GPBF_DATA_DESCRIPTOR; + + /* PKWare encryption uses last_mod, make sure it gets the right value. */ + if (de->changed & ZIP_DIRENT_LAST_MOD) { + zip_stat_t st_mtime; + 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) { + zip_source_free(src_final); + return -1; + } + zip_source_free(src_final); + src_final = src_tmp; + } + } + + if ((src_tmp = impl(za, src_final, de->encryption_method, ZIP_CODEC_ENCODE, password)) == NULL) { + /* error set by impl */ + zip_source_free(src_final); + 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); - return -1; + _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); - ret = -1; + _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); - ret = -1; + _zip_error_set_from_source(&za->error, src_final); + ret = -1; } zip_source_free(src_final); if (ret < 0) { - return -1; + return -1; } if ((offend = zip_source_tell_write(za->src)) < 0) { - _zip_error_set_from_source(&za->error, za->src); - return -1; + _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); - return -1; + _zip_error_set_from_source(&za->error, za->src); + return -1; } if ((st.valid & (ZIP_STAT_COMP_METHOD | ZIP_STAT_CRC | ZIP_STAT_SIZE)) != (ZIP_STAT_COMP_METHOD | ZIP_STAT_CRC | ZIP_STAT_SIZE)) { - zip_error_set(&za->error, ZIP_ER_INTERNAL, 0); - return -1; + zip_error_set(&za->error, ZIP_ER_INTERNAL, 0); + return -1; } if ((de->changed & ZIP_DIRENT_LAST_MOD) == 0) { - if (st.valid & ZIP_STAT_MTIME) - de->last_mod = st.mtime; - else - time(&de->last_mod); + if (st.valid & ZIP_STAT_MTIME) + de->last_mod = st.mtime; + else + time(&de->last_mod); } de->comp_method = st.comp_method; de->crc = st.crc; @@ -516,23 +529,23 @@ add_data(zip_t *za, zip_source_t *src, zip_dirent_t *de, zip_uint32_t changed) { _zip_dirent_apply_attributes(de, &attributes, (flags & ZIP_FL_FORCE_ZIP64) != 0, changed); if ((ret = _zip_dirent_write(za, de, flags)) < 0) - return -1; + return -1; if (is_zip64 != ret) { - /* Zip64 mismatch between preliminary file header written before data and final file header written afterwards */ - zip_error_set(&za->error, ZIP_ER_INTERNAL, 0); - return -1; + /* Zip64 mismatch between preliminary file header written before data and final file header written afterwards */ + zip_error_set(&za->error, ZIP_ER_INTERNAL, 0); + return -1; } if (zip_source_seek_write(za->src, offend, SEEK_SET) < 0) { - _zip_error_set_from_source(&za->error, za->src); - return -1; + _zip_error_set_from_source(&za->error, za->src); + return -1; } if (de->bitflags & ZIP_GPBF_DATA_DESCRIPTOR) { - if (write_data_descriptor(za, de, is_zip64) < 0) { - return -1; - } + if (write_data_descriptor(za, de, is_zip64) < 0) { + return -1; + } } return 0; @@ -546,28 +559,28 @@ copy_data(zip_t *za, zip_uint64_t len) { double total = (double)len; if (!byte_array_init(buf, BUFSIZE)) { - zip_error_set(&za->error, ZIP_ER_MEMORY, 0); - return -1; + zip_error_set(&za->error, ZIP_ER_MEMORY, 0); + return -1; } while (len > 0) { - n = len > BUFSIZE ? BUFSIZE : len; - if (_zip_read(za->src, buf, n, &za->error) < 0) { - byte_array_fini(buf); - return -1; - } + n = len > BUFSIZE ? BUFSIZE : len; + if (_zip_read(za->src, buf, n, &za->error) < 0) { + byte_array_fini(buf); + return -1; + } - if (_zip_write(za, buf, n) < 0) { - byte_array_fini(buf); - return -1; - } + if (_zip_write(za, buf, n) < 0) { + byte_array_fini(buf); + return -1; + } - len -= n; + len -= n; - if (_zip_progress_update(za->progress, (total - (double)len) / total) != 0) { - zip_error_set(&za->error, ZIP_ER_CANCELLED, 0); - return -1; - } + if (_zip_progress_update(za->progress, (total - (double)len) / total) != 0) { + zip_error_set(&za->error, ZIP_ER_CANCELLED, 0); + return -1; + } } byte_array_fini(buf); @@ -582,35 +595,35 @@ 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); - return -1; + _zip_error_set_from_source(&za->error, src); + return -1; } if (!byte_array_init(buf, BUFSIZE)) { - zip_error_set(&za->error, ZIP_ER_MEMORY, 0); - return -1; + zip_error_set(&za->error, ZIP_ER_MEMORY, 0); + return -1; } ret = 0; current = 0; while ((n = zip_source_read(src, buf, BUFSIZE)) > 0) { - if (_zip_write(za, buf, (zip_uint64_t)n) < 0) { - ret = -1; - break; - } - if (n == BUFSIZE && za->progress && data_length > 0) { - current += n; - if (_zip_progress_update(za->progress, (double)current / (double)data_length) != 0) { - zip_error_set(&za->error, ZIP_ER_CANCELLED, 0); - ret = -1; - break; - } - } + if (_zip_write(za, buf, (zip_uint64_t)n) < 0) { + ret = -1; + break; + } + if (n == BUFSIZE && za->progress && data_length > 0) { + current += n; + if (_zip_progress_update(za->progress, (double)current / (double)data_length) != 0) { + zip_error_set(&za->error, ZIP_ER_CANCELLED, 0); + ret = -1; + break; + } + } } if (n < 0) { - _zip_error_set_from_source(&za->error, src); - ret = -1; + _zip_error_set_from_source(&za->error, src); + ret = -1; } byte_array_fini(buf); @@ -622,18 +635,16 @@ copy_source(zip_t *za, zip_source_t *src, zip_int64_t data_length) { static int write_cdir(zip_t *za, const zip_filelist_t *filelist, zip_uint64_t survivors) { - zip_int64_t cd_start, end, size; - - if ((cd_start = zip_source_tell_write(za->src)) < 0) { - return -1; + if (zip_source_tell_write(za->src) < 0) { + return -1; } - if ((size = _zip_cdir_write(za, filelist, survivors)) < 0) { - return -1; + if (_zip_cdir_write(za, filelist, survivors) < 0) { + return -1; } - if ((end = zip_source_tell_write(za->src)) < 0) { - return -1; + if (zip_source_tell_write(za->src) < 0) { + return -1; } return 0; @@ -649,20 +660,20 @@ _zip_changed(const zip_t *za, zip_uint64_t *survivorsp) { survivors = 0; if (za->comment_changed || za->ch_flags != za->flags) { - changed = 1; + changed = 1; } for (i = 0; i < za->nentry; i++) { - if (ZIP_ENTRY_HAS_CHANGES(&za->entry[i])) { - changed = 1; - } - if (!za->entry[i].deleted) { - survivors++; - } + if (ZIP_ENTRY_HAS_CHANGES(&za->entry[i])) { + changed = 1; + } + if (!za->entry[i].deleted) { + survivors++; + } } if (survivorsp) { - *survivorsp = survivors; + *survivorsp = survivors; } return changed; @@ -674,27 +685,27 @@ write_data_descriptor(zip_t *za, const zip_dirent_t *de, int is_zip64) { int ret = 0; if (buffer == NULL) { - zip_error_set(&za->error, ZIP_ER_MEMORY, 0); - return -1; + zip_error_set(&za->error, ZIP_ER_MEMORY, 0); + return -1; } _zip_buffer_put(buffer, DATADES_MAGIC, 4); _zip_buffer_put_32(buffer, de->crc); if (is_zip64) { - _zip_buffer_put_64(buffer, de->comp_size); - _zip_buffer_put_64(buffer, de->uncomp_size); + _zip_buffer_put_64(buffer, de->comp_size); + _zip_buffer_put_64(buffer, de->uncomp_size); } else { - _zip_buffer_put_32(buffer, (zip_uint32_t)de->comp_size); - _zip_buffer_put_32(buffer, (zip_uint32_t)de->uncomp_size); + _zip_buffer_put_32(buffer, (zip_uint32_t)de->comp_size); + _zip_buffer_put_32(buffer, (zip_uint32_t)de->uncomp_size); } if (!_zip_buffer_ok(buffer)) { - zip_error_set(&za->error, ZIP_ER_INTERNAL, 0); - ret = -1; + zip_error_set(&za->error, ZIP_ER_INTERNAL, 0); + ret = -1; } else { - ret = _zip_write(za, _zip_buffer_data(buffer), _zip_buffer_offset(buffer)); + ret = _zip_write(za, _zip_buffer_data(buffer), _zip_buffer_offset(buffer)); } _zip_buffer_free(buffer); |