/*
  zip_close.c -- close zip archive and update changes
  Copyright (C) 1999-2020 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>

  Redistribution and use in source and binary forms, with or without
  modification, are permitted provided that the following conditions
  are met:
  1. Redistributions of source code must retain the above copyright
     notice, this list of conditions and the following disclaimer.
  2. Redistributions in binary form must reproduce the above copyright
     notice, this list of conditions and the following disclaimer in
     the documentation and/or other materials provided with the
     distribution.
  3. The names of the authors may not be used to endorse or promote
     products derived from this software without specific prior
     written permission.

  THIS SOFTWARE IS PROVIDED BY THE AUTHORS ``AS IS'' AND ANY EXPRESS
  OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
  WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
  ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY
  DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
  DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
  GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
  INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER
  IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
  OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
  IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/


#include "zipint.h"

#include <stdio.h>
#include <stdlib.h>
#ifdef _WIN32
#include <fcntl.h>
#include <io.h>
#endif


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 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);

ZIP_EXTERN int
zip_close(zip_t *za) {
    zip_uint64_t i, j, survivors, unchanged_offset;
    zip_int64_t off;
    int error;
    zip_filelist_t *filelist;
    int changed;

    if (za == NULL)
        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 (!changed) {
        zip_discard(za);
        return 0;
    }

    if (survivors > za->nentry) {
        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;

    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 (j < survivors) {
        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;
    }
    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 == 0) {
        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;
    }
    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) {
            _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;
            }
            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;
    }

    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 (error) {
        zip_source_rollback_write(za->src);
        return -1;
    }

    zip_discard(za);

    return 0;
}


static int
add_data(zip_t *za, zip_source_t *src, zip_dirent_t *de, zip_uint32_t changed) {
    zip_int64_t offstart, offdata, offend, data_length;
    zip_stat_t st;
    zip_file_attributes_t attributes;
    zip_source_t *src_final, *src_tmp;
    int ret;
    int is_zip64;
    zip_flags_t flags;
    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;
    }

    if ((st.valid & ZIP_STAT_COMP_METHOD) == 0) {
        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;
    else if (de->comp_method == ZIP_CM_STORE && (st.valid & ZIP_STAT_SIZE)) {
        st.valid |= ZIP_STAT_COMP_SIZE;
        st.comp_size = st.size;
    }
    else {
        /* 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;
    }

    flags = ZIP_EF_LOCAL;

    if ((st.valid & ZIP_STAT_SIZE) == 0) {
        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_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;
    }

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

    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);

    needs_reencrypt = needs_recompress || (de->changed & ZIP_DIRENT_PASSWORD) || (de->encryption_method != st.encryption_method);
    needs_decrypt = needs_reencrypt && (st.encryption_method != ZIP_EM_NONE);
    needs_encrypt = needs_reencrypt && (de->encryption_method != ZIP_EM_NONE);

    src_final = src;
    zip_source_keep(src_final);

    if (needs_decrypt) {
        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;
        }

        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;
        }

        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;
        }

        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;
        }

        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;
    }


    if ((offdata = zip_source_tell_write(za->src)) < 0) {
        _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;
    }

    if (zip_source_get_file_attributes(src_final, &attributes) != 0) {
        _zip_error_set_from_source(&za->error, src_final);
        ret = -1;
    }

    zip_source_free(src_final);

    if (ret < 0) {
        return -1;
    }

    if ((offend = zip_source_tell_write(za->src)) < 0) {
        _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;
    }

    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;
    }

    if ((de->changed & ZIP_DIRENT_LAST_MOD) == 0) {
        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;
    de->uncomp_size = st.size;
    de->comp_size = (zip_uint64_t)(offend - offdata);
    _zip_dirent_apply_attributes(de, &attributes, (flags & ZIP_FL_FORCE_ZIP64) != 0, changed);

    if ((ret = _zip_dirent_write(za, de, flags)) < 0)
        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;
    }

    if (zip_source_seek_write(za->src, offend, SEEK_SET) < 0) {
        _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;
        }
    }

    return 0;
}


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)) {
        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;
        }

        if (_zip_write(za, buf, n) < 0) {
            byte_array_fini(buf);
            return -1;
        }

        len -= n;

        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);
    return 0;
}


static int
copy_source(zip_t *za, zip_source_t *src, zip_int64_t data_length) {
    DEFINE_BYTE_ARRAY(buf, BUFSIZE);
    zip_int64_t n, current;
    int ret;

    if (zip_source_open(src) < 0) {
        _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;
    }

    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 (n < 0) {
        _zip_error_set_from_source(&za->error, src);
        ret = -1;
    }

    byte_array_fini(buf);

    zip_source_close(src);

    return ret;
}

static int
write_cdir(zip_t *za, const zip_filelist_t *filelist, zip_uint64_t survivors) {
    if (zip_source_tell_write(za->src) < 0) {
        return -1;
    }

    if (_zip_cdir_write(za, filelist, survivors) < 0) {
        return -1;
    }

    if (zip_source_tell_write(za->src) < 0) {
        return -1;
    }

    return 0;
}


int
_zip_changed(const zip_t *za, zip_uint64_t *survivorsp) {
    int changed;
    zip_uint64_t i, survivors;

    changed = 0;
    survivors = 0;

    if (za->comment_changed || za->ch_flags != za->flags) {
        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 (survivorsp) {
        *survivorsp = survivors;
    }

    return changed;
}

static int
write_data_descriptor(zip_t *za, const zip_dirent_t *de, int is_zip64) {
    zip_buffer_t *buffer = _zip_buffer_new(NULL, MAX_DATA_DESCRIPTOR_LENGTH);
    int ret = 0;

    if (buffer == NULL) {
        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);
    }
    else {
        _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;
    }
    else {
        ret = _zip_write(za, _zip_buffer_data(buffer), _zip_buffer_offset(buffer));
    }

    _zip_buffer_free(buffer);

    return ret;
}
