root/ext/zip/lib/zip_source_zip_new.c

/* [<][>][^][v][top][bottom][index][help] */

DEFINITIONS

This source file includes following definitions.
  1. _zip_source_zip_new

   1 /*
   2   zip_source_zip_new.c -- prepare data structures for zip_fopen/zip_source_zip
   3   Copyright (C) 2012 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 
  36 #include <stdlib.h>
  37 
  38 #include "zipint.h"
  39 
  40 
  41 
  42 struct zip_source *
  43 _zip_source_zip_new(struct zip *za, struct zip *srcza, zip_uint64_t srcidx, zip_flags_t flags,
  44                     zip_uint64_t start, zip_uint64_t len, const char *password)
  45 {
  46     zip_compression_implementation comp_impl;
  47     zip_encryption_implementation enc_impl;
  48     struct zip_source *src, *s2;
  49     zip_uint64_t offset;
  50     struct zip_stat st;
  51 
  52     if (za == NULL)
  53         return NULL;
  54 
  55     if (srcza == NULL ||  srcidx >= srcza->nentry) {
  56         _zip_error_set(&za->error, ZIP_ER_INVAL, 0);
  57         return NULL;
  58     }
  59 
  60     if ((flags & ZIP_FL_UNCHANGED) == 0
  61         && (ZIP_ENTRY_DATA_CHANGED(srcza->entry+srcidx) || srcza->entry[srcidx].deleted)) {
  62         _zip_error_set(&za->error, ZIP_ER_CHANGED, 0);
  63         return NULL;
  64     }
  65 
  66     if (zip_stat_index(srcza, srcidx, flags|ZIP_FL_UNCHANGED, &st) < 0) {
  67         _zip_error_set(&za->error, ZIP_ER_INTERNAL, 0);
  68         return NULL;
  69     }
  70 
  71     if (flags & ZIP_FL_ENCRYPTED)
  72         flags |= ZIP_FL_COMPRESSED;
  73 
  74     if ((start > 0 || len > 0) && (flags & ZIP_FL_COMPRESSED)) {
  75         _zip_error_set(&za->error, ZIP_ER_INVAL, 0);
  76         return NULL;
  77     }
  78 
  79     /* overflow or past end of file */
  80     if ((start > 0 || len > 0) && (start+len < start || start+len > st.size)) {
  81         _zip_error_set(&za->error, ZIP_ER_INVAL, 0);
  82         return NULL;
  83     }
  84 
  85     enc_impl = NULL;
  86     if (((flags & ZIP_FL_ENCRYPTED) == 0) && (st.encryption_method != ZIP_EM_NONE)) {
  87         if (password == NULL) {
  88             _zip_error_set(&za->error, ZIP_ER_NOPASSWD, 0);
  89             return NULL;
  90         }
  91         if ((enc_impl=_zip_get_encryption_implementation(st.encryption_method)) == NULL) {
  92             _zip_error_set(&za->error, ZIP_ER_ENCRNOTSUPP, 0);
  93             return NULL;
  94         }
  95     }
  96 
  97     comp_impl = NULL;
  98     if ((flags & ZIP_FL_COMPRESSED) == 0) {
  99         if (st.comp_method != ZIP_CM_STORE) {
 100             if ((comp_impl=_zip_get_compression_implementation(st.comp_method)) == NULL) {
 101                 _zip_error_set(&za->error, ZIP_ER_COMPNOTSUPP, 0);
 102                 return NULL;
 103             }
 104         }
 105     }
 106 
 107     if ((offset=_zip_file_get_offset(srcza, srcidx, &za->error)) == 0)
 108         return NULL;
 109 
 110     if (st.comp_size == 0) {
 111         if ((src=zip_source_buffer(za, NULL, 0, 0)) == NULL)
 112             return NULL;
 113     }
 114     else {
 115         if (start+len > 0 && enc_impl == NULL && comp_impl == NULL) {
 116             struct zip_stat st2;
 117 
 118             st2.size = len ? len : st.size-start;
 119             st2.comp_size = st2.size;
 120             st2.comp_method = ZIP_CM_STORE;
 121             st2.mtime = st.mtime;
 122             st2.valid = ZIP_STAT_SIZE|ZIP_STAT_COMP_SIZE|ZIP_STAT_COMP_METHOD|ZIP_STAT_MTIME;
 123 
 124             /* TODO: check for overflow of st2.size */
 125             if ((src=_zip_source_file_or_p(za, NULL, srcza->zp, offset+start, (zip_int64_t)st2.size, 0, &st2)) == NULL)
 126                 return NULL;
 127         }
 128         else {
 129             /* TODO: check for overflow of st.comp_size */
 130             if ((src=_zip_source_file_or_p(za, NULL, srcza->zp, offset, (zip_int64_t)st.comp_size, 0, &st)) == NULL)
 131                 return NULL;
 132         }
 133         
 134         if (enc_impl) {
 135             if ((s2=enc_impl(za, src, st.encryption_method, 0, password)) == NULL) {
 136                 zip_source_free(src);
 137                 /* TODO: set error (how?) */
 138                 return NULL;
 139             }
 140             src = s2;
 141         }
 142         if (comp_impl) {
 143             if ((s2=comp_impl(za, src, st.comp_method, 0)) == NULL) {
 144                 zip_source_free(src);
 145                 /* TODO: set error (how?) */
 146                 return NULL;
 147             }
 148             src = s2;
 149         }
 150         if (((flags & ZIP_FL_COMPRESSED) == 0 || st.comp_method == ZIP_CM_STORE)
 151             && (len == 0 || len == st.comp_size)) {
 152             /* when reading the whole file, check for crc errors */
 153             if ((s2=zip_source_crc(za, src, 1)) == NULL) {
 154                 zip_source_free(src);
 155                 /* TODO: set error (how?) */
 156                 return NULL;
 157             }
 158             src = s2;
 159         }
 160 
 161         if (start+len > 0 && (comp_impl || enc_impl)) {
 162             if ((s2=zip_source_window(za, src, start, len ? len : st.size-start)) == NULL) {
 163                 zip_source_free(src);
 164                 /* TODO: set error (how?) (why?) */
 165                 return NULL;
 166             }
 167             src = s2;
 168         }
 169     }
 170 
 171     return src;
 172 }

/* [<][>][^][v][top][bottom][index][help] */