in ios/CodePush/SSZipArchive/minizip/unzip.c [1047:1236]
extern int ZEXPORT unzOpenCurrentFile3(unzFile file, int *method, int *level, int raw, const char *password)
{
int err = UNZ_OK;
int compression_method;
uInt iSizeVar;
unz64_s *s;
file_in_zip64_read_info_s *pfile_in_zip_read_info;
ZPOS64_T offset_local_extrafield;
uInt size_local_extrafield;
#ifndef NOUNCRYPT
char source[12];
#else
if (password != NULL)
return UNZ_PARAMERROR;
#endif
if (file == NULL)
return UNZ_PARAMERROR;
s = (unz64_s *)file;
if (!s->current_file_ok)
return UNZ_PARAMERROR;
if (s->pfile_in_zip_read != NULL)
unzCloseCurrentFile(file);
if (unz64local_CheckCurrentFileCoherencyHeader(s, &iSizeVar, &offset_local_extrafield, &size_local_extrafield) != UNZ_OK)
return UNZ_BADZIPFILE;
pfile_in_zip_read_info = (file_in_zip64_read_info_s *)ALLOC(sizeof(file_in_zip64_read_info_s));
if (pfile_in_zip_read_info == NULL)
return UNZ_INTERNALERROR;
pfile_in_zip_read_info->read_buffer = (Bytef *)ALLOC(UNZ_BUFSIZE);
pfile_in_zip_read_info->offset_local_extrafield = offset_local_extrafield;
pfile_in_zip_read_info->size_local_extrafield = size_local_extrafield;
pfile_in_zip_read_info->pos_local_extrafield = 0;
pfile_in_zip_read_info->raw = raw;
if (pfile_in_zip_read_info->read_buffer == NULL) {
TRYFREE(pfile_in_zip_read_info);
return UNZ_INTERNALERROR;
}
pfile_in_zip_read_info->stream_initialised = 0;
compression_method = (int)s->cur_file_info.compression_method;
#ifdef HAVE_AES
if (compression_method == AES_METHOD)
compression_method = (int)s->cur_file_info_internal.aes_compression_method;
#endif
if (method != NULL)
*method = compression_method;
if (level != NULL) {
*level = 6;
switch (s->cur_file_info.flag & 0x06) {
case 6: *level = 1; break;
case 4: *level = 2; break;
case 2: *level = 9; break;
}
}
if ((compression_method != 0) &&
#ifdef HAVE_BZIP2
(compression_method != Z_BZIP2ED) &&
#endif
(compression_method != Z_DEFLATED))
err = UNZ_BADZIPFILE;
pfile_in_zip_read_info->crc32_wait = s->cur_file_info.crc;
pfile_in_zip_read_info->crc32 = 0;
pfile_in_zip_read_info->total_out_64 = 0;
pfile_in_zip_read_info->compression_method = compression_method;
pfile_in_zip_read_info->filestream = s->filestream;
pfile_in_zip_read_info->z_filefunc = s->z_filefunc;
if (s->number_disk == s->gi.number_disk_with_CD)
pfile_in_zip_read_info->byte_before_the_zipfile = s->byte_before_the_zipfile;
else
pfile_in_zip_read_info->byte_before_the_zipfile = 0;
pfile_in_zip_read_info->stream.total_out = 0;
pfile_in_zip_read_info->stream.total_in = 0;
pfile_in_zip_read_info->stream.next_in = NULL;
if (!raw) {
if (compression_method == Z_BZIP2ED) {
#ifdef HAVE_BZIP2
pfile_in_zip_read_info->bstream.bzalloc = (void *(*)(void *, int, int)) 0;
pfile_in_zip_read_info->bstream.bzfree = (free_func)0;
pfile_in_zip_read_info->bstream.opaque = (voidpf)0;
pfile_in_zip_read_info->bstream.state = (voidpf)0;
pfile_in_zip_read_info->stream.zalloc = (alloc_func)0;
pfile_in_zip_read_info->stream.zfree = (free_func)0;
pfile_in_zip_read_info->stream.opaque = (voidpf)0;
pfile_in_zip_read_info->stream.next_in = (voidpf)0;
pfile_in_zip_read_info->stream.avail_in = 0;
err = BZ2_bzDecompressInit(&pfile_in_zip_read_info->bstream, 0, 0);
if (err == Z_OK)
pfile_in_zip_read_info->stream_initialised = Z_BZIP2ED;
else {
TRYFREE(pfile_in_zip_read_info);
return err;
}
#else
pfile_in_zip_read_info->raw = 1;
#endif
} else if (compression_method == Z_DEFLATED) {
pfile_in_zip_read_info->stream.zalloc = (alloc_func)0;
pfile_in_zip_read_info->stream.zfree = (free_func)0;
pfile_in_zip_read_info->stream.opaque = (voidpf)s;
pfile_in_zip_read_info->stream.next_in = 0;
pfile_in_zip_read_info->stream.avail_in = 0;
err = inflateInit2(&pfile_in_zip_read_info->stream, -MAX_WBITS);
if (err == Z_OK)
pfile_in_zip_read_info->stream_initialised = Z_DEFLATED;
else {
TRYFREE(pfile_in_zip_read_info);
return err;
}
/* windowBits is passed < 0 to tell that there is no zlib header.
* Note that in this case inflate *requires* an extra "dummy" byte
* after the compressed stream in order to complete decompression and
* return Z_STREAM_END.
* In unzip, i don't wait absolutely Z_STREAM_END because I known the
* size of both compressed and uncompressed data
*/
}
}
pfile_in_zip_read_info->rest_read_compressed = s->cur_file_info.compressed_size;
pfile_in_zip_read_info->rest_read_uncompressed = s->cur_file_info.uncompressed_size;
pfile_in_zip_read_info->pos_in_zipfile = s->cur_file_info_internal.offset_curfile + SIZEZIPLOCALHEADER + iSizeVar;
pfile_in_zip_read_info->stream.avail_in = (uInt)0;
s->pfile_in_zip_read = pfile_in_zip_read_info;
#ifndef NOUNCRYPT
if ((password != NULL) && ((s->cur_file_info.flag & 1) != 0)) {
if (ZSEEK64(s->z_filefunc, s->filestream,
s->pfile_in_zip_read->pos_in_zipfile + s->pfile_in_zip_read->byte_before_the_zipfile,
ZLIB_FILEFUNC_SEEK_SET) != 0)
return UNZ_INTERNALERROR;
#ifdef HAVE_AES
if (s->cur_file_info.compression_method == AES_METHOD) {
unsigned char passverify[AES_PWVERIFYSIZE];
unsigned char saltvalue[AES_MAXSALTLENGTH];
uInt saltlength;
if ((s->cur_file_info_internal.aes_encryption_mode < 1) ||
(s->cur_file_info_internal.aes_encryption_mode > 3))
return UNZ_INTERNALERROR;
saltlength = SALT_LENGTH(s->cur_file_info_internal.aes_encryption_mode);
if (ZREAD64(s->z_filefunc, s->filestream, saltvalue, saltlength) != saltlength)
return UNZ_INTERNALERROR;
if (ZREAD64(s->z_filefunc, s->filestream, passverify, AES_PWVERIFYSIZE) != AES_PWVERIFYSIZE)
return UNZ_INTERNALERROR;
fcrypt_init((int)s->cur_file_info_internal.aes_encryption_mode, (unsigned char *)password, (unsigned int)strlen(password), saltvalue,
passverify, &s->pfile_in_zip_read->aes_ctx);
pfile_in_zip_read_info->rest_read_compressed -= saltlength + AES_PWVERIFYSIZE;
pfile_in_zip_read_info->rest_read_compressed -= AES_AUTHCODESIZE;
s->pfile_in_zip_read->pos_in_zipfile += saltlength + AES_PWVERIFYSIZE;
} else
#endif
{
int i;
s->pcrc_32_tab = (const unsigned long *)get_crc_table();
init_keys(password, s->keys, s->pcrc_32_tab);
if (ZREAD64(s->z_filefunc, s->filestream, source, 12) < 12)
return UNZ_INTERNALERROR;
for (i = 0; i < 12; i++)
zdecode(s->keys, s->pcrc_32_tab, source[i]);
pfile_in_zip_read_info->rest_read_compressed -= 12;
s->pfile_in_zip_read->pos_in_zipfile += 12;
}
}
#endif
return UNZ_OK;
}