"Fossies" - the Fresh Open Source Software Archive

Member "libzip-1.6.0/lib/zip_algorithm_bzip2.c" (24 Jan 2020, 6126 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_algorithm_bzip2.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_algorithm_bzip2.c -- bzip2 (de)compression routines
    3   Copyright (C) 2017-2019 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 <bzlib.h>
   37 #include <limits.h>
   38 #include <stdlib.h>
   39 
   40 struct ctx {
   41     zip_error_t *error;
   42     bool compress;
   43     int compression_flags;
   44     bool end_of_input;
   45     bz_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 = 9;
   62     }
   63     ctx->end_of_input = false;
   64 
   65     ctx->zstr.bzalloc = NULL;
   66     ctx->zstr.bzfree = 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     return 0;
   96 }
   97 
   98 
   99 static int
  100 map_error(int ret) {
  101     switch (ret) {
  102     case BZ_FINISH_OK:
  103     case BZ_FLUSH_OK:
  104     case BZ_OK:
  105     case BZ_RUN_OK:
  106     case BZ_STREAM_END:
  107     return ZIP_ER_OK;
  108 
  109     case BZ_DATA_ERROR:
  110     case BZ_DATA_ERROR_MAGIC:
  111     case BZ_UNEXPECTED_EOF:
  112     return ZIP_ER_COMPRESSED_DATA;
  113 
  114     case BZ_MEM_ERROR:
  115     return ZIP_ER_MEMORY;
  116 
  117     case BZ_PARAM_ERROR:
  118     return ZIP_ER_INVAL;
  119 
  120     case BZ_CONFIG_ERROR: /* actually, bzip2 miscompiled */
  121     case BZ_IO_ERROR:
  122     case BZ_OUTBUFF_FULL:
  123     case BZ_SEQUENCE_ERROR:
  124     return ZIP_ER_INTERNAL;
  125 
  126     default:
  127     return ZIP_ER_INTERNAL;
  128     }
  129 }
  130 
  131 static bool
  132 start(void *ud) {
  133     struct ctx *ctx = (struct ctx *)ud;
  134     int ret;
  135 
  136     ctx->zstr.avail_in = 0;
  137     ctx->zstr.next_in = NULL;
  138     ctx->zstr.avail_out = 0;
  139     ctx->zstr.next_out = NULL;
  140 
  141     if (ctx->compress) {
  142     ret = BZ2_bzCompressInit(&ctx->zstr, ctx->compression_flags, 0, 30);
  143     }
  144     else {
  145     ret = BZ2_bzDecompressInit(&ctx->zstr, 0, 0);
  146     }
  147 
  148     if (ret != BZ_OK) {
  149     zip_error_set(ctx->error, map_error(ret), 0);
  150     return false;
  151     }
  152 
  153     return true;
  154 }
  155 
  156 
  157 static bool
  158 end(void *ud) {
  159     struct ctx *ctx = (struct ctx *)ud;
  160     int err;
  161 
  162     if (ctx->compress) {
  163     err = BZ2_bzCompressEnd(&ctx->zstr);
  164     }
  165     else {
  166     err = BZ2_bzDecompressEnd(&ctx->zstr);
  167     }
  168 
  169     if (err != BZ_OK) {
  170     zip_error_set(ctx->error, map_error(err), 0);
  171     return false;
  172     }
  173 
  174     return true;
  175 }
  176 
  177 
  178 static bool
  179 input(void *ud, zip_uint8_t *data, zip_uint64_t length) {
  180     struct ctx *ctx = (struct ctx *)ud;
  181 
  182     if (length > UINT_MAX || ctx->zstr.avail_in > 0) {
  183     zip_error_set(ctx->error, ZIP_ER_INVAL, 0);
  184     return false;
  185     }
  186 
  187     ctx->zstr.avail_in = (unsigned int)length;
  188     ctx->zstr.next_in = (char *)data;
  189 
  190     return true;
  191 }
  192 
  193 
  194 static void
  195 end_of_input(void *ud) {
  196     struct ctx *ctx = (struct ctx *)ud;
  197 
  198     ctx->end_of_input = true;
  199 }
  200 
  201 
  202 static zip_compression_status_t
  203 process(void *ud, zip_uint8_t *data, zip_uint64_t *length) {
  204     struct ctx *ctx = (struct ctx *)ud;
  205 
  206     int ret;
  207 
  208     if (ctx->zstr.avail_in == 0 && !ctx->end_of_input) {
  209     *length = 0;
  210     return ZIP_COMPRESSION_NEED_DATA;
  211     }
  212 
  213     ctx->zstr.avail_out = (unsigned int)ZIP_MIN(UINT_MAX, *length);
  214     ctx->zstr.next_out = (char *)data;
  215 
  216     if (ctx->compress) {
  217     ret = BZ2_bzCompress(&ctx->zstr, ctx->end_of_input ? BZ_FINISH : BZ_RUN);
  218     }
  219     else {
  220     ret = BZ2_bzDecompress(&ctx->zstr);
  221     }
  222 
  223     *length = *length - ctx->zstr.avail_out;
  224 
  225     switch (ret) {
  226     case BZ_FINISH_OK: /* compression */
  227     return ZIP_COMPRESSION_OK;
  228 
  229     case BZ_OK:     /* decompression */
  230     case BZ_RUN_OK: /* compression */
  231     if (ctx->zstr.avail_in == 0) {
  232         return ZIP_COMPRESSION_NEED_DATA;
  233     }
  234     return ZIP_COMPRESSION_OK;
  235 
  236     case BZ_STREAM_END:
  237     return ZIP_COMPRESSION_END;
  238 
  239     default:
  240     zip_error_set(ctx->error, map_error(ret), 0);
  241     return ZIP_COMPRESSION_ERROR;
  242     }
  243 }
  244 
  245 // clang-format off
  246 
  247 zip_compression_algorithm_t zip_algorithm_bzip2_compress = {
  248     compress_allocate,
  249     deallocate,
  250     compression_flags,
  251     start,
  252     end,
  253     input,
  254     end_of_input,
  255     process
  256 };
  257 
  258 
  259 zip_compression_algorithm_t zip_algorithm_bzip2_decompress = {
  260     decompress_allocate,
  261     deallocate,
  262     compression_flags,
  263     start,
  264     end,
  265     input,
  266     end_of_input,
  267     process
  268 };
  269 
  270 // clang-format on