This commit is contained in:
Igor Pavlov
2014-11-23 00:00:00 +00:00
committed by Kornel Lesiński
parent 83f8ddcc5b
commit f08f4dcc3c
1158 changed files with 76451 additions and 35082 deletions

193
CPP/7zip/Archive/Cab/CabBlockInStream.cpp Executable file → Normal file
View File

@@ -3,8 +3,7 @@
#include "StdAfx.h"
#include "../../../../C/Alloc.h"
#include "Common/Defs.h"
#include "../../../../C/CpuArch.h"
#include "../../Common/StreamUtils.h"
@@ -17,173 +16,73 @@ static const UInt32 kBlockSize = (1 << 16);
bool CCabBlockInStream::Create()
{
if (!_buffer)
_buffer = (Byte *)::MyAlloc(kBlockSize);
return (_buffer != 0);
if (!_buf)
_buf = (Byte *)::MyAlloc(kBlockSize);
return _buf != 0;
}
CCabBlockInStream::~CCabBlockInStream()
{
MyFree(_buffer);
::MyFree(_buf);
}
class CCheckSum2
static UInt32 CheckSum(const Byte *p, UInt32 size)
{
UInt32 m_Value;
int m_Pos;
Byte m_Hist[4];
public:
CCheckSum2(): m_Value(0){};
void Init() { m_Value = 0; m_Pos = 0; }
void Update(const void *data, UInt32 size);
void FinishDataUpdate()
UInt32 sum = 0;
for (UInt32 i = size >> 2; i != 0; i--)
{
for (int i = 0; i < m_Pos; i++)
m_Value ^= ((UInt32)(m_Hist[i])) << (8 * (m_Pos - i - 1));
sum ^= GetUi32(p);
p += 4;
}
void UpdateUInt32(UInt32 v) { m_Value ^= v; }
UInt32 GetResult() const { return m_Value; }
};
void CCheckSum2::Update(const void *data, UInt32 size)
{
UInt32 checkSum = m_Value;
const Byte *dataPointer = (const Byte *)data;
while (size != 0 && m_Pos != 0)
{
m_Hist[m_Pos] = *dataPointer++;
m_Pos = (m_Pos + 1) & 3;
size--;
if (m_Pos == 0)
for (int i = 0; i < 4; i++)
checkSum ^= ((UInt32)m_Hist[i]) << (8 * i);
}
int numWords = size / 4;
while (numWords-- != 0)
{
UInt32 temp = *dataPointer++;
temp |= ((UInt32)(*dataPointer++)) << 8;
temp |= ((UInt32)(*dataPointer++)) << 16;
temp |= ((UInt32)(*dataPointer++)) << 24;
checkSum ^= temp;
}
m_Value = checkSum;
size &= 3;
while (size != 0)
{
m_Hist[m_Pos] = *dataPointer++;
m_Pos = (m_Pos + 1) & 3;
size--;
}
if (size > 2) sum ^= (UInt32)(*p++) << 16;
if (size > 1) sum ^= (UInt32)(*p++) << 8;
if (size > 0) sum ^= (UInt32)(*p++);
return sum;
}
static const UInt32 kDataBlockHeaderSize = 8;
class CTempCabInBuffer2
HRESULT CCabBlockInStream::PreRead(ISequentialInStream *stream, UInt32 &packSize, UInt32 &unpackSize)
{
public:
Byte Buffer[kDataBlockHeaderSize];
UInt32 Pos;
Byte ReadByte()
{
return Buffer[Pos++];
}
UInt32 ReadUInt32()
{
UInt32 value = 0;
for (int i = 0; i < 4; i++)
value |= (((UInt32)ReadByte()) << (8 * i));
return value;
}
UInt16 ReadUInt16()
{
UInt16 value = 0;
for (int i = 0; i < 2; i++)
value |= (((UInt16)ReadByte()) << (8 * i));
return value;
}
};
HRESULT CCabBlockInStream::PreRead(UInt32 &packSize, UInt32 &unpackSize)
{
CTempCabInBuffer2 inBuffer;
inBuffer.Pos = 0;
RINOK(ReadStream_FALSE(_stream, inBuffer.Buffer, kDataBlockHeaderSize))
UInt32 checkSum = inBuffer.ReadUInt32();
packSize = inBuffer.ReadUInt16();
unpackSize = inBuffer.ReadUInt16();
if (ReservedSize != 0)
{
RINOK(ReadStream_FALSE(_stream, _buffer, ReservedSize));
}
_pos = 0;
CCheckSum2 checkSumCalc;
checkSumCalc.Init();
UInt32 packSize2 = packSize;
if (MsZip && _size == 0)
{
if (packSize < 2)
return S_FALSE; // bad block;
Byte sig[2];
RINOK(ReadStream_FALSE(_stream, sig, 2));
if (sig[0] != 0x43 || sig[1] != 0x4B)
return S_FALSE;
packSize2 -= 2;
checkSumCalc.Update(sig, 2);
}
if (kBlockSize - _size < packSize2)
const UInt32 kHeaderSize = 8;
const UInt32 kReservedMax = 256;
Byte header[kHeaderSize + kReservedMax];
RINOK(ReadStream_FALSE(stream, header, kHeaderSize + ReservedSize))
packSize = GetUi16(header + 4);
unpackSize = GetUi16(header + 6);
if (packSize > kBlockSize - _size)
return S_FALSE;
UInt32 curSize = packSize2;
if (curSize != 0)
RINOK(ReadStream_FALSE(stream, _buf + _size, packSize));
if (MsZip)
{
size_t processedSizeLoc = curSize;
RINOK(ReadStream(_stream, _buffer + _size, &processedSizeLoc));
checkSumCalc.Update(_buffer + _size, (UInt32)processedSizeLoc);
_size += (UInt32)processedSizeLoc;
if (processedSizeLoc != curSize)
if (_size == 0)
{
if (packSize < 2 || _buf[0] != 0x43 || _buf[1] != 0x4B)
return S_FALSE;
_pos = 2;
}
if (_size + packSize > ((UInt32)1 << 15) + 12) /* v9.31 fix. MSZIP specification */
return S_FALSE;
}
TotalPackSize = _size;
checkSumCalc.FinishDataUpdate();
bool dataError;
if (checkSum == 0)
dataError = false;
else
{
checkSumCalc.UpdateUInt32(packSize | (((UInt32)unpackSize) << 16));
dataError = (checkSumCalc.GetResult() != checkSum);
}
DataError |= dataError;
return dataError ? S_FALSE : S_OK;
if (GetUi32(header) != 0) // checkSum
if (CheckSum(header, kHeaderSize + ReservedSize) != CheckSum(_buf + _size, packSize))
return S_FALSE;
_size += packSize;
return S_OK;
}
STDMETHODIMP CCabBlockInStream::Read(void *data, UInt32 size, UInt32 *processedSize)
{
if (processedSize != 0)
*processedSize = 0;
if (size == 0)
return S_OK;
if (_size != 0)
{
size = MyMin(_size, size);
memmove(data, _buffer + _pos, size);
_pos += size;
_size -= size;
if (processedSize != 0)
*processedSize = size;
return S_OK;
}
return S_OK; // no blocks data
UInt32 rem = _size - _pos;
if (size > rem)
size = rem;
memcpy(data, _buf + _pos, size);
_pos += size;
if (processedSize)
*processedSize = size;
return S_OK;
}
}}