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/Archive/7z/7zIn.cpp')
-rwxr-xr-xCPP/7zip/Archive/7z/7zIn.cpp493
1 files changed, 239 insertions, 254 deletions
diff --git a/CPP/7zip/Archive/7z/7zIn.cpp b/CPP/7zip/Archive/7z/7zIn.cpp
index f892e0cd..6cf3fdf6 100755
--- a/CPP/7zip/Archive/7z/7zIn.cpp
+++ b/CPP/7zip/Archive/7z/7zIn.cpp
@@ -6,13 +6,17 @@
#include "7zDecode.h"
#include "../../Common/StreamObjects.h"
#include "../../Common/StreamUtils.h"
-extern "C"
-{
-#include "../../../../C/7zCrc.h"
-#include "../../../../C/CpuArch.h"
+extern "C"
+{
+ #include "../../../../C/7zCrc.h"
+ #include "../../../../C/CpuArch.h"
}
-// define FORMAT_7Z_RECOVERY if you want to recover multivolume archives with empty StartHeader
+#define Get16(p) GetUi16(p)
+#define Get32(p) GetUi32(p)
+#define Get64(p) GetUi64(p)
+
+// define FORMAT_7Z_RECOVERY if you want to recover multivolume archives with empty StartHeader
#ifndef _SFX
#define FORMAT_7Z_RECOVERY
#endif
@@ -36,7 +40,7 @@ public:
{
kUnsupportedVersion = 0,
kUnsupported,
- kIncorrect,
+ kIncorrect,
kEndOfData,
} Cause;
CInArchiveException(CCauseType cause): Cause(cause) {};
@@ -97,16 +101,6 @@ void CStreamSwitch::Set(CInArchive *archive, const CObjectVector<CByteBuffer> *d
}
}
-#ifdef LITTLE_ENDIAN_UNALIGN
-static inline UInt16 GetUInt16FromMem(const Byte *p) { return *(const UInt16 *)p; }
-static inline UInt32 GetUInt32FromMem(const Byte *p) { return *(const UInt32 *)p; }
-static inline UInt64 GetUInt64FromMem(const Byte *p) { return *(const UInt64 *)p; }
-#else
-static inline UInt16 GetUInt16FromMem(const Byte *p) { return p[0] | ((UInt16)p[1] << 8); }
-static inline UInt32 GetUInt32FromMem(const Byte *p) { return p[0] | ((UInt32)p[1] << 8) | ((UInt32)p[2] << 16) | ((UInt32)p[3] << 24); }
-static inline UInt64 GetUInt64FromMem(const Byte *p) { return GetUInt32FromMem(p) | ((UInt64)GetUInt32FromMem(p + 4) << 32); }
-#endif
-
Byte CInByte2::ReadByte()
{
if (_pos >= _size)
@@ -126,6 +120,7 @@ void CInByte2::SkeepData(UInt64 size)
{
if (size > _size - _pos)
ThrowEndOfData();
+ _pos += (size_t)size;
}
void CInByte2::SkeepData()
@@ -157,8 +152,8 @@ UInt64 CInByte2::ReadNumber()
}
CNum CInByte2::ReadNum()
-{
- UInt64 value = ReadNumber();
+{
+ UInt64 value = ReadNumber();
if (value > kNumMax)
ThrowUnsupported();
return (CNum)value;
@@ -168,7 +163,7 @@ UInt32 CInByte2::ReadUInt32()
{
if (_pos + 4 > _size)
ThrowEndOfData();
- UInt32 res = GetUInt32FromMem(_buffer + _pos);
+ UInt32 res = Get32(_buffer + _pos);
_pos += 4;
return res;
}
@@ -177,7 +172,7 @@ UInt64 CInByte2::ReadUInt64()
{
if (_pos + 8 > _size)
ThrowEndOfData();
- UInt64 res = GetUInt64FromMem(_buffer + _pos);
+ UInt64 res = Get64(_buffer + _pos);
_pos += 8;
return res;
}
@@ -200,9 +195,8 @@ void CInByte2::ReadString(UString &s)
ThrowUnsupported();
wchar_t *p = s.GetBuffer(len);
int i;
- for (i = 0; i < len; i++, buf += 2)
- p[i] = (wchar_t)GetUInt16FromMem(buf);
- p[i] = 0;
+ for (i = 0; i < len; i++, buf += 2)
+ p[i] = (wchar_t)Get16(buf);
s.ReleaseBuffer(len);
_pos += rem + 2;
}
@@ -234,23 +228,32 @@ HRESULT CInArchive::FindAndReadSignature(IInStream *stream, const UInt64 *search
if (searchHeaderSizeLimit != NULL)
if (curTestPos - _arhiveBeginStreamPosition > *searchHeaderSizeLimit)
break;
- UInt32 numReadBytes = kBufferSize - numPrevBytes;
- UInt32 processedSize;
- RINOK(stream->Read(buffer + numPrevBytes, numReadBytes, &processedSize));
- UInt32 numBytesInBuffer = numPrevBytes + processedSize;
- if (numBytesInBuffer < kHeaderSize)
- break;
- UInt32 numTests = numBytesInBuffer - kHeaderSize + 1;
- for(UInt32 pos = 0; pos < numTests; pos++, curTestPos++)
- {
+ do
+ {
+ UInt32 numReadBytes = kBufferSize - numPrevBytes;
+ UInt32 processedSize;
+ RINOK(stream->Read(buffer + numPrevBytes, numReadBytes, &processedSize));
+ numPrevBytes += processedSize;
+ if (processedSize == 0)
+ return S_FALSE;
+ }
+ while (numPrevBytes < kHeaderSize);
+ UInt32 numTests = numPrevBytes - kHeaderSize + 1;
+ for (UInt32 pos = 0; pos < numTests; pos++)
+ {
+ for (; buffer[pos] != '7' && pos < numTests; pos++);
+ if (pos == numTests)
+ break;
if (TestSignatureCandidate(buffer + pos))
{
memcpy(_header, buffer + pos, kHeaderSize);
+ curTestPos += pos;
_arhiveBeginStreamPosition = curTestPos;
return stream->Seek(curTestPos + kHeaderSize, STREAM_SEEK_SET, NULL);
}
}
- numPrevBytes = numBytesInBuffer - numTests;
+ curTestPos += numTests;
+ numPrevBytes -= numTests;
memmove(buffer, buffer + numTests, numPrevBytes);
}
return S_FALSE;
@@ -259,6 +262,7 @@ HRESULT CInArchive::FindAndReadSignature(IInStream *stream, const UInt64 *search
// S_FALSE means that file is not archive
HRESULT CInArchive::Open(IInStream *stream, const UInt64 *searchHeaderSizeLimit)
{
+ HeadersSize = 0;
Close();
RINOK(stream->Seek(0, STREAM_SEEK_CUR, &_arhiveBeginStreamPosition))
RINOK(FindAndReadSignature(stream, searchHeaderSizeLimit));
@@ -338,7 +342,7 @@ void CInArchive::GetNextFolderItem(CFolder &folder)
{
CBindPair bindPair;
bindPair.InIndex = ReadNum();
- bindPair.OutIndex = ReadNum();
+ bindPair.OutIndex = ReadNum();
folder.BindPairs.Add(bindPair);
}
@@ -354,7 +358,7 @@ void CInArchive::GetNextFolderItem(CFolder &folder)
}
}
else
- for(i = 0; i < numPackedStreams; i++)
+ for (i = 0; i < numPackedStreams; i++)
folder.PackStreams.Add(ReadNum());
}
@@ -372,13 +376,13 @@ void CInArchive::WaitAttribute(UInt64 attribute)
}
void CInArchive::ReadHashDigests(int numItems,
- CRecordVector<bool> &digestsDefined,
+ CRecordVector<bool> &digestsDefined,
CRecordVector<UInt32> &digests)
{
ReadBoolVector2(numItems, digestsDefined);
digests.Clear();
digests.Reserve(numItems);
- for(int i = 0; i < numItems; i++)
+ for (int i = 0; i < numItems; i++)
{
UInt32 crc = 0;
if (digestsDefined[i])
@@ -410,7 +414,7 @@ void CInArchive::ReadPackInfo(
break;
if (type == NID::kCRC)
{
- ReadHashDigests(numPackStreams, packCRCsDefined, packCRCs);
+ ReadHashDigests(numPackStreams, packCRCsDefined, packCRCs);
continue;
}
SkeepData();
@@ -421,7 +425,7 @@ void CInArchive::ReadPackInfo(
packCRCsDefined.Clear();
packCRCs.Reserve(numPackStreams);
packCRCs.Clear();
- for(CNum i = 0; i < numPackStreams; i++)
+ for (CNum i = 0; i < numPackStreams; i++)
{
packCRCsDefined.Add(false);
packCRCs.Add(0);
@@ -429,7 +433,7 @@ void CInArchive::ReadPackInfo(
}
}
-void CInArchive::ReadUnPackInfo(
+void CInArchive::ReadUnpackInfo(
const CObjectVector<CByteBuffer> *dataVector,
CObjectVector<CFolder> &folders)
{
@@ -441,23 +445,23 @@ void CInArchive::ReadUnPackInfo(
streamSwitch.Set(this, dataVector);
folders.Clear();
folders.Reserve(numFolders);
- for(CNum i = 0; i < numFolders; i++)
+ for (CNum i = 0; i < numFolders; i++)
{
folders.Add(CFolder());
GetNextFolderItem(folders.Back());
}
}
- WaitAttribute(NID::kCodersUnPackSize);
+ WaitAttribute(NID::kCodersUnpackSize);
CNum i;
for (i = 0; i < numFolders; i++)
{
CFolder &folder = folders[i];
CNum numOutStreams = folder.GetNumOutStreams();
- folder.UnPackSizes.Reserve(numOutStreams);
+ folder.UnpackSizes.Reserve(numOutStreams);
for (CNum j = 0; j < numOutStreams; j++)
- folder.UnPackSizes.Add(ReadNumber());
+ folder.UnpackSizes.Add(ReadNumber());
}
for (;;)
@@ -469,12 +473,12 @@ void CInArchive::ReadUnPackInfo(
{
CRecordVector<bool> crcsDefined;
CRecordVector<UInt32> crcs;
- ReadHashDigests(numFolders, crcsDefined, crcs);
- for(i = 0; i < numFolders; i++)
+ ReadHashDigests(numFolders, crcsDefined, crcs);
+ for (i = 0; i < numFolders; i++)
{
CFolder &folder = folders[i];
- folder.UnPackCRCDefined = crcsDefined[i];
- folder.UnPackCRC = crcs[i];
+ folder.UnpackCRCDefined = crcsDefined[i];
+ folder.UnpackCRC = crcs[i];
}
continue;
}
@@ -484,21 +488,21 @@ void CInArchive::ReadUnPackInfo(
void CInArchive::ReadSubStreamsInfo(
const CObjectVector<CFolder> &folders,
- CRecordVector<CNum> &numUnPackStreamsInFolders,
- CRecordVector<UInt64> &unPackSizes,
- CRecordVector<bool> &digestsDefined,
+ CRecordVector<CNum> &numUnpackStreamsInFolders,
+ CRecordVector<UInt64> &unpackSizes,
+ CRecordVector<bool> &digestsDefined,
CRecordVector<UInt32> &digests)
{
- numUnPackStreamsInFolders.Clear();
- numUnPackStreamsInFolders.Reserve(folders.Size());
+ numUnpackStreamsInFolders.Clear();
+ numUnpackStreamsInFolders.Reserve(folders.Size());
UInt64 type;
for (;;)
{
type = ReadID();
- if (type == NID::kNumUnPackStream)
+ if (type == NID::kNumUnpackStream)
{
- for(int i = 0; i < folders.Size(); i++)
- numUnPackStreamsInFolders.Add(ReadNum());
+ for (int i = 0; i < folders.Size(); i++)
+ numUnpackStreamsInFolders.Add(ReadNum());
continue;
}
if (type == NID::kCRC || type == NID::kSize)
@@ -508,16 +512,16 @@ void CInArchive::ReadSubStreamsInfo(
SkeepData();
}
- if (numUnPackStreamsInFolders.IsEmpty())
- for(int i = 0; i < folders.Size(); i++)
- numUnPackStreamsInFolders.Add(1);
+ if (numUnpackStreamsInFolders.IsEmpty())
+ for (int i = 0; i < folders.Size(); i++)
+ numUnpackStreamsInFolders.Add(1);
int i;
- for(i = 0; i < numUnPackStreamsInFolders.Size(); i++)
+ for (i = 0; i < numUnpackStreamsInFolders.Size(); i++)
{
// v3.13 incorrectly worked with empty folders
// v4.07: we check that folder is empty
- CNum numSubstreams = numUnPackStreamsInFolders[i];
+ CNum numSubstreams = numUnpackStreamsInFolders[i];
if (numSubstreams == 0)
continue;
UInt64 sum = 0;
@@ -525,20 +529,20 @@ void CInArchive::ReadSubStreamsInfo(
if (type == NID::kSize)
{
UInt64 size = ReadNumber();
- unPackSizes.Add(size);
+ unpackSizes.Add(size);
sum += size;
}
- unPackSizes.Add(folders[i].GetUnPackSize() - sum);
+ unpackSizes.Add(folders[i].GetUnpackSize() - sum);
}
if (type == NID::kSize)
type = ReadID();
int numDigests = 0;
int numDigestsTotal = 0;
- for(i = 0; i < folders.Size(); i++)
+ for (i = 0; i < folders.Size(); i++)
{
- CNum numSubstreams = numUnPackStreamsInFolders[i];
- if (numSubstreams != 1 || !folders[i].UnPackCRCDefined)
+ CNum numSubstreams = numUnpackStreamsInFolders[i];
+ if (numSubstreams != 1 || !folders[i].UnpackCRCDefined)
numDigests += numSubstreams;
numDigestsTotal += numSubstreams;
}
@@ -547,18 +551,18 @@ void CInArchive::ReadSubStreamsInfo(
{
if (type == NID::kCRC)
{
- CRecordVector<bool> digestsDefined2;
+ CRecordVector<bool> digestsDefined2;
CRecordVector<UInt32> digests2;
ReadHashDigests(numDigests, digestsDefined2, digests2);
int digestIndex = 0;
for (i = 0; i < folders.Size(); i++)
{
- CNum numSubstreams = numUnPackStreamsInFolders[i];
+ CNum numSubstreams = numUnpackStreamsInFolders[i];
const CFolder &folder = folders[i];
- if (numSubstreams == 1 && folder.UnPackCRCDefined)
+ if (numSubstreams == 1 && folder.UnpackCRCDefined)
{
digestsDefined.Add(true);
- digests.Add(folder.UnPackCRC);
+ digests.Add(folder.UnpackCRC);
}
else
for (CNum j = 0; j < numSubstreams; j++, digestIndex++)
@@ -595,9 +599,9 @@ void CInArchive::ReadStreamsInfo(
CRecordVector<bool> &packCRCsDefined,
CRecordVector<UInt32> &packCRCs,
CObjectVector<CFolder> &folders,
- CRecordVector<CNum> &numUnPackStreamsInFolders,
- CRecordVector<UInt64> &unPackSizes,
- CRecordVector<bool> &digestsDefined,
+ CRecordVector<CNum> &numUnpackStreamsInFolders,
+ CRecordVector<UInt64> &unpackSizes,
+ CRecordVector<bool> &digestsDefined,
CRecordVector<UInt32> &digests)
{
for (;;)
@@ -614,15 +618,15 @@ void CInArchive::ReadStreamsInfo(
ReadPackInfo(dataOffset, packSizes, packCRCsDefined, packCRCs);
break;
}
- case NID::kUnPackInfo:
+ case NID::kUnpackInfo:
{
- ReadUnPackInfo(dataVector, folders);
+ ReadUnpackInfo(dataVector, folders);
break;
}
case NID::kSubStreamsInfo:
{
- ReadSubStreamsInfo(folders, numUnPackStreamsInFolders,
- unPackSizes, digestsDefined, digests);
+ ReadSubStreamsInfo(folders, numUnpackStreamsInFolders,
+ unpackSizes, digestsDefined, digests);
break;
}
default:
@@ -637,7 +641,7 @@ void CInArchive::ReadBoolVector(int numItems, CBoolVector &v)
v.Reserve(numItems);
Byte b = 0;
Byte mask = 0;
- for(int i = 0; i < numItems; i++)
+ for (int i = 0; i < numItems; i++)
{
if (mask == 0)
{
@@ -663,54 +667,30 @@ void CInArchive::ReadBoolVector2(int numItems, CBoolVector &v)
v.Add(true);
}
-void CInArchive::ReadTime(const CObjectVector<CByteBuffer> &dataVector,
- CObjectVector<CFileItem> &files, UInt32 type)
+void CInArchive::ReadUInt64DefVector(const CObjectVector<CByteBuffer> &dataVector,
+ CUInt64DefVector &v, int numFiles)
{
- CBoolVector boolVector;
- ReadBoolVector2(files.Size(), boolVector);
+ ReadBoolVector2(numFiles, v.Defined);
CStreamSwitch streamSwitch;
streamSwitch.Set(this, &dataVector);
+ v.Values.Reserve(numFiles);
- for(int i = 0; i < files.Size(); i++)
+ for (int i = 0; i < numFiles; i++)
{
- CFileItem &file = files[i];
- CArchiveFileTime fileTime;
- fileTime.dwLowDateTime = 0;
- fileTime.dwHighDateTime = 0;
- bool defined = boolVector[i];
- if (defined)
- {
- fileTime.dwLowDateTime = ReadUInt32();
- fileTime.dwHighDateTime = ReadUInt32();
- }
- switch(type)
- {
- case NID::kCreationTime:
- file.IsCreationTimeDefined = defined;
- if (defined)
- file.CreationTime = fileTime;
- break;
- case NID::kLastWriteTime:
- file.IsLastWriteTimeDefined = defined;
- if (defined)
- file.LastWriteTime = fileTime;
- break;
- case NID::kLastAccessTime:
- file.IsLastAccessTimeDefined = defined;
- if (defined)
- file.LastAccessTime = fileTime;
- break;
- }
+ UInt64 t = 0;
+ if (v.Defined[i])
+ t = ReadUInt64();
+ v.Values.Add(t);
}
}
HRESULT CInArchive::ReadAndDecodePackedStreams(
DECL_EXTERNAL_CODECS_LOC_VARS
- UInt64 baseOffset,
+ UInt64 baseOffset,
UInt64 &dataOffset, CObjectVector<CByteBuffer> &dataVector
#ifndef _NO_CRYPTO
- , ICryptoGetTextPassword *getTextPassword
+ , ICryptoGetTextPassword *getTextPassword, bool &passwordIsDefined
#endif
)
{
@@ -719,23 +699,23 @@ HRESULT CInArchive::ReadAndDecodePackedStreams(
CRecordVector<UInt32> packCRCs;
CObjectVector<CFolder> folders;
- CRecordVector<CNum> numUnPackStreamsInFolders;
- CRecordVector<UInt64> unPackSizes;
+ CRecordVector<CNum> numUnpackStreamsInFolders;
+ CRecordVector<UInt64> unpackSizes;
CRecordVector<bool> digestsDefined;
CRecordVector<UInt32> digests;
- ReadStreamsInfo(NULL,
+ ReadStreamsInfo(NULL,
dataOffset,
- packSizes,
- packCRCsDefined,
- packCRCs,
+ packSizes,
+ packCRCsDefined,
+ packCRCs,
folders,
- numUnPackStreamsInFolders,
- unPackSizes,
- digestsDefined,
+ numUnpackStreamsInFolders,
+ unpackSizes,
+ digestsDefined,
digests);
- // database.ArchiveInfo.DataStartPosition2 += database.ArchiveInfo.StartPositionAfterHeader;
+ // db.ArchiveInfo.DataStartPosition2 += db.ArchiveInfo.StartPositionAfterHeader;
CNum packIndex = 0;
CDecoder decoder(
@@ -746,27 +726,27 @@ HRESULT CInArchive::ReadAndDecodePackedStreams(
#endif
);
UInt64 dataStartPos = baseOffset + dataOffset;
- for(int i = 0; i < folders.Size(); i++)
+ for (int i = 0; i < folders.Size(); i++)
{
const CFolder &folder = folders[i];
dataVector.Add(CByteBuffer());
CByteBuffer &data = dataVector.Back();
- UInt64 unPackSize64 = folder.GetUnPackSize();
- size_t unPackSize = (size_t)unPackSize64;
- if (unPackSize != unPackSize64)
+ UInt64 unpackSize64 = folder.GetUnpackSize();
+ size_t unpackSize = (size_t)unpackSize64;
+ if (unpackSize != unpackSize64)
ThrowUnsupported();
- data.SetCapacity(unPackSize);
+ data.SetCapacity(unpackSize);
CSequentialOutStreamImp2 *outStreamSpec = new CSequentialOutStreamImp2;
CMyComPtr<ISequentialOutStream> outStream = outStreamSpec;
- outStreamSpec->Init(data, unPackSize);
+ outStreamSpec->Init(data, unpackSize);
HRESULT result = decoder.Decode(
EXTERNAL_CODECS_LOC_VARS
- _stream, dataStartPos,
+ _stream, dataStartPos,
&packSizes[packIndex], folder, outStream, NULL
#ifndef _NO_CRYPTO
- , getTextPassword
+ , getTextPassword, passwordIsDefined
#endif
#ifdef COMPRESS_MT
, false, 1
@@ -774,20 +754,24 @@ HRESULT CInArchive::ReadAndDecodePackedStreams(
);
RINOK(result);
- if (folder.UnPackCRCDefined)
- if (CrcCalc(data, unPackSize) != folder.UnPackCRC)
+ if (folder.UnpackCRCDefined)
+ if (CrcCalc(data, unpackSize) != folder.UnpackCRC)
ThrowIncorrect();
- for (int j = 0; j < folder.PackStreams.Size(); j++)
- dataStartPos += packSizes[packIndex++];
+ for (int j = 0; j < folder.PackStreams.Size(); j++)
+ {
+ UInt64 packSize = packSizes[packIndex++];
+ dataStartPos += packSize;
+ HeadersSize += packSize;
+ }
}
return S_OK;
}
HRESULT CInArchive::ReadHeader(
DECL_EXTERNAL_CODECS_LOC_VARS
- CArchiveDatabaseEx &database
+ CArchiveDatabaseEx &db
#ifndef _NO_CRYPTO
- , ICryptoGetTextPassword *getTextPassword
+ , ICryptoGetTextPassword *getTextPassword, bool &passwordIsDefined
#endif
)
{
@@ -795,7 +779,7 @@ HRESULT CInArchive::ReadHeader(
if (type == NID::kArchiveProperties)
{
- ReadArchiveProperties(database.ArchiveInfo);
+ ReadArchiveProperties(db.ArchiveInfo);
type = ReadID();
}
@@ -805,50 +789,50 @@ HRESULT CInArchive::ReadHeader(
{
HRESULT result = ReadAndDecodePackedStreams(
EXTERNAL_CODECS_LOC_VARS
- database.ArchiveInfo.StartPositionAfterHeader,
- database.ArchiveInfo.DataStartPosition2,
+ db.ArchiveInfo.StartPositionAfterHeader,
+ db.ArchiveInfo.DataStartPosition2,
dataVector
#ifndef _NO_CRYPTO
- , getTextPassword
+ , getTextPassword, passwordIsDefined
#endif
);
RINOK(result);
- database.ArchiveInfo.DataStartPosition2 += database.ArchiveInfo.StartPositionAfterHeader;
+ db.ArchiveInfo.DataStartPosition2 += db.ArchiveInfo.StartPositionAfterHeader;
type = ReadID();
}
- CRecordVector<UInt64> unPackSizes;
+ CRecordVector<UInt64> unpackSizes;
CRecordVector<bool> digestsDefined;
CRecordVector<UInt32> digests;
if (type == NID::kMainStreamsInfo)
{
ReadStreamsInfo(&dataVector,
- database.ArchiveInfo.DataStartPosition,
- database.PackSizes,
- database.PackCRCsDefined,
- database.PackCRCs,
- database.Folders,
- database.NumUnPackStreamsVector,
- unPackSizes,
+ db.ArchiveInfo.DataStartPosition,
+ db.PackSizes,
+ db.PackCRCsDefined,
+ db.PackCRCs,
+ db.Folders,
+ db.NumUnpackStreamsVector,
+ unpackSizes,
digestsDefined,
digests);
- database.ArchiveInfo.DataStartPosition += database.ArchiveInfo.StartPositionAfterHeader;
+ db.ArchiveInfo.DataStartPosition += db.ArchiveInfo.StartPositionAfterHeader;
type = ReadID();
}
else
{
- for(int i = 0; i < database.Folders.Size(); i++)
+ for (int i = 0; i < db.Folders.Size(); i++)
{
- database.NumUnPackStreamsVector.Add(1);
- CFolder &folder = database.Folders[i];
- unPackSizes.Add(folder.GetUnPackSize());
- digestsDefined.Add(folder.UnPackCRCDefined);
- digests.Add(folder.UnPackCRC);
+ db.NumUnpackStreamsVector.Add(1);
+ CFolder &folder = db.Folders[i];
+ unpackSizes.Add(folder.GetUnpackSize());
+ digestsDefined.Add(folder.UnpackCRCDefined);
+ digests.Add(folder.UnpackCRC);
}
}
- database.Files.Clear();
+ db.Files.Clear();
if (type == NID::kEnd)
return S_OK;
@@ -856,20 +840,20 @@ HRESULT CInArchive::ReadHeader(
ThrowIncorrect();
CNum numFiles = ReadNum();
- database.Files.Reserve(numFiles);
+ db.Files.Reserve(numFiles);
CNum i;
- for(i = 0; i < numFiles; i++)
- database.Files.Add(CFileItem());
+ for (i = 0; i < numFiles; i++)
+ db.Files.Add(CFileItem());
- database.ArchiveInfo.FileInfoPopIDs.Add(NID::kSize);
- if (!database.PackSizes.IsEmpty())
- database.ArchiveInfo.FileInfoPopIDs.Add(NID::kPackInfo);
+ db.ArchiveInfo.FileInfoPopIDs.Add(NID::kSize);
+ if (!db.PackSizes.IsEmpty())
+ db.ArchiveInfo.FileInfoPopIDs.Add(NID::kPackInfo);
if (numFiles > 0 && !digests.IsEmpty())
- database.ArchiveInfo.FileInfoPopIDs.Add(NID::kCRC);
+ db.ArchiveInfo.FileInfoPopIDs.Add(NID::kCRC);
CBoolVector emptyStreamVector;
emptyStreamVector.Reserve((int)numFiles);
- for(i = 0; i < numFiles; i++)
+ for (i = 0; i < numFiles; i++)
emptyStreamVector.Add(false);
CBoolVector emptyFileVector;
CBoolVector antiFileVector;
@@ -881,6 +865,8 @@ HRESULT CInArchive::ReadHeader(
if (type == NID::kEnd)
break;
UInt64 size = ReadNumber();
+ size_t ppp = _inByteBack->_pos;
+ bool addPropIdToList = true;
bool isKnownType = true;
if (type > ((UInt32)1 << 30))
isKnownType = false;
@@ -890,37 +876,22 @@ HRESULT CInArchive::ReadHeader(
{
CStreamSwitch streamSwitch;
streamSwitch.Set(this, &dataVector);
- for(int i = 0; i < database.Files.Size(); i++)
- _inByteBack->ReadString(database.Files[i].Name);
+ for (int i = 0; i < db.Files.Size(); i++)
+ _inByteBack->ReadString(db.Files[i].Name);
break;
}
case NID::kWinAttributes:
{
CBoolVector boolVector;
- ReadBoolVector2(database.Files.Size(), boolVector);
- CStreamSwitch streamSwitch;
- streamSwitch.Set(this, &dataVector);
- for(i = 0; i < numFiles; i++)
- {
- CFileItem &file = database.Files[i];
- file.AreAttributesDefined = boolVector[i];
- if (file.AreAttributesDefined)
- file.Attributes = ReadUInt32();
- }
- break;
- }
- case NID::kStartPos:
- {
- CBoolVector boolVector;
- ReadBoolVector2(database.Files.Size(), boolVector);
+ ReadBoolVector2(db.Files.Size(), boolVector);
CStreamSwitch streamSwitch;
streamSwitch.Set(this, &dataVector);
- for(i = 0; i < numFiles; i++)
+ for (i = 0; i < numFiles; i++)
{
- CFileItem &file = database.Files[i];
- file.IsStartPosDefined = boolVector[i];
- if (file.IsStartPosDefined)
- file.StartPos = ReadUInt64();
+ CFileItem &file = db.Files[i];
+ file.AttribDefined = boolVector[i];
+ if (file.AttribDefined)
+ file.Attrib = ReadUInt32();
}
break;
}
@@ -939,55 +910,68 @@ HRESULT CInArchive::ReadHeader(
}
break;
}
- case NID::kEmptyFile:
- {
- ReadBoolVector(numEmptyStreams, emptyFileVector);
- break;
- }
- case NID::kAnti:
- {
- ReadBoolVector(numEmptyStreams, antiFileVector);
- break;
- }
- case NID::kCreationTime:
- case NID::kLastWriteTime:
- case NID::kLastAccessTime:
+ case NID::kEmptyFile: ReadBoolVector(numEmptyStreams, emptyFileVector); break;
+ case NID::kAnti: ReadBoolVector(numEmptyStreams, antiFileVector); break;
+ case NID::kStartPos: ReadUInt64DefVector(dataVector, db.StartPos, (int)numFiles); break;
+ case NID::kCTime: ReadUInt64DefVector(dataVector, db.CTime, (int)numFiles); break;
+ case NID::kATime: ReadUInt64DefVector(dataVector, db.ATime, (int)numFiles); break;
+ case NID::kMTime: ReadUInt64DefVector(dataVector, db.MTime, (int)numFiles); break;
+ case NID::kDummy:
{
- ReadTime(dataVector, database.Files, (UInt32)type);
+ for (UInt64 j = 0; j < size; j++)
+ if (ReadByte() != 0)
+ ThrowIncorrect();
+ addPropIdToList = false;
break;
}
default:
- isKnownType = false;
+ addPropIdToList = isKnownType = false;
}
if (isKnownType)
- database.ArchiveInfo.FileInfoPopIDs.Add(type);
+ {
+ if(addPropIdToList)
+ db.ArchiveInfo.FileInfoPopIDs.Add(type);
+ }
else
SkeepData(size);
+ bool checkRecordsSize = (db.ArchiveInfo.Version.Major > 0 ||
+ db.ArchiveInfo.Version.Minor > 2);
+ if (checkRecordsSize && _inByteBack->_pos - ppp != size)
+ ThrowIncorrect();
}
CNum emptyFileIndex = 0;
CNum sizeIndex = 0;
- for(i = 0; i < numFiles; i++)
+
+ CNum numAntiItems = 0;
+ for (i = 0; i < numEmptyStreams; i++)
+ if (antiFileVector[i])
+ numAntiItems++;
+
+ for (i = 0; i < numFiles; i++)
{
- CFileItem &file = database.Files[i];
+ CFileItem &file = db.Files[i];
+ bool isAnti;
file.HasStream = !emptyStreamVector[i];
- if(file.HasStream)
+ if (file.HasStream)
{
- file.IsDirectory = false;
- file.IsAnti = false;
- file.UnPackSize = unPackSizes[sizeIndex];
- file.FileCRC = digests[sizeIndex];
- file.IsFileCRCDefined = digestsDefined[sizeIndex];
+ file.IsDir = false;
+ isAnti = false;
+ file.Size = unpackSizes[sizeIndex];
+ file.Crc = digests[sizeIndex];
+ file.CrcDefined = digestsDefined[sizeIndex];
sizeIndex++;
}
else
{
- file.IsDirectory = !emptyFileVector[emptyFileIndex];
- file.IsAnti = antiFileVector[emptyFileIndex];
+ file.IsDir = !emptyFileVector[emptyFileIndex];
+ isAnti = antiFileVector[emptyFileIndex];
emptyFileIndex++;
- file.UnPackSize = 0;
- file.IsFileCRCDefined = false;
+ file.Size = 0;
+ file.CrcDefined = false;
}
+ if (numAntiItems != 0)
+ db.IsAnti.Add(isAnti);
}
return S_OK;
}
@@ -998,7 +982,7 @@ void CArchiveDatabaseEx::FillFolderStartPackStream()
FolderStartPackStreamIndex.Clear();
FolderStartPackStreamIndex.Reserve(Folders.Size());
CNum startPos = 0;
- for(int i = 0; i < Folders.Size(); i++)
+ for (int i = 0; i < Folders.Size(); i++)
{
FolderStartPackStreamIndex.Add(startPos);
startPos += (CNum)Folders[i].PackStreams.Size();
@@ -1010,7 +994,7 @@ void CArchiveDatabaseEx::FillStartPos()
PackStreamStartPositions.Clear();
PackStreamStartPositions.Reserve(PackSizes.Size());
UInt64 startPos = 0;
- for(int i = 0; i < PackSizes.Size(); i++)
+ for (int i = 0; i < PackSizes.Size(); i++)
{
PackStreamStartPositions.Add(startPos);
startPos += PackSizes[i];
@@ -1044,7 +1028,7 @@ void CArchiveDatabaseEx::FillFolderStartFileIndex()
if (folderIndex >= Folders.Size())
ThrowIncorrect();
FolderStartFileIndex.Add(i); // check it
- if (NumUnPackStreamsVector[folderIndex] != 0)
+ if (NumUnpackStreamsVector[folderIndex] != 0)
break;
folderIndex++;
}
@@ -1053,7 +1037,7 @@ void CArchiveDatabaseEx::FillFolderStartFileIndex()
if (emptyStream)
continue;
indexInFolder++;
- if (indexInFolder >= NumUnPackStreamsVector[folderIndex])
+ if (indexInFolder >= NumUnpackStreamsVector[folderIndex])
{
folderIndex++;
indexInFolder = 0;
@@ -1063,25 +1047,25 @@ void CArchiveDatabaseEx::FillFolderStartFileIndex()
HRESULT CInArchive::ReadDatabase2(
DECL_EXTERNAL_CODECS_LOC_VARS
- CArchiveDatabaseEx &database
+ CArchiveDatabaseEx &db
#ifndef _NO_CRYPTO
- , ICryptoGetTextPassword *getTextPassword
+ , ICryptoGetTextPassword *getTextPassword, bool &passwordIsDefined
#endif
)
{
- database.Clear();
- database.ArchiveInfo.StartPosition = _arhiveBeginStreamPosition;
+ db.Clear();
+ db.ArchiveInfo.StartPosition = _arhiveBeginStreamPosition;
- database.ArchiveInfo.Version.Major = _header[6];
- database.ArchiveInfo.Version.Minor = _header[7];
+ db.ArchiveInfo.Version.Major = _header[6];
+ db.ArchiveInfo.Version.Minor = _header[7];
- if (database.ArchiveInfo.Version.Major != kMajorVersion)
+ if (db.ArchiveInfo.Version.Major != kMajorVersion)
ThrowUnsupportedVersion();
- UInt32 crcFromArchive = GetUInt32FromMem(_header + 8);
- UInt64 nextHeaderOffset = GetUInt64FromMem(_header + 0xC);
- UInt64 nextHeaderSize = GetUInt64FromMem(_header + 0x14);
- UInt32 nextHeaderCRC = GetUInt32FromMem(_header + 0x1C);
+ UInt32 crcFromArchive = Get32(_header + 8);
+ UInt64 nextHeaderOffset = Get64(_header + 0xC);
+ UInt64 nextHeaderSize = Get64(_header + 0x14);
+ UInt32 nextHeaderCRC = Get32(_header + 0x1C);
UInt32 crc = CrcCalc(_header + 0xC, 20);
#ifdef FORMAT_7Z_RECOVERY
@@ -1097,16 +1081,15 @@ HRESULT CInArchive::ReadDatabase2(
checkSize = (int)(cur2 - cur);
RINOK(_stream->Seek(-checkSize, STREAM_SEEK_END, &cur2));
- UInt32 realProcessedSize;
- RINOK(_stream->Read(buf, (UInt32)kCheckSize, &realProcessedSize));
+ RINOK(ReadStream_FALSE(_stream, buf, (size_t)checkSize));
int i;
- for (i = (int)realProcessedSize - 2; i >= 0; i--)
+ for (i = (int)checkSize - 2; i >= 0; i--)
if (buf[i] == 0x17 && buf[i + 1] == 0x6 || buf[i] == 0x01 && buf[i + 1] == 0x04)
break;
if (i < 0)
return S_FALSE;
- nextHeaderSize = realProcessedSize - i;
+ nextHeaderSize = checkSize - i;
nextHeaderOffset = cur2 - cur + i;
nextHeaderCRC = CrcCalc(buf + i, (size_t)nextHeaderSize);
RINOK(_stream->Seek(cur, STREAM_SEEK_SET, NULL));
@@ -1117,7 +1100,7 @@ HRESULT CInArchive::ReadDatabase2(
crcFromArchive = crc;
#endif
- database.ArchiveInfo.StartPositionAfterHeader = _arhiveBeginStreamPosition + kHeaderSize;
+ db.ArchiveInfo.StartPositionAfterHeader = _arhiveBeginStreamPosition + kHeaderSize;
if (crc != crcFromArchive)
ThrowIncorrect();
@@ -1133,10 +1116,10 @@ HRESULT CInArchive::ReadDatabase2(
CByteBuffer buffer2;
buffer2.SetCapacity((size_t)nextHeaderSize);
- UInt32 realProcessedSize;
- RINOK(_stream->Read(buffer2, (UInt32)nextHeaderSize, &realProcessedSize));
- if (realProcessedSize != (UInt32)nextHeaderSize)
- return S_FALSE;
+ RINOK(ReadStream_FALSE(_stream, buffer2, (size_t)nextHeaderSize));
+ HeadersSize += kHeaderSize + nextHeaderSize;
+ db.PhySize = kHeaderSize + nextHeaderOffset + nextHeaderSize;
+
if (CrcCalc(buffer2, (UInt32)nextHeaderSize) != nextHeaderCRC)
ThrowIncorrect();
@@ -1145,20 +1128,18 @@ HRESULT CInArchive::ReadDatabase2(
CObjectVector<CByteBuffer> dataVector;
- for (;;)
+ UInt64 type = ReadID();
+ if (type != NID::kHeader)
{
- UInt64 type = ReadID();
- if (type == NID::kHeader)
- break;
if (type != NID::kEncodedHeader)
ThrowIncorrect();
HRESULT result = ReadAndDecodePackedStreams(
EXTERNAL_CODECS_LOC_VARS
- database.ArchiveInfo.StartPositionAfterHeader,
- database.ArchiveInfo.DataStartPosition2,
+ db.ArchiveInfo.StartPositionAfterHeader,
+ db.ArchiveInfo.DataStartPosition2,
dataVector
#ifndef _NO_CRYPTO
- , getTextPassword
+ , getTextPassword, passwordIsDefined
#endif
);
RINOK(result);
@@ -1168,31 +1149,35 @@ HRESULT CInArchive::ReadDatabase2(
ThrowIncorrect();
streamSwitch.Remove();
streamSwitch.Set(this, dataVector.Front());
+ if (ReadID() != NID::kHeader)
+ ThrowIncorrect();
}
+ db.HeadersSize = HeadersSize;
+
return ReadHeader(
EXTERNAL_CODECS_LOC_VARS
- database
+ db
#ifndef _NO_CRYPTO
- , getTextPassword
+ , getTextPassword, passwordIsDefined
#endif
);
}
HRESULT CInArchive::ReadDatabase(
DECL_EXTERNAL_CODECS_LOC_VARS
- CArchiveDatabaseEx &database
+ CArchiveDatabaseEx &db
#ifndef _NO_CRYPTO
- , ICryptoGetTextPassword *getTextPassword
+ , ICryptoGetTextPassword *getTextPassword, bool &passwordIsDefined
#endif
)
{
try
{
return ReadDatabase2(
- EXTERNAL_CODECS_LOC_VARS database
+ EXTERNAL_CODECS_LOC_VARS db
#ifndef _NO_CRYPTO
- , getTextPassword
+ , getTextPassword, passwordIsDefined
#endif
);
}