Fixed calculation of each archive file data offset. (#4204)
* Fixed calculation of each archive file data offset. The location of a file entry in a Zip file is calculated after the local file header + the length of the filename + the length of the extra field length per the ZIP file spec. https://pkware.cachefly.net/webdocs/casestudies/APPNOTE.TXT Signed-off-by: lumberyard-employee-dm <56135373+lumberyard-employee-dm@users.noreply.github.com> * Removed bIndependentBlocks variable Signed-off-by: lumberyard-employee-dm <56135373+lumberyard-employee-dm@users.noreply.github.com>
This commit is contained in:
committed by
GitHub
parent
16e806abff
commit
b9d1af9f46
@@ -774,7 +774,7 @@ namespace AZ::IO::ZipDir
|
||||
return ZD_ERROR_INVALID_CALL;
|
||||
}
|
||||
|
||||
if (pFileEntry->nFileDataOffset != pFileEntry->INVALID_DATA_OFFSET)
|
||||
if (pFileEntry->nFileDataOffset != FileEntryBase::INVALID_DATA_OFFSET)
|
||||
{
|
||||
return ZD_ERROR_SUCCESS; // the data offset has been successfully read..
|
||||
}
|
||||
|
||||
@@ -553,7 +553,7 @@ namespace AZ::IO::ZipDir
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
// give the CDR File Header entry, reads the local file header to validate
|
||||
// and determine where the actual file lies
|
||||
// and determine where the actual file resides
|
||||
void CacheFactory::AddFileEntry(char* strFilePath, const ZipFile::CDRFileHeader* pFileHeader, const SExtraZipFileData& extra)
|
||||
{
|
||||
if (pFileHeader->lLocalHeaderOffset > m_CDREnd.lCDROffset)
|
||||
@@ -600,8 +600,7 @@ namespace AZ::IO::ZipDir
|
||||
if (m_encryptedHeaders != ZipFile::HEADERS_NOT_ENCRYPTED)
|
||||
{
|
||||
// use CDR instead of local header
|
||||
// The pak encryption tool asserts that there is no extra data at the end of the local file header, so don't add any extra data from the CDR header.
|
||||
fileEntry.nFileDataOffset = pFileHeader->lLocalHeaderOffset + sizeof(ZipFile::LocalFileHeader) + pFileHeader->nFileNameLength;
|
||||
fileEntry.nFileDataOffset = pFileHeader->lLocalHeaderOffset + sizeof(ZipFile::LocalFileHeader) + pFileHeader->nFileNameLength + pFileHeader->nExtraFieldLength;
|
||||
}
|
||||
else
|
||||
{
|
||||
|
||||
@@ -187,8 +187,7 @@ namespace AZ::IO::ZipDir::ZipDirStructuresInternal
|
||||
|
||||
// If src/dst overlap (in place decompress), then inflate in chunks, copying src locally to ensure
|
||||
// pointers don't foul each other.
|
||||
bool bIndependantBlocks = ((pInput + nInputLen) <= pOutput) || (pInput >= (pOutput + nOutputLen));
|
||||
if (bIndependantBlocks)
|
||||
if ((pInput + nInputLen) <= pOutput || pInput >= (pOutput + nOutputLen))
|
||||
{
|
||||
pZStream->next_in = (Bytef*)pInput;
|
||||
pZStream->avail_in = aznumeric_cast<uint32_t>(nInputLen);
|
||||
@@ -260,8 +259,7 @@ namespace AZ::IO::ZipDir::ZipDirStructuresInternal
|
||||
|
||||
// If src/dst overlap (in place decompress), then inflate in chunks, copying src locally to ensure
|
||||
// pointers don't foul each other.
|
||||
bool bIndependantBlocks = ((pIn + nIn) <= stream.next_out) || (pIn >= (stream.next_out + stream.avail_out));
|
||||
if (bIndependantBlocks)
|
||||
if ((pIn + nIn) <= stream.next_out || pIn >= (stream.next_out + stream.avail_out))
|
||||
{
|
||||
stream.next_in = pIn;
|
||||
stream.avail_in = nIn;
|
||||
@@ -498,18 +496,18 @@ namespace AZ::IO::ZipDir
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
FileEntryBase::FileEntryBase(const ZipFile::CDRFileHeader& header, const SExtraZipFileData& extra)
|
||||
{
|
||||
this->desc = header.desc;
|
||||
this->nFileHeaderOffset = header.lLocalHeaderOffset;
|
||||
//this->nFileDataOffset = INVALID_DATA_OFFSET; // we don't know yet
|
||||
this->nMethod = header.nMethod;
|
||||
this->nNameOffset = 0; // we don't know yet
|
||||
this->nLastModTime = header.nLastModTime;
|
||||
this->nLastModDate = header.nLastModDate;
|
||||
this->nNTFS_LastModifyTime = extra.nLastModifyTime;
|
||||
desc = header.desc;
|
||||
nFileHeaderOffset = header.lLocalHeaderOffset;
|
||||
|
||||
nMethod = header.nMethod;
|
||||
nNameOffset = 0; // we don't know yet
|
||||
nLastModTime = header.nLastModTime;
|
||||
nLastModDate = header.nLastModDate;
|
||||
nNTFS_LastModifyTime = extra.nLastModifyTime;
|
||||
|
||||
// make an estimation (at least this offset should be there), but we don't actually know yet
|
||||
this->nFileDataOffset = header.lLocalHeaderOffset + sizeof(ZipFile::LocalFileHeader) + header.nFileNameLength;
|
||||
this->nEOFOffset = header.lLocalHeaderOffset + sizeof(ZipFile::LocalFileHeader) + header.nFileNameLength + header.desc.lSizeCompressed;
|
||||
nFileDataOffset = header.lLocalHeaderOffset + sizeof(ZipFile::LocalFileHeader) + header.nFileNameLength + header.nExtraFieldLength;
|
||||
nEOFOffset = nFileDataOffset + header.desc.lSizeCompressed;
|
||||
}
|
||||
|
||||
// Uncompresses raw (without wrapping) data that is compressed with method 8 (deflated) in the Zip file
|
||||
@@ -817,8 +815,6 @@ namespace AZ::IO::ZipDir
|
||||
header.nFileNameLength = aznumeric_cast<uint16_t>(nFileNameLength);
|
||||
header.nExtraFieldLength = 0;
|
||||
|
||||
pFileEntry->nFileDataOffset = pFileEntry->nFileHeaderOffset + sizeof(header) + header.nFileNameLength;
|
||||
pFileEntry->nEOFOffset = pFileEntry->nFileDataOffset + pFileEntry->desc.lSizeCompressed;
|
||||
if (!AZ::IO::FileIOBase::GetDirectInstance()->Write(fileHandle, &header, sizeof(header)))
|
||||
{
|
||||
return ZD_ERROR_IO_FAILED;
|
||||
|
||||
@@ -169,7 +169,7 @@ namespace AZ::IO::ZipDir
|
||||
|
||||
inline static constexpr uint32_t INVALID_DATA_OFFSET = 0xFFFFFFFF;
|
||||
ZipFile::DataDescriptor desc{};
|
||||
uint32_t nFileDataOffset{}; // offset of the packed info inside the file; NOTE: this can be INVALID_DATA_OFFSET, if not calculated yet!
|
||||
uint32_t nFileDataOffset{ INVALID_DATA_OFFSET }; // offset of the packed info inside the file; NOTE: this can be INVALID_DATA_OFFSET, if not calculated yet!
|
||||
uint32_t nFileHeaderOffset{ INVALID_DATA_OFFSET }; // offset of the local file header
|
||||
uint32_t nNameOffset{}; // offset of the file name in the name pool for the directory
|
||||
|
||||
|
||||
Reference in New Issue
Block a user