/*
  zip_dirent.c -- read directory entry (local or central), clean dirent
  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 <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/stat.h>
#include <sys/types.h>
#include <time.h>

#include "zipint.h"

static zip_string_t *_zip_dirent_process_ef_utf_8(const zip_dirent_t *de, zip_uint16_t id, zip_string_t *str);
static zip_extra_field_t *_zip_ef_utf8(zip_uint16_t, zip_string_t *, zip_error_t *);
static bool _zip_dirent_process_winzip_aes(zip_dirent_t *de, zip_error_t *error);


void
_zip_cdir_free(zip_cdir_t *cd) {
    zip_uint64_t i;

    if (!cd)
	return;

    for (i = 0; i < cd->nentry; i++)
	_zip_entry_finalize(cd->entry + i);
    free(cd->entry);
    _zip_string_free(cd->comment);
    free(cd);
}


zip_cdir_t *
_zip_cdir_new(zip_uint64_t nentry, zip_error_t *error) {
    zip_cdir_t *cd;

    if ((cd = (zip_cdir_t *)malloc(sizeof(*cd))) == NULL) {
	zip_error_set(error, ZIP_ER_MEMORY, 0);
	return NULL;
    }

    cd->entry = NULL;
    cd->nentry = cd->nentry_alloc = 0;
    cd->size = cd->offset = 0;
    cd->comment = NULL;
    cd->is_zip64 = false;

    if (!_zip_cdir_grow(cd, nentry, error)) {
	_zip_cdir_free(cd);
	return NULL;
    }

    return cd;
}


bool
_zip_cdir_grow(zip_cdir_t *cd, zip_uint64_t additional_entries, zip_error_t *error) {
    zip_uint64_t i, new_alloc;
    zip_entry_t *new_entry;

    if (additional_entries == 0) {
	return true;
    }

    new_alloc = cd->nentry_alloc + additional_entries;

    if (new_alloc < additional_entries || new_alloc > SIZE_MAX / sizeof(*(cd->entry))) {
	zip_error_set(error, ZIP_ER_MEMORY, 0);
	return false;
    }

    if ((new_entry = (zip_entry_t *)realloc(cd->entry, sizeof(*(cd->entry)) * (size_t)new_alloc)) == NULL) {
	zip_error_set(error, ZIP_ER_MEMORY, 0);
	return false;
    }

    cd->entry = new_entry;

    for (i = cd->nentry; i < new_alloc; i++) {
	_zip_entry_init(cd->entry + i);
    }

    cd->nentry = cd->nentry_alloc = new_alloc;

    return true;
}


zip_int64_t
_zip_cdir_write(zip_t *za, const zip_filelist_t *filelist, zip_uint64_t survivors) {
    zip_uint64_t offset, size;
    zip_string_t *comment;
    zip_uint8_t buf[EOCDLEN + EOCD64LEN + EOCD64LOCLEN];
    zip_buffer_t *buffer;
    zip_int64_t off;
    zip_uint64_t i;
    bool is_zip64;
    int ret;

    if ((off = zip_source_tell_write(za->src)) < 0) {
	_zip_error_set_from_source(&za->error, za->src);
	return -1;
    }
    offset = (zip_uint64_t)off;

    is_zip64 = false;

    for (i = 0; i < survivors; i++) {
	zip_entry_t *entry = za->entry + filelist[i].idx;

	if ((ret = _zip_dirent_write(za, entry->changes ? entry->changes : entry->orig, ZIP_FL_CENTRAL)) < 0)
	    return -1;
	if (ret)
	    is_zip64 = true;
    }

    if ((off = zip_source_tell_write(za->src)) < 0) {
	_zip_error_set_from_source(&za->error, za->src);
	return -1;
    }
    size = (zip_uint64_t)off - offset;

    if (offset > ZIP_UINT32_MAX || survivors > ZIP_UINT16_MAX)
	is_zip64 = true;


    if ((buffer = _zip_buffer_new(buf, sizeof(buf))) == NULL) {
	zip_error_set(&za->error, ZIP_ER_MEMORY, 0);
	return -1;
    }

    if (is_zip64) {
	_zip_buffer_put(buffer, EOCD64_MAGIC, 4);
	_zip_buffer_put_64(buffer, EOCD64LEN - 12);
	_zip_buffer_put_16(buffer, 45);
	_zip_buffer_put_16(buffer, 45);
	_zip_buffer_put_32(buffer, 0);
	_zip_buffer_put_32(buffer, 0);
	_zip_buffer_put_64(buffer, survivors);
	_zip_buffer_put_64(buffer, survivors);
	_zip_buffer_put_64(buffer, size);
	_zip_buffer_put_64(buffer, offset);
	_zip_buffer_put(buffer, EOCD64LOC_MAGIC, 4);
	_zip_buffer_put_32(buffer, 0);
	_zip_buffer_put_64(buffer, offset + size);
	_zip_buffer_put_32(buffer, 1);
    }

    _zip_buffer_put(buffer, EOCD_MAGIC, 4);
    _zip_buffer_put_32(buffer, 0);
    _zip_buffer_put_16(buffer, (zip_uint16_t)(survivors >= ZIP_UINT16_MAX ? ZIP_UINT16_MAX : survivors));
    _zip_buffer_put_16(buffer, (zip_uint16_t)(survivors >= ZIP_UINT16_MAX ? ZIP_UINT16_MAX : survivors));
    _zip_buffer_put_32(buffer, size >= ZIP_UINT32_MAX ? ZIP_UINT32_MAX : (zip_uint32_t)size);
    _zip_buffer_put_32(buffer, offset >= ZIP_UINT32_MAX ? ZIP_UINT32_MAX : (zip_uint32_t)offset);

    comment = za->comment_changed ? za->comment_changes : za->comment_orig;

    _zip_buffer_put_16(buffer, (zip_uint16_t)(comment ? comment->length : 0));

    if (!_zip_buffer_ok(buffer)) {
	zip_error_set(&za->error, ZIP_ER_INTERNAL, 0);
	_zip_buffer_free(buffer);
	return -1;
    }

    if (_zip_write(za, _zip_buffer_data(buffer), _zip_buffer_offset(buffer)) < 0) {
	_zip_buffer_free(buffer);
	return -1;
    }

    _zip_buffer_free(buffer);

    if (comment) {
	if (_zip_write(za, comment->raw, comment->length) < 0) {
	    return -1;
	}
    }

    return (zip_int64_t)size;
}


zip_dirent_t *
_zip_dirent_clone(const zip_dirent_t *sde) {
    zip_dirent_t *tde;

    if ((tde = (zip_dirent_t *)malloc(sizeof(*tde))) == NULL)
	return NULL;

    if (sde)
	memcpy(tde, sde, sizeof(*sde));
    else
	_zip_dirent_init(tde);

    tde->changed = 0;
    tde->cloned = 1;

    return tde;
}


void
_zip_dirent_finalize(zip_dirent_t *zde) {
    if (!zde->cloned || zde->changed & ZIP_DIRENT_FILENAME) {
	_zip_string_free(zde->filename);
	zde->filename = NULL;
    }
    if (!zde->cloned || zde->changed & ZIP_DIRENT_EXTRA_FIELD) {
	_zip_ef_free(zde->extra_fields);
	zde->extra_fields = NULL;
    }
    if (!zde->cloned || zde->changed & ZIP_DIRENT_COMMENT) {
	_zip_string_free(zde->comment);
	zde->comment = NULL;
    }
    if (!zde->cloned || zde->changed & ZIP_DIRENT_PASSWORD) {
	if (zde->password) {
	    _zip_crypto_clear(zde->password, strlen(zde->password));
	}
	free(zde->password);
	zde->password = NULL;
    }
}


void
_zip_dirent_free(zip_dirent_t *zde) {
    if (zde == NULL)
	return;

    _zip_dirent_finalize(zde);
    free(zde);
}


void
_zip_dirent_init(zip_dirent_t *de) {
    de->changed = 0;
    de->local_extra_fields_read = 0;
    de->cloned = 0;

    de->crc_valid = true;
    de->version_madeby = 63 | (ZIP_OPSYS_DEFAULT << 8);
    de->version_needed = 10; /* 1.0 */
    de->bitflags = 0;
    de->comp_method = ZIP_CM_DEFAULT;
    de->last_mod = 0;
    de->crc = 0;
    de->comp_size = 0;
    de->uncomp_size = 0;
    de->filename = NULL;
    de->extra_fields = NULL;
    de->comment = NULL;
    de->disk_number = 0;
    de->int_attrib = 0;
    de->ext_attrib = ZIP_EXT_ATTRIB_DEFAULT;
    de->offset = 0;
    de->compression_level = 0;
    de->encryption_method = ZIP_EM_NONE;
    de->password = NULL;
}


bool
_zip_dirent_needs_zip64(const zip_dirent_t *de, zip_flags_t flags) {
    if (de->uncomp_size >= ZIP_UINT32_MAX || de->comp_size >= ZIP_UINT32_MAX || ((flags & ZIP_FL_CENTRAL) && de->offset >= ZIP_UINT32_MAX))
	return true;

    return false;
}


zip_dirent_t *
_zip_dirent_new(void) {
    zip_dirent_t *de;

    if ((de = (zip_dirent_t *)malloc(sizeof(*de))) == NULL)
	return NULL;

    _zip_dirent_init(de);
    return de;
}


/* _zip_dirent_read(zde, fp, bufp, left, localp, error):
   Fills the zip directory entry zde.

   If buffer is non-NULL, data is taken from there; otherwise data is read from fp as needed.

   If local is true, it reads a local header instead of a central directory entry.

   Returns size of dirent read if successful. On error, error is filled in and -1 is returned.
*/

zip_int64_t
_zip_dirent_read(zip_dirent_t *zde, zip_source_t *src, zip_buffer_t *buffer, bool local, zip_error_t *error) {
    zip_uint8_t buf[CDENTRYSIZE];
    zip_uint16_t dostime, dosdate;
    zip_uint32_t size, variable_size;
    zip_uint16_t filename_len, comment_len, ef_len;

    bool from_buffer = (buffer != NULL);

    size = local ? LENTRYSIZE : CDENTRYSIZE;

    if (buffer) {
	if (_zip_buffer_left(buffer) < size) {
	    zip_error_set(error, ZIP_ER_NOZIP, 0);
	    return -1;
	}
    }
    else {
	if ((buffer = _zip_buffer_new_from_source(src, size, buf, error)) == NULL) {
	    return -1;
	}
    }

    if (memcmp(_zip_buffer_get(buffer, 4), (local ? LOCAL_MAGIC : CENTRAL_MAGIC), 4) != 0) {
	zip_error_set(error, ZIP_ER_NOZIP, 0);
	if (!from_buffer) {
	    _zip_buffer_free(buffer);
	}
	return -1;
    }

    /* convert buffercontents to zip_dirent */

    _zip_dirent_init(zde);
    if (!local)
	zde->version_madeby = _zip_buffer_get_16(buffer);
    else
	zde->version_madeby = 0;
    zde->version_needed = _zip_buffer_get_16(buffer);
    zde->bitflags = _zip_buffer_get_16(buffer);
    zde->comp_method = _zip_buffer_get_16(buffer);

    /* convert to time_t */
    dostime = _zip_buffer_get_16(buffer);
    dosdate = _zip_buffer_get_16(buffer);
    zde->last_mod = _zip_d2u_time(dostime, dosdate);

    zde->crc = _zip_buffer_get_32(buffer);
    zde->comp_size = _zip_buffer_get_32(buffer);
    zde->uncomp_size = _zip_buffer_get_32(buffer);

    filename_len = _zip_buffer_get_16(buffer);
    ef_len = _zip_buffer_get_16(buffer);

    if (local) {
	comment_len = 0;
	zde->disk_number = 0;
	zde->int_attrib = 0;
	zde->ext_attrib = 0;
	zde->offset = 0;
    }
    else {
	comment_len = _zip_buffer_get_16(buffer);
	zde->disk_number = _zip_buffer_get_16(buffer);
	zde->int_attrib = _zip_buffer_get_16(buffer);
	zde->ext_attrib = _zip_buffer_get_32(buffer);
	zde->offset = _zip_buffer_get_32(buffer);
    }

    if (!_zip_buffer_ok(buffer)) {
	zip_error_set(error, ZIP_ER_INTERNAL, 0);
	if (!from_buffer) {
	    _zip_buffer_free(buffer);
	}
	return -1;
    }

    if (zde->bitflags & ZIP_GPBF_ENCRYPTED) {
	if (zde->bitflags & ZIP_GPBF_STRONG_ENCRYPTION) {
	    /* TODO */
	    zde->encryption_method = ZIP_EM_UNKNOWN;
	}
	else {
	    zde->encryption_method = ZIP_EM_TRAD_PKWARE;
	}
    }
    else {
	zde->encryption_method = ZIP_EM_NONE;
    }

    zde->filename = NULL;
    zde->extra_fields = NULL;
    zde->comment = NULL;

    variable_size = (zip_uint32_t)filename_len + (zip_uint32_t)ef_len + (zip_uint32_t)comment_len;

    if (from_buffer) {
	if (_zip_buffer_left(buffer) < variable_size) {
	    zip_error_set(error, ZIP_ER_INCONS, 0);
	    return -1;
	}
    }
    else {
	_zip_buffer_free(buffer);

	if ((buffer = _zip_buffer_new_from_source(src, variable_size, NULL, error)) == NULL) {
	    return -1;
	}
    }

    if (filename_len) {
	zde->filename = _zip_read_string(buffer, src, filename_len, 1, error);
	if (!zde->filename) {
	    if (zip_error_code_zip(error) == ZIP_ER_EOF) {
		zip_error_set(error, ZIP_ER_INCONS, 0);
	    }
	    if (!from_buffer) {
		_zip_buffer_free(buffer);
	    }
	    return -1;
	}

	if (zde->bitflags & ZIP_GPBF_ENCODING_UTF_8) {
	    if (_zip_guess_encoding(zde->filename, ZIP_ENCODING_UTF8_KNOWN) == ZIP_ENCODING_ERROR) {
		zip_error_set(error, ZIP_ER_INCONS, 0);
		if (!from_buffer) {
		    _zip_buffer_free(buffer);
		}
		return -1;
	    }
	}
    }

    if (ef_len) {
	zip_uint8_t *ef = _zip_read_data(buffer, src, ef_len, 0, error);

	if (ef == NULL) {
	    if (!from_buffer) {
		_zip_buffer_free(buffer);
	    }
	    return -1;
	}
	if (!_zip_ef_parse(ef, ef_len, local ? ZIP_EF_LOCAL : ZIP_EF_CENTRAL, &zde->extra_fields, error)) {
	    free(ef);
	    if (!from_buffer) {
		_zip_buffer_free(buffer);
	    }
	    return -1;
	}
	free(ef);
	if (local)
	    zde->local_extra_fields_read = 1;
    }

    if (comment_len) {
	zde->comment = _zip_read_string(buffer, src, comment_len, 0, error);
	if (!zde->comment) {
	    if (!from_buffer) {
		_zip_buffer_free(buffer);
	    }
	    return -1;
	}
	if (zde->bitflags & ZIP_GPBF_ENCODING_UTF_8) {
	    if (_zip_guess_encoding(zde->comment, ZIP_ENCODING_UTF8_KNOWN) == ZIP_ENCODING_ERROR) {
		zip_error_set(error, ZIP_ER_INCONS, 0);
		if (!from_buffer) {
		    _zip_buffer_free(buffer);
		}
		return -1;
	    }
	}
    }

    zde->filename = _zip_dirent_process_ef_utf_8(zde, ZIP_EF_UTF_8_NAME, zde->filename);
    zde->comment = _zip_dirent_process_ef_utf_8(zde, ZIP_EF_UTF_8_COMMENT, zde->comment);

    /* Zip64 */

    if (zde->uncomp_size == ZIP_UINT32_MAX || zde->comp_size == ZIP_UINT32_MAX || zde->offset == ZIP_UINT32_MAX) {
	zip_uint16_t got_len;
	zip_buffer_t *ef_buffer;
	const zip_uint8_t *ef = _zip_ef_get_by_id(zde->extra_fields, &got_len, ZIP_EF_ZIP64, 0, local ? ZIP_EF_LOCAL : ZIP_EF_CENTRAL, error);
	/* TODO: if got_len == 0 && !ZIP64_EOCD: no error, 0xffffffff is valid value */
	if (ef == NULL) {
	    if (!from_buffer) {
		_zip_buffer_free(buffer);
	    }
	    return -1;
	}

	if ((ef_buffer = _zip_buffer_new((zip_uint8_t *)ef, got_len)) == NULL) {
	    zip_error_set(error, ZIP_ER_MEMORY, 0);
	    if (!from_buffer) {
		_zip_buffer_free(buffer);
	    }
	    return -1;
	}

	if (zde->uncomp_size == ZIP_UINT32_MAX)
	    zde->uncomp_size = _zip_buffer_get_64(ef_buffer);
	else if (local) {
	    /* From appnote.txt: This entry in the Local header MUST
	       include BOTH original and compressed file size fields. */
	    (void)_zip_buffer_skip(ef_buffer, 8); /* error is caught by _zip_buffer_eof() call */
	}
	if (zde->comp_size == ZIP_UINT32_MAX)
	    zde->comp_size = _zip_buffer_get_64(ef_buffer);
	if (!local) {
	    if (zde->offset == ZIP_UINT32_MAX)
		zde->offset = _zip_buffer_get_64(ef_buffer);
	    if (zde->disk_number == ZIP_UINT16_MAX)
		zde->disk_number = _zip_buffer_get_32(ef_buffer);
	}

	if (!_zip_buffer_eof(ef_buffer)) {
	    zip_error_set(error, ZIP_ER_INCONS, 0);
	    _zip_buffer_free(ef_buffer);
	    if (!from_buffer) {
		_zip_buffer_free(buffer);
	    }
	    return -1;
	}
	_zip_buffer_free(ef_buffer);
    }

    if (!_zip_buffer_ok(buffer)) {
	zip_error_set(error, ZIP_ER_INTERNAL, 0);
	if (!from_buffer) {
	    _zip_buffer_free(buffer);
	}
	return -1;
    }
    if (!from_buffer) {
	_zip_buffer_free(buffer);
    }

    /* zip_source_seek / zip_source_tell don't support values > ZIP_INT64_MAX */
    if (zde->offset > ZIP_INT64_MAX) {
	zip_error_set(error, ZIP_ER_SEEK, EFBIG);
	return -1;
    }

    if (!_zip_dirent_process_winzip_aes(zde, error)) {
	return -1;
    }

    zde->extra_fields = _zip_ef_remove_internal(zde->extra_fields);

    return (zip_int64_t)(size + variable_size);
}


static zip_string_t *
_zip_dirent_process_ef_utf_8(const zip_dirent_t *de, zip_uint16_t id, zip_string_t *str) {
    zip_uint16_t ef_len;
    zip_uint32_t ef_crc;
    zip_buffer_t *buffer;

    const zip_uint8_t *ef = _zip_ef_get_by_id(de->extra_fields, &ef_len, id, 0, ZIP_EF_BOTH, NULL);

    if (ef == NULL || ef_len < 5 || ef[0] != 1) {
	return str;
    }

    if ((buffer = _zip_buffer_new((zip_uint8_t *)ef, ef_len)) == NULL) {
	return str;
    }

    _zip_buffer_get_8(buffer);
    ef_crc = _zip_buffer_get_32(buffer);

    if (_zip_string_crc32(str) == ef_crc) {
	zip_uint16_t len = (zip_uint16_t)_zip_buffer_left(buffer);
	zip_string_t *ef_str = _zip_string_new(_zip_buffer_get(buffer, len), len, ZIP_FL_ENC_UTF_8, NULL);

	if (ef_str != NULL) {
	    _zip_string_free(str);
	    str = ef_str;
	}
    }

    _zip_buffer_free(buffer);

    return str;
}


static bool
_zip_dirent_process_winzip_aes(zip_dirent_t *de, zip_error_t *error) {
    zip_uint16_t ef_len;
    zip_buffer_t *buffer;
    const zip_uint8_t *ef;
    bool crc_valid;
    zip_uint16_t enc_method;


    if (de->comp_method != ZIP_CM_WINZIP_AES) {
	return true;
    }

    ef = _zip_ef_get_by_id(de->extra_fields, &ef_len, ZIP_EF_WINZIP_AES, 0, ZIP_EF_BOTH, NULL);

    if (ef == NULL || ef_len < 7) {
	zip_error_set(error, ZIP_ER_INCONS, 0);
	return false;
    }

    if ((buffer = _zip_buffer_new((zip_uint8_t *)ef, ef_len)) == NULL) {
	zip_error_set(error, ZIP_ER_INTERNAL, 0);
	return false;
    }

    /* version */

    crc_valid = true;
    switch (_zip_buffer_get_16(buffer)) {
    case 1:
	break;

    case 2:
	if (de->uncomp_size < 20 /* TODO: constant */) {
	    crc_valid = false;
	}
	break;

    default:
	zip_error_set(error, ZIP_ER_ENCRNOTSUPP, 0);
	_zip_buffer_free(buffer);
	return false;
    }

    /* vendor */
    if (memcmp(_zip_buffer_get(buffer, 2), "AE", 2) != 0) {
	zip_error_set(error, ZIP_ER_ENCRNOTSUPP, 0);
	_zip_buffer_free(buffer);
	return false;
    }

    /* mode */
    switch (_zip_buffer_get_8(buffer)) {
    case 1:
	enc_method = ZIP_EM_AES_128;
	break;
    case 2:
	enc_method = ZIP_EM_AES_192;
	break;
    case 3:
	enc_method = ZIP_EM_AES_256;
	break;
    default:
	zip_error_set(error, ZIP_ER_ENCRNOTSUPP, 0);
	_zip_buffer_free(buffer);
	return false;
    }

    if (ef_len != 7) {
	zip_error_set(error, ZIP_ER_INCONS, 0);
	_zip_buffer_free(buffer);
	return false;
    }

    de->crc_valid = crc_valid;
    de->encryption_method = enc_method;
    de->comp_method = _zip_buffer_get_16(buffer);

    _zip_buffer_free(buffer);
    return true;
}


zip_int32_t
_zip_dirent_size(zip_source_t *src, zip_uint16_t flags, zip_error_t *error) {
    zip_int32_t size;
    bool local = (flags & ZIP_EF_LOCAL) != 0;
    int i;
    zip_uint8_t b[6];
    zip_buffer_t *buffer;

    size = local ? LENTRYSIZE : CDENTRYSIZE;

    if (zip_source_seek(src, local ? 26 : 28, SEEK_CUR) < 0) {
	_zip_error_set_from_source(error, src);
	return -1;
    }

    if ((buffer = _zip_buffer_new_from_source(src, local ? 4 : 6, b, error)) == NULL) {
	return -1;
    }

    for (i = 0; i < (local ? 2 : 3); i++) {
	size += _zip_buffer_get_16(buffer);
    }

    if (!_zip_buffer_eof(buffer)) {
	zip_error_set(error, ZIP_ER_INTERNAL, 0);
	_zip_buffer_free(buffer);
	return -1;
    }

    _zip_buffer_free(buffer);
    return size;
}


/* _zip_dirent_write
   Writes zip directory entry.

   If flags & ZIP_EF_LOCAL, it writes a local header instead of a central
   directory entry.  If flags & ZIP_EF_FORCE_ZIP64, a ZIP64 extra field is written, even if not needed.

   Returns 0 if successful, 1 if successful and wrote ZIP64 extra field. On error, error is filled in and -1 is
   returned.
*/

int
_zip_dirent_write(zip_t *za, zip_dirent_t *de, zip_flags_t flags) {
    zip_uint16_t dostime, dosdate;
    zip_encoding_type_t com_enc, name_enc;
    zip_extra_field_t *ef;
    zip_extra_field_t *ef64;
    zip_uint32_t ef_total_size;
    bool is_zip64;
    bool is_really_zip64;
    bool is_winzip_aes;
    zip_uint8_t buf[CDENTRYSIZE];
    zip_buffer_t *buffer;

    ef = NULL;

    name_enc = _zip_guess_encoding(de->filename, ZIP_ENCODING_UNKNOWN);
    com_enc = _zip_guess_encoding(de->comment, ZIP_ENCODING_UNKNOWN);

    if ((name_enc == ZIP_ENCODING_UTF8_KNOWN && com_enc == ZIP_ENCODING_ASCII) || (name_enc == ZIP_ENCODING_ASCII && com_enc == ZIP_ENCODING_UTF8_KNOWN) || (name_enc == ZIP_ENCODING_UTF8_KNOWN && com_enc == ZIP_ENCODING_UTF8_KNOWN))
	de->bitflags |= ZIP_GPBF_ENCODING_UTF_8;
    else {
	de->bitflags &= (zip_uint16_t)~ZIP_GPBF_ENCODING_UTF_8;
	if (name_enc == ZIP_ENCODING_UTF8_KNOWN) {
	    ef = _zip_ef_utf8(ZIP_EF_UTF_8_NAME, de->filename, &za->error);
	    if (ef == NULL)
		return -1;
	}
	if ((flags & ZIP_FL_LOCAL) == 0 && com_enc == ZIP_ENCODING_UTF8_KNOWN) {
	    zip_extra_field_t *ef2 = _zip_ef_utf8(ZIP_EF_UTF_8_COMMENT, de->comment, &za->error);
	    if (ef2 == NULL) {
		_zip_ef_free(ef);
		return -1;
	    }
	    ef2->next = ef;
	    ef = ef2;
	}
    }

    if (de->encryption_method == ZIP_EM_NONE) {
	de->bitflags &= (zip_uint16_t)~ZIP_GPBF_ENCRYPTED;
    }
    else {
	de->bitflags |= (zip_uint16_t)ZIP_GPBF_ENCRYPTED;
    }

    is_really_zip64 = _zip_dirent_needs_zip64(de, flags);
    is_zip64 = (flags & (ZIP_FL_LOCAL | ZIP_FL_FORCE_ZIP64)) == (ZIP_FL_LOCAL | ZIP_FL_FORCE_ZIP64) || is_really_zip64;
    is_winzip_aes = de->encryption_method == ZIP_EM_AES_128 || de->encryption_method == ZIP_EM_AES_192 || de->encryption_method == ZIP_EM_AES_256;

    if (is_zip64) {
	zip_uint8_t ef_zip64[EFZIP64SIZE];
	zip_buffer_t *ef_buffer = _zip_buffer_new(ef_zip64, sizeof(ef_zip64));
	if (ef_buffer == NULL) {
	    zip_error_set(&za->error, ZIP_ER_MEMORY, 0);
	    _zip_ef_free(ef);
	    return -1;
	}

	if (flags & ZIP_FL_LOCAL) {
	    if ((flags & ZIP_FL_FORCE_ZIP64) || de->comp_size > ZIP_UINT32_MAX || de->uncomp_size > ZIP_UINT32_MAX) {
		_zip_buffer_put_64(ef_buffer, de->uncomp_size);
		_zip_buffer_put_64(ef_buffer, de->comp_size);
	    }
	}
	else {
	    if ((flags & ZIP_FL_FORCE_ZIP64) || de->comp_size > ZIP_UINT32_MAX || de->uncomp_size > ZIP_UINT32_MAX || de->offset > ZIP_UINT32_MAX) {
		if (de->uncomp_size >= ZIP_UINT32_MAX) {
		    _zip_buffer_put_64(ef_buffer, de->uncomp_size);
		}
		if (de->comp_size >= ZIP_UINT32_MAX) {
		    _zip_buffer_put_64(ef_buffer, de->comp_size);
		}
		if (de->offset >= ZIP_UINT32_MAX) {
		    _zip_buffer_put_64(ef_buffer, de->offset);
		}
	    }
	}

	if (!_zip_buffer_ok(ef_buffer)) {
	    zip_error_set(&za->error, ZIP_ER_INTERNAL, 0);
	    _zip_buffer_free(ef_buffer);
	    _zip_ef_free(ef);
	    return -1;
	}

	ef64 = _zip_ef_new(ZIP_EF_ZIP64, (zip_uint16_t)(_zip_buffer_offset(ef_buffer)), ef_zip64, ZIP_EF_BOTH);
	_zip_buffer_free(ef_buffer);
	ef64->next = ef;
	ef = ef64;
    }

    if (is_winzip_aes) {
	zip_uint8_t data[EF_WINZIP_AES_SIZE];
	zip_buffer_t *ef_buffer = _zip_buffer_new(data, sizeof(data));
	zip_extra_field_t *ef_winzip;

	if (ef_buffer == NULL) {
	    zip_error_set(&za->error, ZIP_ER_MEMORY, 0);
	    _zip_ef_free(ef);
	    return -1;
	}

	_zip_buffer_put_16(ef_buffer, 2);
	_zip_buffer_put(ef_buffer, "AE", 2);
	_zip_buffer_put_8(ef_buffer, (zip_uint8_t)(de->encryption_method & 0xff));
	_zip_buffer_put_16(ef_buffer, (zip_uint16_t)de->comp_method);

	if (!_zip_buffer_ok(ef_buffer)) {
	    zip_error_set(&za->error, ZIP_ER_INTERNAL, 0);
	    _zip_buffer_free(ef_buffer);
	    _zip_ef_free(ef);
	    return -1;
	}

	ef_winzip = _zip_ef_new(ZIP_EF_WINZIP_AES, EF_WINZIP_AES_SIZE, data, ZIP_EF_BOTH);
	_zip_buffer_free(ef_buffer);
	ef_winzip->next = ef;
	ef = ef_winzip;
    }

    if ((buffer = _zip_buffer_new(buf, sizeof(buf))) == NULL) {
	zip_error_set(&za->error, ZIP_ER_MEMORY, 0);
	_zip_ef_free(ef);
	return -1;
    }

    _zip_buffer_put(buffer, (flags & ZIP_FL_LOCAL) ? LOCAL_MAGIC : CENTRAL_MAGIC, 4);

    if ((flags & ZIP_FL_LOCAL) == 0) {
	_zip_buffer_put_16(buffer, (zip_uint16_t)(is_really_zip64 ? 45 : de->version_madeby));
    }
    _zip_buffer_put_16(buffer, (zip_uint16_t)(is_really_zip64 ? 45 : de->version_needed));
    _zip_buffer_put_16(buffer, de->bitflags);
    if (is_winzip_aes) {
	_zip_buffer_put_16(buffer, ZIP_CM_WINZIP_AES);
    }
    else {
	_zip_buffer_put_16(buffer, (zip_uint16_t)de->comp_method);
    }

    _zip_u2d_time(de->last_mod, &dostime, &dosdate);
    _zip_buffer_put_16(buffer, dostime);
    _zip_buffer_put_16(buffer, dosdate);

    if (is_winzip_aes && de->uncomp_size < 20) {
	_zip_buffer_put_32(buffer, 0);
    }
    else {
	_zip_buffer_put_32(buffer, de->crc);
    }

    if (((flags & ZIP_FL_LOCAL) == ZIP_FL_LOCAL) && ((de->comp_size >= ZIP_UINT32_MAX) || (de->uncomp_size >= ZIP_UINT32_MAX))) {
	/* In local headers, if a ZIP64 EF is written, it MUST contain
	 * both compressed and uncompressed sizes (even if one of the
	 * two is smaller than 0xFFFFFFFF); on the other hand, those
	 * may only appear when the corresponding standard entry is
	 * 0xFFFFFFFF.  (appnote.txt 4.5.3) */
	_zip_buffer_put_32(buffer, ZIP_UINT32_MAX);
	_zip_buffer_put_32(buffer, ZIP_UINT32_MAX);
    }
    else {
	if (de->comp_size < ZIP_UINT32_MAX) {
	    _zip_buffer_put_32(buffer, (zip_uint32_t)de->comp_size);
	}
	else {
	    _zip_buffer_put_32(buffer, ZIP_UINT32_MAX);
	}
	if (de->uncomp_size < ZIP_UINT32_MAX) {
	    _zip_buffer_put_32(buffer, (zip_uint32_t)de->uncomp_size);
	}
	else {
	    _zip_buffer_put_32(buffer, ZIP_UINT32_MAX);
	}
    }

    _zip_buffer_put_16(buffer, _zip_string_length(de->filename));
    /* TODO: check for overflow */
    ef_total_size = (zip_uint32_t)_zip_ef_size(de->extra_fields, flags) + (zip_uint32_t)_zip_ef_size(ef, ZIP_EF_BOTH);
    _zip_buffer_put_16(buffer, (zip_uint16_t)ef_total_size);

    if ((flags & ZIP_FL_LOCAL) == 0) {
	_zip_buffer_put_16(buffer, _zip_string_length(de->comment));
	_zip_buffer_put_16(buffer, (zip_uint16_t)de->disk_number);
	_zip_buffer_put_16(buffer, de->int_attrib);
	_zip_buffer_put_32(buffer, de->ext_attrib);
	if (de->offset < ZIP_UINT32_MAX)
	    _zip_buffer_put_32(buffer, (zip_uint32_t)de->offset);
	else
	    _zip_buffer_put_32(buffer, ZIP_UINT32_MAX);
    }

    if (!_zip_buffer_ok(buffer)) {
	zip_error_set(&za->error, ZIP_ER_INTERNAL, 0);
	_zip_buffer_free(buffer);
	_zip_ef_free(ef);
	return -1;
    }

    if (_zip_write(za, buf, _zip_buffer_offset(buffer)) < 0) {
	_zip_buffer_free(buffer);
	_zip_ef_free(ef);
	return -1;
    }

    _zip_buffer_free(buffer);

    if (de->filename) {
	if (_zip_string_write(za, de->filename) < 0) {
	    _zip_ef_free(ef);
	    return -1;
	}
    }

    if (ef) {
	if (_zip_ef_write(za, ef, ZIP_EF_BOTH) < 0) {
	    _zip_ef_free(ef);
	    return -1;
	}
    }
    _zip_ef_free(ef);
    if (de->extra_fields) {
	if (_zip_ef_write(za, de->extra_fields, flags) < 0) {
	    return -1;
	}
    }

    if ((flags & ZIP_FL_LOCAL) == 0) {
	if (de->comment) {
	    if (_zip_string_write(za, de->comment) < 0) {
		return -1;
	    }
	}
    }


    return is_zip64;
}


time_t
_zip_d2u_time(zip_uint16_t dtime, zip_uint16_t ddate) {
    struct tm tm;

    memset(&tm, 0, sizeof(tm));

    /* let mktime decide if DST is in effect */
    tm.tm_isdst = -1;

    tm.tm_year = ((ddate >> 9) & 127) + 1980 - 1900;
    tm.tm_mon = ((ddate >> 5) & 15) - 1;
    tm.tm_mday = ddate & 31;

    tm.tm_hour = (dtime >> 11) & 31;
    tm.tm_min = (dtime >> 5) & 63;
    tm.tm_sec = (dtime << 1) & 62;

    return mktime(&tm);
}


static zip_extra_field_t *
_zip_ef_utf8(zip_uint16_t id, zip_string_t *str, zip_error_t *error) {
    const zip_uint8_t *raw;
    zip_uint32_t len;
    zip_buffer_t *buffer;
    zip_extra_field_t *ef;

    if ((raw = _zip_string_get(str, &len, ZIP_FL_ENC_RAW, NULL)) == NULL) {
	/* error already set */
	return NULL;
    }

    if (len + 5 > ZIP_UINT16_MAX) {
	zip_error_set(error, ZIP_ER_INVAL, 0); /* TODO: better error code? */
	return NULL;
    }

    if ((buffer = _zip_buffer_new(NULL, len + 5)) == NULL) {
	zip_error_set(error, ZIP_ER_MEMORY, 0);
	return NULL;
    }

    _zip_buffer_put_8(buffer, 1);
    _zip_buffer_put_32(buffer, _zip_string_crc32(str));
    _zip_buffer_put(buffer, raw, len);

    if (!_zip_buffer_ok(buffer)) {
	zip_error_set(error, ZIP_ER_INTERNAL, 0);
	_zip_buffer_free(buffer);
	return NULL;
    }

    ef = _zip_ef_new(id, (zip_uint16_t)(_zip_buffer_offset(buffer)), _zip_buffer_data(buffer), ZIP_EF_BOTH);
    _zip_buffer_free(buffer);

    return ef;
}


zip_dirent_t *
_zip_get_dirent(zip_t *za, zip_uint64_t idx, zip_flags_t flags, zip_error_t *error) {
    if (error == NULL)
	error = &za->error;

    if (idx >= za->nentry) {
	zip_error_set(error, ZIP_ER_INVAL, 0);
	return NULL;
    }

    if ((flags & ZIP_FL_UNCHANGED) || za->entry[idx].changes == NULL) {
	if (za->entry[idx].orig == NULL) {
	    zip_error_set(error, ZIP_ER_INVAL, 0);
	    return NULL;
	}
	if (za->entry[idx].deleted && (flags & ZIP_FL_UNCHANGED) == 0) {
	    zip_error_set(error, ZIP_ER_DELETED, 0);
	    return NULL;
	}
	return za->entry[idx].orig;
    }
    else
	return za->entry[idx].changes;
}


void
_zip_u2d_time(time_t intime, zip_uint16_t *dtime, zip_uint16_t *ddate) {
    struct tm *tpm;

#ifdef HAVE_LOCALTIME_R
    struct tm tm;
    tpm = localtime_r(&intime, &tm);
#else
    tpm = localtime(&intime);
#endif
    if (tpm == NULL) {
        /* if localtime() fails, return an arbitrary date (1980-01-01 00:00:00) */
	*ddate = (1 << 5) + 1;
	*dtime = 0;
	return;
    }
    if (tpm->tm_year < 80) {
	tpm->tm_year = 80;
    }

    *ddate = (zip_uint16_t)(((tpm->tm_year + 1900 - 1980) << 9) + ((tpm->tm_mon + 1) << 5) + tpm->tm_mday);
    *dtime = (zip_uint16_t)(((tpm->tm_hour) << 11) + ((tpm->tm_min) << 5) + ((tpm->tm_sec) >> 1));

    return;
}


void
_zip_dirent_set_version_needed(zip_dirent_t *de, bool force_zip64) {
    zip_uint16_t length;

    if (de->comp_method == ZIP_CM_LZMA) {
	de->version_needed = 63;
	return;
    }

    if (de->comp_method == ZIP_CM_BZIP2) {
	de->version_needed = 46;
	return;
    }

    if (force_zip64 || _zip_dirent_needs_zip64(de, 0)) {
	de->version_needed = 45;
	return;
    }

    if (de->comp_method == ZIP_CM_DEFLATE || de->encryption_method == ZIP_EM_TRAD_PKWARE) {
	de->version_needed = 20;
	return;
    }

    /* directory */
    if ((length = _zip_string_length(de->filename)) > 0) {
	if (de->filename->raw[length - 1] == '/') {
	    de->version_needed = 20;
	    return;
	}
    }

    de->version_needed = 10;
}
