"Fossies" - the Fresh Open Source Software Archive

Member "src/Common/libzip/zip_dirent.c" (10 Oct 2018, 29597 Bytes) of package /windows/misc/VeraCrypt_1.23-Hotfix-2_Source.zip:


As a special service "Fossies" has tried to format the requested source page into HTML format using (guessed) C and C++ source code syntax highlighting (style: standard) with prefixed line numbers and code folding option. Alternatively you can here view or download the uninterpreted source code file. For more information about "zip_dirent.c" see the Fossies "Dox" file reference documentation and the last Fossies "Diffs" side-by-side code changes report: 1.21_Source_vs_1.22_Source.

    1 /*
    2   zip_dirent.c -- read directory entry (local or central), clean dirent
    3   Copyright (C) 1999-2017 Dieter Baron and Thomas Klausner
    4 
    5   This file is part of libzip, a library to manipulate ZIP archives.
    6   The authors can be contacted at <libzip@nih.at>
    7 
    8   Redistribution and use in source and binary forms, with or without
    9   modification, are permitted provided that the following conditions
   10   are met:
   11   1. Redistributions of source code must retain the above copyright
   12      notice, this list of conditions and the following disclaimer.
   13   2. Redistributions in binary form must reproduce the above copyright
   14      notice, this list of conditions and the following disclaimer in
   15      the documentation and/or other materials provided with the
   16      distribution.
   17   3. The names of the authors may not be used to endorse or promote
   18      products derived from this software without specific prior
   19      written permission.
   20 
   21   THIS SOFTWARE IS PROVIDED BY THE AUTHORS ``AS IS'' AND ANY EXPRESS
   22   OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
   23   WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
   24   ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY
   25   DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
   26   DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
   27   GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
   28   INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER
   29   IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
   30   OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
   31   IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
   32 */
   33 
   34 
   35 #include <stdio.h>
   36 #include <stdlib.h>
   37 #include <string.h>
   38 #include <sys/stat.h>
   39 #include <sys/types.h>
   40 #include <time.h>
   41 
   42 #include "zipint.h"
   43 
   44 static time_t _zip_d2u_time(zip_uint16_t, zip_uint16_t);
   45 static zip_string_t *_zip_dirent_process_ef_utf_8(const zip_dirent_t *de, zip_uint16_t id, zip_string_t *str);
   46 static zip_extra_field_t *_zip_ef_utf8(zip_uint16_t, zip_string_t *, zip_error_t *);
   47 static bool _zip_dirent_process_winzip_aes(zip_dirent_t *de, zip_error_t *error);
   48 
   49 
   50 void
   51 _zip_cdir_free(zip_cdir_t *cd) {
   52     zip_uint64_t i;
   53 
   54     if (!cd)
   55     return;
   56 
   57     for (i = 0; i < cd->nentry; i++)
   58     _zip_entry_finalize(cd->entry + i);
   59     free(cd->entry);
   60     _zip_string_free(cd->comment);
   61     free(cd);
   62 }
   63 
   64 
   65 zip_cdir_t *
   66 _zip_cdir_new(zip_uint64_t nentry, zip_error_t *error) {
   67     zip_cdir_t *cd;
   68 
   69     if ((cd = (zip_cdir_t *)malloc(sizeof(*cd))) == NULL) {
   70     zip_error_set(error, ZIP_ER_MEMORY, 0);
   71     return NULL;
   72     }
   73 
   74     cd->entry = NULL;
   75     cd->nentry = cd->nentry_alloc = 0;
   76     cd->size = cd->offset = 0;
   77     cd->comment = NULL;
   78     cd->is_zip64 = false;
   79 
   80     if (!_zip_cdir_grow(cd, nentry, error)) {
   81     _zip_cdir_free(cd);
   82     return NULL;
   83     }
   84 
   85     return cd;
   86 }
   87 
   88 
   89 bool
   90 _zip_cdir_grow(zip_cdir_t *cd, zip_uint64_t additional_entries, zip_error_t *error) {
   91     zip_uint64_t i, new_alloc;
   92     zip_entry_t *new_entry;
   93 
   94     if (additional_entries == 0) {
   95     return true;
   96     }
   97 
   98     new_alloc = cd->nentry_alloc + additional_entries;
   99 
  100     if (new_alloc < additional_entries || new_alloc > SIZE_MAX / sizeof(*(cd->entry))) {
  101     zip_error_set(error, ZIP_ER_MEMORY, 0);
  102     return false;
  103     }
  104 
  105     if ((new_entry = (zip_entry_t *)realloc(cd->entry, sizeof(*(cd->entry)) * (size_t)new_alloc)) == NULL) {
  106     zip_error_set(error, ZIP_ER_MEMORY, 0);
  107     return false;
  108     }
  109 
  110     cd->entry = new_entry;
  111 
  112     for (i = cd->nentry; i < new_alloc; i++) {
  113     _zip_entry_init(cd->entry + i);
  114     }
  115 
  116     cd->nentry = cd->nentry_alloc = new_alloc;
  117 
  118     return true;
  119 }
  120 
  121 
  122 zip_int64_t
  123 _zip_cdir_write(zip_t *za, const zip_filelist_t *filelist, zip_uint64_t survivors) {
  124     zip_uint64_t offset, size;
  125     zip_string_t *comment;
  126     zip_uint8_t buf[EOCDLEN + EOCD64LEN + EOCD64LOCLEN];
  127     zip_buffer_t *buffer;
  128     zip_int64_t off;
  129     zip_uint64_t i;
  130     bool is_zip64;
  131     int ret;
  132 
  133     if ((off = zip_source_tell_write(za->src)) < 0) {
  134     _zip_error_set_from_source(&za->error, za->src);
  135     return -1;
  136     }
  137     offset = (zip_uint64_t)off;
  138 
  139     is_zip64 = false;
  140 
  141     for (i = 0; i < survivors; i++) {
  142     zip_entry_t *entry = za->entry + filelist[i].idx;
  143 
  144     if ((ret = _zip_dirent_write(za, entry->changes ? entry->changes : entry->orig, ZIP_FL_CENTRAL)) < 0)
  145         return -1;
  146     if (ret)
  147         is_zip64 = true;
  148     }
  149 
  150     if ((off = zip_source_tell_write(za->src)) < 0) {
  151     _zip_error_set_from_source(&za->error, za->src);
  152     return -1;
  153     }
  154     size = (zip_uint64_t)off - offset;
  155 
  156     if (offset > ZIP_UINT32_MAX || survivors > ZIP_UINT16_MAX)
  157     is_zip64 = true;
  158 
  159 
  160     if ((buffer = _zip_buffer_new(buf, sizeof(buf))) == NULL) {
  161     zip_error_set(&za->error, ZIP_ER_MEMORY, 0);
  162     return -1;
  163     }
  164 
  165     if (is_zip64) {
  166     _zip_buffer_put(buffer, EOCD64_MAGIC, 4);
  167     _zip_buffer_put_64(buffer, EOCD64LEN - 12);
  168     _zip_buffer_put_16(buffer, 45);
  169     _zip_buffer_put_16(buffer, 45);
  170     _zip_buffer_put_32(buffer, 0);
  171     _zip_buffer_put_32(buffer, 0);
  172     _zip_buffer_put_64(buffer, survivors);
  173     _zip_buffer_put_64(buffer, survivors);
  174     _zip_buffer_put_64(buffer, size);
  175     _zip_buffer_put_64(buffer, offset);
  176     _zip_buffer_put(buffer, EOCD64LOC_MAGIC, 4);
  177     _zip_buffer_put_32(buffer, 0);
  178     _zip_buffer_put_64(buffer, offset + size);
  179     _zip_buffer_put_32(buffer, 1);
  180     }
  181 
  182     _zip_buffer_put(buffer, EOCD_MAGIC, 4);
  183     _zip_buffer_put_32(buffer, 0);
  184     _zip_buffer_put_16(buffer, (zip_uint16_t)(survivors >= ZIP_UINT16_MAX ? ZIP_UINT16_MAX : survivors));
  185     _zip_buffer_put_16(buffer, (zip_uint16_t)(survivors >= ZIP_UINT16_MAX ? ZIP_UINT16_MAX : survivors));
  186     _zip_buffer_put_32(buffer, size >= ZIP_UINT32_MAX ? ZIP_UINT32_MAX : (zip_uint32_t)size);
  187     _zip_buffer_put_32(buffer, offset >= ZIP_UINT32_MAX ? ZIP_UINT32_MAX : (zip_uint32_t)offset);
  188 
  189     comment = za->comment_changed ? za->comment_changes : za->comment_orig;
  190 
  191     _zip_buffer_put_16(buffer, (zip_uint16_t)(comment ? comment->length : 0));
  192 
  193     if (!_zip_buffer_ok(buffer)) {
  194     zip_error_set(&za->error, ZIP_ER_INTERNAL, 0);
  195     _zip_buffer_free(buffer);
  196     return -1;
  197     }
  198 
  199     if (_zip_write(za, _zip_buffer_data(buffer), _zip_buffer_offset(buffer)) < 0) {
  200     _zip_buffer_free(buffer);
  201     return -1;
  202     }
  203 
  204     _zip_buffer_free(buffer);
  205 
  206     if (comment) {
  207     if (_zip_write(za, comment->raw, comment->length) < 0) {
  208         return -1;
  209     }
  210     }
  211 
  212     return (zip_int64_t)size;
  213 }
  214 
  215 
  216 zip_dirent_t *
  217 _zip_dirent_clone(const zip_dirent_t *sde) {
  218     zip_dirent_t *tde;
  219 
  220     if ((tde = (zip_dirent_t *)malloc(sizeof(*tde))) == NULL)
  221     return NULL;
  222 
  223     if (sde)
  224     memcpy(tde, sde, sizeof(*sde));
  225     else
  226     _zip_dirent_init(tde);
  227 
  228     tde->changed = 0;
  229     tde->cloned = 1;
  230 
  231     return tde;
  232 }
  233 
  234 
  235 void
  236 _zip_dirent_finalize(zip_dirent_t *zde) {
  237     if (!zde->cloned || zde->changed & ZIP_DIRENT_FILENAME) {
  238     _zip_string_free(zde->filename);
  239     zde->filename = NULL;
  240     }
  241     if (!zde->cloned || zde->changed & ZIP_DIRENT_EXTRA_FIELD) {
  242     _zip_ef_free(zde->extra_fields);
  243     zde->extra_fields = NULL;
  244     }
  245     if (!zde->cloned || zde->changed & ZIP_DIRENT_COMMENT) {
  246     _zip_string_free(zde->comment);
  247     zde->comment = NULL;
  248     }
  249     if (!zde->cloned || zde->changed & ZIP_DIRENT_PASSWORD) {
  250     if (zde->password) {
  251         _zip_crypto_clear(zde->password, strlen(zde->password));
  252     }
  253     free(zde->password);
  254     zde->password = NULL;
  255     }
  256 }
  257 
  258 
  259 void
  260 _zip_dirent_free(zip_dirent_t *zde) {
  261     if (zde == NULL)
  262     return;
  263 
  264     _zip_dirent_finalize(zde);
  265     free(zde);
  266 }
  267 
  268 
  269 void
  270 _zip_dirent_init(zip_dirent_t *de) {
  271     de->changed = 0;
  272     de->local_extra_fields_read = 0;
  273     de->cloned = 0;
  274 
  275     de->crc_valid = true;
  276     de->version_madeby = 63 | (ZIP_OPSYS_DEFAULT << 8);
  277     de->version_needed = 10; /* 1.0 */
  278     de->bitflags = 0;
  279     de->comp_method = ZIP_CM_DEFAULT;
  280     de->last_mod = 0;
  281     de->crc = 0;
  282     de->comp_size = 0;
  283     de->uncomp_size = 0;
  284     de->filename = NULL;
  285     de->extra_fields = NULL;
  286     de->comment = NULL;
  287     de->disk_number = 0;
  288     de->int_attrib = 0;
  289     de->ext_attrib = ZIP_EXT_ATTRIB_DEFAULT;
  290     de->offset = 0;
  291     de->compression_level = 0;
  292     de->encryption_method = ZIP_EM_NONE;
  293     de->password = NULL;
  294 }
  295 
  296 
  297 bool
  298 _zip_dirent_needs_zip64(const zip_dirent_t *de, zip_flags_t flags) {
  299     if (de->uncomp_size >= ZIP_UINT32_MAX || de->comp_size >= ZIP_UINT32_MAX || ((flags & ZIP_FL_CENTRAL) && de->offset >= ZIP_UINT32_MAX))
  300     return true;
  301 
  302     return false;
  303 }
  304 
  305 
  306 zip_dirent_t *
  307 _zip_dirent_new(void) {
  308     zip_dirent_t *de;
  309 
  310     if ((de = (zip_dirent_t *)malloc(sizeof(*de))) == NULL)
  311     return NULL;
  312 
  313     _zip_dirent_init(de);
  314     return de;
  315 }
  316 
  317 
  318 /* _zip_dirent_read(zde, fp, bufp, left, localp, error):
  319    Fills the zip directory entry zde.
  320 
  321    If buffer is non-NULL, data is taken from there; otherwise data is read from fp as needed.
  322 
  323    If local is true, it reads a local header instead of a central directory entry.
  324 
  325    Returns size of dirent read if successful. On error, error is filled in and -1 is returned.
  326 */
  327 
  328 zip_int64_t
  329 _zip_dirent_read(zip_dirent_t *zde, zip_source_t *src, zip_buffer_t *buffer, bool local, zip_error_t *error) {
  330     zip_uint8_t buf[CDENTRYSIZE];
  331     zip_uint16_t dostime, dosdate;
  332     zip_uint32_t size, variable_size;
  333     zip_uint16_t filename_len, comment_len, ef_len;
  334 
  335     bool from_buffer = (buffer != NULL);
  336 
  337     size = local ? LENTRYSIZE : CDENTRYSIZE;
  338 
  339     if (buffer) {
  340     if (_zip_buffer_left(buffer) < size) {
  341         zip_error_set(error, ZIP_ER_NOZIP, 0);
  342         return -1;
  343     }
  344     }
  345     else {
  346     if ((buffer = _zip_buffer_new_from_source(src, size, buf, error)) == NULL) {
  347         return -1;
  348     }
  349     }
  350 
  351     if (memcmp(_zip_buffer_get(buffer, 4), (local ? LOCAL_MAGIC : CENTRAL_MAGIC), 4) != 0) {
  352     zip_error_set(error, ZIP_ER_NOZIP, 0);
  353     if (!from_buffer) {
  354         _zip_buffer_free(buffer);
  355     }
  356     return -1;
  357     }
  358 
  359     /* convert buffercontents to zip_dirent */
  360 
  361     _zip_dirent_init(zde);
  362     if (!local)
  363     zde->version_madeby = _zip_buffer_get_16(buffer);
  364     else
  365     zde->version_madeby = 0;
  366     zde->version_needed = _zip_buffer_get_16(buffer);
  367     zde->bitflags = _zip_buffer_get_16(buffer);
  368     zde->comp_method = _zip_buffer_get_16(buffer);
  369 
  370     /* convert to time_t */
  371     dostime = _zip_buffer_get_16(buffer);
  372     dosdate = _zip_buffer_get_16(buffer);
  373     zde->last_mod = _zip_d2u_time(dostime, dosdate);
  374 
  375     zde->crc = _zip_buffer_get_32(buffer);
  376     zde->comp_size = _zip_buffer_get_32(buffer);
  377     zde->uncomp_size = _zip_buffer_get_32(buffer);
  378 
  379     filename_len = _zip_buffer_get_16(buffer);
  380     ef_len = _zip_buffer_get_16(buffer);
  381 
  382     if (local) {
  383     comment_len = 0;
  384     zde->disk_number = 0;
  385     zde->int_attrib = 0;
  386     zde->ext_attrib = 0;
  387     zde->offset = 0;
  388     }
  389     else {
  390     comment_len = _zip_buffer_get_16(buffer);
  391     zde->disk_number = _zip_buffer_get_16(buffer);
  392     zde->int_attrib = _zip_buffer_get_16(buffer);
  393     zde->ext_attrib = _zip_buffer_get_32(buffer);
  394     zde->offset = _zip_buffer_get_32(buffer);
  395     }
  396 
  397     if (!_zip_buffer_ok(buffer)) {
  398     zip_error_set(error, ZIP_ER_INTERNAL, 0);
  399     if (!from_buffer) {
  400         _zip_buffer_free(buffer);
  401     }
  402     return -1;
  403     }
  404 
  405     if (zde->bitflags & ZIP_GPBF_ENCRYPTED) {
  406     if (zde->bitflags & ZIP_GPBF_STRONG_ENCRYPTION) {
  407         /* TODO */
  408         zde->encryption_method = ZIP_EM_UNKNOWN;
  409     }
  410     else {
  411         zde->encryption_method = ZIP_EM_TRAD_PKWARE;
  412     }
  413     }
  414     else {
  415     zde->encryption_method = ZIP_EM_NONE;
  416     }
  417 
  418     zde->filename = NULL;
  419     zde->extra_fields = NULL;
  420     zde->comment = NULL;
  421 
  422     variable_size = (zip_uint32_t)filename_len + (zip_uint32_t)ef_len + (zip_uint32_t)comment_len;
  423 
  424     if (from_buffer) {
  425     if (_zip_buffer_left(buffer) < variable_size) {
  426         zip_error_set(error, ZIP_ER_INCONS, 0);
  427         return -1;
  428     }
  429     }
  430     else {
  431     _zip_buffer_free(buffer);
  432 
  433     if ((buffer = _zip_buffer_new_from_source(src, variable_size, NULL, error)) == NULL) {
  434         return -1;
  435     }
  436     }
  437 
  438     if (filename_len) {
  439     zde->filename = _zip_read_string(buffer, src, filename_len, 1, error);
  440     if (!zde->filename) {
  441         if (zip_error_code_zip(error) == ZIP_ER_EOF) {
  442         zip_error_set(error, ZIP_ER_INCONS, 0);
  443         }
  444         if (!from_buffer) {
  445         _zip_buffer_free(buffer);
  446         }
  447         return -1;
  448     }
  449 
  450     if (zde->bitflags & ZIP_GPBF_ENCODING_UTF_8) {
  451         if (_zip_guess_encoding(zde->filename, ZIP_ENCODING_UTF8_KNOWN) == ZIP_ENCODING_ERROR) {
  452         zip_error_set(error, ZIP_ER_INCONS, 0);
  453         if (!from_buffer) {
  454             _zip_buffer_free(buffer);
  455         }
  456         return -1;
  457         }
  458     }
  459     }
  460 
  461     if (ef_len) {
  462     zip_uint8_t *ef = _zip_read_data(buffer, src, ef_len, 0, error);
  463 
  464     if (ef == NULL) {
  465         if (!from_buffer) {
  466         _zip_buffer_free(buffer);
  467         }
  468         return -1;
  469     }
  470     if (!_zip_ef_parse(ef, ef_len, local ? ZIP_EF_LOCAL : ZIP_EF_CENTRAL, &zde->extra_fields, error)) {
  471         free(ef);
  472         if (!from_buffer) {
  473         _zip_buffer_free(buffer);
  474         }
  475         return -1;
  476     }
  477     free(ef);
  478     if (local)
  479         zde->local_extra_fields_read = 1;
  480     }
  481 
  482     if (comment_len) {
  483     zde->comment = _zip_read_string(buffer, src, comment_len, 0, error);
  484     if (!zde->comment) {
  485         if (!from_buffer) {
  486         _zip_buffer_free(buffer);
  487         }
  488         return -1;
  489     }
  490     if (zde->bitflags & ZIP_GPBF_ENCODING_UTF_8) {
  491         if (_zip_guess_encoding(zde->comment, ZIP_ENCODING_UTF8_KNOWN) == ZIP_ENCODING_ERROR) {
  492         zip_error_set(error, ZIP_ER_INCONS, 0);
  493         if (!from_buffer) {
  494             _zip_buffer_free(buffer);
  495         }
  496         return -1;
  497         }
  498     }
  499     }
  500 
  501     zde->filename = _zip_dirent_process_ef_utf_8(zde, ZIP_EF_UTF_8_NAME, zde->filename);
  502     zde->comment = _zip_dirent_process_ef_utf_8(zde, ZIP_EF_UTF_8_COMMENT, zde->comment);
  503 
  504     /* Zip64 */
  505 
  506     if (zde->uncomp_size == ZIP_UINT32_MAX || zde->comp_size == ZIP_UINT32_MAX || zde->offset == ZIP_UINT32_MAX) {
  507     zip_uint16_t got_len;
  508     zip_buffer_t *ef_buffer;
  509     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);
  510     /* TODO: if got_len == 0 && !ZIP64_EOCD: no error, 0xffffffff is valid value */
  511     if (ef == NULL) {
  512         if (!from_buffer) {
  513         _zip_buffer_free(buffer);
  514         }
  515         return -1;
  516     }
  517 
  518     if ((ef_buffer = _zip_buffer_new((zip_uint8_t *)ef, got_len)) == NULL) {
  519         zip_error_set(error, ZIP_ER_MEMORY, 0);
  520         if (!from_buffer) {
  521         _zip_buffer_free(buffer);
  522         }
  523         return -1;
  524     }
  525 
  526     if (zde->uncomp_size == ZIP_UINT32_MAX)
  527         zde->uncomp_size = _zip_buffer_get_64(ef_buffer);
  528     else if (local) {
  529         /* From appnote.txt: This entry in the Local header MUST
  530            include BOTH original and compressed file size fields. */
  531         (void)_zip_buffer_skip(ef_buffer, 8); /* error is caught by _zip_buffer_eof() call */
  532     }
  533     if (zde->comp_size == ZIP_UINT32_MAX)
  534         zde->comp_size = _zip_buffer_get_64(ef_buffer);
  535     if (!local) {
  536         if (zde->offset == ZIP_UINT32_MAX)
  537         zde->offset = _zip_buffer_get_64(ef_buffer);
  538         if (zde->disk_number == ZIP_UINT16_MAX)
  539         zde->disk_number = _zip_buffer_get_32(buffer);
  540     }
  541 
  542     if (!_zip_buffer_eof(ef_buffer)) {
  543         zip_error_set(error, ZIP_ER_INCONS, 0);
  544         _zip_buffer_free(ef_buffer);
  545         if (!from_buffer) {
  546         _zip_buffer_free(buffer);
  547         }
  548         return -1;
  549     }
  550     _zip_buffer_free(ef_buffer);
  551     }
  552 
  553     if (!_zip_buffer_ok(buffer)) {
  554     zip_error_set(error, ZIP_ER_INTERNAL, 0);
  555     if (!from_buffer) {
  556         _zip_buffer_free(buffer);
  557     }
  558     return -1;
  559     }
  560     if (!from_buffer) {
  561     _zip_buffer_free(buffer);
  562     }
  563 
  564     /* zip_source_seek / zip_source_tell don't support values > ZIP_INT64_MAX */
  565     if (zde->offset > ZIP_INT64_MAX) {
  566     zip_error_set(error, ZIP_ER_SEEK, EFBIG);
  567     return -1;
  568     }
  569 
  570     if (!_zip_dirent_process_winzip_aes(zde, error)) {
  571     return -1;
  572     }
  573 
  574     zde->extra_fields = _zip_ef_remove_internal(zde->extra_fields);
  575 
  576     return (zip_int64_t)(size + variable_size);
  577 }
  578 
  579 
  580 static zip_string_t *
  581 _zip_dirent_process_ef_utf_8(const zip_dirent_t *de, zip_uint16_t id, zip_string_t *str) {
  582     zip_uint16_t ef_len;
  583     zip_uint32_t ef_crc;
  584     zip_buffer_t *buffer;
  585 
  586     const zip_uint8_t *ef = _zip_ef_get_by_id(de->extra_fields, &ef_len, id, 0, ZIP_EF_BOTH, NULL);
  587 
  588     if (ef == NULL || ef_len < 5 || ef[0] != 1) {
  589     return str;
  590     }
  591 
  592     if ((buffer = _zip_buffer_new((zip_uint8_t *)ef, ef_len)) == NULL) {
  593     return str;
  594     }
  595 
  596     _zip_buffer_get_8(buffer);
  597     ef_crc = _zip_buffer_get_32(buffer);
  598 
  599     if (_zip_string_crc32(str) == ef_crc) {
  600     zip_uint16_t len = (zip_uint16_t)_zip_buffer_left(buffer);
  601     zip_string_t *ef_str = _zip_string_new(_zip_buffer_get(buffer, len), len, ZIP_FL_ENC_UTF_8, NULL);
  602 
  603     if (ef_str != NULL) {
  604         _zip_string_free(str);
  605         str = ef_str;
  606     }
  607     }
  608 
  609     _zip_buffer_free(buffer);
  610 
  611     return str;
  612 }
  613 
  614 
  615 static bool
  616 _zip_dirent_process_winzip_aes(zip_dirent_t *de, zip_error_t *error) {
  617     zip_uint16_t ef_len;
  618     zip_buffer_t *buffer;
  619     const zip_uint8_t *ef;
  620     bool crc_valid;
  621     zip_uint16_t enc_method;
  622 
  623 
  624     if (de->comp_method != ZIP_CM_WINZIP_AES) {
  625     return true;
  626     }
  627 
  628     ef = _zip_ef_get_by_id(de->extra_fields, &ef_len, ZIP_EF_WINZIP_AES, 0, ZIP_EF_BOTH, NULL);
  629 
  630     if (ef == NULL || ef_len < 7) {
  631     zip_error_set(error, ZIP_ER_INCONS, 0);
  632     return false;
  633     }
  634 
  635     if ((buffer = _zip_buffer_new((zip_uint8_t *)ef, ef_len)) == NULL) {
  636     zip_error_set(error, ZIP_ER_INTERNAL, 0);
  637     return false;
  638     }
  639 
  640     /* version */
  641 
  642     crc_valid = true;
  643     switch (_zip_buffer_get_16(buffer)) {
  644     case 1:
  645     break;
  646 
  647     case 2:
  648     if (de->uncomp_size < 20 /* TODO: constant */) {
  649         crc_valid = false;
  650     }
  651     break;
  652 
  653     default:
  654     zip_error_set(error, ZIP_ER_ENCRNOTSUPP, 0);
  655     _zip_buffer_free(buffer);
  656     return false;
  657     }
  658 
  659     /* vendor */
  660     if (memcmp(_zip_buffer_get(buffer, 2), "AE", 2) != 0) {
  661     zip_error_set(error, ZIP_ER_ENCRNOTSUPP, 0);
  662     _zip_buffer_free(buffer);
  663     return false;
  664     }
  665 
  666     /* mode */
  667     switch (_zip_buffer_get_8(buffer)) {
  668     case 1:
  669     enc_method = ZIP_EM_AES_128;
  670     break;
  671     case 2:
  672     enc_method = ZIP_EM_AES_192;
  673     break;
  674     case 3:
  675     enc_method = ZIP_EM_AES_256;
  676     break;
  677     default:
  678     zip_error_set(error, ZIP_ER_ENCRNOTSUPP, 0);
  679     _zip_buffer_free(buffer);
  680     return false;
  681     }
  682 
  683     if (ef_len != 7) {
  684     zip_error_set(error, ZIP_ER_INCONS, 0);
  685     _zip_buffer_free(buffer);
  686     return false;
  687     }
  688 
  689     de->crc_valid = crc_valid;
  690     de->encryption_method = enc_method;
  691     de->comp_method = _zip_buffer_get_16(buffer);
  692 
  693     _zip_buffer_free(buffer);
  694     return true;
  695 }
  696 
  697 
  698 zip_int32_t
  699 _zip_dirent_size(zip_source_t *src, zip_uint16_t flags, zip_error_t *error) {
  700     zip_int32_t size;
  701     bool local = (flags & ZIP_EF_LOCAL) != 0;
  702     int i;
  703     zip_uint8_t b[6];
  704     zip_buffer_t *buffer;
  705 
  706     size = local ? LENTRYSIZE : CDENTRYSIZE;
  707 
  708     if (zip_source_seek(src, local ? 26 : 28, SEEK_CUR) < 0) {
  709     _zip_error_set_from_source(error, src);
  710     return -1;
  711     }
  712 
  713     if ((buffer = _zip_buffer_new_from_source(src, local ? 4 : 6, b, error)) == NULL) {
  714     return -1;
  715     }
  716 
  717     for (i = 0; i < (local ? 2 : 3); i++) {
  718     size += _zip_buffer_get_16(buffer);
  719     }
  720 
  721     if (!_zip_buffer_eof(buffer)) {
  722     zip_error_set(error, ZIP_ER_INTERNAL, 0);
  723     _zip_buffer_free(buffer);
  724     return -1;
  725     }
  726 
  727     _zip_buffer_free(buffer);
  728     return size;
  729 }
  730 
  731 
  732 /* _zip_dirent_write
  733    Writes zip directory entry.
  734 
  735    If flags & ZIP_EF_LOCAL, it writes a local header instead of a central
  736    directory entry.  If flags & ZIP_EF_FORCE_ZIP64, a ZIP64 extra field is written, even if not needed.
  737 
  738    Returns 0 if successful, 1 if successful and wrote ZIP64 extra field. On error, error is filled in and -1 is
  739    returned.
  740 */
  741 
  742 int
  743 _zip_dirent_write(zip_t *za, zip_dirent_t *de, zip_flags_t flags) {
  744     zip_uint16_t dostime, dosdate;
  745     zip_encoding_type_t com_enc, name_enc;
  746     zip_extra_field_t *ef;
  747     zip_extra_field_t *ef64;
  748     zip_uint32_t ef_total_size;
  749     bool is_zip64;
  750     bool is_really_zip64;
  751     bool is_winzip_aes;
  752     zip_uint8_t buf[CDENTRYSIZE];
  753     zip_buffer_t *buffer;
  754 
  755     ef = NULL;
  756 
  757     name_enc = _zip_guess_encoding(de->filename, ZIP_ENCODING_UNKNOWN);
  758     com_enc = _zip_guess_encoding(de->comment, ZIP_ENCODING_UNKNOWN);
  759 
  760     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))
  761     de->bitflags |= ZIP_GPBF_ENCODING_UTF_8;
  762     else {
  763     de->bitflags &= (zip_uint16_t)~ZIP_GPBF_ENCODING_UTF_8;
  764     if (name_enc == ZIP_ENCODING_UTF8_KNOWN) {
  765         ef = _zip_ef_utf8(ZIP_EF_UTF_8_NAME, de->filename, &za->error);
  766         if (ef == NULL)
  767         return -1;
  768     }
  769     if ((flags & ZIP_FL_LOCAL) == 0 && com_enc == ZIP_ENCODING_UTF8_KNOWN) {
  770         zip_extra_field_t *ef2 = _zip_ef_utf8(ZIP_EF_UTF_8_COMMENT, de->comment, &za->error);
  771         if (ef2 == NULL) {
  772         _zip_ef_free(ef);
  773         return -1;
  774         }
  775         ef2->next = ef;
  776         ef = ef2;
  777     }
  778     }
  779 
  780     if (de->encryption_method == ZIP_EM_NONE) {
  781     de->bitflags &= (zip_uint16_t)~ZIP_GPBF_ENCRYPTED;
  782     }
  783     else {
  784     de->bitflags |= (zip_uint16_t)ZIP_GPBF_ENCRYPTED;
  785     }
  786 
  787     is_really_zip64 = _zip_dirent_needs_zip64(de, flags);
  788     is_zip64 = (flags & (ZIP_FL_LOCAL | ZIP_FL_FORCE_ZIP64)) == (ZIP_FL_LOCAL | ZIP_FL_FORCE_ZIP64) || is_really_zip64;
  789     is_winzip_aes = de->encryption_method == ZIP_EM_AES_128 || de->encryption_method == ZIP_EM_AES_192 || de->encryption_method == ZIP_EM_AES_256;
  790 
  791     if (is_zip64) {
  792     zip_uint8_t ef_zip64[EFZIP64SIZE];
  793     zip_buffer_t *ef_buffer = _zip_buffer_new(ef_zip64, sizeof(ef_zip64));
  794     if (ef_buffer == NULL) {
  795         zip_error_set(&za->error, ZIP_ER_MEMORY, 0);
  796         _zip_ef_free(ef);
  797         return -1;
  798     }
  799 
  800     if (flags & ZIP_FL_LOCAL) {
  801         if ((flags & ZIP_FL_FORCE_ZIP64) || de->comp_size > ZIP_UINT32_MAX || de->uncomp_size > ZIP_UINT32_MAX) {
  802         _zip_buffer_put_64(ef_buffer, de->uncomp_size);
  803         _zip_buffer_put_64(ef_buffer, de->comp_size);
  804         }
  805     }
  806     else {
  807         if ((flags & ZIP_FL_FORCE_ZIP64) || de->comp_size > ZIP_UINT32_MAX || de->uncomp_size > ZIP_UINT32_MAX || de->offset > ZIP_UINT32_MAX) {
  808         if (de->uncomp_size >= ZIP_UINT32_MAX) {
  809             _zip_buffer_put_64(ef_buffer, de->uncomp_size);
  810         }
  811         if (de->comp_size >= ZIP_UINT32_MAX) {
  812             _zip_buffer_put_64(ef_buffer, de->comp_size);
  813         }
  814         if (de->offset >= ZIP_UINT32_MAX) {
  815             _zip_buffer_put_64(ef_buffer, de->offset);
  816         }
  817         }
  818     }
  819 
  820     if (!_zip_buffer_ok(ef_buffer)) {
  821         zip_error_set(&za->error, ZIP_ER_INTERNAL, 0);
  822         _zip_buffer_free(ef_buffer);
  823         _zip_ef_free(ef);
  824         return -1;
  825     }
  826 
  827     ef64 = _zip_ef_new(ZIP_EF_ZIP64, (zip_uint16_t)(_zip_buffer_offset(ef_buffer)), ef_zip64, ZIP_EF_BOTH);
  828     _zip_buffer_free(ef_buffer);
  829     ef64->next = ef;
  830     ef = ef64;
  831     }
  832 
  833     if (is_winzip_aes) {
  834     zip_uint8_t data[EF_WINZIP_AES_SIZE];
  835     zip_buffer_t *ef_buffer = _zip_buffer_new(data, sizeof(data));
  836     zip_extra_field_t *ef_winzip;
  837 
  838     if (ef_buffer == NULL) {
  839         zip_error_set(&za->error, ZIP_ER_MEMORY, 0);
  840         _zip_ef_free(ef);
  841         return -1;
  842     }
  843 
  844     _zip_buffer_put_16(ef_buffer, 2);
  845     _zip_buffer_put(ef_buffer, "AE", 2);
  846     _zip_buffer_put_8(ef_buffer, (zip_uint8_t)(de->encryption_method & 0xff));
  847     _zip_buffer_put_16(ef_buffer, (zip_uint16_t)de->comp_method);
  848 
  849     if (!_zip_buffer_ok(ef_buffer)) {
  850         zip_error_set(&za->error, ZIP_ER_INTERNAL, 0);
  851         _zip_buffer_free(ef_buffer);
  852         _zip_ef_free(ef);
  853         return -1;
  854     }
  855 
  856     ef_winzip = _zip_ef_new(ZIP_EF_WINZIP_AES, EF_WINZIP_AES_SIZE, data, ZIP_EF_BOTH);
  857     _zip_buffer_free(ef_buffer);
  858     ef_winzip->next = ef;
  859     ef = ef_winzip;
  860     }
  861 
  862     if ((buffer = _zip_buffer_new(buf, sizeof(buf))) == NULL) {
  863     zip_error_set(&za->error, ZIP_ER_MEMORY, 0);
  864     _zip_ef_free(ef);
  865     return -1;
  866     }
  867 
  868     _zip_buffer_put(buffer, (flags & ZIP_FL_LOCAL) ? LOCAL_MAGIC : CENTRAL_MAGIC, 4);
  869 
  870     if ((flags & ZIP_FL_LOCAL) == 0) {
  871     _zip_buffer_put_16(buffer, (zip_uint16_t)(is_really_zip64 ? 45 : de->version_madeby));
  872     }
  873     _zip_buffer_put_16(buffer, (zip_uint16_t)(is_really_zip64 ? 45 : de->version_needed));
  874     _zip_buffer_put_16(buffer, de->bitflags);
  875     if (is_winzip_aes) {
  876     _zip_buffer_put_16(buffer, ZIP_CM_WINZIP_AES);
  877     }
  878     else {
  879     _zip_buffer_put_16(buffer, (zip_uint16_t)de->comp_method);
  880     }
  881 
  882     _zip_u2d_time(de->last_mod, &dostime, &dosdate);
  883     _zip_buffer_put_16(buffer, dostime);
  884     _zip_buffer_put_16(buffer, dosdate);
  885 
  886     if (is_winzip_aes && de->uncomp_size < 20) {
  887     _zip_buffer_put_32(buffer, 0);
  888     }
  889     else {
  890     _zip_buffer_put_32(buffer, de->crc);
  891     }
  892 
  893     if (((flags & ZIP_FL_LOCAL) == ZIP_FL_LOCAL) && ((de->comp_size >= ZIP_UINT32_MAX) || (de->uncomp_size >= ZIP_UINT32_MAX))) {
  894     /* In local headers, if a ZIP64 EF is written, it MUST contain
  895      * both compressed and uncompressed sizes (even if one of the
  896      * two is smaller than 0xFFFFFFFF); on the other hand, those
  897      * may only appear when the corresponding standard entry is
  898      * 0xFFFFFFFF.  (appnote.txt 4.5.3) */
  899     _zip_buffer_put_32(buffer, ZIP_UINT32_MAX);
  900     _zip_buffer_put_32(buffer, ZIP_UINT32_MAX);
  901     }
  902     else {
  903     if (de->comp_size < ZIP_UINT32_MAX) {
  904         _zip_buffer_put_32(buffer, (zip_uint32_t)de->comp_size);
  905     }
  906     else {
  907         _zip_buffer_put_32(buffer, ZIP_UINT32_MAX);
  908     }
  909     if (de->uncomp_size < ZIP_UINT32_MAX) {
  910         _zip_buffer_put_32(buffer, (zip_uint32_t)de->uncomp_size);
  911     }
  912     else {
  913         _zip_buffer_put_32(buffer, ZIP_UINT32_MAX);
  914     }
  915     }
  916 
  917     _zip_buffer_put_16(buffer, _zip_string_length(de->filename));
  918     /* TODO: check for overflow */
  919     ef_total_size = (zip_uint32_t)_zip_ef_size(de->extra_fields, flags) + (zip_uint32_t)_zip_ef_size(ef, ZIP_EF_BOTH);
  920     _zip_buffer_put_16(buffer, (zip_uint16_t)ef_total_size);
  921 
  922     if ((flags & ZIP_FL_LOCAL) == 0) {
  923     _zip_buffer_put_16(buffer, _zip_string_length(de->comment));
  924     _zip_buffer_put_16(buffer, (zip_uint16_t)de->disk_number);
  925     _zip_buffer_put_16(buffer, de->int_attrib);
  926     _zip_buffer_put_32(buffer, de->ext_attrib);
  927     if (de->offset < ZIP_UINT32_MAX)
  928         _zip_buffer_put_32(buffer, (zip_uint32_t)de->offset);
  929     else
  930         _zip_buffer_put_32(buffer, ZIP_UINT32_MAX);
  931     }
  932 
  933     if (!_zip_buffer_ok(buffer)) {
  934     zip_error_set(&za->error, ZIP_ER_INTERNAL, 0);
  935     _zip_buffer_free(buffer);
  936     _zip_ef_free(ef);
  937     return -1;
  938     }
  939 
  940     if (_zip_write(za, buf, _zip_buffer_offset(buffer)) < 0) {
  941     _zip_buffer_free(buffer);
  942     _zip_ef_free(ef);
  943     return -1;
  944     }
  945 
  946     _zip_buffer_free(buffer);
  947 
  948     if (de->filename) {
  949     if (_zip_string_write(za, de->filename) < 0) {
  950         _zip_ef_free(ef);
  951         return -1;
  952     }
  953     }
  954 
  955     if (ef) {
  956     if (_zip_ef_write(za, ef, ZIP_EF_BOTH) < 0) {
  957         _zip_ef_free(ef);
  958         return -1;
  959     }
  960     }
  961     _zip_ef_free(ef);
  962     if (de->extra_fields) {
  963     if (_zip_ef_write(za, de->extra_fields, flags) < 0) {
  964         return -1;
  965     }
  966     }
  967 
  968     if ((flags & ZIP_FL_LOCAL) == 0) {
  969     if (de->comment) {
  970         if (_zip_string_write(za, de->comment) < 0) {
  971         return -1;
  972         }
  973     }
  974     }
  975 
  976 
  977     return is_zip64;
  978 }
  979 
  980 
  981 static time_t
  982 _zip_d2u_time(zip_uint16_t dtime, zip_uint16_t ddate) {
  983     struct tm tm;
  984 
  985     memset(&tm, 0, sizeof(tm));
  986 
  987     /* let mktime decide if DST is in effect */
  988     tm.tm_isdst = -1;
  989 
  990     tm.tm_year = ((ddate >> 9) & 127) + 1980 - 1900;
  991     tm.tm_mon = ((ddate >> 5) & 15) - 1;
  992     tm.tm_mday = ddate & 31;
  993 
  994     tm.tm_hour = (dtime >> 11) & 31;
  995     tm.tm_min = (dtime >> 5) & 63;
  996     tm.tm_sec = (dtime << 1) & 62;
  997 
  998     return mktime(&tm);
  999 }
 1000 
 1001 
 1002 static zip_extra_field_t *
 1003 _zip_ef_utf8(zip_uint16_t id, zip_string_t *str, zip_error_t *error) {
 1004     const zip_uint8_t *raw;
 1005     zip_uint32_t len;
 1006     zip_buffer_t *buffer;
 1007     zip_extra_field_t *ef;
 1008 
 1009     if ((raw = _zip_string_get(str, &len, ZIP_FL_ENC_RAW, NULL)) == NULL) {
 1010     /* error already set */
 1011     return NULL;
 1012     }
 1013 
 1014     if (len + 5 > ZIP_UINT16_MAX) {
 1015     zip_error_set(error, ZIP_ER_INVAL, 0); /* TODO: better error code? */
 1016     return NULL;
 1017     }
 1018 
 1019     if ((buffer = _zip_buffer_new(NULL, len + 5)) == NULL) {
 1020     zip_error_set(error, ZIP_ER_MEMORY, 0);
 1021     return NULL;
 1022     }
 1023 
 1024     _zip_buffer_put_8(buffer, 1);
 1025     _zip_buffer_put_32(buffer, _zip_string_crc32(str));
 1026     _zip_buffer_put(buffer, raw, len);
 1027 
 1028     if (!_zip_buffer_ok(buffer)) {
 1029     zip_error_set(error, ZIP_ER_INTERNAL, 0);
 1030     _zip_buffer_free(buffer);
 1031     return NULL;
 1032     }
 1033 
 1034     ef = _zip_ef_new(id, (zip_uint16_t)(_zip_buffer_offset(buffer)), _zip_buffer_data(buffer), ZIP_EF_BOTH);
 1035     _zip_buffer_free(buffer);
 1036 
 1037     return ef;
 1038 }
 1039 
 1040 
 1041 zip_dirent_t *
 1042 _zip_get_dirent(zip_t *za, zip_uint64_t idx, zip_flags_t flags, zip_error_t *error) {
 1043     if (error == NULL)
 1044     error = &za->error;
 1045 
 1046     if (idx >= za->nentry) {
 1047     zip_error_set(error, ZIP_ER_INVAL, 0);
 1048     return NULL;
 1049     }
 1050 
 1051     if ((flags & ZIP_FL_UNCHANGED) || za->entry[idx].changes == NULL) {
 1052     if (za->entry[idx].orig == NULL) {
 1053         zip_error_set(error, ZIP_ER_INVAL, 0);
 1054         return NULL;
 1055     }
 1056     if (za->entry[idx].deleted && (flags & ZIP_FL_UNCHANGED) == 0) {
 1057         zip_error_set(error, ZIP_ER_DELETED, 0);
 1058         return NULL;
 1059     }
 1060     return za->entry[idx].orig;
 1061     }
 1062     else
 1063     return za->entry[idx].changes;
 1064 }
 1065 
 1066 
 1067 void
 1068 _zip_u2d_time(time_t intime, zip_uint16_t *dtime, zip_uint16_t *ddate) {
 1069     struct tm *tm;
 1070 
 1071     tm = localtime(&intime);
 1072     if (tm->tm_year < 80) {
 1073     tm->tm_year = 80;
 1074     }
 1075 
 1076     *ddate = (zip_uint16_t)(((tm->tm_year + 1900 - 1980) << 9) + ((tm->tm_mon + 1) << 5) + tm->tm_mday);
 1077     *dtime = (zip_uint16_t)(((tm->tm_hour) << 11) + ((tm->tm_min) << 5) + ((tm->tm_sec) >> 1));
 1078 
 1079     return;
 1080 }
 1081 
 1082 
 1083 void
 1084 _zip_dirent_set_version_needed(zip_dirent_t *de, bool force_zip64) {
 1085     zip_uint16_t length;
 1086 
 1087     if (de->comp_method == ZIP_CM_LZMA) {
 1088     de->version_needed = 63;
 1089     return;
 1090     }
 1091 
 1092     if (de->comp_method == ZIP_CM_BZIP2) {
 1093     de->version_needed = 46;
 1094     return;
 1095     }
 1096 
 1097     if (force_zip64 || _zip_dirent_needs_zip64(de, 0)) {
 1098     de->version_needed = 45;
 1099     return;
 1100     }
 1101 
 1102     if (de->comp_method == ZIP_CM_DEFLATE || de->encryption_method == ZIP_EM_TRAD_PKWARE) {
 1103     de->version_needed = 20;
 1104     return;
 1105     }
 1106 
 1107     /* directory */
 1108     if ((length = _zip_string_length(de->filename)) > 0) {
 1109     if (de->filename->raw[length - 1] == '/') {
 1110         de->version_needed = 20;
 1111         return;
 1112     }
 1113     }
 1114 
 1115     de->version_needed = 10;
 1116 }