/*
  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/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)) {
            /* accept additional fields if values match */
            bool ok = true;
            switch (got_len) {
                case 28:
                    _zip_buffer_set_offset(ef_buffer, 24);
                    if (zde->disk_number != _zip_buffer_get_32(ef_buffer)) {
                        ok = false;
                    }
                    /* fallthrough */
                case 24:
                    _zip_buffer_set_offset(ef_buffer, 0);
                    if ((zde->uncomp_size != _zip_buffer_get_64(ef_buffer))
                        || (zde->comp_size != _zip_buffer_get_64(ef_buffer))
                        || (zde->offset != _zip_buffer_get_64(ef_buffer))) {
                        ok = false;
                    }
                    break;
                    
                default:
                    ok = false;
            }
            if (!ok) {
                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, de->version_madeby);
    }
    _zip_buffer_put_16(buffer, ZIP_MAX(is_really_zip64 ? 45 : 0, 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_apply_attributes(zip_dirent_t *de, zip_file_attributes_t *attributes, bool force_zip64, zip_uint32_t changed) {
    zip_uint16_t length;

    if (attributes->valid & ZIP_FILE_ATTRIBUTES_GENERAL_PURPOSE_BIT_FLAGS) {
	zip_uint16_t mask = attributes->general_purpose_bit_mask & ZIP_FILE_ATTRIBUTES_GENERAL_PURPOSE_BIT_FLAGS_ALLOWED_MASK;
	de->bitflags = (de->bitflags & ~mask) | (attributes->general_purpose_bit_flags & mask);
    }
    if (attributes->valid & ZIP_FILE_ATTRIBUTES_ASCII) {
	de->int_attrib = (de->int_attrib & ~0x1) | (attributes->ascii ? 1 : 0);
    }
    /* manually set attributes are preferred over attributes provided by source */
    if ((changed & ZIP_DIRENT_ATTRIBUTES) == 0 && (attributes->valid & ZIP_FILE_ATTRIBUTES_EXTERNAL_FILE_ATTRIBUTES)) {
	de->ext_attrib = attributes->external_file_attributes;
    }

    if (de->comp_method == ZIP_CM_LZMA) {
	de->version_needed = 63;
    }
    else if (de->encryption_method == ZIP_EM_AES_128 || de->encryption_method == ZIP_EM_AES_192 || de->encryption_method == ZIP_EM_AES_256) {
	de->version_needed = 51;
    }
    else if (de->comp_method == ZIP_CM_BZIP2) {
	de->version_needed = 46;
    }
    else if (force_zip64 || _zip_dirent_needs_zip64(de, 0)) {
	de->version_needed = 45;
    }
    else if (de->comp_method == ZIP_CM_DEFLATE || de->encryption_method == ZIP_EM_TRAD_PKWARE) {
	de->version_needed = 20;
    }
    else if ((length = _zip_string_length(de->filename)) > 0 && de->filename->raw[length - 1] == '/') {
	de->version_needed = 20;
    }
    else {
	de->version_needed = 10;
    }

    if (attributes->valid & ZIP_FILE_ATTRIBUTES_VERSION_NEEDED) {
        de->version_needed = ZIP_MAX(de->version_needed, attributes->version_needed);
    }

    de->version_madeby = 63 | (de->version_madeby & 0xff00);
    if ((changed & ZIP_DIRENT_ATTRIBUTES) == 0 && (attributes->valid & ZIP_FILE_ATTRIBUTES_HOST_SYSTEM)) {
	de->version_madeby = (de->version_madeby & 0xff) | (zip_uint16_t)(attributes->host_system << 8);
    }
}
