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>
monroegm-disable-blank-issue-2
lumberyard-employee-dm 4 years ago committed by GitHub
parent 16e806abff
commit b9d1af9f46
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23

@ -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

Loading…
Cancel
Save