This commit is contained in:
Igor Pavlov
2022-06-23 11:43:16 +01:00
committed by Kornel
parent c3529a41f5
commit ec44a8a070
1248 changed files with 15242 additions and 2443 deletions

155
CPP/7zip/Archive/SquashfsHandler.cpp Normal file → Executable file
View File

@@ -76,7 +76,7 @@ static const char * const k_Methods[] =
, "XZ"
};
static const UInt32 kMetadataBlockSizeLog = 13;
static const unsigned kMetadataBlockSizeLog = 13;
static const UInt32 kMetadataBlockSize = (1 << kMetadataBlockSizeLog);
enum
@@ -408,7 +408,7 @@ UInt32 CNode::Parse1(const Byte *p, UInt32 size, const CHeader &_h)
UInt32 CNode::Parse2(const Byte *p, UInt32 size, const CHeader &_h)
{
bool be = _h.be;
const bool be = _h.be;
if (size < 4)
return 0;
{
@@ -541,7 +541,7 @@ UInt32 CNode::Parse2(const Byte *p, UInt32 size, const CHeader &_h)
UInt32 CNode::Parse3(const Byte *p, UInt32 size, const CHeader &_h)
{
bool be = _h.be;
const bool be = _h.be;
if (size < 12)
return 0;
@@ -843,8 +843,8 @@ class CHandler:
CData _inodesData;
CData _dirs;
CRecordVector<CFrag> _frags;
// CByteBuffer _uids;
// CByteBuffer _gids;
CByteBuffer _uids;
CByteBuffer _gids;
CHeader _h;
bool _noPropsLZMA;
bool _needCheckLzma;
@@ -891,14 +891,20 @@ class CHandler:
_cachedUnpackBlockSize = 0;
}
HRESULT Seek2(UInt64 offset)
{
return _stream->Seek(offset, STREAM_SEEK_SET, NULL);
}
HRESULT Decompress(ISequentialOutStream *outStream, Byte *outBuf, bool *outBufWasWritten, UInt32 *outBufWasWrittenSize,
UInt32 inSize, UInt32 outSizeMax);
HRESULT ReadMetadataBlock(UInt32 &packSize);
HRESULT ReadMetadataBlock2();
HRESULT ReadData(CData &data, UInt64 start, UInt64 end);
HRESULT OpenDir(int parent, UInt32 startBlock, UInt32 offset, unsigned level, int &nodeIndex);
HRESULT ScanInodes(UInt64 ptr);
// HRESULT ReadUids(UInt64 start, UInt32 num, CByteBuffer &ids);
HRESULT ReadUids(UInt64 start, UInt32 num, CByteBuffer &ids);
HRESULT Open2(IInStream *inStream);
AString GetPath(int index) const;
bool GetPackSize(int index, UInt64 &res, bool fillOffsets);
@@ -938,9 +944,9 @@ static const Byte kProps[] =
kpidSize,
kpidPackSize,
kpidMTime,
kpidPosixAttrib
// kpidUser,
// kpidGroup,
kpidPosixAttrib,
kpidUserId,
kpidGroupId
// kpidLinks,
// kpidOffset
};
@@ -1280,14 +1286,14 @@ HRESULT CHandler::Decompress(ISequentialOutStream *outStream, Byte *outBuf, bool
HRESULT CHandler::ReadMetadataBlock(UInt32 &packSize)
{
Byte temp[3];
unsigned offset = _h.NeedCheckData() ? 3 : 2;
const unsigned offset = _h.NeedCheckData() ? 3 : 2;
if (offset > packSize)
return S_FALSE;
RINOK(ReadStream_FALSE(_stream, temp, offset));
// if (NeedCheckData && Major < 4) checkByte must be = 0xFF
bool be = _h.be;
const bool be = _h.be;
UInt32 size = Get16(temp);
bool isCompressed = ((size & kNotCompressedBit16) == 0);
const bool isCompressed = ((size & kNotCompressedBit16) == 0);
if (size != kNotCompressedBit16)
size &= ~kNotCompressedBit16;
@@ -1311,12 +1317,20 @@ HRESULT CHandler::ReadMetadataBlock(UInt32 &packSize)
return S_OK;
}
HRESULT CHandler::ReadMetadataBlock2()
{
_dynOutStreamSpec->Init();
UInt32 packSize = kMetadataBlockSize + 3; // check it
return ReadMetadataBlock(packSize);
}
HRESULT CHandler::ReadData(CData &data, UInt64 start, UInt64 end)
{
if (end < start || end - start >= ((UInt64)1 << 32))
return S_FALSE;
const UInt32 size = (UInt32)(end - start);
RINOK(_stream->Seek(start, STREAM_SEEK_SET, NULL));
RINOK(Seek2(start));
_dynOutStreamSpec->Init();
UInt32 packPos = 0;
while (packPos != size)
@@ -1395,7 +1409,7 @@ HRESULT CHandler::OpenDir(int parent, UInt32 startBlock, UInt32 offset, unsigned
CRecordVector<CTempItem> tempItems;
while (rem != 0)
{
bool be = _h.be;
const bool be = _h.be;
UInt32 count;
CTempItem tempItem;
if (_h.Major <= 2)
@@ -1519,15 +1533,15 @@ HRESULT CHandler::OpenDir(int parent, UInt32 startBlock, UInt32 offset, unsigned
return S_OK;
}
/*
HRESULT CHandler::ReadUids(UInt64 start, UInt32 num, CByteBuffer &ids)
{
size_t size = num * 4;
ids.SetCapacity(size);
RINOK(_stream->Seek(start, STREAM_SEEK_SET, NULL));
const size_t size = (size_t)num * 4;
ids.Alloc(size);
if (num == 0)
return S_OK;
RINOK(Seek2(start));
return ReadStream_FALSE(_stream, ids, size);
}
*/
HRESULT CHandler::Open2(IInStream *inStream)
{
@@ -1560,24 +1574,22 @@ HRESULT CHandler::Open2(IInStream *inStream)
if (_h.NumFrags > kNumFilesMax)
return S_FALSE;
_frags.ClearAndReserve(_h.NumFrags);
unsigned bigFrag = (_h.Major > 2);
const unsigned bigFrag = (_h.Major > 2);
unsigned fragPtrsInBlockLog = kMetadataBlockSizeLog - (3 + bigFrag);
UInt32 numBlocks = (_h.NumFrags + (1 << fragPtrsInBlockLog) - 1) >> fragPtrsInBlockLog;
size_t numBlocksBytes = (size_t)numBlocks << (2 + bigFrag);
const unsigned fragPtrsInBlockLog = kMetadataBlockSizeLog - (3 + bigFrag);
const UInt32 numBlocks = (_h.NumFrags + (1 << fragPtrsInBlockLog) - 1) >> fragPtrsInBlockLog;
const size_t numBlocksBytes = (size_t)numBlocks << (2 + bigFrag);
CByteBuffer data(numBlocksBytes);
RINOK(inStream->Seek(_h.FragTable, STREAM_SEEK_SET, NULL));
RINOK(Seek2(_h.FragTable));
RINOK(ReadStream_FALSE(inStream, data, numBlocksBytes));
bool be = _h.be;
const bool be = _h.be;
for (UInt32 i = 0; i < numBlocks; i++)
{
UInt64 offset = bigFrag ? Get64(data + i * 8) : Get32(data + i * 4);
RINOK(_stream->Seek(offset, STREAM_SEEK_SET, NULL));
_dynOutStreamSpec->Init();
UInt32 packSize = kMetadataBlockSize + 3;
RINOK(ReadMetadataBlock(packSize));
UInt32 unpackSize = (UInt32)_dynOutStreamSpec->GetSize();
const UInt64 offset = bigFrag ? Get64(data + i * 8) : Get32(data + i * 4);
RINOK(Seek2(offset));
RINOK(ReadMetadataBlock2());
const UInt32 unpackSize = (UInt32)_dynOutStreamSpec->GetSize();
if (unpackSize != kMetadataBlockSize)
if (i != numBlocks - 1 || unpackSize != ((_h.NumFrags << (3 + bigFrag)) & (kMetadataBlockSize - 1)))
return S_FALSE;
@@ -1605,8 +1617,6 @@ HRESULT CHandler::Open2(IInStream *inStream)
return S_FALSE;
}
// RINOK(inStream->Seek(_h.InodeTable, STREAM_SEEK_SET, NULL));
RINOK(ReadData(_inodesData, _h.InodeTable, _h.DirTable));
RINOK(ReadData(_dirs, _h.DirTable, _h.FragTable));
@@ -1655,7 +1665,6 @@ HRESULT CHandler::Open2(IInStream *inStream)
int rootNodeIndex;
RINOK(OpenDir(-1, (UInt32)absOffset, (UInt32)_h.RootInode & 0xFFFF, 0, rootNodeIndex));
/*
if (_h.Major < 4)
{
RINOK(ReadUids(_h.UidTable, _h.NumUids, _uids));
@@ -1663,33 +1672,34 @@ HRESULT CHandler::Open2(IInStream *inStream)
}
else
{
UInt32 size = _h.NumIDs * 4;
_uids.SetCapacity(size);
const UInt32 size = (UInt32)_h.NumIDs * 4;
_uids.Alloc(size);
UInt32 numBlocks = (size + kMetadataBlockSize - 1) / kMetadataBlockSize;
UInt32 numBlocksBytes = numBlocks << 3;
const UInt32 numBlocks = (size + kMetadataBlockSize - 1) / kMetadataBlockSize;
const UInt32 numBlocksBytes = numBlocks << 3;
CByteBuffer data;
data.SetCapacity(numBlocksBytes);
RINOK(inStream->Seek(_h.UidTable, STREAM_SEEK_SET, NULL));
data.Alloc(numBlocksBytes);
RINOK(Seek2(_h.UidTable));
RINOK(ReadStream_FALSE(inStream, data, numBlocksBytes));
for (UInt32 i = 0; i < numBlocks; i++)
{
UInt64 offset = GetUi64(data + i * 8);
UInt32 unpackSize, packSize;
RINOK(_stream->Seek(offset, STREAM_SEEK_SET, NULL));
RINOK(ReadMetadataBlock(NULL, _uids + kMetadataBlockSize * i, packSize, unpackSize));
const UInt64 offset = GetUi64(data + i * 8);
RINOK(Seek2(offset));
// RINOK(ReadMetadataBlock(NULL, _uids + kMetadataBlockSize * i, packSize, unpackSize));
RINOK(ReadMetadataBlock2());
const size_t unpackSize = _dynOutStreamSpec->GetSize();
if (unpackSize != kMetadataBlockSize)
if (i != numBlocks - 1 || unpackSize != (size & (kMetadataBlockSize - 1)))
return S_FALSE;
memcpy(_uids + kMetadataBlockSize * i, _dynOutStreamSpec->GetBuffer(), unpackSize);
}
}
*/
{
const UInt32 alignSize = 1 << 12;
Byte buf[alignSize];
RINOK(inStream->Seek(_h.Size, STREAM_SEEK_SET, NULL));
RINOK(Seek2(_h.Size));
UInt32 rem = (UInt32)(0 - _h.Size) & (alignSize - 1);
_sizeCalculated = _h.Size;
if (rem != 0)
@@ -1710,7 +1720,7 @@ AString CHandler::GetPath(int index) const
{
unsigned len = 0;
int indexMem = index;
bool be = _h.be;
const bool be = _h.be;
do
{
const CItem &item = _items[index];
@@ -1804,9 +1814,9 @@ bool CHandler::GetPackSize(int index, UInt64 &totalPack, bool fillOffsets)
totalPack = 0;
const CItem &item = _items[index];
const CNode &node = _nodes[item.Node];
UInt32 ptr = _nodesPos[item.Node];
const UInt32 ptr = _nodesPos[item.Node];
const Byte *p = _inodesData.Data + ptr;
bool be = _h.be;
const bool be = _h.be;
UInt32 type = node.Type;
UInt32 offset;
@@ -1936,11 +1946,7 @@ STDMETHODIMP CHandler::GetArchiveProperty(PROPID propID, PROPVARIANT *value)
case kpidBigEndian: prop = _h.be; break;
case kpidCTime:
if (_h.CTime != 0)
{
FILETIME ft;
NWindows::NTime::UnixTimeToFileTime(_h.CTime, ft);
prop = ft;
}
PropVariant_SetFrom_UnixTime(prop, _h.CTime);
break;
case kpidCharacts: FLAGS_TO_PROP(k_Flags, _h.Flags, prop); break;
// case kpidNumBlocks: prop = _h.NumFrags; break;
@@ -1979,8 +1985,8 @@ STDMETHODIMP CHandler::GetProperty(UInt32 index, PROPID propID, PROPVARIANT *val
NWindows::NCOM::CPropVariant prop;
const CItem &item = _items[index];
const CNode &node = _nodes[item.Node];
bool isDir = node.IsDir();
bool be = _h.be;
const bool isDir = node.IsDir();
const bool be = _h.be;
switch (propID)
{
@@ -2031,9 +2037,7 @@ STDMETHODIMP CHandler::GetProperty(UInt32 index, PROPID propID, PROPVARIANT *val
if (offset != 0)
{
const Byte *p = _inodesData.Data + _nodesPos[item.Node] + offset;
FILETIME ft;
NWindows::NTime::UnixTimeToFileTime(Get32(p), ft);
prop = ft;
PropVariant_SetFrom_UnixTime(prop, Get32(p));
}
break;
}
@@ -2043,31 +2047,38 @@ STDMETHODIMP CHandler::GetProperty(UInt32 index, PROPID propID, PROPVARIANT *val
prop = (UInt32)(node.Mode & 0xFFF) | k_TypeToMode[node.Type];
break;
}
/*
case kpidUser:
case kpidUserId:
{
UInt32 offset = node.Uid * 4;
const UInt32 offset = (UInt32)node.Uid * 4;
if (offset < _uids.Size())
prop = (UInt32)Get32(_uids + offset);
break;
}
case kpidGroup:
case kpidGroupId:
{
if (_h.Major == 4 || node.Gid == _h.GetSpecGuidIndex())
if (_h.Major < 4)
{
UInt32 offset = node.Uid * 4;
if (offset < _uids.Size())
prop = (UInt32)Get32(_uids + offset);
if (node.Gid == _h.GetSpecGuidIndex())
{
const UInt32 offset = (UInt32)node.Uid * 4;
if (offset < _uids.Size())
prop = (UInt32)Get32(_uids + offset);
}
else
{
const UInt32 offset = (UInt32)node.Gid * 4;
if (offset < _gids.Size())
prop = (UInt32)Get32(_gids + offset);
}
}
else
{
UInt32 offset = node.Gid * 4;
if (offset < _gids.Size())
prop = (UInt32)Get32(_gids + offset);
const UInt32 offset = (UInt32)node.Gid * 4;
if (offset < _uids.Size())
prop = (UInt32)Get32(_uids + offset);
}
break;
}
*/
/*
case kpidLinks:
if (_h.Major >= 3 && node.Type != kType_FILE)
@@ -2128,7 +2139,7 @@ HRESULT CHandler::ReadBlock(UInt64 blockIndex, Byte *dest, size_t blockSize)
packBlockSize != _cachedPackBlockSize)
{
ClearCache();
RINOK(_stream->Seek(blockOffset, STREAM_SEEK_SET, NULL));
RINOK(Seek2(blockOffset));
_limitedInStreamSpec->Init(packBlockSize);
if (compressed)