xref: /aosp_15_r20/external/lzma/CPP/7zip/Archive/7z/7zIn.h (revision f6dc9357d832569d4d1f5d24eacdb3935a1ae8e6)
1 // 7zIn.h
2 
3 #ifndef ZIP7_INC_7Z_IN_H
4 #define ZIP7_INC_7Z_IN_H
5 
6 #include "../../../Common/MyCom.h"
7 
8 #include "../../../Windows/PropVariant.h"
9 
10 #include "../../IPassword.h"
11 #include "../../IStream.h"
12 
13 #include "../../Common/CreateCoder.h"
14 #include "../../Common/InBuffer.h"
15 
16 #include "7zItem.h"
17 
18 namespace NArchive {
19 namespace N7z {
20 
21 /*
22   We don't need to init isEncrypted and passwordIsDefined
23   We must upgrade them only */
24 
25 #ifdef Z7_NO_CRYPTO
26 #define Z7_7Z_DECODER_CRYPRO_VARS_DECL
27 #define Z7_7Z_DECODER_CRYPRO_VARS
28 #else
29 #define Z7_7Z_DECODER_CRYPRO_VARS_DECL , ICryptoGetTextPassword *getTextPassword, bool &isEncrypted, bool &passwordIsDefined, UString &password
30 #define Z7_7Z_DECODER_CRYPRO_VARS , getTextPassword, isEncrypted, passwordIsDefined, password
31 #endif
32 
33 struct CParsedMethods
34 {
35   Byte Lzma2Prop;
36   UInt32 LzmaDic;
37   CRecordVector<UInt64> IDs;
38 
CParsedMethodsCParsedMethods39   CParsedMethods(): Lzma2Prop(0), LzmaDic(0) {}
40 };
41 
42 struct CFolderEx: public CFolder
43 {
44   unsigned UnpackCoder;
45 };
46 
47 struct CFolders
48 {
49   CNum NumPackStreams;
50   CNum NumFolders;
51 
52   CObjArray<UInt64> PackPositions; // NumPackStreams + 1
53   // CUInt32DefVector PackCRCs; // we don't use PackCRCs now
54 
55   CUInt32DefVector FolderCRCs;             // NumFolders
56   CObjArray<CNum> NumUnpackStreamsVector;  // NumFolders
57 
58   CObjArray<UInt64> CoderUnpackSizes;      // including unpack sizes of bond coders
59   CObjArray<CNum> FoToCoderUnpackSizes;    // NumFolders + 1
60   CObjArray<CNum> FoStartPackStreamIndex;  // NumFolders + 1
61   CObjArray<Byte> FoToMainUnpackSizeIndex; // NumFolders
62 
63   CObjArray<size_t> FoCodersDataOffset;    // NumFolders + 1
64   CByteBuffer CodersData;
65 
66   CParsedMethods ParsedMethods;
67 
68   void ParseFolderInfo(unsigned folderIndex, CFolder &folder) const;
ParseFolderExCFolders69   void ParseFolderEx(unsigned folderIndex, CFolderEx &folder) const
70   {
71     ParseFolderInfo(folderIndex, folder);
72     folder.UnpackCoder = FoToMainUnpackSizeIndex[folderIndex];
73   }
74 
GetNumFolderUnpackSizesCFolders75   unsigned GetNumFolderUnpackSizes(unsigned folderIndex) const
76   {
77     return (unsigned)(FoToCoderUnpackSizes[folderIndex + 1] - FoToCoderUnpackSizes[folderIndex]);
78   }
79 
GetFolderUnpackSizeCFolders80   UInt64 GetFolderUnpackSize(unsigned folderIndex) const
81   {
82     return CoderUnpackSizes[FoToCoderUnpackSizes[folderIndex] + FoToMainUnpackSizeIndex[folderIndex]];
83   }
84 
GetStreamPackSizeCFolders85   UInt64 GetStreamPackSize(unsigned index) const
86   {
87     return PackPositions[index + 1] - PackPositions[index];
88   }
89 
CFoldersCFolders90   CFolders(): NumPackStreams(0), NumFolders(0) {}
91 
ClearCFolders92   void Clear()
93   {
94     NumPackStreams = 0;
95     PackPositions.Free();
96     // PackCRCs.Clear();
97 
98     NumFolders = 0;
99     FolderCRCs.Clear();
100     NumUnpackStreamsVector.Free();
101     CoderUnpackSizes.Free();
102     FoToCoderUnpackSizes.Free();
103     FoStartPackStreamIndex.Free();
104     FoToMainUnpackSizeIndex.Free();
105     FoCodersDataOffset.Free();
106     CodersData.Free();
107   }
108 };
109 
110 struct CDatabase: public CFolders
111 {
112   CRecordVector<CFileItem> Files;
113 
114   CUInt64DefVector CTime;
115   CUInt64DefVector ATime;
116   CUInt64DefVector MTime;
117   CUInt64DefVector StartPos;
118   CUInt32DefVector Attrib;
119   CBoolVector IsAnti;
120   /*
121   CBoolVector IsAux;
122   CByteBuffer SecureBuf;
123   CRecordVector<UInt32> SecureIDs;
124   */
125 
126   CByteBuffer NamesBuf;
127   CObjArray<size_t> NameOffsets; // numFiles + 1, offsets of utf-16 symbols
128 
129   /*
130   void ClearSecure()
131   {
132     SecureBuf.Free();
133     SecureIDs.Clear();
134   }
135   */
136 
ClearCDatabase137   void Clear()
138   {
139     CFolders::Clear();
140     // ClearSecure();
141 
142     NamesBuf.Free();
143     NameOffsets.Free();
144 
145     Files.Clear();
146     CTime.Clear();
147     ATime.Clear();
148     MTime.Clear();
149     StartPos.Clear();
150     Attrib.Clear();
151     IsAnti.Clear();
152     // IsAux.Clear();
153   }
154 
IsSolidCDatabase155   bool IsSolid() const
156   {
157     for (CNum i = 0; i < NumFolders; i++)
158       if (NumUnpackStreamsVector[i] > 1)
159         return true;
160     return false;
161   }
IsItemAntiCDatabase162   bool IsItemAnti(unsigned index) const { return (index < IsAnti.Size() && IsAnti[index]); }
163   // bool IsItemAux(unsigned index) const { return (index < IsAux.Size() && IsAux[index]); }
164 
165   /*
166   const void* GetName(unsigned index) const
167   {
168     if (!NameOffsets || !NamesBuf)
169       return NULL;
170     return (void *)((const Byte *)NamesBuf + NameOffsets[index] * 2);
171   };
172   */
173   void GetPath(unsigned index, UString &path) const;
174   HRESULT GetPath_Prop(unsigned index, PROPVARIANT *path) const throw();
175 };
176 
177 
178 struct CInArchiveInfo
179 {
180   CArchiveVersion Version;
181   UInt64 StartPosition;               // in stream
182   UInt64 StartPositionAfterHeader;    // in stream
183   UInt64 DataStartPosition;           // in stream
184   UInt64 DataStartPosition2;          // in stream. it's for headers
185   CRecordVector<UInt64> FileInfoPopIDs;
186 
ClearCInArchiveInfo187   void Clear()
188   {
189     StartPosition = 0;
190     StartPositionAfterHeader = 0;
191     DataStartPosition = 0;
192     DataStartPosition2 = 0;
193     FileInfoPopIDs.Clear();
194   }
195 };
196 
197 
198 struct CDbEx: public CDatabase
199 {
200   CInArchiveInfo ArcInfo;
201 
202   CObjArray<CNum> FolderStartFileIndex;
203   CObjArray<CNum> FileIndexToFolderIndexMap;
204 
205   UInt64 HeadersSize;
206   UInt64 PhySize;
207   // UInt64 EndHeaderOffset; // relative to position after StartHeader (32 bytes)
208 
209   /*
210   CRecordVector<size_t> SecureOffsets;
211   bool IsTree;
212   bool ThereAreAltStreams;
213   */
214 
215   bool IsArc;
216   bool PhySizeWasConfirmed;
217 
218   bool ThereIsHeaderError;
219   bool UnexpectedEnd;
220   // bool UnsupportedVersion;
221 
222   bool StartHeaderWasRecovered;
223   bool UnsupportedFeatureWarning;
224   bool UnsupportedFeatureError;
225 
226   /*
227   void ClearSecureEx()
228   {
229     ClearSecure();
230     SecureOffsets.Clear();
231   }
232   */
233 
ClearCDbEx234   void Clear()
235   {
236     IsArc = false;
237     PhySizeWasConfirmed = false;
238 
239     ThereIsHeaderError = false;
240     UnexpectedEnd = false;
241     // UnsupportedVersion = false;
242 
243     StartHeaderWasRecovered = false;
244     UnsupportedFeatureError = false;
245     UnsupportedFeatureWarning = false;
246 
247     /*
248     IsTree = false;
249     ThereAreAltStreams = false;
250     */
251 
252     CDatabase::Clear();
253 
254     // SecureOffsets.Clear();
255     ArcInfo.Clear();
256     FolderStartFileIndex.Free();
257     FileIndexToFolderIndexMap.Free();
258 
259     HeadersSize = 0;
260     PhySize = 0;
261     // EndHeaderOffset = 0;
262   }
263 
CanUpdateCDbEx264   bool CanUpdate() const
265   {
266     if (ThereIsHeaderError
267         || UnexpectedEnd
268         || StartHeaderWasRecovered
269         || UnsupportedFeatureError)
270       return false;
271     return true;
272   }
273 
274   void FillLinks();
275 
GetFolderStreamPosCDbEx276   UInt64 GetFolderStreamPos(size_t folderIndex, size_t indexInFolder) const
277   {
278     return ArcInfo.DataStartPosition + PackPositions.ConstData()
279         [FoStartPackStreamIndex.ConstData()[folderIndex] + indexInFolder];
280   }
281 
GetFolderFullPackSizeCDbEx282   UInt64 GetFolderFullPackSize(size_t folderIndex) const
283   {
284     return
285       PackPositions[FoStartPackStreamIndex.ConstData()[folderIndex + 1]] -
286       PackPositions[FoStartPackStreamIndex.ConstData()[folderIndex]];
287   }
288 
GetFolderPackStreamSizeCDbEx289   UInt64 GetFolderPackStreamSize(size_t folderIndex, size_t streamIndex) const
290   {
291     const size_t i = FoStartPackStreamIndex.ConstData()[folderIndex] + streamIndex;
292     return PackPositions.ConstData()[i + 1] -
293            PackPositions.ConstData()[i];
294   }
295 
296   /*
297   UInt64 GetFilePackSize(size_t fileIndex) const
298   {
299     const CNum folderIndex = FileIndexToFolderIndexMap[fileIndex];
300     if (folderIndex != kNumNoIndex)
301       if (FolderStartFileIndex[folderIndex] == fileIndex)
302         return GetFolderFullPackSize(folderIndex);
303     return 0;
304   }
305   */
306 };
307 
308 const unsigned kNumBufLevelsMax = 4;
309 
310 struct CInByte2
311 {
312   const Byte *_buffer;
313 public:
314   size_t _size;
315   size_t _pos;
316 
GetRemCInByte2317   size_t GetRem() const { return _size - _pos; }
GetPtrCInByte2318   const Byte *GetPtr() const { return _buffer + _pos; }
InitCInByte2319   void Init(const Byte *buffer, size_t size)
320   {
321     _buffer = buffer;
322     _size = size;
323     _pos = 0;
324   }
325   Byte ReadByte();
326   void ReadBytes(Byte *data, size_t size);
SkipDataNoCheckCInByte2327   void SkipDataNoCheck(UInt64 size) { _pos += (size_t)size; }
328   void SkipData(UInt64 size);
329 
330   void SkipData();
SkipRemCInByte2331   void SkipRem() { _pos = _size; }
332   UInt64 ReadNumber();
333   CNum ReadNum();
334   UInt32 ReadUInt32();
335   UInt64 ReadUInt64();
336 
337   void ParseFolder(CFolder &folder);
338 };
339 
340 class CStreamSwitch;
341 
342 const UInt32 kHeaderSize = 32;
343 
344 class CInArchive
345 {
346   friend class CStreamSwitch;
347 
348   CMyComPtr<IInStream> _stream;
349 
350   unsigned _numInByteBufs;
351   CInByte2 _inByteVector[kNumBufLevelsMax];
352 
353   CInByte2 *_inByteBack;
354   bool ThereIsHeaderError;
355 
356   UInt64 _arhiveBeginStreamPosition;
357   UInt64 _fileEndPosition;
358 
359   UInt64 _rangeLimit; // relative to position after StartHeader (32 bytes)
360 
361   Byte _header[kHeaderSize];
362 
363   UInt64 HeadersSize;
364 
365   bool _useMixerMT;
366 
367   void AddByteStream(const Byte *buffer, size_t size);
368 
DeleteByteStream(bool needUpdatePos)369   void DeleteByteStream(bool needUpdatePos)
370   {
371     _numInByteBufs--;
372     if (_numInByteBufs > 0)
373     {
374       _inByteBack = &_inByteVector[_numInByteBufs - 1];
375       if (needUpdatePos)
376         _inByteBack->_pos += _inByteVector[_numInByteBufs]._pos;
377     }
378   }
379 
380   HRESULT FindAndReadSignature(IInStream *stream, const UInt64 *searchHeaderSizeLimit);
381 
ReadBytes(Byte * data,size_t size)382   void ReadBytes(Byte *data, size_t size) { _inByteBack->ReadBytes(data, size); }
ReadByte()383   Byte ReadByte() { return _inByteBack->ReadByte(); }
ReadNumber()384   UInt64 ReadNumber() { return _inByteBack->ReadNumber(); }
ReadNum()385   CNum ReadNum() { return _inByteBack->ReadNum(); }
ReadID()386   UInt64 ReadID() { return _inByteBack->ReadNumber(); }
ReadUInt32()387   UInt32 ReadUInt32() { return _inByteBack->ReadUInt32(); }
ReadUInt64()388   UInt64 ReadUInt64() { return _inByteBack->ReadUInt64(); }
SkipData(UInt64 size)389   void SkipData(UInt64 size) { _inByteBack->SkipData(size); }
SkipData()390   void SkipData() { _inByteBack->SkipData(); }
391   void WaitId(UInt64 id);
392 
393   void Read_UInt32_Vector(CUInt32DefVector &v);
394 
395   void ReadArchiveProperties(CInArchiveInfo &archiveInfo);
396   void ReadHashDigests(unsigned numItems, CUInt32DefVector &crcs);
397 
398   void ReadPackInfo(CFolders &f);
399 
400   void ReadUnpackInfo(
401       const CObjectVector<CByteBuffer> *dataVector,
402       CFolders &folders);
403 
404   void ReadSubStreamsInfo(
405       CFolders &folders,
406       CRecordVector<UInt64> &unpackSizes,
407       CUInt32DefVector &digests);
408 
409   void ReadStreamsInfo(
410       const CObjectVector<CByteBuffer> *dataVector,
411       UInt64 &dataOffset,
412       CFolders &folders,
413       CRecordVector<UInt64> &unpackSizes,
414       CUInt32DefVector &digests);
415 
416   void ReadBoolVector(unsigned numItems, CBoolVector &v);
417   void ReadBoolVector2(unsigned numItems, CBoolVector &v);
418   void ReadUInt64DefVector(const CObjectVector<CByteBuffer> &dataVector,
419       CUInt64DefVector &v, unsigned numItems);
420   HRESULT ReadAndDecodePackedStreams(
421       DECL_EXTERNAL_CODECS_LOC_VARS
422       UInt64 baseOffset, UInt64 &dataOffset,
423       CObjectVector<CByteBuffer> &dataVector
424       Z7_7Z_DECODER_CRYPRO_VARS_DECL
425       );
426   HRESULT ReadHeader(
427       DECL_EXTERNAL_CODECS_LOC_VARS
428       CDbEx &db
429       Z7_7Z_DECODER_CRYPRO_VARS_DECL
430       );
431   HRESULT ReadDatabase2(
432       DECL_EXTERNAL_CODECS_LOC_VARS
433       CDbEx &db
434       Z7_7Z_DECODER_CRYPRO_VARS_DECL
435       );
436 public:
CInArchive(bool useMixerMT)437   CInArchive(bool useMixerMT):
438       _numInByteBufs(0),
439       _useMixerMT(useMixerMT)
440       {}
441 
442   HRESULT Open(IInStream *stream, const UInt64 *searchHeaderSizeLimit); // S_FALSE means is not archive
443   void Close();
444 
445   HRESULT ReadDatabase(
446       DECL_EXTERNAL_CODECS_LOC_VARS
447       CDbEx &db
448       Z7_7Z_DECODER_CRYPRO_VARS_DECL
449       );
450 };
451 
452 }}
453 
454 #endif
455