"Fossies" - the Fresh Open Source Software Archive

Member "libzip-1.5.2/lib/zip_source_window.c" (12 Mar 2019, 7697 Bytes) of package /linux/misc/libzip-1.5.2.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_source_window.c" see the Fossies "Dox" file reference documentation and the latest Fossies "Diffs" side-by-side code changes report: 1.5.1_vs_1.5.2.

    1 /*
    2   zip_source_window.c -- return part of lower source
    3   Copyright (C) 2012-2018 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 <stdlib.h>
   36 #include <string.h>
   37 
   38 #include "zipint.h"
   39 
   40 struct window {
   41     zip_uint64_t start; /* where in file we start reading */
   42     zip_uint64_t end;   /* where in file we stop reading */
   43 
   44     /* if not NULL, read file data for this file */
   45     zip_t *source_archive;
   46     zip_uint64_t source_index;
   47 
   48     zip_uint64_t offset; /* offset in src for next read */
   49 
   50     zip_stat_t stat;
   51     zip_int8_t compression_flags;
   52     zip_error_t error;
   53     zip_int64_t supports;
   54     bool needs_seek;
   55 };
   56 
   57 static zip_int64_t window_read(zip_source_t *, void *, void *, zip_uint64_t, zip_source_cmd_t);
   58 
   59 
   60 zip_source_t *
   61 zip_source_window(zip_t *za, zip_source_t *src, zip_uint64_t start, zip_uint64_t len) {
   62     return _zip_source_window_new(src, start, len, NULL, 0, NULL, 0, &za->error);
   63 }
   64 
   65 
   66 zip_source_t *
   67 _zip_source_window_new(zip_source_t *src, zip_uint64_t start, zip_uint64_t length, zip_stat_t *st, zip_int8_t compression_flags, zip_t *source_archive, zip_uint64_t source_index, zip_error_t *error) {
   68     struct window *ctx;
   69 
   70     if (src == NULL || start + length < start || (source_archive == NULL && source_index != 0)) {
   71     zip_error_set(error, ZIP_ER_INVAL, 0);
   72     return NULL;
   73     }
   74 
   75     if ((ctx = (struct window *)malloc(sizeof(*ctx))) == NULL) {
   76     zip_error_set(error, ZIP_ER_MEMORY, 0);
   77     return NULL;
   78     }
   79 
   80     ctx->start = start;
   81     ctx->end = start + length;
   82     zip_stat_init(&ctx->stat);
   83     ctx->compression_flags = compression_flags;
   84     ctx->source_archive = source_archive;
   85     ctx->source_index = source_index;
   86     zip_error_init(&ctx->error);
   87     ctx->supports = (zip_source_supports(src) & ZIP_SOURCE_SUPPORTS_SEEKABLE) | (zip_source_make_command_bitmap(ZIP_SOURCE_GET_COMPRESSION_FLAGS, ZIP_SOURCE_SUPPORTS, ZIP_SOURCE_TELL, -1));
   88     ctx->needs_seek = (ctx->supports & ZIP_SOURCE_MAKE_COMMAND_BITMASK(ZIP_SOURCE_SEEK)) ? true : false;
   89 
   90     if (st) {
   91     if (_zip_stat_merge(&ctx->stat, st, error) < 0) {
   92         free(ctx);
   93         return NULL;
   94     }
   95     }
   96 
   97     return zip_source_layered_create(src, window_read, ctx, error);
   98 }
   99 
  100 
  101 int
  102 _zip_source_set_source_archive(zip_source_t *src, zip_t *za) {
  103     src->source_archive = za;
  104     return _zip_register_source(za, src);
  105 }
  106 
  107 
  108 /* called by zip_discard to avoid operating on file from closed archive */
  109 void
  110 _zip_source_invalidate(zip_source_t *src) {
  111     src->source_closed = 1;
  112 
  113     if (zip_error_code_zip(&src->error) == ZIP_ER_OK) {
  114     zip_error_set(&src->error, ZIP_ER_ZIPCLOSED, 0);
  115     }
  116 }
  117 
  118 
  119 static zip_int64_t
  120 window_read(zip_source_t *src, void *_ctx, void *data, zip_uint64_t len, zip_source_cmd_t cmd) {
  121     struct window *ctx;
  122     zip_int64_t ret;
  123     zip_uint64_t n, i;
  124 
  125     ctx = (struct window *)_ctx;
  126 
  127     switch (cmd) {
  128     case ZIP_SOURCE_CLOSE:
  129     return 0;
  130 
  131     case ZIP_SOURCE_ERROR:
  132     return zip_error_to_data(&ctx->error, data, len);
  133 
  134     case ZIP_SOURCE_FREE:
  135     free(ctx);
  136     return 0;
  137 
  138     case ZIP_SOURCE_OPEN:
  139     if (ctx->source_archive) {
  140         zip_uint64_t offset;
  141 
  142         if ((offset = _zip_file_get_offset(ctx->source_archive, ctx->source_index, &ctx->error)) == 0) {
  143         return -1;
  144         }
  145         if (ctx->end + offset < ctx->end) {
  146         /* zip archive data claims end of data past zip64 limits */
  147         zip_error_set(&ctx->error, ZIP_ER_INCONS, 0);
  148         return -1;
  149         }
  150         ctx->start += offset;
  151         ctx->end += offset;
  152         ctx->source_archive = NULL;
  153     }
  154 
  155     if (!ctx->needs_seek) {
  156         DEFINE_BYTE_ARRAY(b, BUFSIZE);
  157 
  158         if (!byte_array_init(b, BUFSIZE)) {
  159         zip_error_set(&ctx->error, ZIP_ER_MEMORY, 0);
  160         return -1;
  161         }
  162 
  163         for (n = 0; n < ctx->start; n += (zip_uint64_t)ret) {
  164         i = (ctx->start - n > BUFSIZE ? BUFSIZE : ctx->start - n);
  165         if ((ret = zip_source_read(src, b, i)) < 0) {
  166             _zip_error_set_from_source(&ctx->error, src);
  167             byte_array_fini(b);
  168             return -1;
  169         }
  170         if (ret == 0) {
  171             zip_error_set(&ctx->error, ZIP_ER_EOF, 0);
  172             byte_array_fini(b);
  173             return -1;
  174         }
  175         }
  176         
  177         byte_array_fini(b);
  178     }
  179 
  180     ctx->offset = ctx->start;
  181     return 0;
  182 
  183     case ZIP_SOURCE_READ:
  184     if (len > ctx->end - ctx->offset)
  185         len = ctx->end - ctx->offset;
  186 
  187     if (len == 0)
  188         return 0;
  189 
  190     if (ctx->needs_seek) {
  191         if (zip_source_seek(src, (zip_int64_t)ctx->offset, SEEK_SET) < 0) {
  192         _zip_error_set_from_source(&ctx->error, src);
  193         return -1;
  194         }
  195     }
  196 
  197     if ((ret = zip_source_read(src, data, len)) < 0) {
  198         zip_error_set(&ctx->error, ZIP_ER_EOF, 0);
  199         return -1;
  200     }
  201 
  202     ctx->offset += (zip_uint64_t)ret;
  203 
  204     if (ret == 0) {
  205         if (ctx->offset < ctx->end) {
  206         zip_error_set(&ctx->error, ZIP_ER_EOF, 0);
  207         return -1;
  208         }
  209     }
  210     return ret;
  211 
  212     case ZIP_SOURCE_SEEK: {
  213     zip_int64_t new_offset = zip_source_seek_compute_offset(ctx->offset - ctx->start, ctx->end - ctx->start, data, len, &ctx->error);
  214 
  215     if (new_offset < 0) {
  216         return -1;
  217     }
  218 
  219     ctx->offset = (zip_uint64_t)new_offset + ctx->start;
  220     return 0;
  221     }
  222 
  223     case ZIP_SOURCE_STAT: {
  224     zip_stat_t *st;
  225 
  226     st = (zip_stat_t *)data;
  227 
  228     if (_zip_stat_merge(st, &ctx->stat, &ctx->error) < 0) {
  229         return -1;
  230     }
  231     return 0;
  232     }
  233 
  234     case ZIP_SOURCE_GET_COMPRESSION_FLAGS:
  235     return ctx->compression_flags;
  236 
  237     case ZIP_SOURCE_SUPPORTS:
  238     return ctx->supports;
  239 
  240     case ZIP_SOURCE_TELL:
  241     return (zip_int64_t)(ctx->offset - ctx->start);
  242 
  243     default:
  244     zip_error_set(&ctx->error, ZIP_ER_OPNOTSUPP, 0);
  245     return -1;
  246     }
  247 }
  248 
  249 
  250 void
  251 _zip_deregister_source(zip_t *za, zip_source_t *src) {
  252     unsigned int i;
  253 
  254     for (i = 0; i < za->nopen_source; i++) {
  255     if (za->open_source[i] == src) {
  256         za->open_source[i] = za->open_source[za->nopen_source - 1];
  257         za->nopen_source--;
  258         break;
  259     }
  260     }
  261 }
  262 
  263 
  264 int
  265 _zip_register_source(zip_t *za, zip_source_t *src) {
  266     zip_source_t **open_source;
  267 
  268     if (za->nopen_source + 1 >= za->nopen_source_alloc) {
  269     unsigned int n;
  270     n = za->nopen_source_alloc + 10;
  271     open_source = (zip_source_t **)realloc(za->open_source, n * sizeof(zip_source_t *));
  272     if (open_source == NULL) {
  273         zip_error_set(&za->error, ZIP_ER_MEMORY, 0);
  274         return -1;
  275     }
  276     za->nopen_source_alloc = n;
  277     za->open_source = open_source;
  278     }
  279 
  280     za->open_source[za->nopen_source++] = src;
  281 
  282     return 0;
  283 }