"Fossies" - the Fresh Open Source Software Archive

Member "libzip-1.6.0/lib/zip_dirent.c" (24 Jan 2020, 29796 Bytes) of package /linux/misc/libzip-1.6.0.tar.xz:


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 latest Fossies "Diffs" side-by-side code changes report: 1.5.2_vs_1.6.0.

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