extern int ZEXPORT zipCloseFileInZipRaw64()

in ios/CodePush/SSZipArchive/minizip/zip.c [1494:1740]


extern int ZEXPORT zipCloseFileInZipRaw64(zipFile file, ZPOS64_T uncompressed_size, uLong crc32)
{
    zip64_internal *zi;
    ZPOS64_T compressed_size;
    uLong invalidValue = 0xffffffff;
    uLong i = 0;
    short datasize = 0;
    int err = ZIP_OK;

    if (file == NULL)
        return ZIP_PARAMERROR;
    zi = (zip64_internal *)file;

    if (zi->in_opened_file_inzip == 0)
        return ZIP_PARAMERROR;
    zi->ci.stream.avail_in = 0;

    if (!zi->ci.raw) {
        if (zi->ci.compression_method == Z_DEFLATED) {
            while (err == ZIP_OK) {
                uLong total_out_before;
                if (zi->ci.stream.avail_out == 0) {
                    if (zip64FlushWriteBuffer(zi) == ZIP_ERRNO)
                        err = ZIP_ERRNO;
                    zi->ci.stream.avail_out = (uInt)Z_BUFSIZE;
                    zi->ci.stream.next_out = zi->ci.buffered_data;
                }
                total_out_before = zi->ci.stream.total_out;
                err = deflate(&zi->ci.stream, Z_FINISH);
                zi->ci.pos_in_buffered_data += (uInt)(zi->ci.stream.total_out - total_out_before);
            }
        } else if (zi->ci.compression_method == Z_BZIP2ED) {
#ifdef HAVE_BZIP2
            err = BZ_FINISH_OK;
            while (err == BZ_FINISH_OK) {
                uLong total_out_before;
                if (zi->ci.bstream.avail_out == 0) {
                    if (zip64FlushWriteBuffer(zi) == ZIP_ERRNO)
                        err = ZIP_ERRNO;
                    zi->ci.bstream.avail_out = (uInt)Z_BUFSIZE;
                    zi->ci.bstream.next_out = (char *)zi->ci.buffered_data;
                }
                total_out_before = zi->ci.bstream.total_out_lo32;
                err = BZ2_bzCompress(&zi->ci.bstream, BZ_FINISH);
                if (err == BZ_STREAM_END)
                    err = Z_STREAM_END;
                zi->ci.pos_in_buffered_data += (uInt)(zi->ci.bstream.total_out_lo32 - total_out_before);
            }

            if (err == BZ_FINISH_OK)
                err = ZIP_OK;
#endif
        }
    }

    if (err == Z_STREAM_END)
        err = ZIP_OK; /* this is normal */

    if ((zi->ci.pos_in_buffered_data > 0) && (err == ZIP_OK)) {
        if (zip64FlushWriteBuffer(zi) == ZIP_ERRNO)
            err = ZIP_ERRNO;
    }

#ifdef HAVE_AES
    if (zi->ci.method == AES_METHOD) {
        unsigned char authcode[AES_AUTHCODESIZE];

        fcrypt_end(authcode, &zi->ci.aes_ctx);

        if (ZWRITE64(zi->z_filefunc, zi->filestream, authcode, AES_AUTHCODESIZE) != AES_AUTHCODESIZE)
            err = ZIP_ERRNO;
    }
#endif

    if (!zi->ci.raw) {
        if (zi->ci.compression_method == Z_DEFLATED) {
            int tmp_err = deflateEnd(&zi->ci.stream);
            if (err == ZIP_OK)
                err = tmp_err;
            zi->ci.stream_initialised = 0;
        }
#ifdef HAVE_BZIP2
        else if (zi->ci.compression_method == Z_BZIP2ED) {
            int tmperr = BZ2_bzCompressEnd(&zi->ci.bstream);
            if (err == ZIP_OK)
                err = tmperr;
            zi->ci.stream_initialised = 0;
        }
#endif

        crc32 = (uLong)zi->ci.crc32;
        uncompressed_size = zi->ci.total_uncompressed;
    }

    compressed_size = zi->ci.total_compressed;
#ifndef NOCRYPT
    compressed_size += zi->ci.crypt_header_size;
#endif

    /* Update current item crc and sizes */
    if (compressed_size >= 0xffffffff || uncompressed_size >= 0xffffffff || zi->ci.pos_local_header >= 0xffffffff) {
        zip64local_putValue_inmemory(zi->ci.central_header + 4, (uLong)45, 2); /* version made by */
        zip64local_putValue_inmemory(zi->ci.central_header + 6, (uLong)45, 2); /* version needed */
    }
    zip64local_putValue_inmemory(zi->ci.central_header + 16, crc32, 4); /* crc */
    if (compressed_size >= 0xffffffff)
        zip64local_putValue_inmemory(zi->ci.central_header + 20, invalidValue, 4); /* compr size */
    else
        zip64local_putValue_inmemory(zi->ci.central_header + 20, compressed_size, 4); /* compr size */
    if (zi->ci.stream.data_type == Z_ASCII)
        zip64local_putValue_inmemory(zi->ci.central_header + 36, (uLong)Z_ASCII, 2); /* internal file attrib */
    if (uncompressed_size >= 0xffffffff)
        zip64local_putValue_inmemory(zi->ci.central_header + 24, invalidValue, 4); /* uncompr size */
    else
        zip64local_putValue_inmemory(zi->ci.central_header + 24, uncompressed_size, 4); /* uncompr size */

    /* Add ZIP64 extra info field for uncompressed size */
    if (uncompressed_size >= 0xffffffff)
        datasize += 8;
    /* Add ZIP64 extra info field for compressed size */
    if (compressed_size >= 0xffffffff)
        datasize += 8;
    /* Add ZIP64 extra info field for relative offset to local file header of current file */
    if (zi->ci.pos_local_header >= 0xffffffff)
        datasize += 8;

    /* Add Extra Information Header for 'ZIP64 information' */
    if (datasize > 0) {
        char *p = zi->ci.central_header + zi->ci.size_centralheader;

        if ((uLong)(datasize + 4) > zi->ci.size_centralextrafree)
            return ZIP_BADZIPFILE;

        zip64local_putValue_inmemory(p, 0x0001, 2);
        p += 2;
        zip64local_putValue_inmemory(p, datasize, 2);
        p += 2;

        if (uncompressed_size >= 0xffffffff) {
            zip64local_putValue_inmemory(p, uncompressed_size, 8);
            p += 8;
        }
        if (compressed_size >= 0xffffffff) {
            zip64local_putValue_inmemory(p, compressed_size, 8);
            p += 8;
        }
        if (zi->ci.pos_local_header >= 0xffffffff) {
            zip64local_putValue_inmemory(p, zi->ci.pos_local_header, 8);
            p += 8;
        }

        zi->ci.size_centralextrafree -= datasize + 4;
        zi->ci.size_centralheader += datasize + 4;
        zi->ci.size_centralextra += datasize + 4;

        zip64local_putValue_inmemory(zi->ci.central_header + 30, (uLong)zi->ci.size_centralextra, 2);
    }

#ifdef HAVE_AES
    /* Write the AES extended info */
    if (zi->ci.method == AES_METHOD) {
        char *p = zi->ci.central_header + zi->ci.size_centralheader;

        datasize = 7;

        if ((uLong)(datasize + 4) > zi->ci.size_centralextrafree)
            return ZIP_BADZIPFILE;

        zip64local_putValue_inmemory(p, 0x9901, 2);
        p += 2;
        zip64local_putValue_inmemory(p, datasize, 2);
        p += 2;
        zip64local_putValue_inmemory(p, AES_VERSION, 2);
        p += 2;
        zip64local_putValue_inmemory(p, 'A', 1);
        p += 1;
        zip64local_putValue_inmemory(p, 'E', 1);
        p += 1;
        zip64local_putValue_inmemory(p, AES_ENCRYPTIONMODE, 1);
        p += 1;
        zip64local_putValue_inmemory(p, zi->ci.compression_method, 2);
        p += 2;

        zi->ci.size_centralextrafree -= datasize + 4;
        zi->ci.size_centralheader += datasize + 4;
        zi->ci.size_centralextra += datasize + 4;

        zip64local_putValue_inmemory(zi->ci.central_header + 30, (uLong)zi->ci.size_centralextra, 2);
    }
#endif
    /* Restore comment to correct position */
    for (i = 0; i < zi->ci.size_comment; i++)
        zi->ci.central_header[zi->ci.size_centralheader + i] =
            zi->ci.central_header[zi->ci.size_centralheader + zi->ci.size_centralextrafree + i];
    zi->ci.size_centralheader += zi->ci.size_comment;

    if (err == ZIP_OK)
        err = add_data_in_datablock(&zi->central_dir, zi->ci.central_header, (uLong)zi->ci.size_centralheader);

    free(zi->ci.central_header);

    if (err == ZIP_OK) {
        /* Update the LocalFileHeader with the new values. */
        ZPOS64_T cur_pos_inzip = ZTELL64(zi->z_filefunc, zi->filestream);
        uLong cur_number_disk = zi->number_disk;

        /* Local file header is stored on previous disk, switch to make edits */
        if (zi->ci.number_disk != cur_number_disk)
            err = zipGoToSpecificDisk(file, (int)zi->ci.number_disk, 1);

        if (ZSEEK64(zi->z_filefunc, zi->filestream, zi->ci.pos_local_header + 14, ZLIB_FILEFUNC_SEEK_SET) != 0)
            err = ZIP_ERRNO;
        if (err == ZIP_OK)
            err = zip64local_putValue(&zi->z_filefunc, zi->filestream, crc32, 4); /* crc 32, unknown */

        if (uncompressed_size >= 0xffffffff || compressed_size >= 0xffffffff) {
            if (zi->ci.pos_zip64extrainfo > 0) {
                /* Update the size in the ZIP64 extended field. */
                if (ZSEEK64(zi->z_filefunc, zi->filestream, zi->ci.pos_zip64extrainfo + 4, ZLIB_FILEFUNC_SEEK_SET) != 0)
                    err = ZIP_ERRNO;

                if (err == ZIP_OK) /* compressed size, unknown */
                    err = zip64local_putValue(&zi->z_filefunc, zi->filestream, uncompressed_size, 8);
                if (err == ZIP_OK) /* uncompressed size, unknown */
                    err = zip64local_putValue(&zi->z_filefunc, zi->filestream, compressed_size, 8);
            } else
                err = ZIP_BADZIPFILE; /* Caller passed zip64 = 0, so no room for zip64 info -> fatal */
        } else {
            if (err == ZIP_OK) /* compressed size, unknown */
                err = zip64local_putValue(&zi->z_filefunc, zi->filestream, compressed_size, 4);
            if (err == ZIP_OK) /* uncompressed size, unknown */
                err = zip64local_putValue(&zi->z_filefunc, zi->filestream, uncompressed_size, 4);
        }

        /* Now switch back again to the disk we were on before */
        if (zi->ci.number_disk != cur_number_disk)
            err = zipGoToSpecificDisk(file, (int)cur_number_disk, 1);

        if (ZSEEK64(zi->z_filefunc, zi->filestream, cur_pos_inzip, ZLIB_FILEFUNC_SEEK_SET) != 0)
            err = ZIP_ERRNO;
    }

    zi->number_entry++;
    zi->in_opened_file_inzip = 0;

    return err;
}