"Fossies" - the Fresh Open Source Software Archive

Member "src/Common/libzip/zip_extra_field_api.c" (10 Oct 2018, 8847 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_extra_field_api.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_extra_field_api.c -- public extra fields API functions
    3   Copyright (C) 2012-2014 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 "zipint.h"
   36 
   37 
   38 ZIP_EXTERN int
   39 zip_file_extra_field_delete(zip_t *za, zip_uint64_t idx, zip_uint16_t ef_idx, zip_flags_t flags) {
   40     zip_dirent_t *de;
   41 
   42     if ((flags & ZIP_EF_BOTH) == 0) {
   43     zip_error_set(&za->error, ZIP_ER_INVAL, 0);
   44     return -1;
   45     }
   46 
   47     if (((flags & ZIP_EF_BOTH) == ZIP_EF_BOTH) && (ef_idx != ZIP_EXTRA_FIELD_ALL)) {
   48     zip_error_set(&za->error, ZIP_ER_INVAL, 0);
   49     return -1;
   50     }
   51 
   52     if (_zip_get_dirent(za, idx, 0, NULL) == NULL)
   53     return -1;
   54 
   55     if (ZIP_IS_RDONLY(za)) {
   56     zip_error_set(&za->error, ZIP_ER_RDONLY, 0);
   57     return -1;
   58     }
   59 
   60     if (_zip_file_extra_field_prepare_for_change(za, idx) < 0)
   61     return -1;
   62 
   63     de = za->entry[idx].changes;
   64 
   65     de->extra_fields = _zip_ef_delete_by_id(de->extra_fields, ZIP_EXTRA_FIELD_ALL, ef_idx, flags);
   66     return 0;
   67 }
   68 
   69 
   70 ZIP_EXTERN int
   71 zip_file_extra_field_delete_by_id(zip_t *za, zip_uint64_t idx, zip_uint16_t ef_id, zip_uint16_t ef_idx, zip_flags_t flags) {
   72     zip_dirent_t *de;
   73 
   74     if ((flags & ZIP_EF_BOTH) == 0) {
   75     zip_error_set(&za->error, ZIP_ER_INVAL, 0);
   76     return -1;
   77     }
   78 
   79     if (((flags & ZIP_EF_BOTH) == ZIP_EF_BOTH) && (ef_idx != ZIP_EXTRA_FIELD_ALL)) {
   80     zip_error_set(&za->error, ZIP_ER_INVAL, 0);
   81     return -1;
   82     }
   83 
   84     if (_zip_get_dirent(za, idx, 0, NULL) == NULL)
   85     return -1;
   86 
   87     if (ZIP_IS_RDONLY(za)) {
   88     zip_error_set(&za->error, ZIP_ER_RDONLY, 0);
   89     return -1;
   90     }
   91 
   92     if (_zip_file_extra_field_prepare_for_change(za, idx) < 0)
   93     return -1;
   94 
   95     de = za->entry[idx].changes;
   96 
   97     de->extra_fields = _zip_ef_delete_by_id(de->extra_fields, ef_id, ef_idx, flags);
   98     return 0;
   99 }
  100 
  101 
  102 ZIP_EXTERN const zip_uint8_t *
  103 zip_file_extra_field_get(zip_t *za, zip_uint64_t idx, zip_uint16_t ef_idx, zip_uint16_t *idp, zip_uint16_t *lenp, zip_flags_t flags) {
  104     static const zip_uint8_t empty[1] = {'\0'};
  105 
  106     zip_dirent_t *de;
  107     zip_extra_field_t *ef;
  108     int i;
  109 
  110     if ((flags & ZIP_EF_BOTH) == 0) {
  111     zip_error_set(&za->error, ZIP_ER_INVAL, 0);
  112     return NULL;
  113     }
  114 
  115     if ((de = _zip_get_dirent(za, idx, flags, &za->error)) == NULL)
  116     return NULL;
  117 
  118     if (flags & ZIP_FL_LOCAL)
  119     if (_zip_read_local_ef(za, idx) < 0)
  120         return NULL;
  121 
  122     i = 0;
  123     for (ef = de->extra_fields; ef; ef = ef->next) {
  124     if (ef->flags & flags & ZIP_EF_BOTH) {
  125         if (i < ef_idx) {
  126         i++;
  127         continue;
  128         }
  129 
  130         if (idp)
  131         *idp = ef->id;
  132         if (lenp)
  133         *lenp = ef->size;
  134         if (ef->size > 0)
  135         return ef->data;
  136         else
  137         return empty;
  138     }
  139     }
  140 
  141     zip_error_set(&za->error, ZIP_ER_NOENT, 0);
  142     return NULL;
  143 }
  144 
  145 
  146 ZIP_EXTERN const zip_uint8_t *
  147 zip_file_extra_field_get_by_id(zip_t *za, zip_uint64_t idx, zip_uint16_t ef_id, zip_uint16_t ef_idx, zip_uint16_t *lenp, zip_flags_t flags) {
  148     zip_dirent_t *de;
  149 
  150     if ((flags & ZIP_EF_BOTH) == 0) {
  151     zip_error_set(&za->error, ZIP_ER_INVAL, 0);
  152     return NULL;
  153     }
  154 
  155     if ((de = _zip_get_dirent(za, idx, flags, &za->error)) == NULL)
  156     return NULL;
  157 
  158     if (flags & ZIP_FL_LOCAL)
  159     if (_zip_read_local_ef(za, idx) < 0)
  160         return NULL;
  161 
  162     return _zip_ef_get_by_id(de->extra_fields, lenp, ef_id, ef_idx, flags, &za->error);
  163 }
  164 
  165 
  166 ZIP_EXTERN zip_int16_t
  167 zip_file_extra_fields_count(zip_t *za, zip_uint64_t idx, zip_flags_t flags) {
  168     zip_dirent_t *de;
  169     zip_extra_field_t *ef;
  170     zip_uint16_t n;
  171 
  172     if ((flags & ZIP_EF_BOTH) == 0) {
  173     zip_error_set(&za->error, ZIP_ER_INVAL, 0);
  174     return -1;
  175     }
  176 
  177     if ((de = _zip_get_dirent(za, idx, flags, &za->error)) == NULL)
  178     return -1;
  179 
  180     if (flags & ZIP_FL_LOCAL)
  181     if (_zip_read_local_ef(za, idx) < 0)
  182         return -1;
  183 
  184     n = 0;
  185     for (ef = de->extra_fields; ef; ef = ef->next)
  186     if (ef->flags & flags & ZIP_EF_BOTH)
  187         n++;
  188 
  189     return (zip_int16_t)n;
  190 }
  191 
  192 
  193 ZIP_EXTERN zip_int16_t
  194 zip_file_extra_fields_count_by_id(zip_t *za, zip_uint64_t idx, zip_uint16_t ef_id, zip_flags_t flags) {
  195     zip_dirent_t *de;
  196     zip_extra_field_t *ef;
  197     zip_uint16_t n;
  198 
  199     if ((flags & ZIP_EF_BOTH) == 0) {
  200     zip_error_set(&za->error, ZIP_ER_INVAL, 0);
  201     return -1;
  202     }
  203 
  204     if ((de = _zip_get_dirent(za, idx, flags, &za->error)) == NULL)
  205     return -1;
  206 
  207     if (flags & ZIP_FL_LOCAL)
  208     if (_zip_read_local_ef(za, idx) < 0)
  209         return -1;
  210 
  211     n = 0;
  212     for (ef = de->extra_fields; ef; ef = ef->next)
  213     if (ef->id == ef_id && (ef->flags & flags & ZIP_EF_BOTH))
  214         n++;
  215 
  216     return (zip_int16_t)n;
  217 }
  218 
  219 
  220 ZIP_EXTERN int
  221 zip_file_extra_field_set(zip_t *za, zip_uint64_t idx, zip_uint16_t ef_id, zip_uint16_t ef_idx, const zip_uint8_t *data, zip_uint16_t len, zip_flags_t flags) {
  222     zip_dirent_t *de;
  223     zip_uint16_t ls, cs;
  224     zip_extra_field_t *ef, *ef_prev, *ef_new;
  225     int i, found, new_len;
  226 
  227     if ((flags & ZIP_EF_BOTH) == 0) {
  228     zip_error_set(&za->error, ZIP_ER_INVAL, 0);
  229     return -1;
  230     }
  231 
  232     if (_zip_get_dirent(za, idx, 0, NULL) == NULL)
  233     return -1;
  234 
  235     if (ZIP_IS_RDONLY(za)) {
  236     zip_error_set(&za->error, ZIP_ER_RDONLY, 0);
  237     return -1;
  238     }
  239 
  240     if (ZIP_EF_IS_INTERNAL(ef_id)) {
  241     zip_error_set(&za->error, ZIP_ER_INVAL, 0);
  242     return -1;
  243     }
  244 
  245     if (_zip_file_extra_field_prepare_for_change(za, idx) < 0)
  246     return -1;
  247 
  248     de = za->entry[idx].changes;
  249 
  250     ef = de->extra_fields;
  251     ef_prev = NULL;
  252     i = 0;
  253     found = 0;
  254 
  255     for (; ef; ef = ef->next) {
  256     if (ef->id == ef_id && (ef->flags & flags & ZIP_EF_BOTH)) {
  257         if (i == ef_idx) {
  258         found = 1;
  259         break;
  260         }
  261         i++;
  262     }
  263     ef_prev = ef;
  264     }
  265 
  266     if (i < ef_idx && ef_idx != ZIP_EXTRA_FIELD_NEW) {
  267     zip_error_set(&za->error, ZIP_ER_INVAL, 0);
  268     return -1;
  269     }
  270 
  271     if (flags & ZIP_EF_LOCAL)
  272     ls = _zip_ef_size(de->extra_fields, ZIP_EF_LOCAL);
  273     else
  274     ls = 0;
  275     if (flags & ZIP_EF_CENTRAL)
  276     cs = _zip_ef_size(de->extra_fields, ZIP_EF_CENTRAL);
  277     else
  278     cs = 0;
  279 
  280     new_len = ls > cs ? ls : cs;
  281     if (found)
  282     new_len -= ef->size + 4;
  283     new_len += len + 4;
  284 
  285     if (new_len > ZIP_UINT16_MAX) {
  286     zip_error_set(&za->error, ZIP_ER_INVAL, 0);
  287     return -1;
  288     }
  289 
  290     if ((ef_new = _zip_ef_new(ef_id, len, data, flags)) == NULL) {
  291     zip_error_set(&za->error, ZIP_ER_MEMORY, 0);
  292     return -1;
  293     }
  294 
  295     if (found) {
  296     if ((ef->flags & ZIP_EF_BOTH) == (flags & ZIP_EF_BOTH)) {
  297         ef_new->next = ef->next;
  298         ef->next = NULL;
  299         _zip_ef_free(ef);
  300         if (ef_prev)
  301         ef_prev->next = ef_new;
  302         else
  303         de->extra_fields = ef_new;
  304     }
  305     else {
  306         ef->flags &= ~(flags & ZIP_EF_BOTH);
  307         ef_new->next = ef->next;
  308         ef->next = ef_new;
  309     }
  310     }
  311     else if (ef_prev) {
  312     ef_new->next = ef_prev->next;
  313     ef_prev->next = ef_new;
  314     }
  315     else
  316     de->extra_fields = ef_new;
  317 
  318     return 0;
  319 }
  320 
  321 
  322 int
  323 _zip_file_extra_field_prepare_for_change(zip_t *za, zip_uint64_t idx) {
  324     zip_entry_t *e;
  325 
  326     if (idx >= za->nentry) {
  327     zip_error_set(&za->error, ZIP_ER_INVAL, 0);
  328     return -1;
  329     }
  330 
  331     e = za->entry + idx;
  332 
  333     if (e->changes && (e->changes->changed & ZIP_DIRENT_EXTRA_FIELD))
  334     return 0;
  335 
  336     if (e->orig) {
  337     if (_zip_read_local_ef(za, idx) < 0)
  338         return -1;
  339     }
  340 
  341     if (e->changes == NULL) {
  342     if ((e->changes = _zip_dirent_clone(e->orig)) == NULL) {
  343         zip_error_set(&za->error, ZIP_ER_MEMORY, 0);
  344         return -1;
  345     }
  346     }
  347 
  348     if (e->orig && e->orig->extra_fields) {
  349     if ((e->changes->extra_fields = _zip_ef_clone(e->orig->extra_fields, &za->error)) == NULL)
  350         return -1;
  351     }
  352     e->changes->changed |= ZIP_DIRENT_EXTRA_FIELD;
  353 
  354     return 0;
  355 }