in ios/CodePush/SSZipArchive/minizip/unzip.c [386:536]
local unzFile unzOpenInternal(const void *path, zlib_filefunc64_32_def *pzlib_filefunc64_32_def)
{
unz64_s us;
unz64_s *s;
ZPOS64_T central_pos;
uLong uL;
voidpf filestream = NULL;
ZPOS64_T number_entry_CD;
int err = UNZ_OK;
if (unz_copyright[0] != ' ')
return NULL;
us.filestream = NULL;
us.filestream_with_CD = NULL;
us.z_filefunc.zseek32_file = NULL;
us.z_filefunc.ztell32_file = NULL;
if (pzlib_filefunc64_32_def == NULL)
fill_fopen64_filefunc(&us.z_filefunc.zfile_func64);
else
us.z_filefunc = *pzlib_filefunc64_32_def;
us.filestream = ZOPEN64(us.z_filefunc, path, ZLIB_FILEFUNC_MODE_READ | ZLIB_FILEFUNC_MODE_EXISTING);
if (us.filestream == NULL)
return NULL;
us.filestream_with_CD = us.filestream;
us.isZip64 = 0;
/* Use unz64local_SearchCentralDir first. Only based on the result
is it necessary to locate the unz64local_SearchCentralDir64 */
central_pos = unz64local_SearchCentralDir(&us.z_filefunc, us.filestream);
if (central_pos) {
if (ZSEEK64(us.z_filefunc, us.filestream, central_pos, ZLIB_FILEFUNC_SEEK_SET) != 0)
err = UNZ_ERRNO;
/* the signature, already checked */
if (unz64local_getLong(&us.z_filefunc, us.filestream, &uL) != UNZ_OK)
err = UNZ_ERRNO;
/* number of this disk */
if (unz64local_getShort(&us.z_filefunc, us.filestream, &uL) != UNZ_OK)
err = UNZ_ERRNO;
us.number_disk = uL;
/* number of the disk with the start of the central directory */
if (unz64local_getShort(&us.z_filefunc, us.filestream, &uL) != UNZ_OK)
err = UNZ_ERRNO;
us.gi.number_disk_with_CD = uL;
/* total number of entries in the central directory on this disk */
if (unz64local_getShort(&us.z_filefunc, us.filestream, &uL) != UNZ_OK)
err = UNZ_ERRNO;
us.gi.number_entry = uL;
/* total number of entries in the central directory */
if (unz64local_getShort(&us.z_filefunc, us.filestream, &uL) != UNZ_OK)
err = UNZ_ERRNO;
number_entry_CD = uL;
if (number_entry_CD != us.gi.number_entry)
err = UNZ_BADZIPFILE;
/* size of the central directory */
if (unz64local_getLong(&us.z_filefunc, us.filestream, &uL) != UNZ_OK)
err = UNZ_ERRNO;
us.size_central_dir = uL;
/* offset of start of central directory with respect to the starting disk number */
if (unz64local_getLong(&us.z_filefunc, us.filestream, &uL) != UNZ_OK)
err = UNZ_ERRNO;
us.offset_central_dir = uL;
/* zipfile comment length */
if (unz64local_getShort(&us.z_filefunc, us.filestream, &us.gi.size_comment) != UNZ_OK)
err = UNZ_ERRNO;
if ((err == UNZ_OK) &&
((us.gi.number_entry == 0xffff) || (us.size_central_dir == 0xffff) || (us.offset_central_dir == 0xffffffff))) {
/* Format should be Zip64, as the central directory or file size is too large */
central_pos = unz64local_SearchCentralDir64(&us.z_filefunc, us.filestream, central_pos);
if (central_pos) {
ZPOS64_T uL64;
us.isZip64 = 1;
if (ZSEEK64(us.z_filefunc, us.filestream, central_pos, ZLIB_FILEFUNC_SEEK_SET) != 0)
err = UNZ_ERRNO;
/* the signature, already checked */
if (unz64local_getLong(&us.z_filefunc, us.filestream, &uL) != UNZ_OK)
err = UNZ_ERRNO;
/* size of zip64 end of central directory record */
if (unz64local_getLong64(&us.z_filefunc, us.filestream, &uL64) != UNZ_OK)
err = UNZ_ERRNO;
/* version made by */
if (unz64local_getShort(&us.z_filefunc, us.filestream, &uL) != UNZ_OK)
err = UNZ_ERRNO;
/* version needed to extract */
if (unz64local_getShort(&us.z_filefunc, us.filestream, &uL) != UNZ_OK)
err = UNZ_ERRNO;
/* number of this disk */
if (unz64local_getLong(&us.z_filefunc, us.filestream, &us.number_disk) != UNZ_OK)
err = UNZ_ERRNO;
/* number of the disk with the start of the central directory */
if (unz64local_getLong(&us.z_filefunc, us.filestream, &us.gi.number_disk_with_CD) != UNZ_OK)
err = UNZ_ERRNO;
/* total number of entries in the central directory on this disk */
if (unz64local_getLong64(&us.z_filefunc, us.filestream, &us.gi.number_entry) != UNZ_OK)
err = UNZ_ERRNO;
/* total number of entries in the central directory */
if (unz64local_getLong64(&us.z_filefunc, us.filestream, &number_entry_CD) != UNZ_OK)
err = UNZ_ERRNO;
if (number_entry_CD != us.gi.number_entry)
err = UNZ_BADZIPFILE;
/* size of the central directory */
if (unz64local_getLong64(&us.z_filefunc, us.filestream, &us.size_central_dir) != UNZ_OK)
err = UNZ_ERRNO;
/* offset of start of central directory with respect to the starting disk number */
if (unz64local_getLong64(&us.z_filefunc, us.filestream, &us.offset_central_dir) != UNZ_OK)
err = UNZ_ERRNO;
} else
err = UNZ_BADZIPFILE;
}
} else
err = UNZ_ERRNO;
if ((err == UNZ_OK) && (central_pos < us.offset_central_dir + us.size_central_dir))
err = UNZ_BADZIPFILE;
if (err != UNZ_OK) {
ZCLOSE64(us.z_filefunc, us.filestream);
return NULL;
}
if (us.gi.number_disk_with_CD == 0) {
/* If there is only one disk open another stream so we don't have to seek between the CD
and the file headers constantly */
filestream = ZOPEN64(us.z_filefunc, path, ZLIB_FILEFUNC_MODE_READ | ZLIB_FILEFUNC_MODE_EXISTING);
if (filestream != NULL)
us.filestream = filestream;
}
/* Hack for zip files that have no respect for zip64
if ((central_pos > 0xffffffff) && (us.offset_central_dir < 0xffffffff))
us.offset_central_dir = central_pos - us.size_central_dir;*/
us.byte_before_the_zipfile = central_pos - (us.offset_central_dir + us.size_central_dir);
us.central_pos = central_pos;
us.pfile_in_zip_read = NULL;
s = (unz64_s *)ALLOC(sizeof(unz64_s));
if (s != NULL) {
*s = us;
unzGoToFirstFile((unzFile)s);
}
return (unzFile)s;
}