mirror of
https://github.com/ip7z/7zip.git
synced 2025-12-06 07:12:00 +01:00
Fix reading standard Zip64 extended information fields
This commit is contained in:
parent
65f34b6f2a
commit
9a43bff533
|
|
@ -1114,34 +1114,46 @@ bool CInArchive::ReadExtra(const CLocalItem &item, unsigned extraSize, CExtraBlo
|
|||
}
|
||||
else
|
||||
{
|
||||
size_t expectedExtraRecordSize = 16 + (cdItem && (ZIP64_IS_32_MAX(cdItem->LocalHeaderPos) || ZIP64_IS_16_MAX(cdItem->Disk)) ? 8 : 0) + (cdItem && ZIP64_IS_16_MAX(cdItem->Disk) ? 4 : 0);
|
||||
size_t nonStandardExtraRecordSize = (ZIP64_IS_32_MAX(unpackSize) ? 8 : 0) + (ZIP64_IS_32_MAX(packSize) ? 8 : 0) + (cdItem && ZIP64_IS_32_MAX(cdItem->LocalHeaderPos) ? 8 : 0) + (cdItem && ZIP64_IS_16_MAX(cdItem->Disk) ? 4 : 0);
|
||||
if (expectedExtraRecordSize == size)
|
||||
{
|
||||
// Record seems standards compliant. Read it as per the standard.
|
||||
size -= 8; unpackSize = ReadUInt64();
|
||||
size -= 8; packSize = ReadUInt64();
|
||||
if (cdItem && (ZIP64_IS_32_MAX(cdItem->LocalHeaderPos) || ZIP64_IS_16_MAX(cdItem->Disk)))
|
||||
{
|
||||
size -= 8; cdItem->LocalHeaderPos = ReadUInt64();
|
||||
}
|
||||
if (cdItem && ZIP64_IS_16_MAX(cdItem->Disk))
|
||||
{
|
||||
size -= 4; cdItem->Disk = ReadUInt32();
|
||||
}
|
||||
}
|
||||
else if (nonStandardExtraRecordSize == size)
|
||||
{
|
||||
// Record is not standards compliant, but appears to match previous 7zip behaviour.
|
||||
if (ZIP64_IS_32_MAX(unpackSize))
|
||||
{ if (size < 8) isOK = false; else { size -= 8; unpackSize = ReadUInt64(); }}
|
||||
|
||||
if (isOK && ZIP64_IS_32_MAX(packSize))
|
||||
{ if (size < 8) isOK = false; else { size -= 8; packSize = ReadUInt64(); }}
|
||||
|
||||
if (cdItem)
|
||||
{
|
||||
if (isOK)
|
||||
{
|
||||
if (ZIP64_IS_32_MAX(cdItem->LocalHeaderPos))
|
||||
{ if (size < 8) isOK = false; else { size -= 8; cdItem->LocalHeaderPos = ReadUInt64(); }}
|
||||
/*
|
||||
else if (size == 8)
|
||||
{
|
||||
size -= 8;
|
||||
const UInt64 v = ReadUInt64();
|
||||
// soong_zip, an AOSP tool (written in the Go) writes incorrect value.
|
||||
// we can ignore that minor error here
|
||||
if (v != cdItem->LocalHeaderPos)
|
||||
isOK = false; // ignore error
|
||||
// isOK = false; // force error
|
||||
size -= 8; unpackSize = ReadUInt64();
|
||||
}
|
||||
*/
|
||||
if (ZIP64_IS_32_MAX(packSize))
|
||||
{
|
||||
size -= 8; packSize = ReadUInt64();
|
||||
}
|
||||
|
||||
if (isOK && ZIP64_IS_16_MAX(cdItem->Disk))
|
||||
{ if (size < 4) isOK = false; else { size -= 4; cdItem->Disk = ReadUInt32(); }}
|
||||
if (cdItem && ZIP64_IS_32_MAX(cdItem->LocalHeaderPos))
|
||||
{
|
||||
size -= 8; cdItem->LocalHeaderPos = ReadUInt64();
|
||||
}
|
||||
if (cdItem && ZIP64_IS_16_MAX(cdItem->Disk))
|
||||
{
|
||||
size -= 4; cdItem->Disk = ReadUInt32();
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
// Record doesn't match any known encoding. We can't safely interpret anything in it.
|
||||
isOK = false;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
Loading…
Reference in a new issue