in ios/CodePush/SSZipArchive/minizip/unzip.c [682:916]
local int unz64local_GetCurrentFileInfoInternal(unzFile file, unz_file_info64 *pfile_info,
unz_file_info64_internal *pfile_info_internal, char *filename, uLong filename_size, void *extrafield,
uLong extrafield_size, char *comment, uLong comment_size)
{
unz64_s *s;
unz_file_info64 file_info;
unz_file_info64_internal file_info_internal;
ZPOS64_T bytes_to_read;
int err = UNZ_OK;
uLong uMagic;
long lSeek = 0;
ZPOS64_T current_pos = 0;
uLong acc = 0;
uLong uL;
ZPOS64_T uL64;
if (file == NULL)
return UNZ_PARAMERROR;
s = (unz64_s *)file;
if (ZSEEK64(s->z_filefunc, s->filestream_with_CD,
s->pos_in_central_dir + s->byte_before_the_zipfile, ZLIB_FILEFUNC_SEEK_SET) != 0)
err = UNZ_ERRNO;
/* Check the magic */
if (err == UNZ_OK) {
if (unz64local_getLong(&s->z_filefunc, s->filestream_with_CD, &uMagic) != UNZ_OK)
err = UNZ_ERRNO;
else if (uMagic != CENTRALHEADERMAGIC)
err = UNZ_BADZIPFILE;
}
/* Read central directory header */
if (unz64local_getShort(&s->z_filefunc, s->filestream_with_CD, &file_info.version) != UNZ_OK)
err = UNZ_ERRNO;
if (unz64local_getShort(&s->z_filefunc, s->filestream_with_CD, &file_info.version_needed) != UNZ_OK)
err = UNZ_ERRNO;
if (unz64local_getShort(&s->z_filefunc, s->filestream_with_CD, &file_info.flag) != UNZ_OK)
err = UNZ_ERRNO;
if (unz64local_getShort(&s->z_filefunc, s->filestream_with_CD, &file_info.compression_method) != UNZ_OK)
err = UNZ_ERRNO;
if (unz64local_getLong(&s->z_filefunc, s->filestream_with_CD, &file_info.dosDate) != UNZ_OK)
err = UNZ_ERRNO;
unz64local_DosDateToTmuDate(file_info.dosDate, &file_info.tmu_date);
if (unz64local_getLong(&s->z_filefunc, s->filestream_with_CD, &file_info.crc) != UNZ_OK)
err = UNZ_ERRNO;
if (unz64local_getLong(&s->z_filefunc, s->filestream_with_CD, &uL) != UNZ_OK)
err = UNZ_ERRNO;
file_info.compressed_size = uL;
if (unz64local_getLong(&s->z_filefunc, s->filestream_with_CD, &uL) != UNZ_OK)
err = UNZ_ERRNO;
file_info.uncompressed_size = uL;
if (unz64local_getShort(&s->z_filefunc, s->filestream_with_CD, &file_info.size_filename) != UNZ_OK)
err = UNZ_ERRNO;
if (unz64local_getShort(&s->z_filefunc, s->filestream_with_CD, &file_info.size_file_extra) != UNZ_OK)
err = UNZ_ERRNO;
if (unz64local_getShort(&s->z_filefunc, s->filestream_with_CD, &file_info.size_file_comment) != UNZ_OK)
err = UNZ_ERRNO;
if (unz64local_getShort(&s->z_filefunc, s->filestream_with_CD, &file_info.disk_num_start) != UNZ_OK)
err = UNZ_ERRNO;
if (unz64local_getShort(&s->z_filefunc, s->filestream_with_CD, &file_info.internal_fa) != UNZ_OK)
err = UNZ_ERRNO;
if (unz64local_getLong(&s->z_filefunc, s->filestream_with_CD, &file_info.external_fa) != UNZ_OK)
err = UNZ_ERRNO;
/* Relative offset of local header */
if (unz64local_getLong(&s->z_filefunc, s->filestream_with_CD, &uL) != UNZ_OK)
err = UNZ_ERRNO;
file_info.size_file_extra_internal = 0;
file_info.disk_offset = uL;
file_info_internal.offset_curfile = uL;
#ifdef HAVE_AES
file_info_internal.aes_compression_method = 0;
file_info_internal.aes_encryption_mode = 0;
file_info_internal.aes_version = 0;
#endif
lSeek += file_info.size_filename;
if ((err == UNZ_OK) && (filename != NULL)) {
if (file_info.size_filename < filename_size) {
*(filename + file_info.size_filename) = 0;
bytes_to_read = file_info.size_filename;
} else
bytes_to_read = filename_size;
if ((file_info.size_filename > 0) && (filename_size > 0))
if (ZREAD64(s->z_filefunc, s->filestream_with_CD, filename, (uLong)bytes_to_read) != bytes_to_read)
err = UNZ_ERRNO;
lSeek -= (uLong)bytes_to_read;
}
/* Read extrafield */
if ((err == UNZ_OK) && (extrafield != NULL)) {
if (file_info.size_file_extra < extrafield_size)
bytes_to_read = file_info.size_file_extra;
else
bytes_to_read = extrafield_size;
if (lSeek != 0) {
if (ZSEEK64(s->z_filefunc, s->filestream_with_CD, lSeek, ZLIB_FILEFUNC_SEEK_CUR) == 0)
lSeek = 0;
else
err = UNZ_ERRNO;
}
if ((file_info.size_file_extra > 0) && (extrafield_size > 0))
if (ZREAD64(s->z_filefunc, s->filestream_with_CD, extrafield, (uLong)bytes_to_read) != bytes_to_read)
err = UNZ_ERRNO;
lSeek += file_info.size_file_extra - (uLong)bytes_to_read;
} else
lSeek += file_info.size_file_extra;
if ((err == UNZ_OK) && (file_info.size_file_extra != 0)) {
if (lSeek != 0) {
if (ZSEEK64(s->z_filefunc, s->filestream_with_CD, lSeek, ZLIB_FILEFUNC_SEEK_CUR) == 0)
lSeek = 0;
else
err = UNZ_ERRNO;
}
/* We are going to parse the extra field so we need to move back */
current_pos = ZTELL64(s->z_filefunc, s->filestream_with_CD);
if (current_pos < file_info.size_file_extra)
err = UNZ_ERRNO;
current_pos -= file_info.size_file_extra;
if (ZSEEK64(s->z_filefunc, s->filestream_with_CD, current_pos, ZLIB_FILEFUNC_SEEK_SET) != 0)
err = UNZ_ERRNO;
while ((err != UNZ_ERRNO) && (acc < file_info.size_file_extra)) {
uLong headerid;
uLong datasize;
if (unz64local_getShort(&s->z_filefunc, s->filestream_with_CD, &headerid) != UNZ_OK)
err = UNZ_ERRNO;
if (unz64local_getShort(&s->z_filefunc, s->filestream_with_CD, &datasize) != UNZ_OK)
err = UNZ_ERRNO;
/* ZIP64 extra fields */
if (headerid == 0x0001) {
/* Subtract size of ZIP64 field, since ZIP64 is handled internally */
file_info.size_file_extra_internal += 2 + 2 + datasize;
if (file_info.uncompressed_size == 0xffffffff) {
if (unz64local_getLong64(&s->z_filefunc, s->filestream_with_CD, &file_info.uncompressed_size) != UNZ_OK)
err = UNZ_ERRNO;
}
if (file_info.compressed_size == 0xffffffff) {
if (unz64local_getLong64(&s->z_filefunc, s->filestream_with_CD, &file_info.compressed_size) != UNZ_OK)
err = UNZ_ERRNO;
}
if (file_info_internal.offset_curfile == 0xffffffff) {
/* Relative Header offset */
if (unz64local_getLong64(&s->z_filefunc, s->filestream_with_CD, &uL64) != UNZ_OK)
err = UNZ_ERRNO;
file_info_internal.offset_curfile = uL64;
file_info.disk_offset = uL64;
}
if (file_info.disk_num_start == 0xffffffff) {
/* Disk Start Number */
if (unz64local_getLong(&s->z_filefunc, s->filestream_with_CD, &file_info.disk_num_start) != UNZ_OK)
err = UNZ_ERRNO;
}
}
#ifdef HAVE_AES
/* AES header */
else if (headerid == 0x9901) {
/* Subtract size of AES field, since AES is handled internally */
file_info.size_file_extra_internal += 2 + 2 + datasize;
/* Verify version info */
if (unz64local_getShort(&s->z_filefunc, s->filestream_with_CD, &uL) != UNZ_OK)
err = UNZ_ERRNO;
/* Support AE-1 and AE-2 */
if (uL != 1 && uL != 2)
err = UNZ_ERRNO;
file_info_internal.aes_version = uL;
if (unz64local_getByte(&s->z_filefunc, s->filestream_with_CD, (int *)&uL) != UNZ_OK)
err = UNZ_ERRNO;
if ((char)uL != 'A')
err = UNZ_ERRNO;
if (unz64local_getByte(&s->z_filefunc, s->filestream_with_CD, (int *)&uL) != UNZ_OK)
err = UNZ_ERRNO;
if ((char)uL != 'E')
err = UNZ_ERRNO;
/* Get AES encryption strength and actual compression method */
if (unz64local_getByte(&s->z_filefunc, s->filestream_with_CD, (int *)&uL) != UNZ_OK)
err = UNZ_ERRNO;
file_info_internal.aes_encryption_mode = uL;
if (unz64local_getShort(&s->z_filefunc, s->filestream_with_CD, &uL) != UNZ_OK)
err = UNZ_ERRNO;
file_info_internal.aes_compression_method = uL;
}
#endif
else {
if (ZSEEK64(s->z_filefunc, s->filestream_with_CD, datasize, ZLIB_FILEFUNC_SEEK_CUR) != 0)
err = UNZ_ERRNO;
}
acc += 2 + 2 + datasize;
}
}
if (file_info.disk_num_start == s->gi.number_disk_with_CD)
file_info_internal.byte_before_the_zipfile = s->byte_before_the_zipfile;
else
file_info_internal.byte_before_the_zipfile = 0;
if ((err == UNZ_OK) && (comment != NULL)) {
if (file_info.size_file_comment < comment_size) {
*(comment + file_info.size_file_comment) = 0;
bytes_to_read = file_info.size_file_comment;
} else
bytes_to_read = comment_size;
if (lSeek != 0) {
if (ZSEEK64(s->z_filefunc, s->filestream_with_CD, lSeek, ZLIB_FILEFUNC_SEEK_CUR) != 0)
err = UNZ_ERRNO;
}
if ((file_info.size_file_comment > 0) && (comment_size > 0))
if (ZREAD64(s->z_filefunc, s->filestream_with_CD, comment, (uLong)bytes_to_read) != bytes_to_read)
err = UNZ_ERRNO;
lSeek += file_info.size_file_comment - (uLong)bytes_to_read;
} else
lSeek += file_info.size_file_comment;
if ((err == UNZ_OK) && (pfile_info != NULL))
*pfile_info = file_info;
if ((err == UNZ_OK) && (pfile_info_internal != NULL))
*pfile_info_internal = file_info_internal;
return err;
}