"Fossies" - the Fresh Open Source Software Archive

Member "src/Common/libzip/zip_source_deflate.c" (10 Oct 2018, 10773 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_source_deflate.c" see the Fossies "Dox" file reference documentation.

    1 /*
    2   zip_source_deflate.c -- deflate (de)compressoin routines
    3   Copyright (C) 2009-2015 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 #include <stdlib.h>
   35 #include <string.h>
   36 #include <limits.h>
   37 
   38 #include "zipint.h"
   39 
   40 struct deflate {
   41     zip_error_t error;
   42     
   43     bool eof;
   44     bool can_store;
   45     bool is_stored;
   46     int mem_level;
   47     zip_uint64_t size;
   48     zip_uint8_t buffer[BUFSIZE];
   49     z_stream zstr;
   50 };
   51 
   52 static zip_int64_t compress_read(zip_source_t *, struct deflate *, void *, zip_uint64_t);
   53 static zip_int64_t decompress_read(zip_source_t *, struct deflate *, void *, zip_uint64_t);
   54 static zip_int64_t deflate_compress(zip_source_t *, void *, void *, zip_uint64_t, zip_source_cmd_t);
   55 static zip_int64_t deflate_decompress(zip_source_t *, void *, void *, zip_uint64_t, zip_source_cmd_t);
   56 static void deflate_free(struct deflate *);
   57 
   58 
   59 zip_source_t *
   60 zip_source_deflate(zip_t *za, zip_source_t *src, zip_int32_t cm, int flags)
   61 {
   62     struct deflate *ctx;
   63     zip_source_t *s2;
   64 
   65     if (src == NULL || (cm != ZIP_CM_DEFLATE && !ZIP_CM_IS_DEFAULT(cm))) {
   66     zip_error_set(&za->error, ZIP_ER_INVAL, 0);
   67     return NULL;
   68     }
   69 
   70     if ((ctx=(struct deflate *)malloc(sizeof(*ctx))) == NULL) {
   71     zip_error_set(&za->error, ZIP_ER_MEMORY, 0);
   72     return NULL;
   73     }
   74 
   75     zip_error_init(&ctx->error);
   76     ctx->eof = false;
   77     ctx->is_stored = false;
   78     ctx->can_store = ZIP_CM_IS_DEFAULT(cm);
   79     if (flags & ZIP_CODEC_ENCODE) {
   80     ctx->mem_level = MAX_MEM_LEVEL;
   81     }
   82 
   83     if ((s2=zip_source_layered(za, src,
   84                    ((flags & ZIP_CODEC_ENCODE)
   85                 ? deflate_compress : deflate_decompress),
   86                    ctx)) == NULL) {
   87     deflate_free(ctx);
   88     return NULL;
   89     }
   90 
   91     return s2;
   92 }
   93 
   94 
   95 static zip_int64_t
   96 compress_read(zip_source_t *src, struct deflate *ctx, void *data, zip_uint64_t len)
   97 {
   98     int end, ret;
   99     zip_int64_t n;
  100     zip_uint64_t out_offset;
  101     uInt out_len;
  102 
  103     if (zip_error_code_zip(&ctx->error) != ZIP_ER_OK)
  104     return -1;
  105     
  106     if (len == 0 || ctx->is_stored) {
  107     return 0;
  108     }
  109     
  110     out_offset = 0;
  111     out_len = (uInt)ZIP_MIN(UINT_MAX, len);
  112     ctx->zstr.next_out = (Bytef *)data;
  113     ctx->zstr.avail_out = out_len;
  114 
  115     end = 0;
  116     while (!end) {
  117     ret = deflate(&ctx->zstr, ctx->eof ? Z_FINISH : 0);
  118 
  119     switch (ret) {
  120         case Z_STREAM_END:
  121             if (ctx->can_store && ctx->zstr.total_in <= ctx->zstr.total_out) {
  122                 ctx->is_stored = true;
  123                 ctx->size = ctx->zstr.total_in;
  124                 memcpy(data, ctx->buffer, ctx->size);
  125                 return (zip_int64_t)ctx->size;
  126             }
  127             /* fallthrough */
  128     case Z_OK:
  129         /* all ok */
  130 
  131         if (ctx->zstr.avail_out == 0) {
  132         out_offset += out_len;
  133         if (out_offset < len) {
  134             out_len = (uInt)ZIP_MIN(UINT_MAX, len-out_offset);
  135             ctx->zstr.next_out = (Bytef *)data+out_offset;
  136             ctx->zstr.avail_out = out_len;
  137         }
  138         else {
  139                     ctx->can_store = false;
  140             end = 1;
  141         }
  142         }
  143         else if (ctx->eof && ctx->zstr.avail_in == 0)
  144         end = 1;
  145         break;
  146 
  147     case Z_BUF_ERROR:
  148         if (ctx->zstr.avail_in == 0) {
  149         if (ctx->eof) {
  150             end = 1;
  151             break;
  152         }
  153 
  154         if ((n=zip_source_read(src, ctx->buffer, sizeof(ctx->buffer))) < 0) {
  155                     _zip_error_set_from_source(&ctx->error, src);
  156             end = 1;
  157             break;
  158         }
  159         else if (n == 0) {
  160             ctx->eof = true;
  161             /* TODO: check against stat of src? */
  162             ctx->size = ctx->zstr.total_in;
  163         }
  164         else {
  165                     if (ctx->zstr.total_in > 0) {
  166                         /* we overwrote a previously filled ctx->buffer */
  167                         ctx->can_store = false;
  168                     }
  169             ctx->zstr.next_in = (Bytef *)ctx->buffer;
  170             ctx->zstr.avail_in = (uInt)n;
  171         }
  172         continue;
  173         }
  174         /* fallthrough */
  175     case Z_NEED_DICT:
  176     case Z_DATA_ERROR:
  177     case Z_STREAM_ERROR:
  178     case Z_MEM_ERROR:
  179             zip_error_set(&ctx->error, ZIP_ER_ZLIB, ret);
  180 
  181         end = 1;
  182         break;
  183     }
  184     }
  185 
  186     if (ctx->zstr.avail_out < len) {
  187     ctx->can_store = false;
  188     return (zip_int64_t)(len - ctx->zstr.avail_out);
  189     }
  190 
  191     return (zip_error_code_zip(&ctx->error) == ZIP_ER_OK) ? 0 : -1;
  192 }
  193 
  194 
  195 static zip_int64_t
  196 decompress_read(zip_source_t *src, struct deflate *ctx, void *data, zip_uint64_t len)
  197 {
  198     int end, ret;
  199     zip_int64_t n;
  200     zip_uint64_t out_offset;
  201     uInt out_len;
  202 
  203     if (zip_error_code_zip(&ctx->error) != ZIP_ER_OK)
  204     return -1;
  205     
  206     if (len == 0)
  207     return 0;
  208 
  209     out_offset = 0;
  210     out_len = (uInt)ZIP_MIN(UINT_MAX, len);
  211     ctx->zstr.next_out = (Bytef *)data;
  212     ctx->zstr.avail_out = out_len;
  213 
  214     end = 0;
  215     while (!end) {
  216     ret = inflate(&ctx->zstr, Z_SYNC_FLUSH);
  217 
  218     switch (ret) {
  219     case Z_OK:
  220         if (ctx->zstr.avail_out == 0) {
  221         out_offset += out_len;
  222         if (out_offset < len) {
  223             out_len = (uInt)ZIP_MIN(UINT_MAX, len-out_offset);
  224             ctx->zstr.next_out = (Bytef *)data+out_offset;
  225             ctx->zstr.avail_out = out_len;
  226         }
  227         else {
  228             end = 1;
  229         }
  230         }
  231         break;
  232         
  233     case Z_STREAM_END:
  234         ctx->eof = 1;
  235         end = 1;
  236         break;
  237 
  238     case Z_BUF_ERROR:
  239         if (ctx->zstr.avail_in == 0) {
  240         if (ctx->eof) {
  241             end = 1;
  242             break;
  243         }
  244 
  245         if ((n=zip_source_read(src, ctx->buffer, sizeof(ctx->buffer))) < 0) {
  246                     _zip_error_set_from_source(&ctx->error, src);
  247             end = 1;
  248             break;
  249         }
  250         else if (n == 0) {
  251             ctx->eof = 1;
  252         }
  253         else {
  254             ctx->zstr.next_in = (Bytef *)ctx->buffer;
  255             ctx->zstr.avail_in = (uInt)n;
  256         }
  257         continue;
  258         }
  259         /* fallthrough */
  260     case Z_NEED_DICT:
  261     case Z_DATA_ERROR:
  262     case Z_STREAM_ERROR:
  263     case Z_MEM_ERROR:
  264             zip_error_set(&ctx->error, ZIP_ER_ZLIB, ret);
  265         end = 1;
  266         break;
  267     }
  268     }
  269 
  270     if (ctx->zstr.avail_out < len)
  271     return (zip_int64_t)(len - ctx->zstr.avail_out);
  272 
  273     return (zip_error_code_zip(&ctx->error) == ZIP_ER_OK) ? 0 : -1;
  274 }
  275 
  276 
  277 static zip_int64_t
  278 deflate_compress(zip_source_t *src, void *ud, void *data, zip_uint64_t len, zip_source_cmd_t cmd)
  279 {
  280     struct deflate *ctx;
  281     int ret;
  282 
  283     ctx = (struct deflate *)ud;
  284 
  285     switch (cmd) {
  286     case ZIP_SOURCE_OPEN:
  287     ctx->zstr.zalloc = Z_NULL;
  288     ctx->zstr.zfree = Z_NULL;
  289     ctx->zstr.opaque = NULL;
  290     ctx->zstr.avail_in = 0;
  291     ctx->zstr.next_in = NULL;
  292     ctx->zstr.avail_out = 0;
  293     ctx->zstr.next_out = NULL;
  294 
  295     /* negative value to tell zlib not to write a header */
  296     if ((ret=deflateInit2(&ctx->zstr, Z_BEST_COMPRESSION, Z_DEFLATED, -MAX_WBITS, ctx->mem_level, Z_DEFAULT_STRATEGY)) != Z_OK) {
  297             zip_error_set(&ctx->error, ZIP_ER_ZLIB, ret);
  298         return -1;
  299     }
  300 
  301     return 0;
  302 
  303     case ZIP_SOURCE_READ:
  304     return compress_read(src, ctx, data, len);
  305 
  306     case ZIP_SOURCE_CLOSE:
  307     deflateEnd(&ctx->zstr);
  308     return 0;
  309 
  310     case ZIP_SOURCE_STAT:
  311         {
  312         zip_stat_t *st;
  313 
  314         st = (zip_stat_t *)data;
  315 
  316         st->comp_method = ctx->is_stored ? ZIP_CM_STORE : ZIP_CM_DEFLATE;
  317         st->valid |= ZIP_STAT_COMP_METHOD;
  318         if (ctx->eof) {
  319         st->comp_size = ctx->size;
  320         st->valid |= ZIP_STAT_COMP_SIZE;
  321         }
  322         else
  323         st->valid &= ~ZIP_STAT_COMP_SIZE;
  324     }
  325     return 0;
  326 
  327     case ZIP_SOURCE_ERROR:
  328         return zip_error_to_data(&ctx->error, data, len);
  329 
  330     case ZIP_SOURCE_FREE:
  331     deflate_free(ctx);
  332     return 0;
  333 
  334     case ZIP_SOURCE_SUPPORTS:
  335         return ZIP_SOURCE_SUPPORTS_READABLE;
  336             
  337     default:
  338         zip_error_set(&ctx->error, ZIP_ER_INTERNAL, 0);
  339     return -1;
  340     }
  341 }
  342 
  343 
  344 static zip_int64_t
  345 deflate_decompress(zip_source_t *src, void *ud, void *data,
  346            zip_uint64_t len, zip_source_cmd_t cmd)
  347 {
  348     struct deflate *ctx;
  349     zip_int64_t n;
  350     int ret;
  351 
  352     ctx = (struct deflate *)ud;
  353 
  354     switch (cmd) {
  355         case ZIP_SOURCE_OPEN:
  356             if ((n=zip_source_read(src, ctx->buffer, sizeof(ctx->buffer))) < 0) {
  357                 _zip_error_set_from_source(&ctx->error, src);
  358                 return -1;
  359             }
  360 
  361             ctx->zstr.zalloc = Z_NULL;
  362             ctx->zstr.zfree = Z_NULL;
  363             ctx->zstr.opaque = NULL;
  364             ctx->zstr.next_in = (Bytef *)ctx->buffer;
  365             ctx->zstr.avail_in = (uInt)n;
  366 
  367             /* negative value to tell zlib that there is no header */
  368             if ((ret=inflateInit2(&ctx->zstr, -MAX_WBITS)) != Z_OK) {
  369                 zip_error_set(&ctx->error, ZIP_ER_ZLIB, ret);
  370                 return -1;
  371             }
  372             return 0;
  373 
  374         case ZIP_SOURCE_READ:
  375             return decompress_read(src, ctx, data, len);
  376 
  377         case ZIP_SOURCE_CLOSE:
  378             inflateEnd(&ctx->zstr);
  379             return 0;
  380 
  381         case ZIP_SOURCE_STAT:
  382         {
  383             zip_stat_t *st;
  384             
  385             st = (zip_stat_t *)data;
  386             
  387             st->comp_method = ZIP_CM_STORE;
  388             if (st->comp_size > 0 && st->size > 0)
  389                 st->comp_size = st->size;
  390             
  391             return 0;
  392         }
  393 
  394         case ZIP_SOURCE_ERROR:
  395             return zip_error_to_data(&ctx->error, data, len);
  396 
  397         case ZIP_SOURCE_FREE:
  398             free(ctx);
  399             return 0;
  400             
  401         case ZIP_SOURCE_SUPPORTS:
  402             return zip_source_make_command_bitmap(ZIP_SOURCE_OPEN, ZIP_SOURCE_READ, ZIP_SOURCE_CLOSE, ZIP_SOURCE_STAT, ZIP_SOURCE_ERROR, ZIP_SOURCE_FREE, -1);
  403 
  404         default:
  405             zip_error_set(&ctx->error, ZIP_ER_OPNOTSUPP, 0);
  406             return -1;
  407     }
  408 }
  409 
  410 
  411 static void
  412 deflate_free(struct deflate *ctx)
  413 {
  414     free(ctx);
  415 }