tor-browser

The Tor Browser
git clone https://git.dasho.dev/tor-browser.git
Log | Files | Refs | README | LICENSE

7zIn.h (10804B)


      1 // 7zIn.h
      2 
      3 #ifndef __7Z_IN_H
      4 #define __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 _NO_CRYPTO
     26 #define _7Z_DECODER_CRYPRO_VARS_DECL
     27 #define _7Z_DECODER_CRYPRO_VARS
     28 #else
     29 #define _7Z_DECODER_CRYPRO_VARS_DECL , ICryptoGetTextPassword *getTextPassword, bool &isEncrypted, bool &passwordIsDefined, UString &password
     30 #define _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 
     39  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;
     69  void ParseFolderEx(unsigned folderIndex, CFolderEx &folder) const
     70  {
     71    ParseFolderInfo(folderIndex, folder);
     72    folder.UnpackCoder = FoToMainUnpackSizeIndex[folderIndex];
     73  }
     74  
     75  unsigned GetNumFolderUnpackSizes(unsigned folderIndex) const
     76  {
     77    return (unsigned)(FoToCoderUnpackSizes[folderIndex + 1] - FoToCoderUnpackSizes[folderIndex]);
     78  }
     79 
     80  UInt64 GetFolderUnpackSize(unsigned folderIndex) const
     81  {
     82    return CoderUnpackSizes[FoToCoderUnpackSizes[folderIndex] + FoToMainUnpackSizeIndex[folderIndex]];
     83  }
     84 
     85  UInt64 GetStreamPackSize(unsigned index) const
     86  {
     87    return PackPositions[index + 1] - PackPositions[index];
     88  }
     89 
     90  CFolders(): NumPackStreams(0), NumFolders(0) {}
     91 
     92  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 
    137  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 
    155  bool IsSolid() const
    156  {
    157    for (CNum i = 0; i < NumFolders; i++)
    158      if (NumUnpackStreamsVector[i] > 1)
    159        return true;
    160    return false;
    161  }
    162  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 struct CInArchiveInfo
    178 {
    179  CArchiveVersion Version;
    180  UInt64 StartPosition;
    181  UInt64 StartPositionAfterHeader;
    182  UInt64 DataStartPosition;
    183  UInt64 DataStartPosition2;
    184  CRecordVector<UInt64> FileInfoPopIDs;
    185  
    186  void Clear()
    187  {
    188    StartPosition = 0;
    189    StartPositionAfterHeader = 0;
    190    DataStartPosition = 0;
    191    DataStartPosition2 = 0;
    192    FileInfoPopIDs.Clear();
    193  }
    194 };
    195 
    196 struct CDbEx: public CDatabase
    197 {
    198  CInArchiveInfo ArcInfo;
    199  
    200  CObjArray<CNum> FolderStartFileIndex;
    201  CObjArray<CNum> FileIndexToFolderIndexMap;
    202 
    203  UInt64 HeadersSize;
    204  UInt64 PhySize;
    205 
    206  /*
    207  CRecordVector<size_t> SecureOffsets;
    208  bool IsTree;
    209  bool ThereAreAltStreams;
    210  */
    211 
    212  bool IsArc;
    213  bool PhySizeWasConfirmed;
    214 
    215  bool ThereIsHeaderError;
    216  bool UnexpectedEnd;
    217  // bool UnsupportedVersion;
    218 
    219  bool StartHeaderWasRecovered;
    220  bool UnsupportedFeatureWarning;
    221  bool UnsupportedFeatureError;
    222 
    223  /*
    224  void ClearSecureEx()
    225  {
    226    ClearSecure();
    227    SecureOffsets.Clear();
    228  }
    229  */
    230 
    231  void Clear()
    232  {
    233    IsArc = false;
    234    PhySizeWasConfirmed = false;
    235 
    236    ThereIsHeaderError = false;
    237    UnexpectedEnd = false;
    238    // UnsupportedVersion = false;
    239 
    240    StartHeaderWasRecovered = false;
    241    UnsupportedFeatureError = false;
    242    UnsupportedFeatureWarning = false;
    243 
    244    /*
    245    IsTree = false;
    246    ThereAreAltStreams = false;
    247    */
    248 
    249    CDatabase::Clear();
    250    
    251    // SecureOffsets.Clear();
    252    ArcInfo.Clear();
    253    FolderStartFileIndex.Free();
    254    FileIndexToFolderIndexMap.Free();
    255 
    256    HeadersSize = 0;
    257    PhySize = 0;
    258  }
    259 
    260  void FillLinks();
    261  
    262  UInt64 GetFolderStreamPos(CNum folderIndex, unsigned indexInFolder) const
    263  {
    264    return ArcInfo.DataStartPosition +
    265        PackPositions[FoStartPackStreamIndex[folderIndex] + indexInFolder];
    266  }
    267  
    268  UInt64 GetFolderFullPackSize(CNum folderIndex) const
    269  {
    270    return
    271      PackPositions[FoStartPackStreamIndex[folderIndex + 1]] -
    272      PackPositions[FoStartPackStreamIndex[folderIndex]];
    273  }
    274  
    275  UInt64 GetFolderPackStreamSize(CNum folderIndex, unsigned streamIndex) const
    276  {
    277    size_t i = FoStartPackStreamIndex[folderIndex] + streamIndex;
    278    return PackPositions[i + 1] - PackPositions[i];
    279  }
    280 
    281  UInt64 GetFilePackSize(CNum fileIndex) const
    282  {
    283    CNum folderIndex = FileIndexToFolderIndexMap[fileIndex];
    284    if (folderIndex != kNumNoIndex)
    285      if (FolderStartFileIndex[folderIndex] == fileIndex)
    286        return GetFolderFullPackSize(folderIndex);
    287    return 0;
    288  }
    289 };
    290 
    291 const unsigned kNumBufLevelsMax = 4;
    292 
    293 struct CInByte2
    294 {
    295  const Byte *_buffer;
    296 public:
    297  size_t _size;
    298  size_t _pos;
    299  
    300  size_t GetRem() const { return _size - _pos; }
    301  const Byte *GetPtr() const { return _buffer + _pos; }
    302  void Init(const Byte *buffer, size_t size)
    303  {
    304    _buffer = buffer;
    305    _size = size;
    306    _pos = 0;
    307  }
    308  Byte ReadByte();
    309  void ReadBytes(Byte *data, size_t size);
    310  void SkipDataNoCheck(UInt64 size) { _pos += (size_t)size; }
    311  void SkipData(UInt64 size);
    312 
    313  void SkipData();
    314  void SkipRem() { _pos = _size; }
    315  UInt64 ReadNumber();
    316  CNum ReadNum();
    317  UInt32 ReadUInt32();
    318  UInt64 ReadUInt64();
    319 
    320  void ParseFolder(CFolder &folder);
    321 };
    322 
    323 class CStreamSwitch;
    324 
    325 const UInt32 kHeaderSize = 32;
    326 
    327 class CInArchive
    328 {
    329  friend class CStreamSwitch;
    330 
    331  CMyComPtr<IInStream> _stream;
    332 
    333  unsigned _numInByteBufs;
    334  CInByte2 _inByteVector[kNumBufLevelsMax];
    335 
    336  CInByte2 *_inByteBack;
    337  bool ThereIsHeaderError;
    338 
    339  UInt64 _arhiveBeginStreamPosition;
    340  UInt64 _fileEndPosition;
    341 
    342  Byte _header[kHeaderSize];
    343 
    344  UInt64 HeadersSize;
    345 
    346  bool _useMixerMT;
    347 
    348  void AddByteStream(const Byte *buffer, size_t size);
    349  
    350  void DeleteByteStream(bool needUpdatePos)
    351  {
    352    _numInByteBufs--;
    353    if (_numInByteBufs > 0)
    354    {
    355      _inByteBack = &_inByteVector[_numInByteBufs - 1];
    356      if (needUpdatePos)
    357        _inByteBack->_pos += _inByteVector[_numInByteBufs]._pos;
    358    }
    359  }
    360 
    361  HRESULT FindAndReadSignature(IInStream *stream, const UInt64 *searchHeaderSizeLimit);
    362  
    363  void ReadBytes(Byte *data, size_t size) { _inByteBack->ReadBytes(data, size); }
    364  Byte ReadByte() { return _inByteBack->ReadByte(); }
    365  UInt64 ReadNumber() { return _inByteBack->ReadNumber(); }
    366  CNum ReadNum() { return _inByteBack->ReadNum(); }
    367  UInt64 ReadID() { return _inByteBack->ReadNumber(); }
    368  UInt32 ReadUInt32() { return _inByteBack->ReadUInt32(); }
    369  UInt64 ReadUInt64() { return _inByteBack->ReadUInt64(); }
    370  void SkipData(UInt64 size) { _inByteBack->SkipData(size); }
    371  void SkipData() { _inByteBack->SkipData(); }
    372  void WaitId(UInt64 id);
    373 
    374  void Read_UInt32_Vector(CUInt32DefVector &v);
    375 
    376  void ReadArchiveProperties(CInArchiveInfo &archiveInfo);
    377  void ReadHashDigests(unsigned numItems, CUInt32DefVector &crcs);
    378  
    379  void ReadPackInfo(CFolders &f);
    380  
    381  void ReadUnpackInfo(
    382      const CObjectVector<CByteBuffer> *dataVector,
    383      CFolders &folders);
    384  
    385  void ReadSubStreamsInfo(
    386      CFolders &folders,
    387      CRecordVector<UInt64> &unpackSizes,
    388      CUInt32DefVector &digests);
    389 
    390  void ReadStreamsInfo(
    391      const CObjectVector<CByteBuffer> *dataVector,
    392      UInt64 &dataOffset,
    393      CFolders &folders,
    394      CRecordVector<UInt64> &unpackSizes,
    395      CUInt32DefVector &digests);
    396 
    397  void ReadBoolVector(unsigned numItems, CBoolVector &v);
    398  void ReadBoolVector2(unsigned numItems, CBoolVector &v);
    399  void ReadUInt64DefVector(const CObjectVector<CByteBuffer> &dataVector,
    400      CUInt64DefVector &v, unsigned numItems);
    401  HRESULT ReadAndDecodePackedStreams(
    402      DECL_EXTERNAL_CODECS_LOC_VARS
    403      UInt64 baseOffset, UInt64 &dataOffset,
    404      CObjectVector<CByteBuffer> &dataVector
    405      _7Z_DECODER_CRYPRO_VARS_DECL
    406      );
    407  HRESULT ReadHeader(
    408      DECL_EXTERNAL_CODECS_LOC_VARS
    409      CDbEx &db
    410      _7Z_DECODER_CRYPRO_VARS_DECL
    411      );
    412  HRESULT ReadDatabase2(
    413      DECL_EXTERNAL_CODECS_LOC_VARS
    414      CDbEx &db
    415      _7Z_DECODER_CRYPRO_VARS_DECL
    416      );
    417 public:
    418  CInArchive(bool useMixerMT):
    419      _numInByteBufs(0),
    420      _useMixerMT(useMixerMT)
    421      {}
    422  
    423  HRESULT Open(IInStream *stream, const UInt64 *searchHeaderSizeLimit); // S_FALSE means is not archive
    424  void Close();
    425 
    426  HRESULT ReadDatabase(
    427      DECL_EXTERNAL_CODECS_LOC_VARS
    428      CDbEx &db
    429      _7Z_DECODER_CRYPRO_VARS_DECL
    430      );
    431 };
    432  
    433 }}
    434  
    435 #endif