"Fossies" - the Fresh Open Source Software Archive

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

    1 /*
    2   zip_algorithm_deflate.c -- deflate (de)compression routines
    3   Copyright (C) 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 #include "zipint.h"
   35 
   36 #include <limits.h>
   37 #include <stdlib.h>
   38 #include <zlib.h>
   39 
   40 struct ctx {
   41     zip_error_t *error;
   42     bool compress;
   43     int compression_flags;
   44     bool end_of_input;
   45     z_stream zstr;
   46 };
   47 
   48 
   49 static void *
   50 allocate(bool compress, int compression_flags, zip_error_t *error) {
   51     struct ctx *ctx;
   52 
   53     if ((ctx = (struct ctx *)malloc(sizeof(*ctx))) == NULL) {
   54     return NULL;
   55     }
   56 
   57     ctx->error = error;
   58     ctx->compress = compress;
   59     ctx->compression_flags = compression_flags;
   60     if (ctx->compression_flags < 1 || ctx->compression_flags > 9) {
   61     ctx->compression_flags = Z_BEST_COMPRESSION;
   62     }
   63     ctx->end_of_input = false;
   64 
   65     ctx->zstr.zalloc = Z_NULL;
   66     ctx->zstr.zfree = Z_NULL;
   67     ctx->zstr.opaque = NULL;
   68 
   69     return ctx;
   70 }
   71 
   72 
   73 static void *
   74 compress_allocate(zip_uint16_t method, int compression_flags, zip_error_t *error) {
   75     return allocate(true, compression_flags, error);
   76 }
   77 
   78 
   79 static void *
   80 decompress_allocate(zip_uint16_t method, int compression_flags, zip_error_t *error) {
   81     return allocate(false, compression_flags, error);
   82 }
   83 
   84 
   85 static void
   86 deallocate(void *ud) {
   87     struct ctx *ctx = (struct ctx *)ud;
   88 
   89     free(ctx);
   90 }
   91 
   92 
   93 static int
   94 compression_flags(void *ud) {
   95     struct ctx *ctx = (struct ctx *)ud;
   96 
   97     if (!ctx->compress) {
   98     return 0;
   99     }
  100 
  101     if (ctx->compression_flags < 3) {
  102     return 2;
  103     }
  104     else if (ctx->compression_flags > 7) {
  105     return 1;
  106     }
  107     return 0;
  108 }
  109 
  110 
  111 static bool
  112 start(void *ud) {
  113     struct ctx *ctx = (struct ctx *)ud;
  114     int ret;
  115 
  116     ctx->zstr.avail_in = 0;
  117     ctx->zstr.next_in = NULL;
  118     ctx->zstr.avail_out = 0;
  119     ctx->zstr.next_out = NULL;
  120 
  121     if (ctx->compress) {
  122     /* negative value to tell zlib not to write a header */
  123     ret = deflateInit2(&ctx->zstr, ctx->compression_flags, Z_DEFLATED, -MAX_WBITS, MAX_MEM_LEVEL, Z_DEFAULT_STRATEGY);
  124     }
  125     else {
  126     ret = inflateInit2(&ctx->zstr, -MAX_WBITS);
  127     }
  128 
  129     if (ret != Z_OK) {
  130     zip_error_set(ctx->error, ZIP_ER_ZLIB, ret);
  131     return false;
  132     }
  133 
  134 
  135     return true;
  136 }
  137 
  138 
  139 static bool
  140 end(void *ud) {
  141     struct ctx *ctx = (struct ctx *)ud;
  142     int err;
  143 
  144     if (ctx->compress) {
  145     err = deflateEnd(&ctx->zstr);
  146     }
  147     else {
  148     err = inflateEnd(&ctx->zstr);
  149     }
  150 
  151     if (err != Z_OK) {
  152     zip_error_set(ctx->error, ZIP_ER_ZLIB, err);
  153     return false;
  154     }
  155 
  156     return true;
  157 }
  158 
  159 
  160 static bool
  161 input(void *ud, zip_uint8_t *data, zip_uint64_t length) {
  162     struct ctx *ctx = (struct ctx *)ud;
  163 
  164     if (length > UINT_MAX || ctx->zstr.avail_in > 0) {
  165     zip_error_set(ctx->error, ZIP_ER_INVAL, 0);
  166     return false;
  167     }
  168 
  169     ctx->zstr.avail_in = (uInt)length;
  170     ctx->zstr.next_in = (Bytef *)data;
  171 
  172     return true;
  173 }
  174 
  175 
  176 static void
  177 end_of_input(void *ud) {
  178     struct ctx *ctx = (struct ctx *)ud;
  179 
  180     ctx->end_of_input = true;
  181 }
  182 
  183 
  184 static zip_compression_status_t
  185 process(void *ud, zip_uint8_t *data, zip_uint64_t *length) {
  186     struct ctx *ctx = (struct ctx *)ud;
  187 
  188     int ret;
  189 
  190     ctx->zstr.avail_out = (uInt)ZIP_MIN(UINT_MAX, *length);
  191     ctx->zstr.next_out = (Bytef *)data;
  192 
  193     if (ctx->compress) {
  194     ret = deflate(&ctx->zstr, ctx->end_of_input ? Z_FINISH : 0);
  195     }
  196     else {
  197     ret = inflate(&ctx->zstr, Z_SYNC_FLUSH);
  198     }
  199 
  200     *length = *length - ctx->zstr.avail_out;
  201 
  202     switch (ret) {
  203     case Z_OK:
  204     return ZIP_COMPRESSION_OK;
  205 
  206     case Z_STREAM_END:
  207     return ZIP_COMPRESSION_END;
  208 
  209     case Z_BUF_ERROR:
  210     if (ctx->zstr.avail_in == 0) {
  211         return ZIP_COMPRESSION_NEED_DATA;
  212     }
  213 
  214     /* fallthrough */
  215 
  216     default:
  217     zip_error_set(ctx->error, ZIP_ER_ZLIB, ret);
  218     return ZIP_COMPRESSION_ERROR;
  219     }
  220 }
  221 
  222 // clang-format off
  223 
  224 zip_compression_algorithm_t zip_algorithm_deflate_compress = {
  225     compress_allocate,
  226     deallocate,
  227     compression_flags,
  228     start,
  229     end,
  230     input,
  231     end_of_input,
  232     process
  233 };
  234 
  235 
  236 zip_compression_algorithm_t zip_algorithm_deflate_decompress = {
  237     decompress_allocate,
  238     deallocate,
  239     compression_flags,
  240     start,
  241     end,
  242     input,
  243     end_of_input,
  244     process
  245 };
  246 
  247 // clang-format on