This commit is contained in:
Andreas Martin 2021-12-11 13:07:37 +01:00 committed by GitHub
commit e268dcd37a
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
2 changed files with 96 additions and 0 deletions

2
.gitignore vendored Normal file
View File

@ -0,0 +1,2 @@
amalgamation/

View File

@ -679,6 +679,100 @@ static mz_bool mz_zip_reader_read_central_dir(mz_zip_archive *pZip, mz_uint flag
cdir_size = MZ_READ_LE32(pBuf + MZ_ZIP_ECDH_CDIR_SIZE_OFS);
cdir_ofs = MZ_READ_LE32(pBuf + MZ_ZIP_ECDH_CDIR_OFS_OFS);
/*
ZIP files may contain more files, than "Total number of central directory records" in the EOCD can hold.
Thus iterate through central directory for the truthful number of files. Sanity checks will be done later nevertheless.
*/
if( !pZip->m_pState->m_zip64 )
{
mz_uint8 *buf_ptr = pBuf;
mz_uint32 buf_remain = 0;
mz_uint32 total_files = 0;
mz_uint32 ofs = 0;
mz_bool done = MZ_FALSE;
MZ_ASSERT( sizeof(buf_u32) > MZ_ZIP_CENTRAL_DIR_HEADER_SIZE );
while( buf_ptr && ofs < cdir_size && done != MZ_TRUE )
{
mz_uint32 cdh_signature = 0;
mz_uint32 cdh_size = 0;
mz_bool need_data = MZ_FALSE;
/* Try to get the current header size */
if( buf_remain > sizeof(mz_uint32) )
{
cdh_signature = MZ_READ_LE32(buf_ptr);
switch( cdh_signature )
{
case MZ_ZIP_CENTRAL_DIR_HEADER_SIG:
if( buf_remain >= MZ_ZIP_CENTRAL_DIR_HEADER_SIZE )
{
if( MZ_READ_LE16(buf_ptr + MZ_ZIP_CDH_DISK_START_OFS) == 0 )
{
cdh_size = MZ_ZIP_CENTRAL_DIR_HEADER_SIZE +
MZ_READ_LE16(buf_ptr + MZ_ZIP_CDH_FILENAME_LEN_OFS) +
MZ_READ_LE16(buf_ptr + MZ_ZIP_CDH_EXTRA_LEN_OFS) +
MZ_READ_LE16(buf_ptr + MZ_ZIP_CDH_COMMENT_LEN_OFS);
total_files++;
}
else buf_ptr = NULL; /* fail */
}
break;
case MZ_ZIP_END_OF_CENTRAL_DIR_HEADER_SIG:
if( cdir_size - ofs >= MZ_ZIP_END_OF_CENTRAL_DIR_HEADER_SIZE )
{
done = MZ_TRUE;
}
else buf_ptr = NULL; /* fail */
break;
default:
buf_ptr = NULL; /* fail */
break;
}
}
if( buf_ptr && done != MZ_TRUE )
{
if( !cdh_size )
need_data = MZ_TRUE;
else
{
ofs += cdh_size;
if( cdh_size < buf_remain )
{
buf_ptr += cdh_size;
buf_remain -= cdh_size;
}
else need_data = MZ_TRUE;
}
if( need_data )
{
mz_uint32 bytes_to_read = MZ_MIN( sizeof(buf_u32), cdir_size - ofs );
if( bytes_to_read )
{
if (pZip->m_pRead(pZip->m_pIO_opaque, cdir_ofs + ofs, pBuf, bytes_to_read ) != bytes_to_read )
return mz_zip_set_error(pZip, MZ_ZIP_FILE_READ_FAILED);
buf_ptr = pBuf;
buf_remain = bytes_to_read;
}
else done = (total_files > 0) ? MZ_TRUE : MZ_FALSE;
}
}
}
if( done )
{
pZip->m_total_files = cdir_entries_on_this_disk = total_files;
}
}
if (pZip->m_pState->m_zip64)
{
mz_uint32 zip64_total_num_of_disks = MZ_READ_LE32(pZip64_locator + MZ_ZIP64_ECDL_TOTAL_NUMBER_OF_DISKS_OFS);