Welcome to mirror list, hosted at ThFree Co, Russian Federation.

github.com/kornelski/7z.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
Diffstat (limited to 'CPP/7zip/Compress/Rar3Decoder.cpp')
-rw-r--r--[-rwxr-xr-x]CPP/7zip/Compress/Rar3Decoder.cpp104
1 files changed, 55 insertions, 49 deletions
diff --git a/CPP/7zip/Compress/Rar3Decoder.cpp b/CPP/7zip/Compress/Rar3Decoder.cpp
index dde7c6de..3c70e1c0 100755..100644
--- a/CPP/7zip/Compress/Rar3Decoder.cpp
+++ b/CPP/7zip/Compress/Rar3Decoder.cpp
@@ -25,7 +25,7 @@ static const UInt32 kSymbolReadTable = 256;
static const UInt32 kSymbolRep = 259;
static const UInt32 kSymbolLen2 = kSymbolRep + kNumReps;
-static const Byte kLenStart[kLenTableSize] = {0,1,2,3,4,5,6,7,8,10,12,14,16,20,24,28,32,40,48,56,64,80,96,112,128,160,192,224};
+static const Byte kLenStart [kLenTableSize] = {0,1,2,3,4,5,6,7,8,10,12,14,16,20,24,28,32,40,48,56,64,80,96,112,128,160,192,224};
static const Byte kLenDirectBits[kLenTableSize] = {0,0,0,0,0,0,0,0,1, 1, 1, 1, 2, 2, 2, 2, 3, 3, 3, 3, 4, 4, 4, 4, 5, 5, 5, 5};
static const Byte kDistDirectBits[kDistTableSize] =
@@ -153,7 +153,7 @@ HRESULT CDecoder::WriteBuf()
{
UInt32 writtenBorder = _wrPtr;
UInt32 writeSize = (_winPos - writtenBorder) & kWindowMask;
- for (int i = 0; i < _tempFilters.Size(); i++)
+ FOR_VECTOR (i, _tempFilters)
{
CTempFilter *filter = _tempFilters[i];
if (filter == NULL)
@@ -202,7 +202,7 @@ HRESULT CDecoder::WriteBuf()
}
else
{
- for (int j = i; j < _tempFilters.Size(); j++)
+ for (unsigned j = i; j < _tempFilters.Size(); j++)
{
CTempFilter *filter = _tempFilters[j];
if (filter != NULL && filter->NextWindow)
@@ -221,7 +221,7 @@ HRESULT CDecoder::WriteBuf()
void CDecoder::InitFilters()
{
_lastFilter = 0;
- int i;
+ unsigned i;
for (i = 0; i < _tempFilters.Size(); i++)
delete _tempFilters[i];
_tempFilters.Clear();
@@ -238,7 +238,7 @@ bool CDecoder::AddVmCode(UInt32 firstByte, UInt32 codeSize)
UInt32 filterIndex;
if (firstByte & 0x80)
{
- filterIndex = NVm::ReadEncodedUInt32(inp);
+ filterIndex = inp.ReadEncodedUInt32();
if (filterIndex == 0)
InitFilters();
else
@@ -267,7 +267,7 @@ bool CDecoder::AddVmCode(UInt32 firstByte, UInt32 codeSize)
}
int numEmptyItems = 0;
- int i;
+ unsigned i;
for (i = 0; i < _tempFilters.Size(); i++)
{
_tempFilters[i - numEmptyItems] = _tempFilters[i];
@@ -284,62 +284,56 @@ bool CDecoder::AddVmCode(UInt32 firstByte, UInt32 codeSize)
CTempFilter *tempFilter = new CTempFilter;
_tempFilters[_tempFilters.Size() - numEmptyItems] = tempFilter;
tempFilter->FilterIndex = filterIndex;
- tempFilter->ExecCount = filter->ExecCount;
- UInt32 blockStart = NVm::ReadEncodedUInt32(inp);
+ UInt32 blockStart = inp.ReadEncodedUInt32();
if (firstByte & 0x40)
blockStart += 258;
tempFilter->BlockStart = (blockStart + _winPos) & kWindowMask;
if (firstByte & 0x20)
- filter->BlockSize = NVm::ReadEncodedUInt32(inp);
+ filter->BlockSize = inp.ReadEncodedUInt32();
tempFilter->BlockSize = filter->BlockSize;
tempFilter->NextWindow = _wrPtr != _winPos && ((_wrPtr - _winPos) & kWindowMask) <= blockStart;
memset(tempFilter->InitR, 0, sizeof(tempFilter->InitR));
tempFilter->InitR[3] = NVm::kGlobalOffset;
tempFilter->InitR[4] = tempFilter->BlockSize;
- tempFilter->InitR[5] = tempFilter->ExecCount;
+ tempFilter->InitR[5] = filter->ExecCount;
if (firstByte & 0x10)
{
UInt32 initMask = inp.ReadBits(NVm::kNumGpRegs);
for (int i = 0; i < NVm::kNumGpRegs; i++)
if (initMask & (1 << i))
- tempFilter->InitR[i] = NVm::ReadEncodedUInt32(inp);
+ tempFilter->InitR[i] = inp.ReadEncodedUInt32();
}
if (newFilter)
{
- UInt32 vmCodeSize = NVm::ReadEncodedUInt32(inp);
+ UInt32 vmCodeSize = inp.ReadEncodedUInt32();
if (vmCodeSize >= kVmCodeSizeMax || vmCodeSize == 0)
return false;
for (UInt32 i = 0; i < vmCodeSize; i++)
_vmCode[i] = (Byte)inp.ReadBits(8);
- _vm.PrepareProgram(_vmCode, vmCodeSize, filter);
+ filter->PrepareProgram(_vmCode, vmCodeSize);
}
- tempFilter->AllocateEmptyFixedGlobal();
-
Byte *globalData = &tempFilter->GlobalData[0];
for (i = 0; i < NVm::kNumGpRegs; i++)
NVm::SetValue32(&globalData[i * 4], tempFilter->InitR[i]);
NVm::SetValue32(&globalData[NVm::NGlobalOffset::kBlockSize], tempFilter->BlockSize);
NVm::SetValue32(&globalData[NVm::NGlobalOffset::kBlockPos], 0); // It was commented. why?
- NVm::SetValue32(&globalData[NVm::NGlobalOffset::kExecCount], tempFilter->ExecCount);
+ NVm::SetValue32(&globalData[NVm::NGlobalOffset::kExecCount], filter->ExecCount);
if (firstByte & 8)
{
- UInt32 dataSize = NVm::ReadEncodedUInt32(inp);
+ UInt32 dataSize = inp.ReadEncodedUInt32();
if (dataSize > NVm::kGlobalSize - NVm::kFixedGlobalSize)
return false;
CRecordVector<Byte> &globalData = tempFilter->GlobalData;
- int requredSize = (int)(dataSize + NVm::kFixedGlobalSize);
- if (globalData.Size() < requredSize)
- {
- globalData.Reserve(requredSize);
- for (; globalData.Size() < requredSize; i++)
- globalData.Add(0);
- }
+ unsigned requiredSize = (unsigned)(dataSize + NVm::kFixedGlobalSize);
+ if (globalData.Size() < requiredSize)
+ globalData.ChangeSize_KeepData(requiredSize);
+ Byte *dest = &globalData[NVm::kFixedGlobalSize];
for (UInt32 i = 0; i < dataSize; i++)
- globalData[NVm::kFixedGlobalSize + i] = (Byte)inp.ReadBits(8);
+ dest[i] = (Byte)inp.ReadBits(8);
}
return true;
}
@@ -384,6 +378,8 @@ bool CDecoder::ReadVmCodePPM()
}
if (length > kVmDataSizeMax)
return false;
+ if (InputEofError_Fast())
+ return false;
for (UInt32 i = 0; i < length; i++)
{
int b = DecodePpmSymbol();
@@ -396,14 +392,13 @@ bool CDecoder::ReadVmCodePPM()
#define RIF(x) { if (!(x)) return S_FALSE; }
-UInt32 CDecoder::ReadBits(int numBits) { return m_InBitStream.bitDecoder.ReadBits(numBits); }
+UInt32 CDecoder::ReadBits(int numBits) { return m_InBitStream.BitDecoder.ReadBits(numBits); }
-/////////////////////////////////////////////////
-// PPM
+// ---------- PPM ----------
HRESULT CDecoder::InitPPM()
{
- Byte maxOrder = (Byte)ReadBits(7);
+ unsigned maxOrder = (unsigned)ReadBits(7);
bool reset = ((maxOrder & 0x20) != 0);
int maxMB = 0;
@@ -458,6 +453,8 @@ HRESULT CDecoder::DecodePPM(Int32 num, bool &keepDecompressing)
return S_OK;
}
}
+ if (InputEofError_Fast())
+ return false;
int c = DecodePpmSymbol();
if (c < 0)
{
@@ -526,13 +523,12 @@ HRESULT CDecoder::DecodePPM(Int32 num, bool &keepDecompressing)
return S_OK;
}
-/////////////////////////////////////////////////
-// LZ
+// ---------- LZ ----------
HRESULT CDecoder::ReadTables(bool &keepDecompressing)
{
keepDecompressing = true;
- ReadBits((8 - m_InBitStream.bitDecoder.GetBitPosition()) & 7);
+ m_InBitStream.BitDecoder.AlignToByte();
if (ReadBits(1) != 0)
{
_lzMode = false;
@@ -571,7 +567,7 @@ HRESULT CDecoder::ReadTables(bool &keepDecompressing)
i = 0;
while (i < kTablesSizesSum)
{
- UInt32 number = m_LevelDecoder.DecodeSymbol(&m_InBitStream.bitDecoder);
+ UInt32 number = m_LevelDecoder.DecodeSymbol(&m_InBitStream.BitDecoder);
if (number < 16)
{
newLevels[i] = Byte((number + m_LastLevels[i]) & 15);
@@ -620,6 +616,7 @@ HRESULT CDecoder::ReadTables(bool &keepDecompressing)
return S_OK;
}
+/*
class CCoderReleaser
{
CDecoder *m_Coder;
@@ -630,6 +627,7 @@ public:
m_Coder->ReleaseStreams();
}
};
+*/
HRESULT CDecoder::ReadEndOfBlock(bool &keepDecompressing)
{
@@ -680,7 +678,11 @@ HRESULT CDecoder::DecodeLZ(bool &keepDecompressing)
return S_OK;
}
}
- UInt32 number = m_MainDecoder.DecodeSymbol(&m_InBitStream.bitDecoder);
+
+ if (InputEofError_Fast())
+ return S_FALSE;
+
+ UInt32 number = m_MainDecoder.DecodeSymbol(&m_InBitStream.BitDecoder);
if (number < 256)
{
PutByte((Byte)number);
@@ -724,10 +726,10 @@ HRESULT CDecoder::DecodeLZ(bool &keepDecompressing)
rep0 = distance;
}
- UInt32 number = m_LenDecoder.DecodeSymbol(&m_InBitStream.bitDecoder);
+ UInt32 number = m_LenDecoder.DecodeSymbol(&m_InBitStream.BitDecoder);
if (number >= kLenTableSize)
return S_FALSE;
- length = 2 + kLenStart[number] + m_InBitStream.bitDecoder.ReadBits(kLenDirectBits[number]);
+ length = 2 + kLenStart[number] + m_InBitStream.BitDecoder.ReadBits(kLenDirectBits[number]);
}
else
{
@@ -737,14 +739,14 @@ HRESULT CDecoder::DecodeLZ(bool &keepDecompressing)
if (number < 271)
{
number -= 263;
- rep0 = kLen2DistStarts[number] + m_InBitStream.bitDecoder.ReadBits(kLen2DistDirectBits[number]);
+ rep0 = kLen2DistStarts[number] + m_InBitStream.BitDecoder.ReadBits(kLen2DistDirectBits[number]);
length = 2;
}
else if (number < 299)
{
number -= 271;
- length = kNormalMatchMinLen + (UInt32)kLenStart[number] + m_InBitStream.bitDecoder.ReadBits(kLenDirectBits[number]);
- UInt32 number = m_DistDecoder.DecodeSymbol(&m_InBitStream.bitDecoder);
+ length = kNormalMatchMinLen + (UInt32)kLenStart[number] + m_InBitStream.BitDecoder.ReadBits(kLenDirectBits[number]);
+ UInt32 number = m_DistDecoder.DecodeSymbol(&m_InBitStream.BitDecoder);
if (number >= kDistTableSize)
return S_FALSE;
rep0 = kDistStart[number];
@@ -752,7 +754,7 @@ HRESULT CDecoder::DecodeLZ(bool &keepDecompressing)
if (number >= (kNumAlignBits * 2) + 2)
{
if (numBits > kNumAlignBits)
- rep0 += (m_InBitStream.bitDecoder.ReadBits(numBits - kNumAlignBits) << kNumAlignBits);
+ rep0 += (m_InBitStream.BitDecoder.ReadBits(numBits - kNumAlignBits) << kNumAlignBits);
if (PrevAlignCount > 0)
{
PrevAlignCount--;
@@ -760,13 +762,13 @@ HRESULT CDecoder::DecodeLZ(bool &keepDecompressing)
}
else
{
- UInt32 number = m_AlignDecoder.DecodeSymbol(&m_InBitStream.bitDecoder);
+ UInt32 number = m_AlignDecoder.DecodeSymbol(&m_InBitStream.BitDecoder);
if (number < (1 << kNumAlignBits))
{
rep0 += number;
PrevAlignBits = number;
}
- else if (number == (1 << kNumAlignBits))
+ else if (number == (1 << kNumAlignBits))
{
PrevAlignCount = kNumAlignReps;
rep0 += PrevAlignBits;
@@ -776,7 +778,7 @@ HRESULT CDecoder::DecodeLZ(bool &keepDecompressing)
}
}
else
- rep0 += m_InBitStream.bitDecoder.ReadBits(numBits);
+ rep0 += m_InBitStream.BitDecoder.ReadBits(numBits);
length += ((kDistLimit4 - rep0) >> 31) + ((kDistLimit3 - rep0) >> 31);
}
else
@@ -831,13 +833,17 @@ HRESULT CDecoder::CodeReal(ICompressProgressInfo *progress)
{
RINOK(DecodePPM(1 << 18, keepDecompressing))
}
- UInt64 packSize = m_InBitStream.bitDecoder.GetProcessedSize();
+
+ if (InputEofError())
+ return S_FALSE;
+
+ UInt64 packSize = m_InBitStream.BitDecoder.GetProcessedSize();
RINOK(progress->SetRatioInfo(&packSize, &_writtenFileSize));
if (!keepDecompressing)
break;
}
RINOK(WriteBuf());
- UInt64 packSize = m_InBitStream.bitDecoder.GetProcessedSize();
+ UInt64 packSize = m_InBitStream.BitDecoder.GetProcessedSize();
RINOK(progress->SetRatioInfo(&packSize, &_writtenFileSize));
if (_writtenFileSize < _unpackSize)
return S_FALSE;
@@ -866,17 +872,17 @@ STDMETHODIMP CDecoder::Code(ISequentialInStream *inStream, ISequentialOutStream
if (_window == 0)
return E_OUTOFMEMORY;
}
- if (!m_InBitStream.bitDecoder.Create(1 << 20))
+ if (!m_InBitStream.BitDecoder.Create(1 << 20))
return E_OUTOFMEMORY;
if (!_vm.Create())
return E_OUTOFMEMORY;
- m_InBitStream.bitDecoder.SetStream(inStream);
- m_InBitStream.bitDecoder.Init();
+ m_InBitStream.BitDecoder.SetStream(inStream);
+ m_InBitStream.BitDecoder.Init();
_outStream = outStream;
- CCoderReleaser coderReleaser(this);
+ // CCoderReleaser coderReleaser(this);
_unpackSize = *outSize;
return CodeReal(progress);
}