mirror of
https://github.com/Xevion/easy7zip.git
synced 2025-12-08 04:07:02 -06:00
4.60 beta
This commit is contained in:
committed by
Kornel Lesiński
parent
173c07e166
commit
c10e6b16f6
@@ -236,25 +236,40 @@ STDMETHODIMP CUdfInStream::Read(void *data, UInt32 size, UInt32 *processedSize)
|
||||
const CFile &file = _archive->Files[ref.FileIndex];
|
||||
const CItem &item = _archive->Items[file.ItemIndex];
|
||||
|
||||
const CMyExtent &extent = item.Extents[_extentIndex];
|
||||
UInt32 rem = extent.GetLen() - _offsetInExtent;
|
||||
if (rem == 0)
|
||||
HRESULT res = S_OK;
|
||||
if (item.IsInline)
|
||||
{
|
||||
_extentIndex++;
|
||||
_offsetInExtent = 0;
|
||||
continue;
|
||||
size_t rem = item.InlineData.GetCapacity() - _offsetInExtent;
|
||||
if (rem == 0)
|
||||
return S_OK;
|
||||
if (rem > _rem)
|
||||
rem = (size_t)_rem;
|
||||
memcpy(data, (const Byte *)item.InlineData + _offsetInExtent, rem);
|
||||
}
|
||||
if (size > rem)
|
||||
size = rem;
|
||||
|
||||
int partitionIndex = vol.PartitionMaps[extent.PartitionRef].PartitionIndex;
|
||||
UInt32 logBlockNumber = extent.Pos;
|
||||
const CPartition &partition = _archive->Partitions[partitionIndex];
|
||||
UInt64 offset = ((UInt64)partition.Pos << _archive->SecLogSize) +
|
||||
else
|
||||
{
|
||||
if (_extentIndex >= item.Extents.Size())
|
||||
return S_OK;
|
||||
const CMyExtent &extent = item.Extents[_extentIndex];
|
||||
UInt32 rem = extent.GetLen() - _offsetInExtent;
|
||||
if (rem == 0)
|
||||
{
|
||||
_extentIndex++;
|
||||
_offsetInExtent = 0;
|
||||
continue;
|
||||
}
|
||||
if (size > rem)
|
||||
size = rem;
|
||||
|
||||
int partitionIndex = vol.PartitionMaps[extent.PartitionRef].PartitionIndex;
|
||||
UInt32 logBlockNumber = extent.Pos;
|
||||
const CPartition &partition = _archive->Partitions[partitionIndex];
|
||||
UInt64 offset = ((UInt64)partition.Pos << _archive->SecLogSize) +
|
||||
(UInt64)logBlockNumber * vol.BlockSize + _offsetInExtent;
|
||||
|
||||
RINOK(_stream->Seek(offset, STREAM_SEEK_SET, NULL));
|
||||
HRESULT res = _stream->Read(data, size, &size);
|
||||
|
||||
RINOK(_stream->Seek(offset, STREAM_SEEK_SET, NULL));
|
||||
res = _stream->Read(data, size, &size);
|
||||
}
|
||||
_offsetInExtent += size;
|
||||
_rem -= size;
|
||||
if (processedSize)
|
||||
|
||||
@@ -26,6 +26,7 @@ const int kNumFilesMax = 1 << 28;
|
||||
const int kNumRefsMax = 1 << 28;
|
||||
const UInt32 kNumExtentsMax = (UInt32)1 << 30;
|
||||
const UInt64 kFileNameLengthTotalMax = (UInt64)1 << 33;
|
||||
const UInt64 kInlineExtentsSizeMax = (UInt64)1 << 33;
|
||||
|
||||
void MY_FAST_CALL Crc16GenerateTable(void);
|
||||
|
||||
@@ -275,6 +276,11 @@ HRESULT CInArchive::ReadFromFile(int volIndex, const CItem &item, CByteBuffer &b
|
||||
{
|
||||
if (item.Size >= (UInt32)1 << 30)
|
||||
return S_FALSE;
|
||||
if (item.IsInline)
|
||||
{
|
||||
buf = item.InlineData;
|
||||
return S_OK;
|
||||
}
|
||||
buf.SetCapacity((size_t)item.Size);
|
||||
size_t pos = 0;
|
||||
for (int i = 0; i < item.Extents.Size(); i++)
|
||||
@@ -448,37 +454,46 @@ HRESULT CInArchive::ReadItem(int volIndex, int fsIndex, const CLongAllocDesc &la
|
||||
pos += extendedAttrLen;
|
||||
|
||||
int desctType = item.IcbTag.GetDescriptorType();
|
||||
// if (desctType == ICB_DESC_TYPE_INLINE || desctType == ICB_DESC_TYPE_EXTENDED)
|
||||
if (desctType != ICB_DESC_TYPE_SHORT && desctType != ICB_DESC_TYPE_LONG)
|
||||
return S_FALSE;
|
||||
if (allocDescriptorsLen > size - pos)
|
||||
return S_FALSE;
|
||||
for (UInt32 i = 0; i < allocDescriptorsLen;)
|
||||
if (desctType == ICB_DESC_TYPE_INLINE)
|
||||
{
|
||||
CMyExtent e;
|
||||
if (desctType == ICB_DESC_TYPE_SHORT)
|
||||
item.IsInline = true;
|
||||
item.InlineData.SetCapacity(allocDescriptorsLen);
|
||||
memcpy(item.InlineData, p + pos, allocDescriptorsLen);
|
||||
}
|
||||
else
|
||||
{
|
||||
item.IsInline = false;
|
||||
if (desctType != ICB_DESC_TYPE_SHORT && desctType != ICB_DESC_TYPE_LONG)
|
||||
return S_FALSE;
|
||||
for (UInt32 i = 0; i < allocDescriptorsLen;)
|
||||
{
|
||||
if (i + 8 > allocDescriptorsLen)
|
||||
return S_FALSE;
|
||||
CShortAllocDesc sad;
|
||||
sad.Parse(p + pos + i);
|
||||
e.Pos = sad.Pos;
|
||||
e.Len = sad.Len;
|
||||
e.PartitionRef = lad.Location.PartitionRef;
|
||||
i += 8;
|
||||
CMyExtent e;
|
||||
if (desctType == ICB_DESC_TYPE_SHORT)
|
||||
{
|
||||
if (i + 8 > allocDescriptorsLen)
|
||||
return S_FALSE;
|
||||
CShortAllocDesc sad;
|
||||
sad.Parse(p + pos + i);
|
||||
e.Pos = sad.Pos;
|
||||
e.Len = sad.Len;
|
||||
e.PartitionRef = lad.Location.PartitionRef;
|
||||
i += 8;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (i + 16 > allocDescriptorsLen)
|
||||
return S_FALSE;
|
||||
CLongAllocDesc ladNew;
|
||||
ladNew.Parse(p + pos + i);
|
||||
e.Pos = ladNew.Location.Pos;
|
||||
e.PartitionRef = ladNew.Location.PartitionRef;
|
||||
e.Len = ladNew.Len;
|
||||
i += 16;
|
||||
}
|
||||
item.Extents.Add(e);
|
||||
}
|
||||
else
|
||||
{
|
||||
if (i + 16 > allocDescriptorsLen)
|
||||
return S_FALSE;
|
||||
CLongAllocDesc ladNew;
|
||||
ladNew.Parse(p + pos + i);
|
||||
e.Pos = ladNew.Location.Pos;
|
||||
e.PartitionRef = ladNew.Location.PartitionRef;
|
||||
e.Len = ladNew.Len;
|
||||
i += 16;
|
||||
}
|
||||
item.Extents.Add(e);
|
||||
}
|
||||
|
||||
if (item.IcbTag.IsDir())
|
||||
@@ -489,6 +504,7 @@ HRESULT CInArchive::ReadItem(int volIndex, int fsIndex, const CLongAllocDesc &la
|
||||
RINOK(ReadFromFile(volIndex, item, buf));
|
||||
item.Size = 0;
|
||||
item.Extents.ClearAndFree();
|
||||
item.InlineData.Free();
|
||||
|
||||
const Byte *p = buf;
|
||||
size = buf.GetCapacity();
|
||||
@@ -524,6 +540,10 @@ HRESULT CInArchive::ReadItem(int volIndex, int fsIndex, const CLongAllocDesc &la
|
||||
if ((UInt32)item.Extents.Size() > kNumExtentsMax - _numExtents)
|
||||
return S_FALSE;
|
||||
_numExtents += item.Extents.Size();
|
||||
|
||||
if (item.InlineData.GetCapacity() > kInlineExtentsSizeMax - _inlineExtentsSize)
|
||||
return S_FALSE;
|
||||
_inlineExtentsSize += item.InlineData.GetCapacity();
|
||||
}
|
||||
|
||||
return S_OK;
|
||||
@@ -769,6 +789,7 @@ void CInArchive::Clear()
|
||||
_fileNameLengthTotal = 0;
|
||||
_numRefs = 0;
|
||||
_numExtents = 0;
|
||||
_inlineExtentsSize = 0;
|
||||
_processedProgressBytes = 0;
|
||||
}
|
||||
|
||||
|
||||
@@ -167,6 +167,8 @@ struct CPartitionMap
|
||||
int PartitionIndex;
|
||||
};
|
||||
|
||||
// ECMA 4/14.6
|
||||
|
||||
enum EIcbFileType
|
||||
{
|
||||
ICB_FILE_TYPE_DIR = 4,
|
||||
@@ -243,6 +245,8 @@ struct CItem
|
||||
// CRegId ImplId;
|
||||
// UInt64 UniqueId;
|
||||
|
||||
bool IsInline;
|
||||
CByteBuffer InlineData;
|
||||
CRecordVector<CMyExtent> Extents;
|
||||
CRecordVector<int> SubFiles;
|
||||
|
||||
@@ -258,6 +262,8 @@ struct CItem
|
||||
|
||||
UInt64 GetChunksSumSize() const
|
||||
{
|
||||
if (IsInline)
|
||||
return InlineData.GetCapacity();
|
||||
UInt64 size = 0;
|
||||
for (int i = 0; i < Extents.Size(); i++)
|
||||
size += Extents[i].GetLen();
|
||||
@@ -343,6 +349,7 @@ class CInArchive
|
||||
UInt64 _fileNameLengthTotal;
|
||||
int _numRefs;
|
||||
UInt32 _numExtents;
|
||||
UInt64 _inlineExtentsSize;
|
||||
bool CheckExtent(int volIndex, int partitionRef, UInt32 blockPos, UInt32 len) const;
|
||||
public:
|
||||
HRESULT Open(IInStream *inStream, CProgressVirt *progress);
|
||||
|
||||
Reference in New Issue
Block a user