in zlib/contrib/minizip/unzip.c [763:996]
local int unz64local_GetCurrentFileInfoInternal(unzFile file,
unz_file_info64 *pfile_info,
unz_file_info64_internal
*pfile_info_internal,
char *szFileName,
uLong fileNameBufferSize,
void *extraField,
uLong extraFieldBufferSize,
char *szComment,
uLong commentBufferSize) {
unz64_s* s;
unz_file_info64 file_info;
unz_file_info64_internal file_info_internal;
int err=UNZ_OK;
uLong uMagic;
long lSeek=0;
uLong uL;
if (file==NULL)
return UNZ_PARAMERROR;
s=(unz64_s*)file;
if (ZSEEK64(s->z_filefunc, s->filestream,
s->pos_in_central_dir+s->byte_before_the_zipfile,
ZLIB_FILEFUNC_SEEK_SET)!=0)
err=UNZ_ERRNO;
/* we check the magic */
if (err==UNZ_OK)
{
if (unz64local_getLong(&s->z_filefunc, s->filestream,&uMagic) != UNZ_OK)
err=UNZ_ERRNO;
else if (uMagic!=0x02014b50)
err=UNZ_BADZIPFILE;
}
if (unz64local_getShort(&s->z_filefunc, s->filestream,&file_info.version) != UNZ_OK)
err=UNZ_ERRNO;
if (unz64local_getShort(&s->z_filefunc, s->filestream,&file_info.version_needed) != UNZ_OK)
err=UNZ_ERRNO;
if (unz64local_getShort(&s->z_filefunc, s->filestream,&file_info.flag) != UNZ_OK)
err=UNZ_ERRNO;
if (unz64local_getShort(&s->z_filefunc, s->filestream,&file_info.compression_method) != UNZ_OK)
err=UNZ_ERRNO;
if (unz64local_getLong(&s->z_filefunc, s->filestream,&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,&file_info.crc) != UNZ_OK)
err=UNZ_ERRNO;
if (unz64local_getLong(&s->z_filefunc, s->filestream,&uL) != UNZ_OK)
err=UNZ_ERRNO;
file_info.compressed_size = uL;
if (unz64local_getLong(&s->z_filefunc, s->filestream,&uL) != UNZ_OK)
err=UNZ_ERRNO;
file_info.uncompressed_size = uL;
if (unz64local_getShort(&s->z_filefunc, s->filestream,&file_info.size_filename) != UNZ_OK)
err=UNZ_ERRNO;
if (unz64local_getShort(&s->z_filefunc, s->filestream,&file_info.size_file_extra) != UNZ_OK)
err=UNZ_ERRNO;
if (unz64local_getShort(&s->z_filefunc, s->filestream,&file_info.size_file_comment) != UNZ_OK)
err=UNZ_ERRNO;
if (unz64local_getShort(&s->z_filefunc, s->filestream,&file_info.disk_num_start) != UNZ_OK)
err=UNZ_ERRNO;
if (unz64local_getShort(&s->z_filefunc, s->filestream,&file_info.internal_fa) != UNZ_OK)
err=UNZ_ERRNO;
if (unz64local_getLong(&s->z_filefunc, s->filestream,&file_info.external_fa) != UNZ_OK)
err=UNZ_ERRNO;
// relative offset of local header
if (unz64local_getLong(&s->z_filefunc, s->filestream,&uL) != UNZ_OK)
err=UNZ_ERRNO;
file_info_internal.offset_curfile = uL;
lSeek+=file_info.size_filename;
if ((err==UNZ_OK) && (szFileName!=NULL))
{
uLong uSizeRead ;
if (file_info.size_filename<fileNameBufferSize)
{
*(szFileName+file_info.size_filename)='\0';
uSizeRead = file_info.size_filename;
}
else
uSizeRead = fileNameBufferSize;
if ((file_info.size_filename>0) && (fileNameBufferSize>0))
if (ZREAD64(s->z_filefunc, s->filestream,szFileName,uSizeRead)!=uSizeRead)
err=UNZ_ERRNO;
lSeek -= uSizeRead;
}
// Read extrafield
if ((err==UNZ_OK) && (extraField!=NULL))
{
ZPOS64_T uSizeRead ;
if (file_info.size_file_extra<extraFieldBufferSize)
uSizeRead = file_info.size_file_extra;
else
uSizeRead = extraFieldBufferSize;
if (lSeek!=0)
{
if (ZSEEK64(s->z_filefunc, s->filestream,(ZPOS64_T)lSeek,ZLIB_FILEFUNC_SEEK_CUR)==0)
lSeek=0;
else
err=UNZ_ERRNO;
}
if ((file_info.size_file_extra>0) && (extraFieldBufferSize>0))
if (ZREAD64(s->z_filefunc, s->filestream,extraField,(uLong)uSizeRead)!=uSizeRead)
err=UNZ_ERRNO;
lSeek += file_info.size_file_extra - (uLong)uSizeRead;
}
else
lSeek += file_info.size_file_extra;
if ((err==UNZ_OK) && (file_info.size_file_extra != 0))
{
uLong acc = 0;
// since lSeek now points to after the extra field we need to move back
lSeek -= file_info.size_file_extra;
if (lSeek!=0)
{
if (ZSEEK64(s->z_filefunc, s->filestream,(ZPOS64_T)lSeek,ZLIB_FILEFUNC_SEEK_CUR)==0)
lSeek=0;
else
err=UNZ_ERRNO;
}
while(acc < file_info.size_file_extra)
{
uLong headerId;
uLong dataSize;
if (unz64local_getShort(&s->z_filefunc, s->filestream,&headerId) != UNZ_OK)
err=UNZ_ERRNO;
if (unz64local_getShort(&s->z_filefunc, s->filestream,&dataSize) != UNZ_OK)
err=UNZ_ERRNO;
/* ZIP64 extra fields */
if (headerId == 0x0001)
{
if(file_info.uncompressed_size == MAXU32)
{
if (unz64local_getLong64(&s->z_filefunc, s->filestream,&file_info.uncompressed_size) != UNZ_OK)
err=UNZ_ERRNO;
}
if(file_info.compressed_size == MAXU32)
{
if (unz64local_getLong64(&s->z_filefunc, s->filestream,&file_info.compressed_size) != UNZ_OK)
err=UNZ_ERRNO;
}
if(file_info_internal.offset_curfile == MAXU32)
{
/* Relative Header offset */
if (unz64local_getLong64(&s->z_filefunc, s->filestream,&file_info_internal.offset_curfile) != UNZ_OK)
err=UNZ_ERRNO;
}
if(file_info.disk_num_start == 0xffff)
{
/* Disk Start Number */
if (unz64local_getLong(&s->z_filefunc, s->filestream,&file_info.disk_num_start) != UNZ_OK)
err=UNZ_ERRNO;
}
}
else
{
if (ZSEEK64(s->z_filefunc, s->filestream,dataSize,ZLIB_FILEFUNC_SEEK_CUR)!=0)
err=UNZ_ERRNO;
}
acc += 2 + 2 + dataSize;
}
}
if ((err==UNZ_OK) && (szComment!=NULL))
{
uLong uSizeRead ;
if (file_info.size_file_comment<commentBufferSize)
{
*(szComment+file_info.size_file_comment)='\0';
uSizeRead = file_info.size_file_comment;
}
else
uSizeRead = commentBufferSize;
if (lSeek!=0)
{
if (ZSEEK64(s->z_filefunc, s->filestream,(ZPOS64_T)lSeek,ZLIB_FILEFUNC_SEEK_CUR)==0)
lSeek=0;
else
err=UNZ_ERRNO;
}
if ((file_info.size_file_comment>0) && (commentBufferSize>0))
if (ZREAD64(s->z_filefunc, s->filestream,szComment,uSizeRead)!=uSizeRead)
err=UNZ_ERRNO;
lSeek+=file_info.size_file_comment - uSizeRead;
}
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;
}