Really parse the extra field seeking for ZIP64 extended data
Extended ZIP64 data are stored in the field with Header ID = 1 and we need to iterate over all fields to find it because it is not stated in the documentation the it must be the first record in the collection. wxZipHeader is designed to process standard 64-byte headers and it is safe to use it to process data in the field with Header ID = 1 which can have up to 28 bytes. Closes #17170.
This commit is contained in:
committed by
Vadim Zeitlin
parent
4e00229b6e
commit
231c9c7168
@@ -1016,24 +1016,38 @@ void wxZipEntry::UnsetNotifier()
|
|||||||
|
|
||||||
bool wxZipEntry::LoadExtraInfo(const char* extraData, wxUint16 extraLen, bool localInfo)
|
bool wxZipEntry::LoadExtraInfo(const char* extraData, wxUint16 extraLen, bool localInfo)
|
||||||
{
|
{
|
||||||
wxZipHeader ds(extraData, extraLen);
|
// We need to iterate over all headers
|
||||||
|
// seeking for the field with Header ID = 1.
|
||||||
|
// (There is not stated in the documentation
|
||||||
|
// that it should be the first one in the collection.)
|
||||||
|
while ( extraLen >= 4 )
|
||||||
|
{
|
||||||
|
// Parse extra header
|
||||||
|
wxZipHeader hds(extraData, 4);
|
||||||
|
wxUint16 fieldID = hds.Read16();
|
||||||
|
wxUint16 fieldLen = hds.Read16();
|
||||||
|
if ( fieldID == 1 )
|
||||||
|
{
|
||||||
|
// Data block for extra field with Header ID = 1 (ZIP64)
|
||||||
|
// can have length up to 28 bytes.
|
||||||
|
wxZipHeader ds(extraData+4, wxMin(fieldLen, 28));
|
||||||
// A file may contain larger size, compressed size or offset
|
// A file may contain larger size, compressed size or offset
|
||||||
// in a zip64 extra data block. Use the 64 bit values if available
|
// in a zip64 extra data block. Use the 64 bit values if available
|
||||||
if ( extraLen > 4 && ds.Read16() == 1 )
|
|
||||||
{
|
|
||||||
ds.Read16(); // skip record size
|
|
||||||
if ( m_Size == 0xffffffff )
|
if ( m_Size == 0xffffffff )
|
||||||
m_Size = ds.Read64();
|
m_Size = ds.Read64();
|
||||||
if ( m_CompressedSize == 0xffffffff )
|
if ( m_CompressedSize == 0xffffffff )
|
||||||
m_CompressedSize = ds.Read64();
|
m_CompressedSize = ds.Read64();
|
||||||
if ( !localInfo && m_Offset == 0xffffffff )
|
if ( !localInfo && m_Offset == 0xffffffff )
|
||||||
m_Offset = ds.Read64();
|
m_Offset = ds.Read64();
|
||||||
|
|
||||||
// extraInfo was used and parsed
|
// extraInfo was used and parsed
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fieldLen += 4;
|
||||||
|
extraData += fieldLen;
|
||||||
|
extraLen -= fieldLen;
|
||||||
|
}
|
||||||
|
|
||||||
// extraInfo had unknown format
|
// extraInfo had unknown format
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
Reference in New Issue
Block a user