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