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')
-rw-r--r--CPP/7zip/Archive/7z/7zIn.cpp136
1 files changed, 78 insertions, 58 deletions
diff --git a/CPP/7zip/Archive/7z/7zIn.cpp b/CPP/7zip/Archive/7z/7zIn.cpp
index d8c27175..3db5f515 100644
--- a/CPP/7zip/Archive/7z/7zIn.cpp
+++ b/CPP/7zip/Archive/7z/7zIn.cpp
@@ -32,6 +32,21 @@ using namespace NCOM;
namespace NArchive {
namespace N7z {
+unsigned BoolVector_CountSum(const CBoolVector &v)
+{
+ unsigned sum = 0;
+ const unsigned size = v.Size();
+ for (unsigned i = 0; i < size; i++)
+ if (v[i])
+ sum++;
+ return sum;
+}
+
+static inline bool BoolVector_Item_IsValidAndTrue(const CBoolVector &v, unsigned i)
+{
+ return (i < v.Size() ? v[i] : false);
+}
+
static void BoolVector_Fill_False(CBoolVector &v, unsigned size)
{
v.ClearAndSetSize(size);
@@ -40,6 +55,7 @@ static void BoolVector_Fill_False(CBoolVector &v, unsigned size)
p[i] = false;
}
+
class CInArchiveException {};
class CUnsupportedFeatureException: public CInArchiveException {};
@@ -566,21 +582,30 @@ void CInArchive::WaitId(UInt64 id)
}
}
-void CInArchive::ReadHashDigests(unsigned numItems, CUInt32DefVector &crcs)
+
+void CInArchive::Read_UInt32_Vector(CUInt32DefVector &v)
{
- ReadBoolVector2(numItems, crcs.Defs);
- crcs.Vals.ClearAndSetSize(numItems);
- UInt32 *p = &crcs.Vals[0];
- const bool *defs = &crcs.Defs[0];
+ unsigned numItems = v.Defs.Size();
+ v.Vals.ClearAndSetSize(numItems);
+ UInt32 *p = &v.Vals[0];
+ const bool *defs = &v.Defs[0];
for (unsigned i = 0; i < numItems; i++)
{
- UInt32 crc = 0;
+ UInt32 a = 0;
if (defs[i])
- crc = ReadUInt32();
- p[i] = crc;
+ a = ReadUInt32();
+ p[i] = a;
}
}
+
+void CInArchive::ReadHashDigests(unsigned numItems, CUInt32DefVector &crcs)
+{
+ ReadBoolVector2(numItems, crcs.Defs);
+ Read_UInt32_Vector(crcs);
+}
+
+
#define k_Scan_NumCoders_MAX 64
#define k_Scan_NumCodersStreams_in_Folder_MAX 64
@@ -1075,6 +1100,8 @@ HRESULT CInArchive::ReadAndDecodePackedStreams(
CMyComPtr<ISequentialOutStream> outStream = outStreamSpec;
outStreamSpec->Init(data, unpackSize);
+ bool dataAfterEnd_Error = false;
+
HRESULT result = decoder.Decode(
EXTERNAL_CODECS_LOC_VARS
_stream, baseOffset + dataOffset,
@@ -1083,16 +1110,23 @@ HRESULT CInArchive::ReadAndDecodePackedStreams(
outStream,
NULL, // *compressProgress
+
NULL // **inStreamMainRes
+ , dataAfterEnd_Error
_7Z_DECODER_CRYPRO_VARS
#if !defined(_7ZIP_ST) && !defined(_SFX)
, false // mtMode
, 1 // numThreads
#endif
+
);
+
RINOK(result);
+ if (dataAfterEnd_Error)
+ ThereIsHeaderError = true;
+
if (folders.FolderCRCs.ValidAndDefined(i))
if (CrcCalc(data, unpackSize) != folders.FolderCRCs.Vals[i])
ThrowIncorrect();
@@ -1148,19 +1182,10 @@ HRESULT CInArchive::ReadHeader(
type = ReadID();
}
- db.Files.Clear();
-
if (type == NID::kFilesInfo)
{
const CNum numFiles = ReadNum();
- db.Files.ClearAndSetSize(numFiles);
- /*
- db.Files.Reserve(numFiles);
- CNum i;
- for (i = 0; i < numFiles; i++)
- db.Files.Add(CFileItem());
- */
db.ArcInfo.FileInfoPopIDs.Add(NID::kSize);
// if (!db.PackSizes.IsEmpty())
@@ -1169,7 +1194,6 @@ HRESULT CInArchive::ReadHeader(
db.ArcInfo.FileInfoPopIDs.Add(NID::kCRC);
CBoolVector emptyStreamVector;
- BoolVector_Fill_False(emptyStreamVector, (unsigned)numFiles);
CBoolVector emptyFileVector;
CBoolVector antiFileVector;
CNum numEmptyStreams = 0;
@@ -1197,10 +1221,10 @@ HRESULT CInArchive::ReadHeader(
size_t rem = _inByteBack->GetRem();
db.NamesBuf.Alloc(rem);
ReadBytes(db.NamesBuf, rem);
- db.NameOffsets.Alloc(db.Files.Size() + 1);
+ db.NameOffsets.Alloc(numFiles + 1);
size_t pos = 0;
unsigned i;
- for (i = 0; i < db.Files.Size(); i++)
+ for (i = 0; i < numFiles; i++)
{
size_t curRem = (rem - pos) / 2;
const UInt16 *buf = (const UInt16 *)(db.NamesBuf + pos);
@@ -1216,36 +1240,31 @@ HRESULT CInArchive::ReadHeader(
ThereIsHeaderError = true;
break;
}
+
case NID::kWinAttrib:
{
- CBoolVector boolVector;
- ReadBoolVector2(db.Files.Size(), boolVector);
+ ReadBoolVector2(numFiles, db.Attrib.Defs);
CStreamSwitch streamSwitch;
streamSwitch.Set(this, &dataVector);
- for (CNum i = 0; i < numFiles; i++)
- {
- CFileItem &file = db.Files[i];
- file.AttribDefined = boolVector[i];
- if (file.AttribDefined)
- file.Attrib = ReadUInt32();
- }
+ Read_UInt32_Vector(db.Attrib);
break;
}
+
/*
case NID::kIsAux:
{
- ReadBoolVector(db.Files.Size(), db.IsAux);
+ ReadBoolVector(numFiles, db.IsAux);
break;
}
case NID::kParent:
{
db.IsTree = true;
// CBoolVector boolVector;
- // ReadBoolVector2(db.Files.Size(), boolVector);
+ // ReadBoolVector2(numFiles, boolVector);
// CStreamSwitch streamSwitch;
// streamSwitch.Set(this, &dataVector);
CBoolVector boolVector;
- ReadBoolVector2(db.Files.Size(), boolVector);
+ ReadBoolVector2(numFiles, boolVector);
db.ThereAreAltStreams = false;
for (i = 0; i < numFiles; i++)
@@ -1264,14 +1283,9 @@ HRESULT CInArchive::ReadHeader(
case NID::kEmptyStream:
{
ReadBoolVector(numFiles, emptyStreamVector);
- numEmptyStreams = 0;
- for (CNum i = 0; i < (CNum)emptyStreamVector.Size(); i++)
- if (emptyStreamVector[i])
- numEmptyStreams++;
-
- BoolVector_Fill_False(emptyFileVector, numEmptyStreams);
- BoolVector_Fill_False(antiFileVector, numEmptyStreams);
-
+ numEmptyStreams = BoolVector_CountSum(emptyStreamVector);
+ emptyFileVector.Clear();
+ antiFileVector.Clear();
break;
}
case NID::kEmptyFile: ReadBoolVector(numEmptyStreams, emptyFileVector); break;
@@ -1314,7 +1328,7 @@ HRESULT CInArchive::ReadHeader(
ReadBytes(db.SecureBuf + offset, db.SecureOffsets[i + 1] - offset);
}
db.SecureIDs.Clear();
- for (unsigned i = 0; i < db.Files.Size(); i++)
+ for (unsigned i = 0; i < numFiles; i++)
{
db.SecureIDs.Add(ReadNum());
// db.SecureIDs.Add(ReadUInt32());
@@ -1359,22 +1373,21 @@ HRESULT CInArchive::ReadHeader(
CNum emptyFileIndex = 0;
CNum sizeIndex = 0;
- CNum numAntiItems = 0;
+ const CNum numAntiItems = BoolVector_CountSum(antiFileVector);
- CNum i;
+ if (numAntiItems != 0)
+ db.IsAnti.ClearAndSetSize(numFiles);
- for (i = 0; i < numEmptyStreams; i++)
- if (antiFileVector[i])
- numAntiItems++;
+ db.Files.ClearAndSetSize(numFiles);
- for (i = 0; i < numFiles; i++)
+ for (CNum i = 0; i < numFiles; i++)
{
CFileItem &file = db.Files[i];
bool isAnti;
- file.HasStream = !emptyStreamVector[i];
file.Crc = 0;
- if (file.HasStream)
+ if (!BoolVector_Item_IsValidAndTrue(emptyStreamVector, i))
{
+ file.HasStream = true;
file.IsDir = false;
isAnti = false;
file.Size = unpackSizes[sizeIndex];
@@ -1385,26 +1398,31 @@ HRESULT CInArchive::ReadHeader(
}
else
{
- file.IsDir = !emptyFileVector[emptyFileIndex];
- isAnti = antiFileVector[emptyFileIndex];
+ file.HasStream = false;
+ file.IsDir = !BoolVector_Item_IsValidAndTrue(emptyFileVector, emptyFileIndex);
+ isAnti = BoolVector_Item_IsValidAndTrue(antiFileVector, emptyFileIndex);
emptyFileIndex++;
file.Size = 0;
file.CrcDefined = false;
}
if (numAntiItems != 0)
- db.IsAnti.Add(isAnti);
+ db.IsAnti[i] = isAnti;
}
+
}
+
db.FillLinks();
- /*
- if (type != NID::kEnd)
- ThrowIncorrect();
- if (_inByteBack->GetRem() != 0)
- ThrowIncorrect();
- */
+
+ if (type != NID::kEnd || _inByteBack->GetRem() != 0)
+ {
+ db.UnsupportedFeatureWarning = true;
+ // ThrowIncorrect();
+ }
+
return S_OK;
}
+
void CDbEx::FillLinks()
{
FolderStartFileIndex.Alloc(NumFolders);
@@ -1466,6 +1484,7 @@ void CDbEx::FillLinks()
}
}
+
HRESULT CInArchive::ReadDatabase2(
DECL_EXTERNAL_CODECS_LOC_VARS
CDbEx &db
@@ -1610,6 +1629,7 @@ HRESULT CInArchive::ReadDatabase2(
);
}
+
HRESULT CInArchive::ReadDatabase(
DECL_EXTERNAL_CODECS_LOC_VARS
CDbEx &db