extern int ZEXPORT unzOpenCurrentFile3()

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;
}