View | Details | Raw Unified | Return to bug 46318
Collapse All | Expand All

(-)unrar-6.1.7/UnRARDll.vcxproj (-6 / +6 lines)
Lines 138-144 Link Here
138
      <ExceptionHandling>Sync</ExceptionHandling>
138
      <ExceptionHandling>Sync</ExceptionHandling>
139
      <BasicRuntimeChecks>EnableFastChecks</BasicRuntimeChecks>
139
      <BasicRuntimeChecks>EnableFastChecks</BasicRuntimeChecks>
140
      <RuntimeLibrary>MultiThreadedDebug</RuntimeLibrary>
140
      <RuntimeLibrary>MultiThreadedDebug</RuntimeLibrary>
141
      <StructMemberAlignment>4Bytes</StructMemberAlignment>
141
      <StructMemberAlignment>Default</StructMemberAlignment>
142
      <RuntimeTypeInfo>false</RuntimeTypeInfo>
142
      <RuntimeTypeInfo>false</RuntimeTypeInfo>
143
      <PrecompiledHeader>Use</PrecompiledHeader>
143
      <PrecompiledHeader>Use</PrecompiledHeader>
144
      <PrecompiledHeaderFile>rar.hpp</PrecompiledHeaderFile>
144
      <PrecompiledHeaderFile>rar.hpp</PrecompiledHeaderFile>
Lines 168-174 Link Here
168
      <ExceptionHandling>Sync</ExceptionHandling>
168
      <ExceptionHandling>Sync</ExceptionHandling>
169
      <BasicRuntimeChecks>EnableFastChecks</BasicRuntimeChecks>
169
      <BasicRuntimeChecks>EnableFastChecks</BasicRuntimeChecks>
170
      <RuntimeLibrary>MultiThreadedDebug</RuntimeLibrary>
170
      <RuntimeLibrary>MultiThreadedDebug</RuntimeLibrary>
171
      <StructMemberAlignment>4Bytes</StructMemberAlignment>
171
      <StructMemberAlignment>Default</StructMemberAlignment>
172
      <RuntimeTypeInfo>false</RuntimeTypeInfo>
172
      <RuntimeTypeInfo>false</RuntimeTypeInfo>
173
      <PrecompiledHeader>Use</PrecompiledHeader>
173
      <PrecompiledHeader>Use</PrecompiledHeader>
174
      <PrecompiledHeaderFile>rar.hpp</PrecompiledHeaderFile>
174
      <PrecompiledHeaderFile>rar.hpp</PrecompiledHeaderFile>
Lines 198-204 Link Here
198
      <MinimalRebuild>false</MinimalRebuild>
198
      <MinimalRebuild>false</MinimalRebuild>
199
      <ExceptionHandling>Sync</ExceptionHandling>
199
      <ExceptionHandling>Sync</ExceptionHandling>
200
      <RuntimeLibrary>MultiThreaded</RuntimeLibrary>
200
      <RuntimeLibrary>MultiThreaded</RuntimeLibrary>
201
      <StructMemberAlignment>4Bytes</StructMemberAlignment>
201
      <StructMemberAlignment>Default</StructMemberAlignment>
202
      <BufferSecurityCheck>true</BufferSecurityCheck>
202
      <BufferSecurityCheck>true</BufferSecurityCheck>
203
      <FunctionLevelLinking>true</FunctionLevelLinking>
203
      <FunctionLevelLinking>true</FunctionLevelLinking>
204
      <EnableEnhancedInstructionSet>NoExtensions</EnableEnhancedInstructionSet>
204
      <EnableEnhancedInstructionSet>NoExtensions</EnableEnhancedInstructionSet>
Lines 239-245 Link Here
239
      <MinimalRebuild>false</MinimalRebuild>
239
      <MinimalRebuild>false</MinimalRebuild>
240
      <ExceptionHandling>Sync</ExceptionHandling>
240
      <ExceptionHandling>Sync</ExceptionHandling>
241
      <RuntimeLibrary>MultiThreaded</RuntimeLibrary>
241
      <RuntimeLibrary>MultiThreaded</RuntimeLibrary>
242
      <StructMemberAlignment>4Bytes</StructMemberAlignment>
242
      <StructMemberAlignment>Default</StructMemberAlignment>
243
      <BufferSecurityCheck>true</BufferSecurityCheck>
243
      <BufferSecurityCheck>true</BufferSecurityCheck>
244
      <FunctionLevelLinking>true</FunctionLevelLinking>
244
      <FunctionLevelLinking>true</FunctionLevelLinking>
245
      <RuntimeTypeInfo>false</RuntimeTypeInfo>
245
      <RuntimeTypeInfo>false</RuntimeTypeInfo>
Lines 274-280 Link Here
274
      <MinimalRebuild>false</MinimalRebuild>
274
      <MinimalRebuild>false</MinimalRebuild>
275
      <ExceptionHandling>Sync</ExceptionHandling>
275
      <ExceptionHandling>Sync</ExceptionHandling>
276
      <RuntimeLibrary>MultiThreaded</RuntimeLibrary>
276
      <RuntimeLibrary>MultiThreaded</RuntimeLibrary>
277
      <StructMemberAlignment>4Bytes</StructMemberAlignment>
277
      <StructMemberAlignment>Default</StructMemberAlignment>
278
      <BufferSecurityCheck>true</BufferSecurityCheck>
278
      <BufferSecurityCheck>true</BufferSecurityCheck>
279
      <FunctionLevelLinking>true</FunctionLevelLinking>
279
      <FunctionLevelLinking>true</FunctionLevelLinking>
280
      <EnableEnhancedInstructionSet>NoExtensions</EnableEnhancedInstructionSet>
280
      <EnableEnhancedInstructionSet>NoExtensions</EnableEnhancedInstructionSet>
Lines 315-321 Link Here
315
      <MinimalRebuild>false</MinimalRebuild>
315
      <MinimalRebuild>false</MinimalRebuild>
316
      <ExceptionHandling>Sync</ExceptionHandling>
316
      <ExceptionHandling>Sync</ExceptionHandling>
317
      <RuntimeLibrary>MultiThreaded</RuntimeLibrary>
317
      <RuntimeLibrary>MultiThreaded</RuntimeLibrary>
318
      <StructMemberAlignment>4Bytes</StructMemberAlignment>
318
      <StructMemberAlignment>Default</StructMemberAlignment>
319
      <BufferSecurityCheck>true</BufferSecurityCheck>
319
      <BufferSecurityCheck>true</BufferSecurityCheck>
320
      <FunctionLevelLinking>true</FunctionLevelLinking>
320
      <FunctionLevelLinking>true</FunctionLevelLinking>
321
      <RuntimeTypeInfo>false</RuntimeTypeInfo>
321
      <RuntimeTypeInfo>false</RuntimeTypeInfo>
(-)unrar-6.1.7/archive.cpp (-6 / +6 lines)
Lines 3-17 Link Here
3
#include "arccmt.cpp"
3
#include "arccmt.cpp"
4
4
5
5
6
Archive::Archive(RAROptions *InitCmd)
6
Archive::Archive(CommandData *InitCmd)
7
{
7
{
8
  Cmd=NULL; // Just in case we'll have an exception in 'new' below.
8
  Cmd=NULL; // Just in case we'll have an exception in 'new' below.
9
9
10
  DummyCmd=(InitCmd==NULL);
10
  DummyCmd=(InitCmd==NULL);
11
  Cmd=DummyCmd ? (new RAROptions):InitCmd;
11
  Cmd=DummyCmd ? (new CommandData):InitCmd;
12
12
13
  OpenShared=Cmd->OpenShared;
13
  OpenShared=Cmd->OpenShared;
14
  Format=RARFMT15;
14
  Format=RARFMT_NONE;
15
  Solid=false;
15
  Solid=false;
16
  Volume=false;
16
  Volume=false;
17
  MainComment=false;
17
  MainComment=false;
Lines 31-39 Link Here
31
  NextBlockPos=0;
31
  NextBlockPos=0;
32
32
33
33
34
  memset(&MainHead,0,sizeof(MainHead));
34
  MainHead.Reset();
35
  memset(&CryptHead,0,sizeof(CryptHead));
35
  CryptHead={};
36
  memset(&EndArcHead,0,sizeof(EndArcHead));
36
  EndArcHead.Reset();
37
37
38
  VolNumber=0;
38
  VolNumber=0;
39
  VolWrite=0;
39
  VolWrite=0;
(-)unrar-6.1.7/archive.hpp (-5 / +5 lines)
Lines 32-39 Link Here
32
    size_t ReadHeader14();
32
    size_t ReadHeader14();
33
    size_t ReadHeader15();
33
    size_t ReadHeader15();
34
    size_t ReadHeader50();
34
    size_t ReadHeader50();
35
    void ProcessExtra50(RawRead *Raw,size_t ExtraSize,BaseBlock *bb);
35
    void ProcessExtra50(RawRead *Raw,size_t ExtraSize,const BaseBlock *bb);
36
    void RequestArcPassword();
36
    void RequestArcPassword(RarCheckPassword *SelPwd);
37
    void UnexpEndArcMsg();
37
    void UnexpEndArcMsg();
38
    void BrokenHeaderMsg();
38
    void BrokenHeaderMsg();
39
    void UnkEncVerMsg(const wchar *Name,const wchar *Info);
39
    void UnkEncVerMsg(const wchar *Name,const wchar *Info);
Lines 45-51 Link Here
45
#endif
45
#endif
46
    ComprDataIO SubDataIO;
46
    ComprDataIO SubDataIO;
47
    bool DummyCmd;
47
    bool DummyCmd;
48
    RAROptions *Cmd;
48
    CommandData *Cmd;
49
49
50
50
51
    RarTime LatestTime;
51
    RarTime LatestTime;
Lines 58-64 Link Here
58
    bool ProhibitQOpen;
58
    bool ProhibitQOpen;
59
#endif
59
#endif
60
  public:
60
  public:
61
    Archive(RAROptions *InitCmd=NULL);
61
    Archive(CommandData *InitCmd=NULL);
62
    ~Archive();
62
    ~Archive();
63
    static RARFORMAT IsSignature(const byte *D,size_t Size);
63
    static RARFORMAT IsSignature(const byte *D,size_t Size);
64
    bool IsArchive(bool EnableBroken);
64
    bool IsArchive(bool EnableBroken);
Lines 83-89 Link Here
83
         const wchar *Name,uint Flags);
83
         const wchar *Name,uint Flags);
84
    bool ReadSubData(Array<byte> *UnpData,File *DestFile,bool TestMode);
84
    bool ReadSubData(Array<byte> *UnpData,File *DestFile,bool TestMode);
85
    HEADER_TYPE GetHeaderType() {return CurHeaderType;}
85
    HEADER_TYPE GetHeaderType() {return CurHeaderType;}
86
    RAROptions* GetRAROptions() {return Cmd;}
86
    CommandData* GetCommandData() {return Cmd;}
87
    void SetSilentOpen(bool Mode) {SilentOpen=Mode;}
87
    void SetSilentOpen(bool Mode) {SilentOpen=Mode;}
88
#if 0
88
#if 0
89
    void GetRecoveryInfo(bool Required,int64 *Size,int *Percent);
89
    void GetRecoveryInfo(bool Required,int64 *Size,int *Percent);
(-)unrar-6.1.7/arcread.cpp (-44 / +73 lines)
Lines 100-105 Link Here
100
  // If block positions are equal to file size, this is not an error.
100
  // If block positions are equal to file size, this is not an error.
101
  // It can happen when we reached the end of older RAR 1.5 archive,
101
  // It can happen when we reached the end of older RAR 1.5 archive,
102
  // which did not have the end of archive block.
102
  // which did not have the end of archive block.
103
  // We can't replace this check by checking that read size is exactly 0
104
  // in the beginning of file header, because in this case the read position
105
  // still can be beyond the end of archive.
103
  if (CurBlockPos!=ArcSize || NextBlockPos!=ArcSize)
106
  if (CurBlockPos!=ArcSize || NextBlockPos!=ArcSize)
104
  {
107
  {
105
    uiMsg(UIERROR_UNEXPEOF,FileName);
108
    uiMsg(UIERROR_UNEXPEOF,FileName);
Lines 145-151 Link Here
145
#ifdef RAR_NOCRYPT // For rarext.dll and unrar_nocrypt.dll.
148
#ifdef RAR_NOCRYPT // For rarext.dll and unrar_nocrypt.dll.
146
    return 0;
149
    return 0;
147
#else
150
#else
148
    RequestArcPassword();
151
    RequestArcPassword(NULL);
149
152
150
    byte Salt[SIZE_SALT30];
153
    byte Salt[SIZE_SALT30];
151
    if (Read(Salt,SIZE_SALT30)!=SIZE_SALT30)
154
    if (Read(Salt,SIZE_SALT30)!=SIZE_SALT30)
Lines 251-257 Link Here
251
        hd->SplitAfter=(hd->Flags & LHD_SPLIT_AFTER)!=0;
254
        hd->SplitAfter=(hd->Flags & LHD_SPLIT_AFTER)!=0;
252
        hd->Encrypted=(hd->Flags & LHD_PASSWORD)!=0;
255
        hd->Encrypted=(hd->Flags & LHD_PASSWORD)!=0;
253
        hd->SaltSet=(hd->Flags & LHD_SALT)!=0;
256
        hd->SaltSet=(hd->Flags & LHD_SALT)!=0;
257
        
258
        // RAR versions earlier than 2.0 do not set the solid flag
259
        // in file header. They use only a global solid archive flag.
254
        hd->Solid=FileBlock && (hd->Flags & LHD_SOLID)!=0;
260
        hd->Solid=FileBlock && (hd->Flags & LHD_SOLID)!=0;
261
255
        hd->SubBlock=!FileBlock && (hd->Flags & LHD_SOLID)!=0;
262
        hd->SubBlock=!FileBlock && (hd->Flags & LHD_SOLID)!=0;
256
        hd->Dir=(hd->Flags & LHD_WINDOWMASK)==LHD_DIRECTORY;
263
        hd->Dir=(hd->Flags & LHD_WINDOWMASK)==LHD_DIRECTORY;
257
        hd->WinSize=hd->Dir ? 0:0x10000<<((hd->Flags & LHD_WINDOWMASK)>>5);
264
        hd->WinSize=hd->Dir ? 0:0x10000<<((hd->Flags & LHD_WINDOWMASK)>>5);
Lines 577-590 Link Here
577
    // in -p<pwd> to not stop batch processing for encrypted archives.
584
    // in -p<pwd> to not stop batch processing for encrypted archives.
578
    bool GlobalPassword=Cmd->Password.IsSet() || uiIsGlobalPasswordSet();
585
    bool GlobalPassword=Cmd->Password.IsSet() || uiIsGlobalPasswordSet();
579
586
587
    RarCheckPassword CheckPwd;
588
    if (CryptHead.UsePswCheck && !BrokenHeader)
589
      CheckPwd.Set(CryptHead.Salt,HeadersInitV,CryptHead.Lg2Count,CryptHead.PswCheck);
590
    
580
    while (true) // Repeat the password prompt for wrong passwords.
591
    while (true) // Repeat the password prompt for wrong passwords.
581
    {
592
    {
582
      RequestArcPassword();
593
      RequestArcPassword(CheckPwd.IsSet() ? &CheckPwd:NULL);
583
594
584
      byte PswCheck[SIZE_PSWCHECK];
595
      byte PswCheck[SIZE_PSWCHECK];
585
      HeadersCrypt.SetCryptKeys(false,CRYPT_RAR50,&Cmd->Password,CryptHead.Salt,HeadersInitV,CryptHead.Lg2Count,NULL,PswCheck);
596
      HeadersCrypt.SetCryptKeys(false,CRYPT_RAR50,&Cmd->Password,CryptHead.Salt,HeadersInitV,CryptHead.Lg2Count,NULL,PswCheck);
586
      // Verify password validity.
597
      // Verify password validity. If header is damaged, we cannot rely on
587
      if (CryptHead.UsePswCheck && memcmp(PswCheck,CryptHead.PswCheck,SIZE_PSWCHECK)!=0)
598
      // password check value, because it can be damaged too.
599
      if (CryptHead.UsePswCheck && !BrokenHeader &&
600
          memcmp(PswCheck,CryptHead.PswCheck,SIZE_PSWCHECK)!=0)
588
      {
601
      {
589
        if (GlobalPassword) // For -p<pwd> or Ctrl+P.
602
        if (GlobalPassword) // For -p<pwd> or Ctrl+P.
590
        {
603
        {
Lines 850-857 Link Here
850
        hd->Dir=(hd->FileFlags & FHFL_DIRECTORY)!=0;
863
        hd->Dir=(hd->FileFlags & FHFL_DIRECTORY)!=0;
851
        hd->WinSize=hd->Dir ? 0:size_t(0x20000)<<((CompInfo>>10)&0xf);
864
        hd->WinSize=hd->Dir ? 0:size_t(0x20000)<<((CompInfo>>10)&0xf);
852
865
853
        hd->CryptMethod=hd->Encrypted ? CRYPT_RAR50:CRYPT_NONE;
854
855
        char FileName[NM*4];
866
        char FileName[NM*4];
856
        size_t ReadNameSize=Min(NameSize,ASIZE(FileName)-1);
867
        size_t ReadNameSize=Min(NameSize,ASIZE(FileName)-1);
857
        Raw.GetB((byte *)FileName,ReadNameSize);
868
        Raw.GetB((byte *)FileName,ReadNameSize);
Lines 875-900 Link Here
875
        if (!FileBlock && hd->CmpName(SUBHEAD_TYPE_CMT))
886
        if (!FileBlock && hd->CmpName(SUBHEAD_TYPE_CMT))
876
          MainComment=true;
887
          MainComment=true;
877
888
878
#if 0
879
        // For RAR5 format we read the user specified recovery percent here.
880
        // It would be useful to do it for shell extension too, so we display
881
        // the correct recovery record size in archive properties. But then
882
        // we would need to include the entire recovery record processing
883
        // code to shell extension, which is not done now.
884
        if (!FileBlock && hd->CmpName(SUBHEAD_TYPE_RR) && hd->SubData.Size()>0)
885
        {
886
          // It is stored as a single byte up to RAR 6.02 and as vint since
887
          // 6.10, where we extended the maximum RR size from 99% to 1000%.
888
          RawRead RawPercent;
889
          RawPercent.Read(&hd->SubData[0],hd->SubData.Size());
890
          RecoveryPercent=(int)RawPercent.GetV();
891
889
892
          RSBlockHeader Header;
893
          GetRRInfo(this,&Header);
894
          RecoverySize=Header.RecSectionSize*Header.RecCount;
895
        }
896
#endif
897
898
        if (BadCRC) // Add the file name to broken header message displayed above.
890
        if (BadCRC) // Add the file name to broken header message displayed above.
899
          uiMsg(UIERROR_FHEADERBROKEN,Archive::FileName,hd->FileName);
891
          uiMsg(UIERROR_FHEADERBROKEN,Archive::FileName,hd->FileName);
900
      }
892
      }
Lines 916-922 Link Here
916
908
917
909
918
#if !defined(RAR_NOCRYPT)
910
#if !defined(RAR_NOCRYPT)
919
void Archive::RequestArcPassword()
911
void Archive::RequestArcPassword(RarCheckPassword *CheckPwd)
920
{
912
{
921
  if (!Cmd->Password.IsSet())
913
  if (!Cmd->Password.IsSet())
922
  {
914
  {
Lines 946-952 Link Here
946
      ErrHandler.Exit(RARX_USERBREAK);
938
      ErrHandler.Exit(RARX_USERBREAK);
947
    }
939
    }
948
#else
940
#else
949
    if (!uiGetPassword(UIPASSWORD_ARCHIVE,FileName,&Cmd->Password))
941
    if (!uiGetPassword(UIPASSWORD_ARCHIVE,FileName,&Cmd->Password,CheckPwd))
950
    {
942
    {
951
      Close();
943
      Close();
952
      uiMsg(UIERROR_INCERRCOUNT); // Prevent archive deleting if delete after extraction is on.
944
      uiMsg(UIERROR_INCERRCOUNT); // Prevent archive deleting if delete after extraction is on.
Lines 959-965 Link Here
959
#endif
951
#endif
960
952
961
953
962
void Archive::ProcessExtra50(RawRead *Raw,size_t ExtraSize,BaseBlock *bb)
954
void Archive::ProcessExtra50(RawRead *Raw,size_t ExtraSize,const BaseBlock *bb)
963
{
955
{
964
  // Read extra data from the end of block skipping any fields before it.
956
  // Read extra data from the end of block skipping any fields before it.
965
  size_t ExtraStart=Raw->Size()-ExtraSize;
957
  size_t ExtraStart=Raw->Size()-ExtraSize;
Lines 982-1003 Link Here
982
    if (bb->HeaderType==HEAD_MAIN)
974
    if (bb->HeaderType==HEAD_MAIN)
983
    {
975
    {
984
      MainHeader *hd=(MainHeader *)bb;
976
      MainHeader *hd=(MainHeader *)bb;
985
      if (FieldType==MHEXTRA_LOCATOR)
977
      switch(FieldType)
986
      {
978
      {
987
        hd->Locator=true;
979
        case MHEXTRA_LOCATOR:
988
        uint Flags=(uint)Raw->GetV();
980
          {
989
        if ((Flags & MHEXTRA_LOCATOR_QLIST)!=0)
981
            hd->Locator=true;
990
        {
982
            uint Flags=(uint)Raw->GetV();
991
          uint64 Offset=Raw->GetV();
983
            if ((Flags & MHEXTRA_LOCATOR_QLIST)!=0)
992
          if (Offset!=0) // 0 means that reserved space was not enough to write the offset.
984
            {
993
            hd->QOpenOffset=Offset+CurBlockPos;
985
              uint64 Offset=Raw->GetV();
994
        }
986
              if (Offset!=0) // 0 means that reserved space was not enough to write the offset.
995
        if ((Flags & MHEXTRA_LOCATOR_RR)!=0)
987
                hd->QOpenOffset=Offset+CurBlockPos;
996
        {
988
            }
997
          uint64 Offset=Raw->GetV();
989
            if ((Flags & MHEXTRA_LOCATOR_RR)!=0)
998
          if (Offset!=0) // 0 means that reserved space was not enough to write the offset.
990
            {
999
            hd->RROffset=Offset+CurBlockPos;
991
              uint64 Offset=Raw->GetV();
1000
        }
992
              if (Offset!=0) // 0 means that reserved space was not enough to write the offset.
993
                hd->RROffset=Offset+CurBlockPos;
994
            }
995
          }
996
          break;
997
        case MHEXTRA_METADATA:
998
          {
999
            uint Flags=(uint)Raw->GetV();
1000
            if ((Flags & MHEXTRA_METADATA_NAME)!=0)
1001
            {
1002
              uint64 NameSize=Raw->GetV();
1003
              if (NameSize<0x10000) // Prevent excessive allocation.
1004
              {
1005
                std::vector<char> NameU((size_t)NameSize); // UTF-8 name.
1006
                Raw->GetB(&NameU[0],(size_t)NameSize);
1007
                // If starts from 0, the name was longer than reserved space
1008
                // when saving this extra field.
1009
                if (NameU[0]!=0)
1010
                {
1011
                  NameU.push_back(0);
1012
                  std::vector<wchar> NameW(NameU.size()*4);
1013
                  UtfToWide(&NameU[0],&NameW[0],NameW.size());
1014
                  hd->OrigName.assign(&NameW[0]);
1015
                }
1016
              }
1017
            }
1018
            if ((Flags & MHEXTRA_METADATA_CTIME)!=0)
1019
              if ((Flags & MHEXTRA_METADATA_UNIXTIME)!=0)
1020
                if ((Flags & MHEXTRA_METADATA_UNIX_NS)!=0)
1021
                  hd->OrigTime.SetUnixNS(Raw->Get8());
1022
                else
1023
                  hd->OrigTime.SetUnix((time_t)Raw->Get4());
1024
              else
1025
                hd->OrigTime.SetWin(Raw->Get8());
1026
          }
1027
          break;
1001
      }
1028
      }
1002
    }
1029
    }
1003
1030
Lines 1453-1459 Link Here
1453
  {
1480
  {
1454
    if (SubHead.UnpSize>0x1000000)
1481
    if (SubHead.UnpSize>0x1000000)
1455
    {
1482
    {
1456
      // So huge allocation must never happen in valid archives.
1483
      // Prevent the excessive allocation. When reading to memory, normally
1484
      // this function operates with reasonably small blocks, such as
1485
      // the archive comment, NTFS ACL or "Zone.Identifier" NTFS stream.
1457
      uiMsg(UIERROR_SUBHEADERUNKNOWN,FileName);
1486
      uiMsg(UIERROR_SUBHEADERUNKNOWN,FileName);
1458
      return false;
1487
      return false;
1459
    }
1488
    }
(-)unrar-6.1.7/array.hpp (-28 / +6 lines)
Lines 10-16 Link Here
10
    size_t BufSize;
10
    size_t BufSize;
11
    size_t AllocSize;
11
    size_t AllocSize;
12
    size_t MaxSize;
12
    size_t MaxSize;
13
    bool Secure; // Clean memory if true.
14
  public:
13
  public:
15
    Array();
14
    Array();
16
    Array(size_t Size);
15
    Array(size_t Size);
Lines 24-37 Link Here
24
    void Alloc(size_t Items);
23
    void Alloc(size_t Items);
25
    void Reset();
24
    void Reset();
26
    void SoftReset();
25
    void SoftReset();
27
    void operator = (Array<T> &Src);
26
    Array<T>& operator = (const Array<T> &Src);
28
    void Push(T Item);
27
    void Push(T Item);
29
    void Append(T *Item,size_t Count);
28
    void Append(T *Item,size_t Count);
30
    T* Addr(size_t Item) {return Buffer+Item;}
29
    T* Addr(size_t Item) {return Buffer+Item;}
31
    void SetMaxSize(size_t Size) {MaxSize=Size;}
30
    void SetMaxSize(size_t Size) {MaxSize=Size;}
32
    T* Begin() {return Buffer;}
31
    T* Begin() {return Buffer;}
33
    T* End() {return Buffer==NULL ? NULL:Buffer+BufSize;}
32
    T* End() {return Buffer==NULL ? NULL:Buffer+BufSize;}
34
    void SetSecure() {Secure=true;}
35
};
33
};
36
34
37
35
Lines 41-47 Link Here
41
  BufSize=0;
39
  BufSize=0;
42
  AllocSize=0;
40
  AllocSize=0;
43
  MaxSize=0;
41
  MaxSize=0;
44
  Secure=false;
45
}
42
}
46
43
47
44
Lines 71-81 Link Here
71
template <class T> Array<T>::~Array()
68
template <class T> Array<T>::~Array()
72
{
69
{
73
  if (Buffer!=NULL)
70
  if (Buffer!=NULL)
74
  {
75
    if (Secure)
76
      cleandata(Buffer,AllocSize*sizeof(T));
77
    free(Buffer);
71
    free(Buffer);
78
  }
79
}
72
}
80
73
81
74
Lines 111-135 Link Here
111
    size_t Suggested=AllocSize+AllocSize/4+32;
104
    size_t Suggested=AllocSize+AllocSize/4+32;
112
    size_t NewSize=Max(BufSize,Suggested);
105
    size_t NewSize=Max(BufSize,Suggested);
113
106
114
    T *NewBuffer;
107
    T *NewBuffer=(T *)realloc(Buffer,NewSize*sizeof(T));
115
    if (Secure)
108
    if (NewBuffer==NULL)
116
    {
109
      ErrHandler.MemoryError();
117
      NewBuffer=(T *)malloc(NewSize*sizeof(T));
118
      if (NewBuffer==NULL)
119
        ErrHandler.MemoryError();
120
      if (Buffer!=NULL)
121
      {
122
        memcpy(NewBuffer,Buffer,AllocSize*sizeof(T));
123
        cleandata(Buffer,AllocSize*sizeof(T));
124
        free(Buffer);
125
      }
126
    }
127
    else
128
    {
129
      NewBuffer=(T *)realloc(Buffer,NewSize*sizeof(T));
130
      if (NewBuffer==NULL)
131
        ErrHandler.MemoryError();
132
    }
133
    Buffer=NewBuffer;
110
    Buffer=NewBuffer;
134
    AllocSize=NewSize;
111
    AllocSize=NewSize;
135
  }
112
  }
Lines 165-176 Link Here
165
}
142
}
166
143
167
144
168
template <class T> void Array<T>::operator =(Array<T> &Src)
145
template <class T> Array<T>& Array<T>::operator =(const Array<T> &Src)
169
{
146
{
170
  Reset();
147
  Reset();
171
  Alloc(Src.BufSize);
148
  Alloc(Src.BufSize);
172
  if (Src.BufSize!=0)
149
  if (Src.BufSize!=0)
173
    memcpy((void *)Buffer,(void *)Src.Buffer,Src.BufSize*sizeof(T));
150
    memcpy((void *)Buffer,(void *)Src.Buffer,Src.BufSize*sizeof(T));
151
  return *this;
174
}
152
}
175
153
176
154
(-)unrar-6.1.7/blake2s.hpp (-2 / +7 lines)
Lines 20-29 Link Here
20
// 'new' operator.
20
// 'new' operator.
21
struct blake2s_state
21
struct blake2s_state
22
{
22
{
23
  enum { BLAKE_ALIGNMENT = 64 };
23
  // Use constexpr instead of enums, because otherwise clang -std=c++20
24
  // issues a warning about "arithmetic between different enumeration types"
25
  // in ubuf[BLAKE_DATA_SIZE + BLAKE_ALIGNMENT] declaration.
26
  static constexpr size_t BLAKE_ALIGNMENT = 64;
24
27
25
  // buffer and uint32 h[8], t[2], f[2];
28
  // buffer and uint32 h[8], t[2], f[2];
26
  enum { BLAKE_DATA_SIZE = 48 + 2 * BLAKE2S_BLOCKBYTES };
29
  // 2 * BLAKE2S_BLOCKBYTES is the buf size in blake2_code_20140114.zip.
30
  // It might differ in later versions.
31
  static constexpr size_t BLAKE_DATA_SIZE = 48 + 2 * BLAKE2S_BLOCKBYTES;
27
32
28
  byte ubuf[BLAKE_DATA_SIZE + BLAKE_ALIGNMENT];
33
  byte ubuf[BLAKE_DATA_SIZE + BLAKE_ALIGNMENT];
29
34
(-)unrar-6.1.7/cmddata.cpp (-4 / +20 lines)
Lines 26-34 Link Here
26
  FileArgs.Reset();
26
  FileArgs.Reset();
27
  ExclArgs.Reset();
27
  ExclArgs.Reset();
28
  InclArgs.Reset();
28
  InclArgs.Reset();
29
  StoreArgs.Reset();
30
  ArcNames.Reset();
29
  ArcNames.Reset();
31
  NextVolSizes.Reset();
30
  StoreArgs.Reset();
31
  Password.Clean();
32
  NextVolSizes.clear();
32
}
33
}
33
34
34
35
Lines 314-319 Link Here
314
        case 'I':
315
        case 'I':
315
          IgnoreGeneralAttr=true;
316
          IgnoreGeneralAttr=true;
316
          break;
317
          break;
318
        case 'M':
319
          switch(toupperw(Switch[2]))
320
          {
321
            case 0:
322
            case 'S':
323
              ArcMetadata=ARCMETA_SAVE;
324
              break;
325
            case 'R':
326
              ArcMetadata=ARCMETA_RESTORE;
327
              break;
328
            default:
329
              BadSwitch(Switch);
330
              break;
331
          }
332
          break;
317
        case 'N': // Reserved for archive name.
333
        case 'N': // Reserved for archive name.
318
          break;
334
          break;
319
        case 'O':
335
        case 'O':
Lines 415-421 Link Here
415
          else
431
          else
416
            if (!Password.IsSet())
432
            if (!Password.IsSet())
417
            {
433
            {
418
              uiGetPassword(UIPASSWORD_GLOBAL,NULL,&Password);
434
              uiGetPassword(UIPASSWORD_GLOBAL,NULL,&Password,NULL);
419
              eprintf(L"\n");
435
              eprintf(L"\n");
420
            }
436
            }
421
          break;
437
          break;
Lines 685-691 Link Here
685
    case 'P':
701
    case 'P':
686
      if (Switch[1]==0)
702
      if (Switch[1]==0)
687
      {
703
      {
688
        uiGetPassword(UIPASSWORD_GLOBAL,NULL,&Password);
704
        uiGetPassword(UIPASSWORD_GLOBAL,NULL,&Password,NULL);
689
        eprintf(L"\n");
705
        eprintf(L"\n");
690
      }
706
      }
691
      else
707
      else
(-)unrar-6.1.7/cmddata.hpp (-1 / +5 lines)
Lines 2-8 Link Here
2
#define _RAR_CMDDATA_
2
#define _RAR_CMDDATA_
3
3
4
4
5
#define DefaultStoreList L"7z;ace;arj;bz2;cab;gz;jpeg;jpg;lha;lz;lzh;mp3;rar;taz;tgz;xz;z;zip;zipx"
5
#define DefaultStoreList L"7z;ace;arj;bz2;cab;gz;jpeg;jpg;lha;lz;lzh;mp3;rar;taz;tbz;tbz2;tgz;txz;xz;z;zip;zipx;zst;tzst"
6
6
7
enum RAR_CMD_LIST_MODE {RCLM_AUTO,RCLM_REJECT_LISTS,RCLM_ACCEPT_LISTS};
7
enum RAR_CMD_LIST_MODE {RCLM_AUTO,RCLM_REJECT_LISTS,RCLM_ACCEPT_LISTS};
8
8
Lines 65-70 Link Here
65
    StringList InclArgs;
65
    StringList InclArgs;
66
    StringList ArcNames;
66
    StringList ArcNames;
67
    StringList StoreArgs;
67
    StringList StoreArgs;
68
69
    SecPassword Password;
70
71
    std::vector<int64> NextVolSizes;
68
};
72
};
69
73
70
#endif
74
#endif
(-)unrar-6.1.7/cmdfilter.cpp (-2 / +2 lines)
Lines 289-296 Link Here
289
    return 0;
289
    return 0;
290
  if ((FileHead.FileAttr & ExclFileAttr)!=0 || FileHead.Dir && ExclDir)
290
  if ((FileHead.FileAttr & ExclFileAttr)!=0 || FileHead.Dir && ExclDir)
291
    return 0;
291
    return 0;
292
  if (InclAttrSet && (!FileHead.Dir && (FileHead.FileAttr & InclFileAttr)==0 ||
292
  if (InclAttrSet && (FileHead.FileAttr & InclFileAttr)==0 &&
293
      FileHead.Dir && !InclDir))
293
      (!FileHead.Dir || !InclDir))
294
    return 0;
294
    return 0;
295
  if (!Dir && SizeCheck(FileHead.UnpSize))
295
  if (!Dir && SizeCheck(FileHead.UnpSize))
296
    return 0;
296
    return 0;
(-)unrar-6.1.7/cmdmix.cpp (+7 lines)
Lines 92-97 Link Here
92
    if (Found)
92
    if (Found)
93
      continue;
93
      continue;
94
#endif
94
#endif
95
#ifdef _UNIX
96
    if (CmpMSGID(Help[I],MRARTitle2))
97
    {
98
      mprintf(St(MFwrSlTitle2));
99
      continue;
100
    }
101
#endif
95
#if !defined(_UNIX) && !defined(_WIN_ALL)
102
#if !defined(_UNIX) && !defined(_WIN_ALL)
96
    if (CmpMSGID(Help[I],MCHelpSwOW))
103
    if (CmpMSGID(Help[I],MCHelpSwOW))
97
      continue;
104
      continue;
(-)unrar-6.1.7/compress.hpp (+1 lines)
Lines 17-22 Link Here
17
    static const uint MAX_INC_LZ_MATCH = MAX_LZ_MATCH + 3;
17
    static const uint MAX_INC_LZ_MATCH = MAX_LZ_MATCH + 3;
18
18
19
    static const uint MAX3_LZ_MATCH = 0x101; // Maximum match length for RAR v3.
19
    static const uint MAX3_LZ_MATCH = 0x101; // Maximum match length for RAR v3.
20
    static const uint MAX3_INC_LZ_MATCH = MAX3_LZ_MATCH + 3;
20
    static const uint LOW_DIST_REP_COUNT = 16;
21
    static const uint LOW_DIST_REP_COUNT = 16;
21
22
22
    static const uint NC    = 306; /* alphabet = {0, 1, 2, ..., NC - 1} */
23
    static const uint NC    = 306; /* alphabet = {0, 1, 2, ..., NC - 1} */
(-)unrar-6.1.7/crc.cpp (+161 lines)
Lines 110-112 Link Here
110
#endif
110
#endif
111
111
112
112
113
#if 0
114
static uint64 crc64_tables[8][256]; // Tables for Slicing-by-8 for CRC64.
115
116
void InitCRC64(uint64 *CRCTab)
117
{
118
  const uint64 poly=INT32TO64(0xC96C5795, 0xD7870F42); // 0xC96C5795D7870F42;
119
  for (uint I=0;I<256;I++)
120
  {
121
    uint64 C=I;
122
    for (uint J=0;J<8;J++)
123
      C=(C & 1) ? (C>>1)^poly: (C>>1);
124
    CRCTab[I]=C;
125
  }
126
}
127
128
129
static void InitTables64()
130
{
131
  InitCRC64(crc64_tables[0]);
132
133
  for (uint I=0;I<256;I++) // Build additional lookup tables.
134
  {
135
    uint64 C=crc64_tables[0][I];
136
    for (uint J=1;J<8;J++)
137
    {
138
      C=crc64_tables[0][(byte)C]^(C>>8);
139
      crc64_tables[J][I]=C;
140
    }
141
  }
142
}
143
144
145
// We cannot place the intialization to CRC64(), because we use this function
146
// in multithreaded mode and it conflicts with multithreading.
147
struct CallInitCRC64 {CallInitCRC64() {InitTables64();}} static CallInit64;
148
149
uint64 CRC64(uint64 StartCRC,const void *Addr,size_t Size)
150
{
151
  byte *Data=(byte *)Addr;
152
153
  // Align Data to 8 for better performance.
154
  for (;Size>0 && ((size_t)Data & 7)!=0;Size--,Data++)
155
    StartCRC=crc64_tables[0][(byte)(StartCRC^Data[0])]^(StartCRC>>8);
156
157
  for (byte *DataEnd=Data+Size/8*8; Data<DataEnd; Data+=8 )
158
  {
159
    uint64 Index=StartCRC;
160
#ifdef BIG_ENDIAN
161
    Index ^= (uint64(Data[0])|(uint64(Data[1])<<8)|(uint64(Data[2])<<16)|(uint64(Data[3])<<24))|
162
             (uint64(Data[4])<<32)|(uint64(Data[5])<<40)|(uint64(Data[6])<<48)|(uint64(Data[7])<<56);
163
#else
164
    Index ^= *(uint64 *)Data;
165
#endif
166
    StartCRC = crc64_tables[ 7 ] [ ( byte ) (Index       ) ] ^
167
               crc64_tables[ 6 ] [ ( byte ) (Index >>  8 ) ] ^
168
               crc64_tables[ 5 ] [ ( byte ) (Index >> 16 ) ] ^
169
               crc64_tables[ 4 ] [ ( byte ) (Index >> 24 ) ] ^
170
               crc64_tables[ 3 ] [ ( byte ) (Index >> 32 ) ] ^
171
               crc64_tables[ 2 ] [ ( byte ) (Index >> 40 ) ] ^
172
               crc64_tables[ 1 ] [ ( byte ) (Index >> 48 ) ] ^
173
               crc64_tables[ 0 ] [ ( byte ) (Index >> 56 ) ] ;
174
  }
175
176
  for (Size%=8;Size>0;Size--,Data++) // Process left data.
177
    StartCRC=crc64_tables[0][(byte)(StartCRC^Data[0])]^(StartCRC>>8);
178
179
  return StartCRC;
180
}
181
182
183
#if 0
184
static void TestCRC();
185
struct TestCRCStruct {TestCRCStruct() {TestCRC();exit(0);}} GlobalTesCRC;
186
187
void TestCRC()
188
{
189
  const uint FirstSize=300;
190
  byte b[FirstSize];
191
192
  if ((CRC32(0xffffffff,(byte*)"testtesttest",12)^0xffffffff)==0x44608e84)
193
    mprintf(L"\nCRC32 test1 OK");
194
  else
195
    mprintf(L"\nCRC32 test1 FAILED");
196
197
  if (CRC32(0,(byte*)"te\x80st",5)==0xB2E5C5AE)
198
    mprintf(L"\nCRC32 test2 OK");
199
  else
200
    mprintf(L"\nCRC32 test2 FAILED");
201
202
  for (uint I=0;I<14;I++) // Check for possible int sign extension.
203
    b[I]=(byte)0x7f+I;
204
  if ((CRC32(0xffffffff,b,14)^0xffffffff)==0x1DFA75DA)
205
    mprintf(L"\nCRC32 test3 OK");
206
  else
207
    mprintf(L"\nCRC32 test3 FAILED");
208
209
  for (uint I=0;I<FirstSize;I++)
210
    b[I]=(byte)I;
211
  uint r32=CRC32(0xffffffff,b,FirstSize);
212
  for (uint I=FirstSize;I<1024;I++)
213
  {
214
    b[0]=(byte)I;
215
    r32=CRC32(r32,b,1);
216
  }
217
  if ((r32^0xffffffff)==0xB70B4C26)
218
    mprintf(L"\nCRC32 test4 OK");
219
  else
220
    mprintf(L"\nCRC32 test4 FAILED");
221
222
  if ((CRC64(0xffffffffffffffff,(byte*)"testtesttest",12)^0xffffffffffffffff)==0x7B1C2D230EDEB436)
223
    mprintf(L"\nCRC64 test1 OK");
224
  else
225
    mprintf(L"\nCRC64 test1 FAILED");
226
227
  if (CRC64(0,(byte*)"te\x80st",5)==0xB5DBF9583A6EED4A)
228
    mprintf(L"\nCRC64 test2 OK");
229
  else
230
    mprintf(L"\nCRC64 test2 FAILED");
231
232
  for (uint I=0;I<14;I++) // Check for possible int sign extension.
233
    b[I]=(byte)0x7f+I;
234
  if ((CRC64(0xffffffffffffffff,b,14)^0xffffffffffffffff)==0xE019941C05B2820C)
235
    mprintf(L"\nCRC64 test3 OK");
236
  else
237
    mprintf(L"\nCRC64 test3 FAILED");
238
239
  for (uint I=0;I<FirstSize;I++)
240
    b[I]=(byte)I;
241
  uint64 r64=CRC64(0xffffffffffffffff,b,FirstSize);
242
  for (uint I=FirstSize;I<1024;I++)
243
  {
244
    b[0]=(byte)I;
245
    r64=CRC64(r64,b,1);
246
  }
247
  if ((r64^0xffffffffffffffff)==0xD51FB58DC789C400)
248
    mprintf(L"\nCRC64 test4 OK");
249
  else
250
    mprintf(L"\nCRC64 test4 FAILED");
251
252
  const size_t BufSize=0x100000;
253
  byte *Buf=new byte[BufSize];
254
  memset(Buf,0,BufSize);
255
256
  clock_t StartTime=clock();
257
  r32=0xffffffff;
258
  const uint BufCount=5000;
259
  for (uint I=0;I<BufCount;I++)
260
    r32=CRC32(r32,Buf,BufSize);
261
  if (r32!=0) // Otherwise compiler optimizer removes CRC calculation.
262
    mprintf(L"\nCRC32 speed: %d MB/s",BufCount*1000/(clock()-StartTime));
263
264
  StartTime=clock();
265
  r64=0xffffffffffffffff;
266
  for (uint I=0;I<BufCount;I++)
267
    r64=CRC64(r64,Buf,BufSize);
268
  if (r64!=0) // Otherwise compiler optimizer removes CRC calculation.
269
    mprintf(L"\nCRC64 speed: %d MB/s",BufCount*1000/(clock()-StartTime));
270
}
271
#endif
272
273
#endif
(-)unrar-6.1.7/crc.hpp (+4 lines)
Lines 11-15 Link Here
11
ushort Checksum14(ushort StartCRC,const void *Addr,size_t Size);
11
ushort Checksum14(ushort StartCRC,const void *Addr,size_t Size);
12
#endif
12
#endif
13
13
14
#if 0
15
void InitCRC64(uint64 *CRCTab);
16
uint64 CRC64(uint64 StartCRC,const void *Addr,size_t Size);
17
#endif
14
18
15
#endif
19
#endif
(-)unrar-6.1.7/crypt.cpp (-10 / +4 lines)
Lines 11-33 Link Here
11
CryptData::CryptData()
11
CryptData::CryptData()
12
{
12
{
13
  Method=CRYPT_NONE;
13
  Method=CRYPT_NONE;
14
  memset(KDF3Cache,0,sizeof(KDF3Cache));
15
  memset(KDF5Cache,0,sizeof(KDF5Cache));
16
  KDF3CachePos=0;
14
  KDF3CachePos=0;
17
  KDF5CachePos=0;
15
  KDF5CachePos=0;
18
  memset(CRCTab,0,sizeof(CRCTab));
16
  memset(CRCTab,0,sizeof(CRCTab));
19
}
17
}
20
18
21
19
22
CryptData::~CryptData()
23
{
24
  cleandata(KDF3Cache,sizeof(KDF3Cache));
25
  cleandata(KDF5Cache,sizeof(KDF5Cache));
26
}
27
20
28
21
29
30
31
void CryptData::DecryptBlock(byte *Buf,size_t Size)
22
void CryptData::DecryptBlock(byte *Buf,size_t Size)
32
{
23
{
33
  switch(Method)
24
  switch(Method)
Lines 56-70 Link Here
56
     SecPassword *Password,const byte *Salt,
47
     SecPassword *Password,const byte *Salt,
57
     const byte *InitV,uint Lg2Cnt,byte *HashKey,byte *PswCheck)
48
     const byte *InitV,uint Lg2Cnt,byte *HashKey,byte *PswCheck)
58
{
49
{
59
  if (!Password->IsSet() || Method==CRYPT_NONE)
50
  if (Method==CRYPT_NONE || !Password->IsSet())
60
    return false;
51
    return false;
61
52
62
  CryptData::Method=Method;
53
  CryptData::Method=Method;
63
54
64
  wchar PwdW[MAXPASSWORD];
55
  wchar PwdW[MAXPASSWORD];
65
  Password->Get(PwdW,ASIZE(PwdW));
56
  Password->Get(PwdW,ASIZE(PwdW));
57
  PwdW[Min(MAXPASSWORD_RAR,MAXPASSWORD)-1]=0; // For compatibility with existing archives.
58
66
  char PwdA[MAXPASSWORD];
59
  char PwdA[MAXPASSWORD];
67
  WideToChar(PwdW,PwdA,ASIZE(PwdA));
60
  WideToChar(PwdW,PwdA,ASIZE(PwdA));
61
  PwdA[Min(MAXPASSWORD_RAR,MAXPASSWORD)-1]=0; // For compatibility with existing archives.
68
62
69
  switch(Method)
63
  switch(Method)
70
  {
64
  {
(-)unrar-6.1.7/crypt.hpp (-1 / +71 lines)
Lines 30-35 Link Here
30
    uint Lg2Count; // Log2 of PBKDF2 repetition count.
30
    uint Lg2Count; // Log2 of PBKDF2 repetition count.
31
    byte PswCheckValue[SHA256_DIGEST_SIZE];
31
    byte PswCheckValue[SHA256_DIGEST_SIZE];
32
    byte HashKeyValue[SHA256_DIGEST_SIZE];
32
    byte HashKeyValue[SHA256_DIGEST_SIZE];
33
34
    KDF5CacheItem() {Clean();}
35
    ~KDF5CacheItem() {Clean();}
36
37
    void Clean()
38
    {
39
      cleandata(Salt,sizeof(Salt));
40
      cleandata(Key,sizeof(Key));
41
      cleandata(&Lg2Count,sizeof(Lg2Count));
42
      cleandata(PswCheckValue,sizeof(PswCheckValue));
43
      cleandata(HashKeyValue,sizeof(HashKeyValue));
44
    }
33
  };
45
  };
34
46
35
  struct KDF3CacheItem
47
  struct KDF3CacheItem
Lines 39-44 Link Here
39
    byte Key[16];
51
    byte Key[16];
40
    byte Init[16];
52
    byte Init[16];
41
    bool SaltPresent;
53
    bool SaltPresent;
54
55
    KDF3CacheItem() {Clean();}
56
    ~KDF3CacheItem() {Clean();}
57
58
    void Clean()
59
    {
60
      cleandata(Salt,sizeof(Salt));
61
      cleandata(Key,sizeof(Key));
62
      cleandata(Init,sizeof(Init));
63
      cleandata(&SaltPresent,sizeof(SaltPresent));
64
    }
42
  };
65
  };
43
66
44
67
Lines 77-83 Link Here
77
    ushort Key15[4];
100
    ushort Key15[4];
78
  public:
101
  public:
79
    CryptData();
102
    CryptData();
80
    ~CryptData();
81
    bool SetCryptKeys(bool Encrypt,CRYPT_METHOD Method,SecPassword *Password,
103
    bool SetCryptKeys(bool Encrypt,CRYPT_METHOD Method,SecPassword *Password,
82
         const byte *Salt,const byte *InitV,uint Lg2Cnt,
104
         const byte *Salt,const byte *InitV,uint Lg2Cnt,
83
         byte *HashKey,byte *PswCheck);
105
         byte *HashKey,byte *PswCheck);
Lines 86-91 Link Here
86
    void EncryptBlock(byte *Buf,size_t Size);
108
    void EncryptBlock(byte *Buf,size_t Size);
87
    void DecryptBlock(byte *Buf,size_t Size);
109
    void DecryptBlock(byte *Buf,size_t Size);
88
    static void SetSalt(byte *Salt,size_t SaltSize);
110
    static void SetSalt(byte *Salt,size_t SaltSize);
111
};
112
113
114
class CheckPassword
115
{
116
  public:
117
    enum CONFIDENCE {CONFIDENCE_HIGH,CONFIDENCE_MEDIUM,CONFIDENCE_LOW};
118
    virtual CONFIDENCE GetConfidence()=0;
119
    virtual bool Check(SecPassword *Password)=0;
120
};
121
122
class RarCheckPassword:public CheckPassword
123
{
124
  private:
125
    CryptData *Crypt;
126
    uint Lg2Count;
127
    byte Salt[SIZE_SALT50];
128
    byte InitV[SIZE_INITV];
129
    byte PswCheck[SIZE_PSWCHECK];
130
  public:
131
    RarCheckPassword()
132
    {
133
      Crypt=NULL;
134
    }
135
    ~RarCheckPassword()
136
    {
137
      delete Crypt;
138
    }
139
    void Set(byte *Salt,byte *InitV,uint Lg2Count,byte *PswCheck)
140
    {
141
      if (Crypt==NULL)
142
        Crypt=new CryptData;
143
      memcpy(this->Salt,Salt,sizeof(this->Salt));
144
      memcpy(this->InitV,InitV,sizeof(this->InitV));
145
      this->Lg2Count=Lg2Count;
146
      memcpy(this->PswCheck,PswCheck,sizeof(this->PswCheck));
147
    }
148
    bool IsSet() {return Crypt!=NULL;}
149
150
    // RAR5 provides the higly reliable 64 bit password verification value.
151
    CONFIDENCE GetConfidence() {return CONFIDENCE_HIGH;}
152
153
    bool Check(SecPassword *Password)
154
    {
155
      byte PswCheck[SIZE_PSWCHECK];
156
      Crypt->SetCryptKeys(false,CRYPT_RAR50,Password,Salt,InitV,Lg2Count,NULL,PswCheck);
157
      return memcmp(PswCheck,this->PswCheck,sizeof(this->PswCheck))==0;
158
    }
89
};
159
};
90
160
91
void GetRnd(byte *RndBuf,size_t BufSize);
161
void GetRnd(byte *RndBuf,size_t BufSize);
(-)unrar-6.1.7/crypt3.cpp (-2 / +3 lines)
Lines 18-25 Link Here
18
  if (!Cached)
18
  if (!Cached)
19
  {
19
  {
20
    byte RawPsw[2*MAXPASSWORD+SIZE_SALT30];
20
    byte RawPsw[2*MAXPASSWORD+SIZE_SALT30];
21
    WideToRaw(PwdW,RawPsw,ASIZE(RawPsw));
21
    size_t PswLength=wcslen(PwdW);
22
    size_t RawLength=2*wcslen(PwdW);
22
    size_t RawLength=2*PswLength;
23
    WideToRaw(PwdW,PswLength,RawPsw,RawLength);
23
    if (Salt!=NULL)
24
    if (Salt!=NULL)
24
    {
25
    {
25
      memcpy(RawPsw+RawLength,Salt,SIZE_SALT30);
26
      memcpy(RawPsw+RawLength,Salt,SIZE_SALT30);
(-)unrar-6.1.7/crypt5.cpp (-6 / +6 lines)
Lines 21-27 Link Here
21
  sha256_context ICtx;
21
  sha256_context ICtx;
22
22
23
  if (ICtxOpt!=NULL && *SetIOpt)
23
  if (ICtxOpt!=NULL && *SetIOpt)
24
    ICtx=*ICtxOpt; // Use already calculated first block context.
24
    ICtx=*ICtxOpt; // Use already calculated the first block context.
25
  else
25
  else
26
  {
26
  {
27
    // This calculation is the same for all iterations with same password.
27
    // This calculation is the same for all iterations with same password.
Lines 90-99 Link Here
90
  byte SaltData[MaxSalt+4];
90
  byte SaltData[MaxSalt+4];
91
  memcpy(SaltData, Salt, Min(SaltLength,MaxSalt));
91
  memcpy(SaltData, Salt, Min(SaltLength,MaxSalt));
92
92
93
  SaltData[SaltLength + 0] = 0; // Salt concatenated to 1.
93
  SaltData[SaltLength + 0] = 0; // Block index appened to salt.
94
  SaltData[SaltLength + 1] = 0;
94
  SaltData[SaltLength + 1] = 0; //
95
  SaltData[SaltLength + 2] = 0;
95
  SaltData[SaltLength + 2] = 0; // Since we do not request the key width
96
  SaltData[SaltLength + 3] = 1;
96
  SaltData[SaltLength + 3] = 1; // exceeding HMAC width, it is always 1.
97
97
98
  // First iteration: HMAC of password, salt and block index (1).
98
  // First iteration: HMAC of password, salt and block index (1).
99
  byte U1[SHA256_DIGEST_SIZE];
99
  byte U1[SHA256_DIGEST_SIZE];
Lines 140-146 Link Here
140
  for (uint I=0;I<ASIZE(KDF5Cache);I++)
140
  for (uint I=0;I<ASIZE(KDF5Cache);I++)
141
  {
141
  {
142
    KDF5CacheItem *Item=KDF5Cache+I;
142
    KDF5CacheItem *Item=KDF5Cache+I;
143
    if (Item->Lg2Count==Lg2Cnt && Item->Pwd==*Password &&
143
    if (Item->Pwd==*Password && Item->Lg2Count==Lg2Cnt && 
144
        memcmp(Item->Salt,Salt,SIZE_SALT50)==0)
144
        memcmp(Item->Salt,Salt,SIZE_SALT50)==0)
145
    {
145
    {
146
      memcpy(Key,Item->Key,sizeof(Key));
146
      memcpy(Key,Item->Key,sizeof(Key));
(-)unrar-6.1.7/dll.rc (-5 / +5 lines)
Lines 2-9 Link Here
2
#include <commctrl.h>
2
#include <commctrl.h>
3
3
4
VS_VERSION_INFO VERSIONINFO
4
VS_VERSION_INFO VERSIONINFO
5
FILEVERSION 6, 12, 100, 489
5
FILEVERSION 6, 22, 1, 865
6
PRODUCTVERSION 6, 12, 100, 489
6
PRODUCTVERSION 6, 22, 1, 865
7
FILEOS VOS__WINDOWS32
7
FILEOS VOS__WINDOWS32
8
FILETYPE VFT_APP
8
FILETYPE VFT_APP
9
{
9
{
Lines 14-22 Link Here
14
      VALUE "CompanyName", "Alexander Roshal\0"
14
      VALUE "CompanyName", "Alexander Roshal\0"
15
      VALUE "ProductName", "RAR decompression library\0"
15
      VALUE "ProductName", "RAR decompression library\0"
16
      VALUE "FileDescription", "RAR decompression library\0"
16
      VALUE "FileDescription", "RAR decompression library\0"
17
      VALUE "FileVersion", "6.12.0\0"
17
      VALUE "FileVersion", "6.22.1\0"
18
      VALUE "ProductVersion", "6.12.0\0"
18
      VALUE "ProductVersion", "6.22.1\0"
19
      VALUE "LegalCopyright", "Copyright © Alexander Roshal 1993-2022\0"
19
      VALUE "LegalCopyright", "Copyright © Alexander Roshal 1993-2023\0"
20
      VALUE "OriginalFilename", "Unrar.dll\0"
20
      VALUE "OriginalFilename", "Unrar.dll\0"
21
    }
21
    }
22
  }
22
  }
(-)unrar-6.1.7/errhnd.cpp (-1 / +4 lines)
Lines 169-178 Link Here
169
169
170
void ErrorHandler::OpenErrorMsg(const wchar *ArcName,const wchar *FileName)
170
void ErrorHandler::OpenErrorMsg(const wchar *ArcName,const wchar *FileName)
171
{
171
{
172
  Wait(); // Keep GUI responsive if many files cannot be opened when archiving.
173
  uiMsg(UIERROR_FILEOPEN,ArcName,FileName);
172
  uiMsg(UIERROR_FILEOPEN,ArcName,FileName);
174
  SysErrMsg();
173
  SysErrMsg();
175
  SetErrorCode(RARX_OPEN);
174
  SetErrorCode(RARX_OPEN);
175
176
  // Keep GUI responsive if many files cannot be opened when archiving.
177
  // Call after SysErrMsg to avoid modifying the error code and SysErrMsg text.
178
  Wait();
176
}
179
}
177
180
178
181
(-)unrar-6.1.7/extinfo.cpp (-6 / +83 lines)
Lines 112-117 Link Here
112
}
112
}
113
113
114
114
115
// Delete symbolic links in file path, if any, and replace them by directories.
116
// Prevents extracting files outside of destination folder with symlink chains.
117
bool LinksToDirs(const wchar *SrcName,const wchar *SkipPart,std::wstring &LastChecked)
118
{
119
  // Unlike Unix, Windows doesn't expand lnk1 in symlink targets like
120
  // "lnk1/../dir", but converts the path to "dir". In Unix we need to call
121
  // this function to prevent placing unpacked files outside of destination
122
  // folder if previously we unpacked "dir/lnk1" -> "..",
123
  // "dir/lnk2" -> "lnk1/.." and "dir/lnk2/anypath/poc.txt".
124
  // We may still need this function to prevent abusing symlink chains
125
  // in link source path if we remove detection of such chains
126
  // in IsRelativeSymlinkSafe. This function seems to make other symlink
127
  // related safety checks redundant, but for now we prefer to keep them too.
128
  //
129
  // 2022.12.01: the performance impact is minimized after adding the check
130
  // against the previous path and enabling this verification only after
131
  // extracting a symlink with ".." in target. So we enabled it for Windows
132
  // as well for extra safety.
133
//#ifdef _UNIX
134
  wchar Path[NM];
135
  if (wcslen(SrcName)>=ASIZE(Path))
136
    return false;  // It should not be that long, skip.
137
  wcsncpyz(Path,SrcName,ASIZE(Path));
138
139
  size_t SkipLength=wcslen(SkipPart);
140
141
  if (SkipLength>0 && wcsncmp(Path,SkipPart,SkipLength)!=0)
142
    SkipLength=0; // Parameter validation, not really needed now.
143
144
  // Do not check parts already checked in previous path to improve performance.
145
  for (uint I=0;Path[I]!=0 && I<LastChecked.size() && Path[I]==LastChecked[I];I++)
146
    if (IsPathDiv(Path[I]) && I>SkipLength)
147
      SkipLength=I;
148
149
  wchar *Name=Path;
150
  if (SkipLength>0)
151
  {
152
    // Avoid converting symlinks in destination path part specified by user.
153
    Name+=SkipLength;
154
    while (IsPathDiv(*Name))
155
      Name++;
156
  }
157
158
  for (wchar *s=Path+wcslen(Path)-1;s>Name;s--)
159
    if (IsPathDiv(*s))
160
    {
161
      *s=0;
162
      FindData FD;
163
      if (FindFile::FastFind(Path,&FD,true) && FD.IsLink)
164
#ifdef _WIN_ALL
165
        if (!DelDir(Path))
166
#else
167
        if (!DelFile(Path))
168
#endif
169
          return false; // Couldn't delete the symlink to replace it with directory.
170
    }
171
  LastChecked=SrcName;
172
//#endif
173
  return true;
174
}
175
176
115
bool IsRelativeSymlinkSafe(CommandData *Cmd,const wchar *SrcName,const wchar *PrepSrcName,const wchar *TargetName)
177
bool IsRelativeSymlinkSafe(CommandData *Cmd,const wchar *SrcName,const wchar *PrepSrcName,const wchar *TargetName)
116
{
178
{
117
  // Catch root dir based /path/file paths also as stuff like \\?\.
179
  // Catch root dir based /path/file paths also as stuff like \\?\.
Lines 131-140 Link Here
131
      UpLevels++;
193
      UpLevels++;
132
    TargetName++;
194
    TargetName++;
133
  }
195
  }
134
  // If link target includes "..", it must not have another links
196
  // If link target includes "..", it must not have another links in its
135
  // in the path, because they can bypass our safety check. For example,
197
  // source path, because they can bypass our safety check. For example,
136
  // suppose we extracted "lnk1" -> "." first and "lnk1/lnk2" -> ".." next
198
  // suppose we extracted "lnk1" -> "." first and "lnk1/lnk2" -> ".." next
137
  // or "dir/lnk1" -> ".." first and "dir/lnk1/lnk2" -> ".." next.
199
  // or "dir/lnk1" -> ".." first, "dir/lnk1/lnk2" -> ".." next and
200
  // file "dir/lnk1/lnk2/poc.txt" last.
201
  // Do not confuse with link chains in target, this is in link source path.
202
  // It is important for Windows too, though this check can be omitted
203
  // if LinksToDirs is invoked in Windows as well.
138
  if (UpLevels>0 && LinkInPath(PrepSrcName))
204
  if (UpLevels>0 && LinkInPath(PrepSrcName))
139
    return false;
205
    return false;
140
    
206
    
Lines 160-174 Link Here
160
}
226
}
161
227
162
228
163
bool ExtractSymlink(CommandData *Cmd,ComprDataIO &DataIO,Archive &Arc,const wchar *LinkName)
229
bool ExtractSymlink(CommandData *Cmd,ComprDataIO &DataIO,Archive &Arc,const wchar *LinkName,bool &UpLink)
164
{
230
{
231
  // Returning true in Uplink indicates that link target might include ".."
232
  // and enables additional checks. It is ok to falsely return true here,
233
  // as it implies only the minor performance penalty. But we shall always
234
  // return true for links with ".." in target for security reason.
235
236
  UpLink=true; // Assume the target might include potentially unsafe "..".
237
#if defined(SAVE_LINKS) && defined(_UNIX) || defined(_WIN_ALL)
238
  if (Arc.Format==RARFMT50) // For RAR5 archives we can check RedirName for both Unix and Windows.
239
    UpLink=wcsstr(Arc.FileHead.RedirName,L"..")!=NULL;
240
#endif
241
165
#if defined(SAVE_LINKS) && defined(_UNIX)
242
#if defined(SAVE_LINKS) && defined(_UNIX)
166
  // For RAR 3.x archives we process links even in test mode to skip link data.
243
  // For RAR 3.x archives we process links even in test mode to skip link data.
167
  if (Arc.Format==RARFMT15)
244
  if (Arc.Format==RARFMT15)
168
    return ExtractUnixLink30(Cmd,DataIO,Arc,LinkName);
245
    return ExtractUnixLink30(Cmd,DataIO,Arc,LinkName,UpLink);
169
  if (Arc.Format==RARFMT50)
246
  if (Arc.Format==RARFMT50)
170
    return ExtractUnixLink50(Cmd,LinkName,&Arc.FileHead);
247
    return ExtractUnixLink50(Cmd,LinkName,&Arc.FileHead);
171
#elif defined _WIN_ALL
248
#elif defined(_WIN_ALL)
172
  // RAR 5.0 archives store link information in file header, so there is
249
  // RAR 5.0 archives store link information in file header, so there is
173
  // no need to additionally test it if we do not create a file.
250
  // no need to additionally test it if we do not create a file.
174
  if (Arc.Format==RARFMT50)
251
  if (Arc.Format==RARFMT50)
(-)unrar-6.1.7/extinfo.hpp (-1 / +2 lines)
Lines 1-8 Link Here
1
#ifndef _RAR_EXTINFO_
1
#ifndef _RAR_EXTINFO_
2
#define _RAR_EXTINFO_
2
#define _RAR_EXTINFO_
3
3
4
bool LinksToDirs(const wchar *SrcName,const wchar *SkipPart,std::wstring &LastChecked);
4
bool IsRelativeSymlinkSafe(CommandData *Cmd,const wchar *SrcName,const wchar *PrepSrcName,const wchar *TargetName);
5
bool IsRelativeSymlinkSafe(CommandData *Cmd,const wchar *SrcName,const wchar *PrepSrcName,const wchar *TargetName);
5
bool ExtractSymlink(CommandData *Cmd,ComprDataIO &DataIO,Archive &Arc,const wchar *LinkName);
6
bool ExtractSymlink(CommandData *Cmd,ComprDataIO &DataIO,Archive &Arc,const wchar *LinkName,bool &UpLink);
6
#ifdef _UNIX
7
#ifdef _UNIX
7
void SetUnixOwner(Archive &Arc,const wchar *FileName);
8
void SetUnixOwner(Archive &Arc,const wchar *FileName);
8
#endif
9
#endif
(-)unrar-6.1.7/extract.cpp (-100 / +406 lines)
Lines 5-14 Link Here
5
  CmdExtract::Cmd=Cmd;
5
  CmdExtract::Cmd=Cmd;
6
6
7
  *ArcName=0;
7
  *ArcName=0;
8
9
  *DestFileName=0;
8
  *DestFileName=0;
10
9
10
  ArcAnalyzed=false;
11
  Analyze=new AnalyzeData;
12
  memset(Analyze,0,sizeof(*Analyze));
13
11
  TotalFileCount=0;
14
  TotalFileCount=0;
15
16
  // Common for all archives involved. Set here instead of DoExtract()
17
  // to use in unrar.dll too. Allows to avoid LinksToDirs() calls
18
  // and save CPU time in no symlinks including ".." in target were extracted.
19
#if defined(_WIN_ALL)
20
  // We can't expand symlink path components in another symlink target
21
  // in Windows. We can't create symlinks in Android now. Even though we do not
22
  // really need LinksToDirs() calls in these systems, we still call it
23
  // for extra safety, but only if symlink with ".." in target was extracted.
24
  ConvertSymlinkPaths=false;
25
#else
26
  // We enable it by default in Unix to care about the case when several
27
  // archives are unpacked to same directory with several independent RAR runs.
28
  // Worst case performance penalty for a lot of small files seems to be ~3%.
29
  ConvertSymlinkPaths=true;
30
#endif
31
12
  Unp=new Unpack(&DataIO);
32
  Unp=new Unpack(&DataIO);
13
#ifdef RAR_SMP
33
#ifdef RAR_SMP
14
  Unp->SetThreads(Cmd->Threads);
34
  Unp->SetThreads(Cmd->Threads);
Lines 18-27 Link Here
18
38
19
CmdExtract::~CmdExtract()
39
CmdExtract::~CmdExtract()
20
{
40
{
41
  FreeAnalyzeData();
21
  delete Unp;
42
  delete Unp;
43
  delete Analyze;
22
}
44
}
23
45
24
46
47
void CmdExtract::FreeAnalyzeData()
48
{
49
  for (size_t I=0;I<RefList.Size();I++)
50
  {
51
    // We can have undeleted temporary reference source here if extraction
52
    // was interrupted early or if user refused to overwrite prompt.
53
    if (RefList[I].TmpName!=NULL)
54
      DelFile(RefList[I].TmpName);
55
    free(RefList[I].RefName);
56
    free(RefList[I].TmpName);
57
  }
58
  RefList.Reset();
59
60
  memset(Analyze,0,sizeof(*Analyze));
61
}
62
63
25
void CmdExtract::DoExtract()
64
void CmdExtract::DoExtract()
26
{
65
{
27
#if defined(_WIN_ALL) && !defined(SFX_MODULE) && !defined(SILENT)
66
#if defined(_WIN_ALL) && !defined(SFX_MODULE) && !defined(SILENT)
Lines 30-39 Link Here
30
  PasswordCancelled=false;
69
  PasswordCancelled=false;
31
  DataIO.SetCurrentCommand(Cmd->Command[0]);
70
  DataIO.SetCurrentCommand(Cmd->Command[0]);
32
71
33
  FindData FD;
72
  if (*Cmd->UseStdin==0)
34
  while (Cmd->GetArcName(ArcName,ASIZE(ArcName)))
73
  {
35
    if (FindFile::FastFind(ArcName,&FD))
74
    FindData FD;
36
      DataIO.TotalArcSize+=FD.Size;
75
    while (Cmd->GetArcName(ArcName,ASIZE(ArcName)))
76
      if (FindFile::FastFind(ArcName,&FD))
77
        DataIO.TotalArcSize+=FD.Size;
78
  }
37
79
38
  Cmd->ArcNames.Rewind();
80
  Cmd->ArcNames.Rewind();
39
  while (Cmd->GetArcName(ArcName,ASIZE(ArcName)))
81
  while (Cmd->GetArcName(ArcName,ASIZE(ArcName)))
Lines 97-103 Link Here
97
  AllMatchesExact=true;
139
  AllMatchesExact=true;
98
  AnySolidDataUnpackedWell=false;
140
  AnySolidDataUnpackedWell=false;
99
141
142
  ArcAnalyzed=false;
143
100
  StartTime.SetCurrentTime();
144
  StartTime.SetCurrentTime();
145
146
  LastCheckedSymlink.clear();
101
}
147
}
102
148
103
149
Lines 168-187 Link Here
168
  }
214
  }
169
#endif
215
#endif
170
216
217
  Arc.ViewComment(); // Must be before possible EXTRACT_ARC_REPEAT.
218
171
  int64 VolumeSetSize=0; // Total size of volumes after the current volume.
219
  int64 VolumeSetSize=0; // Total size of volumes after the current volume.
172
220
221
#ifndef SFX_MODULE
222
  if (!ArcAnalyzed && *Cmd->UseStdin==0)
223
  {
224
    AnalyzeArchive(Arc.FileName,Arc.Volume,Arc.NewNumbering);
225
    ArcAnalyzed=true; // Avoid repeated analysis on EXTRACT_ARC_REPEAT.
226
  }
227
#endif
228
173
  if (Arc.Volume)
229
  if (Arc.Volume)
174
  {
230
  {
175
#ifndef SFX_MODULE
231
#ifndef SFX_MODULE
176
    // Try to speed up extraction for independent solid volumes by starting
232
    // Try to speed up extraction for independent solid volumes by starting
177
    // extraction from non-first volume if we can.
233
    // extraction from non-first volume if we can.
178
    if (!UseExactVolName && Arc.Solid && DetectStartVolume(Arc.FileName,Arc.NewNumbering))
234
    if (*Analyze->StartName!=0)
179
    {
235
    {
236
      wcsncpyz(ArcName,Analyze->StartName,ASIZE(ArcName));
237
      *Analyze->StartName=0;
238
180
      UseExactVolName=true;
239
      UseExactVolName=true;
181
      return EXTRACT_ARC_REPEAT;
240
      return EXTRACT_ARC_REPEAT;
182
    }
241
    }
183
#endif
242
#endif
184
243
    
185
    // Calculate the total size of all accessible volumes.
244
    // Calculate the total size of all accessible volumes.
186
    // This size is necessary to display the correct total progress indicator.
245
    // This size is necessary to display the correct total progress indicator.
187
246
Lines 216-222 Link Here
216
  else
275
  else
217
    uiStartArchiveExtract(!Cmd->Test,ArcName);
276
    uiStartArchiveExtract(!Cmd->Test,ArcName);
218
277
219
  Arc.ViewComment();
278
#ifndef SFX_MODULE
279
  if (Analyze->StartPos!=0)
280
  {
281
    Arc.Seek(Analyze->StartPos,SEEK_SET);
282
    Analyze->StartPos=0;
283
  }
284
#endif
220
285
221
286
222
  while (1)
287
  while (1)
Lines 272-279 Link Here
272
      return false;
337
      return false;
273
338
274
  HEADER_TYPE HeaderType=Arc.GetHeaderType();
339
  HEADER_TYPE HeaderType=Arc.GetHeaderType();
275
  if (HeaderType!=HEAD_FILE)
340
  if (HeaderType==HEAD_FILE)
276
  {
341
  {
342
    // Unlike Arc.FileName, ArcName might store an old volume name here.
343
    if (Analyze->EndPos!=0 && Analyze->EndPos==Arc.CurBlockPos &&
344
        (*Analyze->EndName==0 || wcscmp(Analyze->EndName,Arc.FileName)==0))
345
      return false;
346
  }
347
  else
348
  {
277
#ifndef SFX_MODULE
349
#ifndef SFX_MODULE
278
    if (Arc.Format==RARFMT15 && HeaderType==HEAD3_OLDSERVICE && PrevProcessed)
350
    if (Arc.Format==RARFMT15 && HeaderType==HEAD3_OLDSERVICE && PrevProcessed)
279
      SetExtraInfo20(Cmd,Arc,DestFileName);
351
      SetExtraInfo20(Cmd,Arc,DestFileName);
Lines 315-320 Link Here
315
  if (Arc.FileHead.UnpSize<0)
387
  if (Arc.FileHead.UnpSize<0)
316
    Arc.FileHead.UnpSize=0;
388
    Arc.FileHead.UnpSize=0;
317
389
390
  // 2022.03.20: We might remove this check in the future.
391
  // It duplicates Analyze->EndPos and Analyze->EndName in all cases except
392
  // volumes on removable media.
318
  if (!Cmd->Recurse && MatchedArgs>=Cmd->FileArgs.ItemsCount() && AllMatchesExact)
393
  if (!Cmd->Recurse && MatchedArgs>=Cmd->FileArgs.ItemsCount() && AllMatchesExact)
319
    return false;
394
    return false;
320
395
Lines 413-425 Link Here
413
  FirstFile=false;
488
  FirstFile=false;
414
#endif
489
#endif
415
490
491
  bool RefTarget=false;
492
  if (!MatchFound)
493
    for (size_t I=0;I<RefList.Size();I++)
494
      if (wcscmp(ArcFileName,RefList[I].RefName)==0)
495
      {
496
        ExtractRef *MatchedRef=&RefList[I];
497
      
498
        if (!Cmd->Test) // While harmless, it is useless for 't'.
499
        {
500
          // If reference source isn't selected, but target is selected,
501
          // we unpack the source under the temporary name and then rename
502
          // or copy it to target name. We do not unpack it under the target
503
          // name immediately, because the same source can be used by multiple
504
          // targets and it is possible that first target isn't unpacked
505
          // for some reason. Also targets might have associated service blocks
506
          // like ACLs. All this would complicate processing a lot.
507
          wcsncpyz(DestFileName,*Cmd->TempPath!=0 ? Cmd->TempPath:Cmd->ExtrPath,ASIZE(DestFileName));
508
          AddEndSlash(DestFileName,ASIZE(DestFileName));
509
          wcsncatz(DestFileName,L"__tmp_reference_source_",ASIZE(DestFileName));
510
          MkTemp(DestFileName,ASIZE(DestFileName));
511
          MatchedRef->TmpName=wcsdup(DestFileName);
512
        }
513
        RefTarget=true; // Need it even for 't' to test the reference source.
514
        break;
515
      }
516
  
416
  if (Arc.FileHead.Encrypted && Cmd->SkipEncrypted)
517
  if (Arc.FileHead.Encrypted && Cmd->SkipEncrypted)
417
    if (Arc.Solid)
518
    if (Arc.Solid)
418
      return false; // Abort the entire extraction for solid archive.
519
      return false; // Abort the entire extraction for solid archive.
419
    else
520
    else
420
      MatchFound=false; // Skip only the current file for non-solid archive.
521
      MatchFound=false; // Skip only the current file for non-solid archive.
421
  
522
  
422
  if (MatchFound || (SkipSolid=Arc.Solid)!=0)
523
  if (MatchFound || RefTarget || (SkipSolid=Arc.Solid)!=0)
423
  {
524
  {
424
    // First common call of uiStartFileExtract. It is done before overwrite
525
    // First common call of uiStartFileExtract. It is done before overwrite
425
    // prompts, so if SkipSolid state is changed below, we'll need to make
526
    // prompts, so if SkipSolid state is changed below, we'll need to make
Lines 427-433 Link Here
427
    if (!uiStartFileExtract(ArcFileName,!Cmd->Test,Cmd->Test && Command!='I',SkipSolid))
528
    if (!uiStartFileExtract(ArcFileName,!Cmd->Test,Cmd->Test && Command!='I',SkipSolid))
428
      return false;
529
      return false;
429
530
430
    ExtrPrepareName(Arc,ArcFileName,DestFileName,ASIZE(DestFileName));
531
    if (!RefTarget)
532
      ExtrPrepareName(Arc,ArcFileName,DestFileName,ASIZE(DestFileName));
431
533
432
    // DestFileName can be set empty in case of excessive -ap switch.
534
    // DestFileName can be set empty in case of excessive -ap switch.
433
    ExtrFile=!SkipSolid && *DestFileName!=0 && !Arc.FileHead.SplitBefore;
535
    ExtrFile=!SkipSolid && *DestFileName!=0 && !Arc.FileHead.SplitBefore;
Lines 464-472 Link Here
464
      return !Arc.Solid; // Can try extracting next file only in non-solid archive.
566
      return !Arc.Solid; // Can try extracting next file only in non-solid archive.
465
    }
567
    }
466
568
467
    while (true) // Repeat the password prompt for wrong and empty passwords.
569
    if (Arc.FileHead.Encrypted)
468
    {
570
    {
469
      if (Arc.FileHead.Encrypted)
571
      RarCheckPassword CheckPwd;
572
      if (Arc.Format==RARFMT50 && Arc.FileHead.UsePswCheck && !Arc.BrokenHeader)
573
        CheckPwd.Set(Arc.FileHead.Salt,Arc.FileHead.InitV,Arc.FileHead.Lg2Count,Arc.FileHead.PswCheck);
574
575
      while (true) // Repeat the password prompt for wrong and empty passwords.
470
      {
576
      {
471
        // Stop archive extracting if user cancelled a password prompt.
577
        // Stop archive extracting if user cancelled a password prompt.
472
#ifdef RARDLL
578
#ifdef RARDLL
Lines 476-552 Link Here
476
          return false;
582
          return false;
477
        }
583
        }
478
#else
584
#else
479
        if (!ExtrGetPassword(Arc,ArcFileName))
585
        if (!ExtrGetPassword(Arc,ArcFileName,CheckPwd.IsSet() ? &CheckPwd:NULL))
480
        {
586
        {
481
          PasswordCancelled=true;
587
          PasswordCancelled=true;
482
          return false;
588
          return false;
483
        }
589
        }
484
#endif
590
#endif
485
      }
486
591
487
      // Set a password before creating the file, so we can skip creating
592
        // Set a password before creating the file, so we can skip creating
488
      // in case of wrong password.
593
        // in case of wrong password.
489
      SecPassword FilePassword=Cmd->Password;
594
        SecPassword FilePassword=Cmd->Password;
490
#if defined(_WIN_ALL) && !defined(SFX_MODULE)
595
  #if defined(_WIN_ALL) && !defined(SFX_MODULE)
491
      ConvertDosPassword(Arc,FilePassword);
596
        ConvertDosPassword(Arc,FilePassword);
492
#endif
597
  #endif
493
598
494
      byte PswCheck[SIZE_PSWCHECK];
599
        byte PswCheck[SIZE_PSWCHECK];
495
      DataIO.SetEncryption(false,Arc.FileHead.CryptMethod,&FilePassword,
600
        DataIO.SetEncryption(false,Arc.FileHead.CryptMethod,&FilePassword,
496
             Arc.FileHead.SaltSet ? Arc.FileHead.Salt:NULL,
601
               Arc.FileHead.SaltSet ? Arc.FileHead.Salt:NULL,
497
             Arc.FileHead.InitV,Arc.FileHead.Lg2Count,
602
               Arc.FileHead.InitV,Arc.FileHead.Lg2Count,
498
             Arc.FileHead.HashKey,PswCheck);
603
               Arc.FileHead.HashKey,PswCheck);
499
604
500
      // If header is damaged, we cannot rely on password check value,
605
        // If header is damaged, we cannot rely on password check value,
501
      // because it can be damaged too.
606
        // because it can be damaged too.
502
      if (Arc.FileHead.Encrypted && Arc.FileHead.UsePswCheck &&
607
        if (Arc.FileHead.UsePswCheck && !Arc.BrokenHeader &&
503
          memcmp(Arc.FileHead.PswCheck,PswCheck,SIZE_PSWCHECK)!=0 &&
608
            memcmp(Arc.FileHead.PswCheck,PswCheck,SIZE_PSWCHECK)!=0)
504
          !Arc.BrokenHeader)
505
      {
506
        if (GlobalPassword) // For -p<pwd> or Ctrl+P to avoid the infinite loop.
507
        {
609
        {
508
          // This message is used by Android GUI to reset cached passwords.
610
          if (GlobalPassword) // For -p<pwd> or Ctrl+P to avoid the infinite loop.
509
          // Update appropriate code if changed.
611
          {
510
          uiMsg(UIERROR_BADPSW,Arc.FileName,ArcFileName);
612
            // This message is used by Android GUI to reset cached passwords.
511
        }
613
            // Update appropriate code if changed.
512
        else // For passwords entered manually.
614
            uiMsg(UIERROR_BADPSW,Arc.FileName,ArcFileName);
513
        {
615
          }
514
          // This message is used by Android GUI and Windows GUI and SFX to
616
          else // For passwords entered manually.
515
          // reset cached passwords. Update appropriate code if changed.
617
          {
516
          uiMsg(UIWAIT_BADPSW,Arc.FileName,ArcFileName);
618
            // This message is used by Android GUI and Windows GUI and SFX to
517
          Cmd->Password.Clean();
619
            // reset cached passwords. Update appropriate code if changed.
620
            uiMsg(UIWAIT_BADPSW,Arc.FileName,ArcFileName);
621
            Cmd->Password.Clean();
518
622
519
          // Avoid new requests for unrar.dll to prevent the infinite loop
623
            // Avoid new requests for unrar.dll to prevent the infinite loop
520
          // if app always returns the same password.
624
            // if app always returns the same password.
521
#ifndef RARDLL
625
  #ifndef RARDLL
522
          continue; // Request a password again.
626
            continue; // Request a password again.
523
#endif
627
  #endif
628
          }
629
  #ifdef RARDLL
630
          // If we already have ERAR_EOPEN as result of missing volume,
631
          // we should not replace it with less precise ERAR_BAD_PASSWORD.
632
          if (Cmd->DllError!=ERAR_EOPEN)
633
            Cmd->DllError=ERAR_BAD_PASSWORD;
634
  #endif
635
          ErrHandler.SetErrorCode(RARX_BADPWD);
636
          ExtrFile=false;
524
        }
637
        }
525
#ifdef RARDLL
638
        break;
526
        // If we already have ERAR_EOPEN as result of missing volume,
527
        // we should not replace it with less precise ERAR_BAD_PASSWORD.
528
        if (Cmd->DllError!=ERAR_EOPEN)
529
          Cmd->DllError=ERAR_BAD_PASSWORD;
530
#endif
531
        ErrHandler.SetErrorCode(RARX_BADPWD);
532
        ExtrFile=false;
533
      }
639
      }
534
      break;
535
    }
640
    }
641
    else
642
      DataIO.SetEncryption(false,CRYPT_NONE,NULL,NULL,NULL,0,NULL,NULL);
536
643
537
#ifdef RARDLL
644
#ifdef RARDLL
538
    if (*Cmd->DllDestName!=0)
645
    if (*Cmd->DllDestName!=0)
539
      wcsncpyz(DestFileName,Cmd->DllDestName,ASIZE(DestFileName));
646
      wcsncpyz(DestFileName,Cmd->DllDestName,ASIZE(DestFileName));
540
#endif
647
#endif
541
648
649
    if (ExtrFile && Command!='P' && !Cmd->Test && !Cmd->AbsoluteLinks &&
650
        ConvertSymlinkPaths)
651
      ExtrFile=LinksToDirs(DestFileName,Cmd->ExtrPath,LastCheckedSymlink);
652
542
    File CurFile;
653
    File CurFile;
543
654
544
    bool LinkEntry=Arc.FileHead.RedirType!=FSREDIR_NONE;
655
    bool LinkEntry=Arc.FileHead.RedirType!=FSREDIR_NONE;
545
    if (LinkEntry && Arc.FileHead.RedirType!=FSREDIR_FILECOPY)
656
    if (LinkEntry && (Arc.FileHead.RedirType!=FSREDIR_FILECOPY))
546
    {
657
    {
547
      if (ExtrFile && Command!='P' && !Cmd->Test)
658
      if (ExtrFile && Command!='P' && !Cmd->Test)
548
      {
659
      {
549
        // Overwrite prompt for symbolic and hard links.
660
        // Overwrite prompt for symbolic and hard links and when we move
661
        // a temporary file to the file reference instead of copying it.
550
        bool UserReject=false;
662
        bool UserReject=false;
551
        if (FileExist(DestFileName) && !UserReject)
663
        if (FileExist(DestFileName) && !UserReject)
552
          FileCreate(Cmd,NULL,DestFileName,ASIZE(DestFileName),&UserReject,Arc.FileHead.UnpSize,&Arc.FileHead.mtime);
664
          FileCreate(Cmd,NULL,DestFileName,ASIZE(DestFileName),&UserReject,Arc.FileHead.UnpSize,&Arc.FileHead.mtime);
Lines 667-691 Link Here
667
        if (Type==FSREDIR_HARDLINK || Type==FSREDIR_FILECOPY)
779
        if (Type==FSREDIR_HARDLINK || Type==FSREDIR_FILECOPY)
668
        {
780
        {
669
          wchar RedirName[NM];
781
          wchar RedirName[NM];
670
          ConvertPath(Arc.FileHead.RedirName,RedirName,ASIZE(RedirName));
782
        
783
          // 2022.11.15: Might be needed when unpacking WinRAR 5.0 links with
784
          // Unix RAR. WinRAR 5.0 used \ path separators here, when beginning
785
          // from 5.10 even Windows version uses / internally and converts
786
          // them to \ when reading FHEXTRA_REDIR.
787
          // We must perform this conversion before ConvertPath call,
788
          // so paths mixing different slashes like \dir1/dir2\file are
789
          // processed correctly.
790
          SlashToNative(Arc.FileHead.RedirName,RedirName,ASIZE(RedirName));
671
791
792
          ConvertPath(RedirName,RedirName,ASIZE(RedirName));
793
672
          wchar NameExisting[NM];
794
          wchar NameExisting[NM];
673
          ExtrPrepareName(Arc,RedirName,NameExisting,ASIZE(NameExisting));
795
          ExtrPrepareName(Arc,RedirName,NameExisting,ASIZE(NameExisting));
674
          if (FileCreateMode && *NameExisting!=0) // *NameExisting can be 0 in case of excessive -ap switch.
796
          if (FileCreateMode && *NameExisting!=0) // *NameExisting can be 0 in case of excessive -ap switch.
675
            if (Type==FSREDIR_HARDLINK)
797
            if (Type==FSREDIR_HARDLINK)
676
              LinkSuccess=ExtractHardlink(Cmd,DestFileName,NameExisting,ASIZE(NameExisting));
798
              LinkSuccess=ExtractHardlink(Cmd,DestFileName,NameExisting,ASIZE(NameExisting));
677
            else
799
            else
678
              LinkSuccess=ExtractFileCopy(CurFile,Arc.FileName,DestFileName,NameExisting,ASIZE(NameExisting));
800
              LinkSuccess=ExtractFileCopy(CurFile,Arc.FileName,RedirName,DestFileName,NameExisting,ASIZE(NameExisting),Arc.FileHead.UnpSize);
679
        }
801
        }
680
        else
802
        else
681
          if (Type==FSREDIR_UNIXSYMLINK || Type==FSREDIR_WINSYMLINK || Type==FSREDIR_JUNCTION)
803
          if (Type==FSREDIR_UNIXSYMLINK || Type==FSREDIR_WINSYMLINK || Type==FSREDIR_JUNCTION)
682
          {
804
          {
683
            if (FileCreateMode)
805
            if (FileCreateMode)
684
              LinkSuccess=ExtractSymlink(Cmd,DataIO,Arc,DestFileName);
806
            {
807
              bool UpLink;
808
              LinkSuccess=ExtractSymlink(Cmd,DataIO,Arc,DestFileName,UpLink);
809
              ConvertSymlinkPaths|=LinkSuccess && UpLink;
810
811
              // We do not actually need to reset the cache here if we cache
812
              // only the single last checked path, because at this point
813
              // it will always contain the link own path and link can't
814
              // overwrite its parent folder. But if we ever decide to cache
815
              // several already checked paths, we'll need to reset them here.
816
              // Otherwise if no files were created in one of such paths,
817
              // let's say because of file create error, it might be possible
818
              // to overwrite the path with link and avoid checks. We keep this
819
              // code here as a reminder in case of possible modifications.
820
              LastCheckedSymlink.clear(); // Reset cache for safety reason.
821
            }
685
          }
822
          }
686
          else
823
          else
687
          {
824
          {
688
            uiMsg(UIERROR_UNKNOWNEXTRA,Arc.FileName,DestFileName);
825
            uiMsg(UIERROR_UNKNOWNEXTRA,Arc.FileName,ArcFileName);
689
            LinkSuccess=false;
826
            LinkSuccess=false;
690
          }
827
          }
691
          
828
          
Lines 709-714 Link Here
709
            Unp->Init(Arc.FileHead.WinSize,Arc.FileHead.Solid);
846
            Unp->Init(Arc.FileHead.WinSize,Arc.FileHead.Solid);
710
            Unp->SetDestSize(Arc.FileHead.UnpSize);
847
            Unp->SetDestSize(Arc.FileHead.UnpSize);
711
#ifndef SFX_MODULE
848
#ifndef SFX_MODULE
849
            // RAR 1.3 - 1.5 archives do not set per file solid flag.
712
            if (Arc.Format!=RARFMT50 && Arc.FileHead.UnpVer<=15)
850
            if (Arc.Format!=RARFMT50 && Arc.FileHead.UnpVer<=15)
713
              Unp->DoUnpack(15,FileCount>1 && Arc.Solid);
851
              Unp->DoUnpack(15,FileCount>1 && Arc.Solid);
714
            else
852
            else
Lines 866-887 Link Here
866
}
1004
}
867
1005
868
1006
869
bool CmdExtract::ExtractFileCopy(File &New,wchar *ArcName,wchar *NameNew,wchar *NameExisting,size_t NameExistingSize)
1007
bool CmdExtract::ExtractFileCopy(File &New,wchar *ArcName,const wchar *RedirName,wchar *NameNew,wchar *NameExisting,size_t NameExistingSize,int64 UnpSize)
870
{
1008
{
871
  SlashToNative(NameExisting,NameExisting,NameExistingSize); // Not needed for RAR 5.1+ archives.
872
873
  File Existing;
1009
  File Existing;
874
  if (!Existing.WOpen(NameExisting))
1010
  if (!Existing.Open(NameExisting))
875
  {
1011
  {
876
    uiMsg(UIERROR_FILECOPY,ArcName,NameExisting,NameNew);
1012
    bool OpenFailed=true;
877
    uiMsg(UIERROR_FILECOPYHINT,ArcName);
1013
    // If we couldn't find the existing file, check if match is present
1014
    // in temporary reference sources list.
1015
    for (size_t I=0;I<RefList.Size();I++)
1016
      if (wcscmp(RedirName,RefList[I].RefName)==0 && RefList[I].TmpName!=NULL)
1017
      {
1018
        // If only one reference left targeting to this temporary file,
1019
        // it is faster to move the file instead of copying and deleting it.
1020
        bool RefMove=RefList[I].RefCount-- == 1;
1021
        NameExisting=RefList[I].TmpName;
1022
        if (RefMove) // Only one reference left for this temporary file.
1023
        {
1024
          New.Delete(); // Delete the previously opened destination file.
1025
          // Try moving the file first.
1026
          bool MoveFailed=!RenameFile(NameExisting,NameNew);
1027
          if (MoveFailed)
1028
          {
1029
            // If move failed, re-create the destination and try coping.
1030
            if (!New.WCreate(NameNew,FMF_WRITE|FMF_SHAREREAD))
1031
              return false;
1032
            RefMove=false; // Try copying below.
1033
          }
1034
          else
1035
          {
1036
            // If moved successfully, reopen the destination file and seek to
1037
            // end for SetOpenFileTime() and possible Truncate() calls later.
1038
            if (New.Open(NameNew))
1039
              New.Seek(0,SEEK_END);
1040
            // We already moved the file, so clean the name to not try
1041
            // deleting non-existent temporary file later.
1042
            free(RefList[I].TmpName);
1043
            RefList[I].TmpName=NULL;
1044
            return true;
1045
          }
1046
        }
1047
        if (!RefMove)
1048
          OpenFailed=!Existing.Open(NameExisting);
1049
        break;
1050
      }
1051
1052
    if (OpenFailed)
1053
    {
1054
      ErrHandler.OpenErrorMsg(NameExisting);
1055
      uiMsg(UIERROR_FILECOPY,ArcName,NameExisting,NameNew);
1056
      uiMsg(UIERROR_FILECOPYHINT,ArcName);
878
#ifdef RARDLL
1057
#ifdef RARDLL
879
    Cmd->DllError=ERAR_EREFERENCE;
1058
      Cmd->DllError=ERAR_EREFERENCE;
880
#endif
1059
#endif
881
    return false;
1060
      return false;
1061
    }
882
  }
1062
  }
883
1063
884
  Array<char> Buffer(0x100000);
1064
  Array<byte> Buffer(0x100000);
885
  int64 CopySize=0;
1065
  int64 CopySize=0;
886
1066
887
  while (true)
1067
  while (true)
Lines 890-895 Link Here
890
    int ReadSize=Existing.Read(&Buffer[0],Buffer.Size());
1070
    int ReadSize=Existing.Read(&Buffer[0],Buffer.Size());
891
    if (ReadSize==0)
1071
    if (ReadSize==0)
892
      break;
1072
      break;
1073
    // Update only the current file progress in WinRAR, set the total to 0
1074
    // to keep it as is. It looks better for WinRAR.
1075
    uiExtractProgress(CopySize,UnpSize,0,0);
1076
893
    New.Write(&Buffer[0],ReadSize);
1077
    New.Write(&Buffer[0],ReadSize);
894
    CopySize+=ReadSize;
1078
    CopySize+=ReadSize;
895
  }
1079
  }
Lines 900-905 Link Here
900
1084
901
void CmdExtract::ExtrPrepareName(Archive &Arc,const wchar *ArcFileName,wchar *DestName,size_t DestSize)
1085
void CmdExtract::ExtrPrepareName(Archive &Arc,const wchar *ArcFileName,wchar *DestName,size_t DestSize)
902
{
1086
{
1087
  if (Cmd->Test)
1088
  {
1089
    // Destination name conversion isn't needed for simple archive test.
1090
    // This check also allows to avoid issuing "Attempting to correct...
1091
    // Renaming..." messages in MakeNameCompatible() below for problematic
1092
    // names like aux.txt when testing an archive.
1093
    wcsncpyz(DestName,ArcFileName,DestSize);
1094
    return;
1095
  }
1096
  
903
  wcsncpyz(DestName,Cmd->ExtrPath,DestSize);
1097
  wcsncpyz(DestName,Cmd->ExtrPath,DestSize);
904
1098
905
  if (*Cmd->ExtrPath!=0)
1099
  if (*Cmd->ExtrPath!=0)
Lines 1033-1043 Link Here
1033
1227
1034
1228
1035
#ifndef RARDLL
1229
#ifndef RARDLL
1036
bool CmdExtract::ExtrGetPassword(Archive &Arc,const wchar *ArcFileName)
1230
bool CmdExtract::ExtrGetPassword(Archive &Arc,const wchar *ArcFileName,RarCheckPassword *CheckPwd)
1037
{
1231
{
1038
  if (!Cmd->Password.IsSet())
1232
  if (!Cmd->Password.IsSet())
1039
  {
1233
  {
1040
    if (!uiGetPassword(UIPASSWORD_FILE,ArcFileName,&Cmd->Password)/* || !Cmd->Password.IsSet()*/)
1234
    if (!uiGetPassword(UIPASSWORD_FILE,ArcFileName,&Cmd->Password,CheckPwd)/* || !Cmd->Password.IsSet()*/)
1041
    {
1235
    {
1042
      // Suppress "test is ok" message if user cancelled the password prompt.
1236
      // Suppress "test is ok" message if user cancelled the password prompt.
1043
      uiMsg(UIERROR_INCERRCOUNT);
1237
      uiMsg(UIERROR_INCERRCOUNT);
Lines 1055-1061 Link Here
1055
        case -1:
1249
        case -1:
1056
          ErrHandler.Exit(RARX_USERBREAK);
1250
          ErrHandler.Exit(RARX_USERBREAK);
1057
        case 2:
1251
        case 2:
1058
          if (!uiGetPassword(UIPASSWORD_FILE,ArcFileName,&Cmd->Password))
1252
          if (!uiGetPassword(UIPASSWORD_FILE,ArcFileName,&Cmd->Password,CheckPwd))
1059
            return false;
1253
            return false;
1060
          break;
1254
          break;
1061
        case 3:
1255
        case 3:
Lines 1131-1136 Link Here
1131
        DirExist=FileExist(DestFileName) && IsDir(GetFileAttr(DestFileName));
1325
        DirExist=FileExist(DestFileName) && IsDir(GetFileAttr(DestFileName));
1132
        if (!DirExist)
1326
        if (!DirExist)
1133
        {
1327
        {
1328
          if (!Cmd->AbsoluteLinks && ConvertSymlinkPaths)
1329
            LinksToDirs(DestFileName,Cmd->ExtrPath,LastCheckedSymlink);
1134
          CreatePath(DestFileName,true,Cmd->DisableNames);
1330
          CreatePath(DestFileName,true,Cmd->DisableNames);
1135
          MDCode=MakeDir(DestFileName,!Cmd->IgnoreGeneralAttr,Arc.FileHead.FileAttr);
1331
          MDCode=MakeDir(DestFileName,!Cmd->IgnoreGeneralAttr,Arc.FileHead.FileAttr);
1136
        }
1332
        }
Lines 1212-1217 Link Here
1212
1408
1213
          MakeNameUsable(DestFileName,true);
1409
          MakeNameUsable(DestFileName,true);
1214
1410
1411
          if (!Cmd->AbsoluteLinks && ConvertSymlinkPaths)
1412
            LinksToDirs(DestFileName,Cmd->ExtrPath,LastCheckedSymlink);
1215
          CreatePath(DestFileName,true,Cmd->DisableNames);
1413
          CreatePath(DestFileName,true,Cmd->DisableNames);
1216
          if (FileCreate(Cmd,&CurFile,DestFileName,ASIZE(DestFileName),&UserReject,Arc.FileHead.UnpSize,&Arc.FileHead.mtime,true))
1414
          if (FileCreate(Cmd,&CurFile,DestFileName,ASIZE(DestFileName),&UserReject,Arc.FileHead.UnpSize,&Arc.FileHead.mtime,true))
1217
          {
1415
          {
Lines 1258-1288 Link Here
1258
1456
1259
1457
1260
#ifndef SFX_MODULE
1458
#ifndef SFX_MODULE
1261
// To speed up solid volumes extraction, try to find a non-first start volume,
1459
// Find non-matched reference sources in solid and non-solid archives.
1262
// which still allows to unpack all files. It is possible for independent
1460
// Detect the optimal start position for semi-solid archives
1263
// solid volumes with solid statistics reset in the beginning.
1461
// and optimal start volume for independent solid volumes.
1264
bool CmdExtract::DetectStartVolume(const wchar *VolName,bool NewNumbering)
1462
// 
1463
// Alternatively we could collect references while extracting an archive
1464
// and perform the second extraction pass for references only.
1465
// But it would be slower for solid archives than scaning headers
1466
// in first pass and extracting everything in second, as implemented now.
1467
// 
1468
void CmdExtract::AnalyzeArchive(const wchar *ArcName,bool Volume,bool NewNumbering)
1265
{
1469
{
1470
  FreeAnalyzeData(); // If processing non-first archive in multiple archives set.
1471
1266
  wchar *ArgName=Cmd->FileArgs.GetString();
1472
  wchar *ArgName=Cmd->FileArgs.GetString();
1267
  Cmd->FileArgs.Rewind();
1473
  Cmd->FileArgs.Rewind();
1268
  if (ArgName!=NULL && (wcscmp(ArgName,L"*")==0 || wcscmp(ArgName,L"*.*")==0))
1474
  if (ArgName!=NULL && (wcscmp(ArgName,L"*")==0 || wcscmp(ArgName,L"*.*")==0))
1269
    return false; // No need to check further for * and *.* masks.
1475
    return; // No need to check further for * and *.* masks.
1270
1476
1271
  wchar StartName[NM];
1272
  *StartName=0;
1273
  
1274
  // Start search from first volume if all volumes preceding current are available.
1477
  // Start search from first volume if all volumes preceding current are available.
1275
  wchar NextName[NM];
1478
  wchar NextName[NM];
1276
  GetFirstVolIfFullSet(VolName,NewNumbering,NextName,ASIZE(NextName));
1479
  if (Volume)
1480
    GetFirstVolIfFullSet(ArcName,NewNumbering,NextName,ASIZE(NextName));
1481
  else
1482
    wcsncpyz(NextName,ArcName,ASIZE(NextName));
1483
  
1484
  bool MatchFound=false;
1485
  bool PrevMatched=false;
1486
  bool OpenNext=false;
1277
1487
1278
  bool Matched=false;
1488
  bool FirstVolume=true;
1279
  while (!Matched)
1489
  
1490
  // We shall set FirstFile once for all volumes and not for each volume.
1491
  // So we do not reuse the outdated Analyze->StartPos from previous volume
1492
  // if extracted file resides completely in the beginning of current one.
1493
  bool FirstFile=true;
1494
1495
  while (true)
1280
  {
1496
  {
1281
    Archive Arc(Cmd);
1497
    Archive Arc(Cmd);
1282
    if (!Arc.Open(NextName) || !Arc.IsArchive(false) || !Arc.Volume)
1498
    if (!Arc.Open(NextName) || !Arc.IsArchive(false))
1499
    {
1500
      if (OpenNext)
1501
      {
1502
        // If we couldn't open trailing volumes, we can't set early exit
1503
        // parameters. It is possible that some volume are on removable media
1504
        // and will be provided by user when extracting.
1505
        *Analyze->EndName=0;
1506
        Analyze->EndPos=0;
1507
      }
1283
      break;
1508
      break;
1509
    }
1284
1510
1285
    bool OpenNext=false;
1511
    OpenNext=false;
1286
    while (Arc.ReadHeader()>0)
1512
    while (Arc.ReadHeader()>0)
1287
    {
1513
    {
1288
      Wait();
1514
      Wait();
Lines 1295-1311 Link Here
1295
      }
1521
      }
1296
      if (HeaderType==HEAD_FILE)
1522
      if (HeaderType==HEAD_FILE)
1297
      {
1523
      {
1524
        if ((Arc.Format==RARFMT14 || Arc.Format==RARFMT15) && Arc.FileHead.UnpVer<=15)
1525
        {
1526
          // RAR versions earlier than 2.0 do not set per file solid flag.
1527
          // They have only the global archive solid flag, so we can't
1528
          // reliably analyze them here.
1529
          OpenNext=false;
1530
          break;
1531
        }
1532
1298
        if (!Arc.FileHead.SplitBefore)
1533
        if (!Arc.FileHead.SplitBefore)
1299
        {
1534
        {
1300
          if (!Arc.FileHead.Solid) // Can start extraction from here.
1535
          if (!MatchFound && !Arc.FileHead.Solid) // Can start extraction from here.
1301
            wcsncpyz(StartName,NextName,ASIZE(StartName));
1536
          {
1537
            // We would gain nothing and unnecessarily complicate extraction
1538
            // if we set StartName for first volume or StartPos for first
1539
            // archived file.
1540
            if (!FirstVolume)
1541
              wcsncpyz(Analyze->StartName,NextName,ASIZE(Analyze->StartName));
1302
1542
1543
            // We shall set FirstFile once for all volumes for this code
1544
            // to work properly. Alternatively we could append 
1545
            // "|| Analyze->StartPos!=0" to the condition, so we do not reuse
1546
            // the outdated Analyze->StartPos value from previous volume.
1547
            if (!FirstFile)
1548
              Analyze->StartPos=Arc.CurBlockPos;
1549
          }
1550
1303
          if (Cmd->IsProcessFile(Arc.FileHead,NULL,MATCH_WILDSUBPATH,0,NULL,0)!=0)
1551
          if (Cmd->IsProcessFile(Arc.FileHead,NULL,MATCH_WILDSUBPATH,0,NULL,0)!=0)
1304
          {
1552
          {
1305
            Matched=true; // First matched file found, must stop further scan.
1553
            MatchFound = true;
1306
            break;
1554
            PrevMatched = true;
1555
1556
            // Reset the previously set early exit position, if any, because
1557
            // we found a new matched file.
1558
            Analyze->EndPos=0;
1559
1560
            // Matched file reference pointing at maybe non-matched source file.
1561
            // Even though we know RedirName, we can't check if source file
1562
            // is certainly non-matched, because it can be filtered out by
1563
            // date or attributes, which we do not know here.
1564
            if (Arc.FileHead.RedirType==FSREDIR_FILECOPY)
1565
            {
1566
              bool AlreadyAdded=false;
1567
              for (size_t I=0;I<RefList.Size();I++)
1568
                if (wcscmp(Arc.FileHead.RedirName,RefList[I].RefName)==0)
1569
                {
1570
                  // Increment the reference count if we added such reference
1571
                  // source earlier.
1572
                  RefList[I].RefCount++;
1573
                  AlreadyAdded=true;
1574
                  break;
1575
                }
1576
1577
              // Limit the maximum size of reference sources list to some
1578
              // sensible value to prevent the excessive memory allocation.
1579
              size_t MaxListSize=1000000;
1580
1581
              if (!AlreadyAdded && RefList.Size()<MaxListSize)
1582
              {
1583
                ExtractRef Ref={0};
1584
                Ref.RefName=wcsdup(Arc.FileHead.RedirName);
1585
                Ref.RefCount=1;
1586
                RefList.Push(Ref);
1587
              }
1588
            }
1307
          }
1589
          }
1590
          else
1591
          {
1592
            if (PrevMatched) // First non-matched item after matched.
1593
            {
1594
              // We would perform the unnecessarily string comparison
1595
              // when extracting if we set this value for first volume
1596
              // or non-volume archive.
1597
              if (!FirstVolume)
1598
                wcsncpyz(Analyze->EndName,NextName,ASIZE(Analyze->EndName));
1599
              Analyze->EndPos=Arc.CurBlockPos;
1600
            }
1601
            PrevMatched=false;
1602
          }
1308
        }
1603
        }
1604
1605
        FirstFile=false;
1309
        if (Arc.FileHead.SplitAfter)
1606
        if (Arc.FileHead.SplitAfter)
1310
        {
1607
        {
1311
          OpenNext=true; // Allow open next volume.
1608
          OpenNext=true; // Allow open next volume.
Lines 1316-1331 Link Here
1316
    }
1613
    }
1317
    Arc.Close();
1614
    Arc.Close();
1318
1615
1319
    if (!OpenNext)
1616
    if (Volume && OpenNext)
1320
      break;
1617
    {
1618
      NextVolumeName(NextName,ASIZE(NextName),!Arc.NewNumbering);
1619
      FirstVolume=false;
1321
1620
1322
    NextVolumeName(NextName,ASIZE(NextName),!Arc.NewNumbering);
1621
      // Needed for multivolume archives. Added in case some 'break'
1622
      // will quit early from loop above, so we do not set it in the loop.
1623
      // Now it can happen for hypothetical archive without file records
1624
      // and with HEAD_ENDARC record.
1625
      FirstFile=false;
1626
    }
1627
    else
1628
      break;
1323
  }
1629
  }
1324
  bool NewStartFound=wcscmp(VolName,StartName)!=0;
1630
1325
  if (NewStartFound) // Found a new volume to start extraction.
1631
  // If file references are present, we can't reliably skip in semi-solid
1326
    wcsncpyz(ArcName,StartName,ASIZE(ArcName));
1632
  // archives, because reference source can be present in skipped data.
1327
  
1633
  if (RefList.Size()!=0)
1328
  return NewStartFound;
1634
    memset(Analyze,0,sizeof(*Analyze));
1329
}
1635
}
1330
#endif
1636
#endif
1331
1637
(-)unrar-6.1.7/extract.hpp (-3 / +31 lines)
Lines 6-18 Link Here
6
class CmdExtract
6
class CmdExtract
7
{
7
{
8
  private:
8
  private:
9
    struct ExtractRef
10
    {
11
      wchar *RefName;
12
      wchar *TmpName;
13
      uint64 RefCount;
14
    };
15
    Array<ExtractRef> RefList;
16
17
    struct AnalyzeData
18
    {
19
      wchar StartName[NM];
20
      uint64 StartPos;
21
      wchar EndName[NM];
22
      uint64 EndPos;
23
    } *Analyze;
24
25
    bool ArcAnalyzed;
26
27
    void FreeAnalyzeData();
9
    EXTRACT_ARC_CODE ExtractArchive();
28
    EXTRACT_ARC_CODE ExtractArchive();
10
    bool ExtractFileCopy(File &New,wchar *ArcName,wchar *NameNew,wchar *NameExisting,size_t NameExistingSize);
29
    bool ExtractFileCopy(File &New,wchar *ArcName,const wchar *RedirName,wchar *NameNew,wchar *NameExisting,size_t NameExistingSize,int64 UnpSize);
11
    void ExtrPrepareName(Archive &Arc,const wchar *ArcFileName,wchar *DestName,size_t DestSize);
30
    void ExtrPrepareName(Archive &Arc,const wchar *ArcFileName,wchar *DestName,size_t DestSize);
12
#ifdef RARDLL
31
#ifdef RARDLL
13
    bool ExtrDllGetPassword();
32
    bool ExtrDllGetPassword();
14
#else
33
#else
15
    bool ExtrGetPassword(Archive &Arc,const wchar *ArcFileName);
34
    bool ExtrGetPassword(Archive &Arc,const wchar *ArcFileName,RarCheckPassword *CheckPwd);
16
#endif
35
#endif
17
#if defined(_WIN_ALL) && !defined(SFX_MODULE)
36
#if defined(_WIN_ALL) && !defined(SFX_MODULE)
18
    void ConvertDosPassword(Archive &Arc,SecPassword &DestPwd);
37
    void ConvertDosPassword(Archive &Arc,SecPassword &DestPwd);
Lines 21-27 Link Here
21
    bool ExtrCreateFile(Archive &Arc,File &CurFile);
40
    bool ExtrCreateFile(Archive &Arc,File &CurFile);
22
    bool CheckUnpVer(Archive &Arc,const wchar *ArcFileName);
41
    bool CheckUnpVer(Archive &Arc,const wchar *ArcFileName);
23
#ifndef SFX_MODULE
42
#ifndef SFX_MODULE
24
    bool DetectStartVolume(const wchar *VolName,bool NewNumbering);
43
    void AnalyzeArchive(const wchar *ArcName,bool Volume,bool NewNumbering);
25
    void GetFirstVolIfFullSet(const wchar *SrcName,bool NewNumbering,wchar *DestName,size_t DestSize);
44
    void GetFirstVolIfFullSet(const wchar *SrcName,bool NewNumbering,wchar *DestName,size_t DestSize);
26
#endif
45
#endif
27
46
Lines 52-57 Link Here
52
    bool PrevProcessed; // If previous file was successfully extracted or tested.
71
    bool PrevProcessed; // If previous file was successfully extracted or tested.
53
    wchar DestFileName[NM];
72
    wchar DestFileName[NM];
54
    bool PasswordCancelled;
73
    bool PasswordCancelled;
74
75
    // In Windows it is set to true if at least one symlink with ".."
76
    // in target was extracted.
77
    bool ConvertSymlinkPaths;
78
79
    // Last path checked for symlinks. We use it to improve the performance,
80
    // so we do not check recently checked folders again.
81
    std::wstring LastCheckedSymlink;
82
55
#if defined(_WIN_ALL) && !defined(SFX_MODULE) && !defined(SILENT)
83
#if defined(_WIN_ALL) && !defined(SFX_MODULE) && !defined(SILENT)
56
    bool Fat32,NotFat32;
84
    bool Fat32,NotFat32;
57
#endif
85
#endif
(-)unrar-6.1.7/filcreat.cpp (-1 / +1 lines)
Lines 3-9 Link Here
3
// If NewFile==NULL, we delete created file after user confirmation.
3
// If NewFile==NULL, we delete created file after user confirmation.
4
// It is useful if we need to overwrite an existing folder or file,
4
// It is useful if we need to overwrite an existing folder or file,
5
// but need user confirmation for that.
5
// but need user confirmation for that.
6
bool FileCreate(RAROptions *Cmd,File *NewFile,wchar *Name,size_t MaxNameSize,
6
bool FileCreate(CommandData *Cmd,File *NewFile,wchar *Name,size_t MaxNameSize,
7
                bool *UserReject,int64 FileSize,RarTime *FileTime,bool WriteOnly)
7
                bool *UserReject,int64 FileSize,RarTime *FileTime,bool WriteOnly)
8
{
8
{
9
  if (UserReject!=NULL)
9
  if (UserReject!=NULL)
(-)unrar-6.1.7/filcreat.hpp (-1 / +1 lines)
Lines 1-7 Link Here
1
#ifndef _RAR_FILECREATE_
1
#ifndef _RAR_FILECREATE_
2
#define _RAR_FILECREATE_
2
#define _RAR_FILECREATE_
3
3
4
bool FileCreate(RAROptions *Cmd,File *NewFile,wchar *Name,size_t MaxNameSize,
4
bool FileCreate(CommandData *Cmd,File *NewFile,wchar *Name,size_t MaxNameSize,
5
                bool *UserReject,int64 FileSize=INT64NDF,
5
                bool *UserReject,int64 FileSize=INT64NDF,
6
                RarTime *FileTime=NULL,bool WriteOnly=false);
6
                RarTime *FileTime=NULL,bool WriteOnly=false);
7
7
(-)unrar-6.1.7/file.cpp (-19 / +48 lines)
Lines 522-550 Link Here
522
{
522
{
523
  if (hFile==FILE_BAD_HANDLE)
523
  if (hFile==FILE_BAD_HANDLE)
524
    return true;
524
    return true;
525
  if (!IsSeekable())
525
  if (!IsSeekable()) // To extract archives from stdin with -si.
526
  {
526
  {
527
    if (Method==SEEK_CUR)
527
    // We tried to dynamically allocate 32 KB buffer here, but it improved
528
    // speed in Windows 10 by mere ~1.5%.
529
    byte Buf[4096];
530
    if (Method==SEEK_CUR || Method==SEEK_SET && Offset>=CurFilePos)
528
    {
531
    {
529
      Offset+=CurFilePos;
532
      uint64 SkipSize=Method==SEEK_CUR ? Offset:Offset-CurFilePos;
530
      Method=SEEK_SET;
533
      while (SkipSize>0) // Reading to emulate seek forward.
531
    }
532
    if (Method==SEEK_SET && Offset>=CurFilePos) // Reading for seek forward.
533
    {
534
      uint64 SkipSize=Offset-CurFilePos;
535
      while (SkipSize>0)
536
      {
534
      {
537
        byte Buf[4096];
538
        int ReadSize=Read(Buf,(size_t)Min(SkipSize,ASIZE(Buf)));
535
        int ReadSize=Read(Buf,(size_t)Min(SkipSize,ASIZE(Buf)));
539
        if (ReadSize<=0)
536
        if (ReadSize<=0)
540
          return false;
537
          return false;
541
        SkipSize-=ReadSize;
538
        SkipSize-=ReadSize;
539
        CurFilePos+=ReadSize;
542
      }
540
      }
543
      CurFilePos=Offset;
544
      return true;
541
      return true;
545
    }
542
    }
543
    // May need it in FileLength() in Archive::UnexpEndArcMsg() when unpacking
544
    // RAR 4.x archives without the end of archive block created with -en.
545
    if (Method==SEEK_END)
546
    {
547
      int ReadSize;
548
      while ((ReadSize=Read(Buf,ASIZE(Buf)))>0)
549
        CurFilePos+=ReadSize;
550
      return true;
551
    }
546
552
547
    return false; // Backward or end of file seek on unseekable file.
553
    return false; // Backward seek on unseekable file.
548
  }
554
  }
549
  if (Offset<0 && Method!=SEEK_SET)
555
  if (Offset<0 && Method!=SEEK_SET)
550
  {
556
  {
Lines 732-748 Link Here
732
}
738
}
733
739
734
740
735
void File::GetOpenFileTime(RarTime *ft)
741
#ifdef _UNIX
742
void File::StatToRarTime(struct stat &st,RarTime *ftm,RarTime *ftc,RarTime *fta)
736
{
743
{
737
#ifdef _WIN_ALL
744
#ifdef UNIX_TIME_NS
738
  FILETIME FileTime;
745
#if defined(_APPLE)
739
  GetFileTime(hFile,NULL,NULL,&FileTime);
746
  if (ftm!=NULL) ftm->SetUnixNS(st.st_mtimespec.tv_sec*(uint64)1000000000+st.st_mtimespec.tv_nsec);
740
  ft->SetWinFT(&FileTime);
747
  if (ftc!=NULL) ftc->SetUnixNS(st.st_ctimespec.tv_sec*(uint64)1000000000+st.st_ctimespec.tv_nsec);
748
  if (fta!=NULL) fta->SetUnixNS(st.st_atimespec.tv_sec*(uint64)1000000000+st.st_atimespec.tv_nsec);
749
#else
750
  if (ftm!=NULL) ftm->SetUnixNS(st.st_mtim.tv_sec*(uint64)1000000000+st.st_mtim.tv_nsec);
751
  if (ftc!=NULL) ftc->SetUnixNS(st.st_ctim.tv_sec*(uint64)1000000000+st.st_ctim.tv_nsec);
752
  if (fta!=NULL) fta->SetUnixNS(st.st_atim.tv_sec*(uint64)1000000000+st.st_atim.tv_nsec);
741
#endif
753
#endif
742
#if defined(_UNIX) || defined(_EMX)
754
#else
755
  if (ftm!=NULL) ftm->SetUnix(st.st_mtime);
756
  if (ftc!=NULL) ftc->SetUnix(st.st_ctime);
757
  if (fta!=NULL) fta->SetUnix(st.st_atime);
758
#endif
759
}
760
#endif
761
762
763
void File::GetOpenFileTime(RarTime *ftm,RarTime *ftc,RarTime *fta)
764
{
765
#ifdef _WIN_ALL
766
  FILETIME ctime,atime,mtime;
767
  GetFileTime(hFile,&ctime,&atime,&mtime);
768
  if (ftm!=NULL) ftm->SetWinFT(&mtime);
769
  if (ftc!=NULL) ftc->SetWinFT(&ctime);
770
  if (fta!=NULL) fta->SetWinFT(&atime);
771
#elif defined(_UNIX)
743
  struct stat st;
772
  struct stat st;
744
  fstat(GetFD(),&st);
773
  fstat(GetFD(),&st);
745
  ft->SetUnix(st.st_mtime);
774
  StatToRarTime(st,ftm,ftc,fta);
746
#endif
775
#endif
747
}
776
}
748
777
(-)unrar-6.1.7/file.hpp (-3 / +7 lines)
Lines 14-21 Link Here
14
  #define FILE_BAD_HANDLE NULL
14
  #define FILE_BAD_HANDLE NULL
15
#endif
15
#endif
16
16
17
class RAROptions;
18
19
enum FILE_HANDLETYPE {FILE_HANDLENORMAL,FILE_HANDLESTD};
17
enum FILE_HANDLETYPE {FILE_HANDLENORMAL,FILE_HANDLESTD};
20
18
21
enum FILE_ERRORTYPE {FILE_SUCCESS,FILE_NOTFOUND,FILE_READERROR};
19
enum FILE_ERRORTYPE {FILE_SUCCESS,FILE_NOTFOUND,FILE_READERROR};
Lines 88-93 Link Here
88
    wchar FileName[NM];
86
    wchar FileName[NM];
89
87
90
    FILE_ERRORTYPE ErrorType;
88
    FILE_ERRORTYPE ErrorType;
89
90
    byte *SeekBuf; // To read instead of seek for stdin files.
91
    static const size_t SeekBufSize=0x10000;
91
  public:
92
  public:
92
    File();
93
    File();
93
    virtual ~File();
94
    virtual ~File();
Lines 118-124 Link Here
118
    void SetOpenFileTime(RarTime *ftm,RarTime *ftc=NULL,RarTime *fta=NULL);
119
    void SetOpenFileTime(RarTime *ftm,RarTime *ftc=NULL,RarTime *fta=NULL);
119
    void SetCloseFileTime(RarTime *ftm,RarTime *fta=NULL);
120
    void SetCloseFileTime(RarTime *ftm,RarTime *fta=NULL);
120
    static void SetCloseFileTimeByName(const wchar *Name,RarTime *ftm,RarTime *fta);
121
    static void SetCloseFileTimeByName(const wchar *Name,RarTime *ftm,RarTime *fta);
121
    void GetOpenFileTime(RarTime *ft);
122
#ifdef _UNIX
123
    static void StatToRarTime(struct stat &st,RarTime *ftm,RarTime *ftc,RarTime *fta);
124
#endif
125
    void GetOpenFileTime(RarTime *ftm,RarTime *ftc=NULL,RarTime *fta=NULL);
122
    virtual bool IsOpened() {return hFile!=FILE_BAD_HANDLE;} // 'virtual' for MultiFile class.
126
    virtual bool IsOpened() {return hFile!=FILE_BAD_HANDLE;} // 'virtual' for MultiFile class.
123
    int64 FileLength();
127
    int64 FileLength();
124
    void SetHandleType(FILE_HANDLETYPE Type) {HandleType=Type;}
128
    void SetHandleType(FILE_HANDLETYPE Type) {HandleType=Type;}
(-)unrar-6.1.7/filefn.cpp (-3 / +1 lines)
Lines 320-326 Link Here
320
}
320
}
321
321
322
322
323
#if 0
324
wchar *MkTemp(wchar *Name,size_t MaxSize)
323
wchar *MkTemp(wchar *Name,size_t MaxSize)
325
{
324
{
326
  size_t Length=wcslen(Name);
325
  size_t Length=wcslen(Name);
Lines 354-360 Link Here
354
  }
353
  }
355
  return Name;
354
  return Name;
356
}
355
}
357
#endif
358
356
359
357
360
#if !defined(SFX_MODULE)
358
#if !defined(SFX_MODULE)
Lines 399-405 Link Here
399
      if ((Flags & CALCFSUM_SHOWPROGRESS)!=0)
397
      if ((Flags & CALCFSUM_SHOWPROGRESS)!=0)
400
      {
398
      {
401
        // Update only the current file progress in WinRAR, set the total to 0
399
        // Update only the current file progress in WinRAR, set the total to 0
402
        // to keep it as is. It looks better for WinRAR,
400
        // to keep it as is. It looks better for WinRAR.
403
        uiExtractProgress(TotalRead,FileLength,0,0);
401
        uiExtractProgress(TotalRead,FileLength,0,0);
404
      }
402
      }
405
      else
403
      else
(-)unrar-6.1.7/filefn.hpp (-2 lines)
Lines 27-35 Link Here
27
void PrepareToDelete(const wchar *Name);
27
void PrepareToDelete(const wchar *Name);
28
uint GetFileAttr(const wchar *Name);
28
uint GetFileAttr(const wchar *Name);
29
bool SetFileAttr(const wchar *Name,uint Attr);
29
bool SetFileAttr(const wchar *Name,uint Attr);
30
#if 0
31
wchar* MkTemp(wchar *Name,size_t MaxSize);
30
wchar* MkTemp(wchar *Name,size_t MaxSize);
32
#endif
33
31
34
enum CALCFSUM_FLAGS {CALCFSUM_SHOWTEXT=1,CALCFSUM_SHOWPERCENT=2,CALCFSUM_SHOWPROGRESS=4,CALCFSUM_CURPOS=8};
32
enum CALCFSUM_FLAGS {CALCFSUM_SHOWTEXT=1,CALCFSUM_SHOWPERCENT=2,CALCFSUM_SHOWPROGRESS=4,CALCFSUM_CURPOS=8};
35
33
(-)unrar-6.1.7/find.cpp (-16 / +2 lines)
Lines 117-123 Link Here
117
  if (hFind==INVALID_HANDLE_VALUE)
117
  if (hFind==INVALID_HANDLE_VALUE)
118
    return false;
118
    return false;
119
  FindClose(hFind);
119
  FindClose(hFind);
120
#else
120
#elif defined(_UNIX)
121
  char FindMaskA[NM];
121
  char FindMaskA[NM];
122
  WideToChar(FindMask,FindMaskA,ASIZE(FindMaskA));
122
  WideToChar(FindMask,FindMaskA,ASIZE(FindMaskA));
123
123
Lines 143-163 Link Here
143
  fd->FileAttr=st.st_mode;
143
  fd->FileAttr=st.st_mode;
144
  fd->Size=st.st_size;
144
  fd->Size=st.st_size;
145
145
146
#ifdef UNIX_TIME_NS
146
  File::StatToRarTime(st,&fd->mtime,&fd->ctime,&fd->atime);
147
#if defined(_APPLE)
148
  fd->mtime.SetUnixNS(st.st_mtimespec.tv_sec*(uint64)1000000000+st.st_mtimespec.tv_nsec);
149
  fd->atime.SetUnixNS(st.st_atimespec.tv_sec*(uint64)1000000000+st.st_atimespec.tv_nsec);
150
  fd->ctime.SetUnixNS(st.st_ctimespec.tv_sec*(uint64)1000000000+st.st_ctimespec.tv_nsec);
151
#else
152
  fd->mtime.SetUnixNS(st.st_mtim.tv_sec*(uint64)1000000000+st.st_mtim.tv_nsec);
153
  fd->atime.SetUnixNS(st.st_atim.tv_sec*(uint64)1000000000+st.st_atim.tv_nsec);
154
  fd->ctime.SetUnixNS(st.st_ctim.tv_sec*(uint64)1000000000+st.st_ctim.tv_nsec);
155
#endif
156
#else
157
  fd->mtime.SetUnix(st.st_mtime);
158
  fd->atime.SetUnix(st.st_atime);
159
  fd->ctime.SetUnix(st.st_ctime);
160
#endif
161
147
162
  wcsncpyz(fd->Name,FindMask,ASIZE(fd->Name));
148
  wcsncpyz(fd->Name,FindMask,ASIZE(fd->Name));
163
#endif
149
#endif
(-)unrar-6.1.7/getbits.cpp (-1 / +1 lines)
Lines 5-11 Link Here
5
  ExternalBuffer=false;
5
  ExternalBuffer=false;
6
  if (AllocBuffer)
6
  if (AllocBuffer)
7
  {
7
  {
8
    // getbits32 attempts to read data from InAddr, ... InAddr+3 positions.
8
    // getbits*() attempt to read data from InAddr, ... InAddr+3 positions.
9
    // So let's allocate 3 additional bytes for situation, when we need to
9
    // So let's allocate 3 additional bytes for situation, when we need to
10
    // read only 1 byte from the last position of buffer and avoid a crash
10
    // read only 1 byte from the last position of buffer and avoid a crash
11
    // from access to next 3 bytes, which contents we do not need.
11
    // from access to next 3 bytes, which contents we do not need.
(-)unrar-6.1.7/getbits.hpp (-1 / +13 lines)
Lines 28-53 Link Here
28
      InAddr+=Bits>>3;
28
      InAddr+=Bits>>3;
29
      InBit=Bits&7;
29
      InBit=Bits&7;
30
    }
30
    }
31
    
31
32
    // Return 16 bits from current position in the buffer.
32
    // Return 16 bits from current position in the buffer.
33
    // Bit at (InAddr,InBit) has the highest position in returning data.
33
    // Bit at (InAddr,InBit) has the highest position in returning data.
34
    uint getbits()
34
    uint getbits()
35
    {
35
    {
36
#if defined(LITTLE_ENDIAN) && defined(ALLOW_MISALIGNED)
37
      uint32 BitField=*(uint32*)(InBuf+InAddr);
38
      BitField=ByteSwap32(BitField);
39
      BitField >>= (16-InBit);
40
#else
36
      uint BitField=(uint)InBuf[InAddr] << 16;
41
      uint BitField=(uint)InBuf[InAddr] << 16;
37
      BitField|=(uint)InBuf[InAddr+1] << 8;
42
      BitField|=(uint)InBuf[InAddr+1] << 8;
38
      BitField|=(uint)InBuf[InAddr+2];
43
      BitField|=(uint)InBuf[InAddr+2];
39
      BitField >>= (8-InBit);
44
      BitField >>= (8-InBit);
45
#endif
40
      return BitField & 0xffff;
46
      return BitField & 0xffff;
41
    }
47
    }
42
48
49
43
    // Return 32 bits from current position in the buffer.
50
    // Return 32 bits from current position in the buffer.
44
    // Bit at (InAddr,InBit) has the highest position in returning data.
51
    // Bit at (InAddr,InBit) has the highest position in returning data.
45
    uint getbits32()
52
    uint getbits32()
46
    {
53
    {
54
#if defined(LITTLE_ENDIAN) && defined(ALLOW_MISALIGNED)
55
      uint32 BitField=*(uint32*)(InBuf+InAddr);
56
      BitField=ByteSwap32(BitField);
57
#else
47
      uint BitField=(uint)InBuf[InAddr] << 24;
58
      uint BitField=(uint)InBuf[InAddr] << 24;
48
      BitField|=(uint)InBuf[InAddr+1] << 16;
59
      BitField|=(uint)InBuf[InAddr+1] << 16;
49
      BitField|=(uint)InBuf[InAddr+2] << 8;
60
      BitField|=(uint)InBuf[InAddr+2] << 8;
50
      BitField|=(uint)InBuf[InAddr+3];
61
      BitField|=(uint)InBuf[InAddr+3];
62
#endif
51
      BitField <<= InBit;
63
      BitField <<= InBit;
52
      BitField|=(uint)InBuf[InAddr+4] >> (8-InBit);
64
      BitField|=(uint)InBuf[InAddr+4] >> (8-InBit);
53
      return BitField & 0xffffffff;
65
      return BitField & 0xffffffff;
(-)unrar-6.1.7/hardlinks.cpp (-2 lines)
Lines 1-7 Link Here
1
bool ExtractHardlink(CommandData *Cmd,wchar *NameNew,wchar *NameExisting,size_t NameExistingSize)
1
bool ExtractHardlink(CommandData *Cmd,wchar *NameNew,wchar *NameExisting,size_t NameExistingSize)
2
{
2
{
3
  SlashToNative(NameExisting,NameExisting,NameExistingSize); // Not needed for RAR 5.1+ archives.
4
5
  if (!FileExist(NameExisting))
3
  if (!FileExist(NameExisting))
6
  {
4
  {
7
    uiMsg(UIERROR_HLINKCREATE,NameNew);
5
    uiMsg(UIERROR_HLINKCREATE,NameNew);
(-)unrar-6.1.7/hash.cpp (-1 / +1 lines)
Lines 26-32 Link Here
26
}
26
}
27
27
28
28
29
bool HashValue::operator == (const HashValue &cmp)
29
bool HashValue::operator == (const HashValue &cmp) const
30
{
30
{
31
  if (Type==HASH_NONE || cmp.Type==HASH_NONE)
31
  if (Type==HASH_NONE || cmp.Type==HASH_NONE)
32
    return true;
32
    return true;
(-)unrar-6.1.7/hash.hpp (-2 / +8 lines)
Lines 6-13 Link Here
6
struct HashValue
6
struct HashValue
7
{
7
{
8
  void Init(HASH_TYPE Type);
8
  void Init(HASH_TYPE Type);
9
  bool operator == (const HashValue &cmp);
9
10
  bool operator != (const HashValue &cmp) {return !(*this==cmp);}
10
  // Use the const member, so types on both sides of "==" match.
11
  // Otherwise clang -std=c++20 issues "ambiguity is between a regular call
12
  // to this operator and a call with the argument order reversed" warning.
13
  bool operator == (const HashValue &cmp) const;
14
15
  // Not actually used now. Const member for same reason as operator == above.
16
  bool operator != (const HashValue &cmp) const {return !(*this==cmp);}
11
17
12
  HASH_TYPE Type;
18
  HASH_TYPE Type;
13
  union
19
  union
(-)unrar-6.1.7/headers.cpp (-9 / +1 lines)
Lines 49-61 Link Here
49
49
50
void MainHeader::Reset()
50
void MainHeader::Reset()
51
{
51
{
52
  HighPosAV=0;
52
  *this={};
53
  PosAV=0;
54
  CommentInHeader=false;
55
  PackComment=false;
56
  Locator=false;
57
  QOpenOffset=0;
58
  QOpenMaxSize=0;
59
  RROffset=0;
60
  RRMaxSize=0;
61
}
53
}
(-)unrar-6.1.7/headers.hpp (-7 / +11 lines)
Lines 6-12 Link Here
6
#define  SIZEOF_MAINHEAD3       13 // Size of RAR 4.x main archive header.
6
#define  SIZEOF_MAINHEAD3       13 // Size of RAR 4.x main archive header.
7
#define  SIZEOF_FILEHEAD14      21 // Size of RAR 1.4 file header.
7
#define  SIZEOF_FILEHEAD14      21 // Size of RAR 1.4 file header.
8
#define  SIZEOF_FILEHEAD3       32 // Size of RAR 3.0 file header.
8
#define  SIZEOF_FILEHEAD3       32 // Size of RAR 3.0 file header.
9
#define  SIZEOF_SHORTBLOCKHEAD   7
9
#define  SIZEOF_SHORTBLOCKHEAD   7 // Smallest RAR 4.x block size.
10
#define  SIZEOF_LONGBLOCKHEAD   11
10
#define  SIZEOF_LONGBLOCKHEAD   11
11
#define  SIZEOF_SUBBLOCKHEAD    14
11
#define  SIZEOF_SUBBLOCKHEAD    14
12
#define  SIZEOF_COMMHEAD        13
12
#define  SIZEOF_COMMHEAD        13
Lines 162-173 Link Here
162
  ushort HighPosAV;
162
  ushort HighPosAV;
163
  uint PosAV;
163
  uint PosAV;
164
  bool CommentInHeader;
164
  bool CommentInHeader;
165
  bool PackComment; // For RAR 1.4 archive format only.
165
  bool PackComment;     // For RAR 1.4 archive format only.
166
  bool Locator;
166
  bool Locator;
167
  uint64 QOpenOffset;  // Offset of quick list record.
167
  uint64 QOpenOffset;   // Offset of quick list record.
168
  uint64 QOpenMaxSize; // Maximum size of QOpen offset in locator extra field.
168
  uint64 QOpenMaxSize;  // Maximum size of QOpen offset in locator extra field.
169
  uint64 RROffset;     // Offset of recovery record.
169
  uint64 RROffset;      // Offset of recovery record.
170
  uint64 RRMaxSize;    // Maximum size of RR offset in locator extra field.
170
  uint64 RRMaxSize;     // Maximum size of RR offset in locator extra field.
171
  size_t MetaNameMaxSize; // Maximum size of archive name in metadata extra field.
172
  std::wstring OrigName;  // Original archive name.
173
  RarTime OrigTime;       // Original archive time.
174
171
  void Reset();
175
  void Reset();
172
};
176
};
173
177
Lines 230-236 Link Here
230
  bool LargeFile;
234
  bool LargeFile;
231
  
235
  
232
  // 'true' for HEAD_SERVICE block, which is a child of preceding file block.
236
  // 'true' for HEAD_SERVICE block, which is a child of preceding file block.
233
  // RAR 4.x uses 'solid' flag to indicate child subheader blocks in archives.
237
  // RAR 4.x uses 'solid' flag to indicate children subheader blocks in archives.
234
  bool SubBlock;
238
  bool SubBlock;
235
239
236
  HOST_SYSTEM_TYPE HSType;
240
  HOST_SYSTEM_TYPE HSType;
(-)unrar-6.1.7/headers5.hpp (+7 lines)
Lines 59-68 Link Here
59
59
60
// Main header extra field values.
60
// Main header extra field values.
61
#define MHEXTRA_LOCATOR       0x01 // Position of quick list and other blocks.
61
#define MHEXTRA_LOCATOR       0x01 // Position of quick list and other blocks.
62
#define MHEXTRA_METADATA      0x02 // Archive metadata.
62
63
63
// Flags for MHEXTRA_LOCATOR.
64
// Flags for MHEXTRA_LOCATOR.
64
#define MHEXTRA_LOCATOR_QLIST 0x01 // Quick open offset is present.
65
#define MHEXTRA_LOCATOR_QLIST 0x01 // Quick open offset is present.
65
#define MHEXTRA_LOCATOR_RR    0x02 // Recovery record offset is present.
66
#define MHEXTRA_LOCATOR_RR    0x02 // Recovery record offset is present.
67
68
// Flags for MHEXTRA_METADATA.
69
#define MHEXTRA_METADATA_NAME      0x01 // Archive name is present.
70
#define MHEXTRA_METADATA_CTIME     0x02 // Archive creation time is present.
71
#define MHEXTRA_METADATA_UNIXTIME  0x04 // Use Unix nanosecond time format.
72
#define MHEXTRA_METADATA_UNIX_NS   0x08 // Unix format with nanosecond precision.
66
73
67
// File and service header extra field values.
74
// File and service header extra field values.
68
#define FHEXTRA_CRYPT         0x01 // Encryption parameters.
75
#define FHEXTRA_CRYPT         0x01 // Encryption parameters.
(-)unrar-6.1.7/isnt.cpp (-1 / +1 lines)
Lines 40-46 Link Here
40
40
41
  IWbemServices *pSvc = NULL;
41
  IWbemServices *pSvc = NULL;
42
 
42
 
43
  hres = pLoc->ConnectServer(_bstr_t(L"ROOT\\CIMV2"),NULL,NULL,0,NULL,0,0,&pSvc);
43
  hres = pLoc->ConnectServer(_bstr_t(L"ROOT\\CIMV2"),NULL,NULL,NULL,NULL,0,0,&pSvc);
44
    
44
    
45
  if (FAILED(hres))
45
  if (FAILED(hres))
46
  {
46
  {
(-)unrar-6.1.7/list.cpp (+11 lines)
Lines 36-41 Link Here
36
        {
36
        {
37
          Arc.ViewComment();
37
          Arc.ViewComment();
38
          mprintf(L"\n%s: %s",St(MListArchive),Arc.FileName);
38
          mprintf(L"\n%s: %s",St(MListArchive),Arc.FileName);
39
39
          mprintf(L"\n%s: ",St(MListDetails));
40
          mprintf(L"\n%s: ",St(MListDetails));
40
          uint SetCount=0;
41
          uint SetCount=0;
41
          const wchar *Fmt=Arc.Format==RARFMT14 ? L"RAR 1.4":(Arc.Format==RARFMT15 ? L"RAR 4":L"RAR 5");
42
          const wchar *Fmt=Arc.Format==RARFMT14 ? L"RAR 1.4":(Arc.Format==RARFMT15 ? L"RAR 4":L"RAR 5");
Lines 61-66 Link Here
61
            mprintf(L"%s%s", SetCount++ > 0 ? L", ":L"", St(MListLock));
62
            mprintf(L"%s%s", SetCount++ > 0 ? L", ":L"", St(MListLock));
62
          if (Arc.Encrypted)
63
          if (Arc.Encrypted)
63
            mprintf(L"%s%s", SetCount++ > 0 ? L", ":L"", St(MListEncHead));
64
            mprintf(L"%s%s", SetCount++ > 0 ? L", ":L"", St(MListEncHead));
65
66
          if (!Arc.MainHead.OrigName.empty())
67
            mprintf(L"\n%s: %s",St(MOrigName),Arc.MainHead.OrigName.c_str());
68
          if (Arc.MainHead.OrigTime.IsSet())
69
          {
70
            wchar DateStr[50];
71
            Arc.MainHead.OrigTime.GetText(DateStr,ASIZE(DateStr),Technical);
72
            mprintf(L"\n%s: %s",St(MOriginalTime),DateStr);
73
          }
74
64
          mprintf(L"\n");
75
          mprintf(L"\n");
65
        }
76
        }
66
77
(-)unrar-6.1.7/loclang.hpp (+5 lines)
Lines 28-33 Link Here
28
#define   MRARTitle1         L"\nUsage:     rar <command> -<switch 1> -<switch N> <archive> <files...>"
28
#define   MRARTitle1         L"\nUsage:     rar <command> -<switch 1> -<switch N> <archive> <files...>"
29
#define   MUNRARTitle1       L"\nUsage:     unrar <command> -<switch 1> -<switch N> <archive> <files...>"
29
#define   MUNRARTitle1       L"\nUsage:     unrar <command> -<switch 1> -<switch N> <archive> <files...>"
30
#define   MRARTitle2         L"\n               <@listfiles...> <path_to_extract\\>"
30
#define   MRARTitle2         L"\n               <@listfiles...> <path_to_extract\\>"
31
#define   MFwrSlTitle2       L"\n               <@listfiles...> <path_to_extract/>"
31
#define   MCHelpCmd          L"\n\n<Commands>"
32
#define   MCHelpCmd          L"\n\n<Commands>"
32
#define   MCHelpCmdA         L"\n  a             Add files to archive"
33
#define   MCHelpCmdA         L"\n  a             Add files to archive"
33
#define   MCHelpCmdC         L"\n  c             Add archive comment"
34
#define   MCHelpCmdC         L"\n  c             Add archive comment"
Lines 58-63 Link Here
58
#define   MCHelpSwAD         L"\n  ad[1,2]       Alternate destination path"
59
#define   MCHelpSwAD         L"\n  ad[1,2]       Alternate destination path"
59
#define   MCHelpSwAG         L"\n  ag[format]    Generate archive name using the current date"
60
#define   MCHelpSwAG         L"\n  ag[format]    Generate archive name using the current date"
60
#define   MCHelpSwAI         L"\n  ai            Ignore file attributes"
61
#define   MCHelpSwAI         L"\n  ai            Ignore file attributes"
62
#define   MCHelpSwAM         L"\n  am[s,r]       Archive name and time [save, restore]"
61
#define   MCHelpSwAO         L"\n  ao            Add files with Archive attribute set"
63
#define   MCHelpSwAO         L"\n  ao            Add files with Archive attribute set"
62
#define   MCHelpSwAP         L"\n  ap<path>      Set path inside archive"
64
#define   MCHelpSwAP         L"\n  ap<path>      Set path inside archive"
63
#define   MCHelpSwAS         L"\n  as            Synchronize archive contents"
65
#define   MCHelpSwAS         L"\n  as            Synchronize archive contents"
Lines 394-396 Link Here
394
#define   MAdjustValue       L"\nAdjusting %s value to %s."
396
#define   MAdjustValue       L"\nAdjusting %s value to %s."
395
#define   MOpFailed          L"\nOperation failed"
397
#define   MOpFailed          L"\nOperation failed"
396
#define   MSkipEncArc        L"\nSkipping the encrypted archive %s"
398
#define   MSkipEncArc        L"\nSkipping the encrypted archive %s"
399
#define   MOrigName          L"Original name"
400
#define   MOriginalTime      L"Original time"
401
#define   MFileRenamed       L"\n%s is renamed to %s"
(-)unrar-6.1.7/makefile (-4 / +7 lines)
Lines 126-132 Link Here
126
	archive.o arcread.o unicode.o system.o crypt.o crc.o rawread.o encname.o \
126
	archive.o arcread.o unicode.o system.o crypt.o crc.o rawread.o encname.o \
127
	resource.o match.o timefn.o rdwrfn.o consio.o options.o errhnd.o rarvm.o secpassword.o \
127
	resource.o match.o timefn.o rdwrfn.o consio.o options.o errhnd.o rarvm.o secpassword.o \
128
	rijndael.o getbits.o sha1.o sha256.o blake2s.o hash.o extinfo.o extract.o volume.o \
128
	rijndael.o getbits.o sha1.o sha256.o blake2s.o hash.o extinfo.o extract.o volume.o \
129
  list.o find.o unpack.o headers.o threadpool.o rs16.o cmddata.o ui.o
129
	list.o find.o unpack.o headers.o threadpool.o rs16.o cmddata.o ui.o
130
130
131
.cpp.o:
131
.cpp.o:
132
	$(COMPILE) -D$(WHAT) -c $<
132
	$(COMPILE) -D$(WHAT) -c $<
Lines 142-161 Link Here
142
	@rm -f $(OBJECTS) $(UNRAR_OBJ) $(LIB_OBJ)
142
	@rm -f $(OBJECTS) $(UNRAR_OBJ) $(LIB_OBJ)
143
	@rm -f unrar libunrar.*
143
	@rm -f unrar libunrar.*
144
144
145
unrar:	clean $(OBJECTS) $(UNRAR_OBJ)
145
# We removed 'clean' from dependencies, because it prevented parallel
146
# 'make -Jn' builds.
147
148
unrar:	$(OBJECTS) $(UNRAR_OBJ)
146
	@rm -f unrar
149
	@rm -f unrar
147
	$(LINK) -o unrar $(LDFLAGS) $(OBJECTS) $(UNRAR_OBJ) $(LIBS)	
150
	$(LINK) -o unrar $(LDFLAGS) $(OBJECTS) $(UNRAR_OBJ) $(LIBS)	
148
	$(STRIP) unrar
151
	$(STRIP) unrar
149
152
150
sfx:	WHAT=SFX_MODULE
153
sfx:	WHAT=SFX_MODULE
151
sfx:	clean $(OBJECTS)
154
sfx:	$(OBJECTS)
152
	@rm -f default.sfx
155
	@rm -f default.sfx
153
	$(LINK) -o default.sfx $(LDFLAGS) $(OBJECTS)
156
	$(LINK) -o default.sfx $(LDFLAGS) $(OBJECTS)
154
	$(STRIP) default.sfx
157
	$(STRIP) default.sfx
155
158
156
lib:	WHAT=RARDLL
159
lib:	WHAT=RARDLL
157
lib:	CXXFLAGS+=$(LIBFLAGS)
160
lib:	CXXFLAGS+=$(LIBFLAGS)
158
lib:	clean $(OBJECTS) $(LIB_OBJ)
161
lib:	$(OBJECTS) $(LIB_OBJ)
159
	@rm -f libunrar.*
162
	@rm -f libunrar.*
160
	$(LINK) -shared -o libunrar.so $(LDFLAGS) $(OBJECTS) $(LIB_OBJ)
163
	$(LINK) -shared -o libunrar.so $(LDFLAGS) $(OBJECTS) $(LIB_OBJ)
161
	$(AR) rcs libunrar.a $(OBJECTS) $(LIB_OBJ)
164
	$(AR) rcs libunrar.a $(OBJECTS) $(LIB_OBJ)
(-)unrar-6.1.7/model.cpp (-2 / +4 lines)
Lines 532-544 Link Here
532
    Model->Coder.SubRange.LowCount=HiCnt;
532
    Model->Coder.SubRange.LowCount=HiCnt;
533
    Model->Coder.SubRange.HighCount=Model->Coder.SubRange.scale;
533
    Model->Coder.SubRange.HighCount=Model->Coder.SubRange.scale;
534
    i=NumStats-Model->NumMasked;
534
    i=NumStats-Model->NumMasked;
535
    pps--;
535
536
    // 2022.12.02: we removed pps-- here and changed the code below to avoid
537
    // "array subscript -1 is outside array bounds" warning in some compilers.
536
    do 
538
    do 
537
    { 
539
    { 
538
      pps++;
539
      if (pps>=ps+ASIZE(ps)) // Extra safety check.
540
      if (pps>=ps+ASIZE(ps)) // Extra safety check.
540
        return false;
541
        return false;
541
      Model->CharMask[(*pps)->Symbol]=Model->EscCount; 
542
      Model->CharMask[(*pps)->Symbol]=Model->EscCount; 
543
      pps++;
542
    } while ( --i );
544
    } while ( --i );
543
    psee2c->Summ += Model->Coder.SubRange.scale;
545
    psee2c->Summ += Model->Coder.SubRange.scale;
544
    Model->NumMasked = NumStats;
546
    Model->NumMasked = NumStats;
(-)unrar-6.1.7/options.cpp (-8 lines)
Lines 6-19 Link Here
6
}
6
}
7
7
8
8
9
RAROptions::~RAROptions()
10
{
11
  // It is important for security reasons, so we do not have the unnecessary
12
  // password data left in memory.
13
  memset(this,0,sizeof(RAROptions));
14
}
15
16
17
void RAROptions::Init()
9
void RAROptions::Init()
18
{
10
{
19
  memset(this,0,sizeof(RAROptions));
11
  memset(this,0,sizeof(RAROptions));
(-)unrar-6.1.7/options.hpp (-3 / +9 lines)
Lines 45-50 Link Here
45
  OVERWRITE_FORCE_ASK
45
  OVERWRITE_FORCE_ASK
46
};
46
};
47
47
48
enum ARC_METADATA
49
{
50
  ARCMETA_NONE=0,
51
  ARCMETA_SAVE,    // -ams
52
  ARCMETA_RESTORE  // -amr
53
};
48
54
49
enum QOPEN_MODE { QOPEN_NONE, QOPEN_AUTO, QOPEN_ALWAYS };
55
enum QOPEN_MODE { QOPEN_NONE, QOPEN_AUTO, QOPEN_ALWAYS };
50
56
Lines 84-94 Link Here
84
#define MAX_GENERATE_MASK  128
90
#define MAX_GENERATE_MASK  128
85
91
86
92
93
// Here we store simple data types, which we can clear and move all together
94
// quickly. Rest of data types goes to CommandData.
87
class RAROptions
95
class RAROptions
88
{
96
{
89
  public:
97
  public:
90
    RAROptions();
98
    RAROptions();
91
    ~RAROptions();
92
    void Init();
99
    void Init();
93
100
94
    uint ExclFileAttr;
101
    uint ExclFileAttr;
Lines 118-124 Link Here
118
125
119
    wchar ArcPath[NM]; // For -ap<path>.
126
    wchar ArcPath[NM]; // For -ap<path>.
120
    wchar ExclArcPath[NM]; // For -ep4<path> switch.
127
    wchar ExclArcPath[NM]; // For -ep4<path> switch.
121
    SecPassword Password;
122
    bool EncryptHeaders;
128
    bool EncryptHeaders;
123
    bool SkipEncrypted;
129
    bool SkipEncrypted;
124
    
130
    
Lines 132-137 Link Here
132
    HASH_TYPE HashType;
138
    HASH_TYPE HashType;
133
    int Recovery;
139
    int Recovery;
134
    int RecVolNumber;
140
    int RecVolNumber;
141
    ARC_METADATA ArcMetadata;
135
    bool DisablePercentage;
142
    bool DisablePercentage;
136
    bool DisableCopyright;
143
    bool DisableCopyright;
137
    bool DisableDone;
144
    bool DisableDone;
Lines 147-153 Link Here
147
    PATH_EXCL_MODE ExclPath;
154
    PATH_EXCL_MODE ExclPath;
148
    RECURSE_MODE Recurse;
155
    RECURSE_MODE Recurse;
149
    int64 VolSize;
156
    int64 VolSize;
150
    Array<int64> NextVolSizes;
151
    uint CurVolNum;
157
    uint CurVolNum;
152
    bool AllYes;
158
    bool AllYes;
153
    bool VerboseOutput; // -iv, display verbose output, used only in "WinRAR t" now.
159
    bool VerboseOutput; // -iv, display verbose output, used only in "WinRAR t" now.
(-)unrar-6.1.7/os.hpp (-4 / +9 lines)
Lines 13-18 Link Here
13
#endif
13
#endif
14
14
15
#include <new>
15
#include <new>
16
#include <string>
17
#include <vector>
16
18
17
19
18
#if defined(_WIN_ALL) || defined(_EMX)
20
#if defined(_WIN_ALL) || defined(_EMX)
Lines 39-46 Link Here
39
#define _UNICODE // Set _T() macro to convert from narrow to wide strings.
41
#define _UNICODE // Set _T() macro to convert from narrow to wide strings.
40
#endif
42
#endif
41
43
44
#if 0
45
// 2021.09.05: Allow newer Vista+ APIs like IFileOpenDialog for WinRAR,
46
// but still keep SFX modules XP compatible.
47
#define WINVER _WIN32_WINNT_VISTA
48
#define _WIN32_WINNT _WIN32_WINNT_VISTA
49
#else
42
#define WINVER _WIN32_WINNT_WINXP
50
#define WINVER _WIN32_WINNT_WINXP
43
#define _WIN32_WINNT _WIN32_WINNT_WINXP
51
#define _WIN32_WINNT _WIN32_WINNT_WINXP
52
#endif
44
53
45
#if !defined(ZIPSFX)
54
#if !defined(ZIPSFX)
46
#define RAR_SMP
55
#define RAR_SMP
Lines 72-80 Link Here
72
  #include <dir.h>
81
  #include <dir.h>
73
#endif
82
#endif
74
#ifdef _MSC_VER
83
#ifdef _MSC_VER
75
  #if _MSC_VER<1500
76
    #define for if (0) ; else for
77
  #endif
78
  #include <direct.h>
84
  #include <direct.h>
79
  #include <intrin.h>
85
  #include <intrin.h>
80
86
Lines 97-103 Link Here
97
#include <io.h>
103
#include <io.h>
98
#include <time.h>
104
#include <time.h>
99
#include <signal.h>
105
#include <signal.h>
100
101
106
102
#define SAVE_LINKS
107
#define SAVE_LINKS
103
108
(-)unrar-6.1.7/pathfn.cpp (-37 / +52 lines)
Lines 31-41 Link Here
31
    const wchar *s=DestPtr;
31
    const wchar *s=DestPtr;
32
    if (s[0]!=0 && IsDriveDiv(s[1]))
32
    if (s[0]!=0 && IsDriveDiv(s[1]))
33
      s+=2;
33
      s+=2;
34
    if (s[0]=='\\' && s[1]=='\\')
34
35
    // Skip UNC Windows \\server\share\ or Unix //server/share/
36
    if (IsPathDiv(s[0]) && IsPathDiv(s[1]))
35
    {
37
    {
36
      const wchar *Slash=wcschr(s+2,'\\');
38
      uint SlashCount=0;
37
      if (Slash!=NULL && (Slash=wcschr(Slash+1,'\\'))!=NULL)
39
      for (const wchar *t=s+2;*t!=0;t++)
38
        s=Slash+1;
40
        if (IsPathDiv(*t) && ++SlashCount==2)
41
        {
42
          s=t+1; // Found two more path separators after leading two.
43
          break;
44
        }
39
    }
45
    }
40
    for (const wchar *t=s;*t!=0;t++)
46
    for (const wchar *t=s;*t!=0;t++)
41
      if (IsPathDiv(*t))
47
      if (IsPathDiv(*t))
Lines 422-471 Link Here
422
428
423
bool IsNameUsable(const wchar *Name)
429
bool IsNameUsable(const wchar *Name)
424
{
430
{
425
#ifndef _UNIX
431
  // We were asked to apply Windows-like conversion in Linux in case
426
  if (Name[0] && Name[1] && wcschr(Name+2,':')!=NULL)
432
  // files are unpacked to Windows share. This code is invoked only
433
  // if file failed to be created, so it doesn't affect extraction
434
  // of Unix compatible names to native Unix drives.
435
#ifdef _UNIX
436
  // Windows shares in Unix do not allow the drive letter,
437
  // so unlike Windows version, we check all characters here.
438
  if (wcschr(Name,':')!=NULL)
427
    return false;
439
    return false;
440
#else
441
  if (Name[0]!=0 && Name[1]!=0 && wcschr(Name+2,':')!=NULL)
442
    return false;
443
#endif
428
  for (const wchar *s=Name;*s!=0;s++)
444
  for (const wchar *s=Name;*s!=0;s++)
429
  {
445
  {
430
    if ((uint)*s<32)
446
    if ((uint)*s<32)
431
      return false;
447
      return false;
448
449
     // It is for Windows shares in Unix. We can create such names in Windows.
450
#ifdef _UNIX
451
    // No spaces or dots before the path separator are allowed in Windows
452
    // shares. But they are allowed and automtically removed at the end of
453
    // file or folder name, so it is useless to replace them here.
454
    // Since such files or folders are created successfully, a supposed
455
    // conversion here would never be invoked.
432
    if ((*s==' ' || *s=='.') && IsPathDiv(s[1]))
456
    if ((*s==' ' || *s=='.') && IsPathDiv(s[1]))
433
      return false;
457
      return false;
434
  }
435
#endif
458
#endif
459
  }
436
  return *Name!=0 && wcspbrk(Name,L"?*<>|\"")==NULL;
460
  return *Name!=0 && wcspbrk(Name,L"?*<>|\"")==NULL;
437
}
461
}
438
462
439
463
440
void MakeNameUsable(char *Name,bool Extended)
441
{
442
#ifdef _WIN_ALL
443
  // In Windows we also need to convert characters not defined in current
444
  // code page. This double conversion changes them to '?', which is
445
  // catched by code below.
446
  size_t NameLength=strlen(Name);
447
  wchar NameW[NM];
448
  CharToWide(Name,NameW,ASIZE(NameW));
449
  WideToChar(NameW,Name,NameLength+1);
450
  Name[NameLength]=0;
451
#endif
452
  for (char *s=Name;*s!=0;s=charnext(s))
453
  {
454
    if (strchr(Extended ? "?*<>|\"":"?*",*s)!=NULL || Extended && (byte)*s<32)
455
      *s='_';
456
#ifdef _EMX
457
    if (*s=='=')
458
      *s='_';
459
#endif
460
#ifndef _UNIX
461
    if (s-Name>1 && *s==':')
462
      *s='_';
463
    // Remove ' ' and '.' before path separator, but allow .\ and ..\.
464
    if ((*s==' ' || *s=='.' && s>Name && !IsPathDiv(s[-1]) && s[-1]!='.') && IsPathDiv(s[1]))
465
      *s='_';
466
#endif
467
  }
468
}
469
464
470
465
471
void MakeNameUsable(wchar *Name,bool Extended)
466
void MakeNameUsable(wchar *Name,bool Extended)
Lines 474-480 Link Here
474
  {
469
  {
475
    if (wcschr(Extended ? L"?*<>|\"":L"?*",*s)!=NULL || Extended && (uint)*s<32)
470
    if (wcschr(Extended ? L"?*<>|\"":L"?*",*s)!=NULL || Extended && (uint)*s<32)
476
      *s='_';
471
      *s='_';
477
#ifndef _UNIX
472
#ifdef _UNIX
473
    // We were asked to apply Windows-like conversion in Linux in case
474
    // files are unpacked to Windows share. This code is invoked only
475
    // if file failed to be created, so it doesn't affect extraction
476
    // of Unix compatible names to native Unix drives.
477
    if (Extended)
478
    {
479
      // Windows shares in Unix do not allow the drive letter,
480
      // so unlike Windows version, we check all characters here.
481
      if (*s==':')
482
        *s='_';
483
484
      // No spaces or dots before the path separator are allowed on Windows
485
      // shares. But they are allowed and automtically removed at the end of
486
      // file or folder name, so it is useless to replace them here.
487
      // Since such files or folders are created successfully, a supposed
488
      // conversion here would never be invoked.
489
      if ((*s==' ' || *s=='.') && IsPathDiv(s[1]))
490
        *s='_';
491
    }
492
#else
478
    if (s-Name>1 && *s==':')
493
    if (s-Name>1 && *s==':')
479
      *s='_';
494
      *s='_';
480
#if 0  // We already can create such files.
495
#if 0  // We already can create such files.
(-)unrar-6.1.7/pathfn.hpp (-1 lines)
Lines 29-35 Link Here
29
wchar* GetVolNumPart(const wchar *ArcName);
29
wchar* GetVolNumPart(const wchar *ArcName);
30
void NextVolumeName(wchar *ArcName,uint MaxLength,bool OldNumbering);
30
void NextVolumeName(wchar *ArcName,uint MaxLength,bool OldNumbering);
31
bool IsNameUsable(const wchar *Name);
31
bool IsNameUsable(const wchar *Name);
32
void MakeNameUsable(char *Name,bool Extended);
33
void MakeNameUsable(wchar *Name,bool Extended);
32
void MakeNameUsable(wchar *Name,bool Extended);
34
33
35
void UnixSlashToDos(const char *SrcName,char *DestName,size_t MaxLength);
34
void UnixSlashToDos(const char *SrcName,char *DestName,size_t MaxLength);
(-)unrar-6.1.7/qopen.cpp (-1 / +1 lines)
Lines 97-103 Link Here
97
97
98
  if (Arc->SubHead.Encrypted)
98
  if (Arc->SubHead.Encrypted)
99
  {
99
  {
100
    RAROptions *Cmd=Arc->GetRAROptions();
100
    CommandData *Cmd=Arc->GetCommandData();
101
#ifndef RAR_NOCRYPT
101
#ifndef RAR_NOCRYPT
102
    if (Cmd->Password.IsSet())
102
    if (Cmd->Password.IsSet())
103
      Crypt.SetCryptKeys(false,CRYPT_RAR50,&Cmd->Password,Arc->SubHead.Salt,
103
      Crypt.SetCryptKeys(false,CRYPT_RAR50,&Cmd->Password,Arc->SubHead.Salt,
(-)unrar-6.1.7/rar.hpp (-2 / +2 lines)
Lines 12-17 Link Here
12
#include "version.hpp"
12
#include "version.hpp"
13
#include "rardefs.hpp"
13
#include "rardefs.hpp"
14
#include "rarlang.hpp"
14
#include "rarlang.hpp"
15
#include "rawint.hpp"
15
#include "unicode.hpp"
16
#include "unicode.hpp"
16
#include "errhnd.hpp"
17
#include "errhnd.hpp"
17
#include "secpassword.hpp"
18
#include "secpassword.hpp"
Lines 34-40 Link Here
34
#endif
35
#endif
35
#include "file.hpp"
36
#include "file.hpp"
36
#include "crc.hpp"
37
#include "crc.hpp"
37
#include "ui.hpp"
38
#include "filefn.hpp"
38
#include "filefn.hpp"
39
#include "filestr.hpp"
39
#include "filestr.hpp"
40
#include "find.hpp"
40
#include "find.hpp"
Lines 47-57 Link Here
47
#include "archive.hpp"
47
#include "archive.hpp"
48
#include "match.hpp"
48
#include "match.hpp"
49
#include "cmddata.hpp"
49
#include "cmddata.hpp"
50
#include "ui.hpp"
50
#include "filcreat.hpp"
51
#include "filcreat.hpp"
51
#include "consio.hpp"
52
#include "consio.hpp"
52
#include "system.hpp"
53
#include "system.hpp"
53
#include "log.hpp"
54
#include "log.hpp"
54
#include "rawint.hpp"
55
#include "rawread.hpp"
55
#include "rawread.hpp"
56
#include "encname.hpp"
56
#include "encname.hpp"
57
#include "resource.hpp"
57
#include "resource.hpp"
(-)unrar-6.1.7/rardefs.hpp (-3 / +7 lines)
Lines 9-17 Link Here
9
9
10
#define  ASIZE(x) (sizeof(x)/sizeof(x[0]))
10
#define  ASIZE(x) (sizeof(x)/sizeof(x[0]))
11
11
12
// MAXPASSWORD is expected to be multiple of CRYPTPROTECTMEMORY_BLOCK_SIZE (16)
12
// MAXPASSWORD and MAXPASSWORD_RAR are expected to be multiple of
13
// for CryptProtectMemory in SecPassword.
13
// CRYPTPROTECTMEMORY_BLOCK_SIZE (16) for CryptProtectMemory in SecPassword.
14
#define  MAXPASSWORD       128
14
// We allow a larger MAXPASSWORD to unpack archives with lengthy passwords
15
// in non-RAR formats in GUI versions. For RAR format we set MAXPASSWORD_RAR
16
// to 128 for compatibility and because it is enough for AES-256.
17
#define  MAXPASSWORD       512
18
#define  MAXPASSWORD_RAR   128
15
19
16
#define  MAXSFXSIZE        0x200000
20
#define  MAXSFXSIZE        0x200000
17
21
(-)unrar-6.1.7/rawint.hpp (-3 / +3 lines)
Lines 84-90 Link Here
84
{
84
{
85
#if defined(USE_MEM_BYTESWAP) && defined(_MSC_VER)
85
#if defined(USE_MEM_BYTESWAP) && defined(_MSC_VER)
86
  return _byteswap_ulong(*(uint32 *)m);
86
  return _byteswap_ulong(*(uint32 *)m);
87
#elif defined(USE_MEM_BYTESWAP) && (__GNUC__ > 3) && (__GNUC_MINOR__ > 2)
87
#elif defined(USE_MEM_BYTESWAP) && (defined(__clang__) || defined(__GNUC__))
88
  return __builtin_bswap32(*(uint32 *)m);
88
  return __builtin_bswap32(*(uint32 *)m);
89
#else
89
#else
90
  return uint32(m[0]<<24) | uint32(m[1]<<16) | uint32(m[2]<<8) | m[3];
90
  return uint32(m[0]<<24) | uint32(m[1]<<16) | uint32(m[2]<<8) | m[3];
Lines 97-103 Link Here
97
{
97
{
98
#if defined(USE_MEM_BYTESWAP) && defined(_MSC_VER)
98
#if defined(USE_MEM_BYTESWAP) && defined(_MSC_VER)
99
  *(uint32*)mem = _byteswap_ulong(i);
99
  *(uint32*)mem = _byteswap_ulong(i);
100
#elif defined(USE_MEM_BYTESWAP) && (__GNUC__ > 3) && (__GNUC_MINOR__ > 2)
100
#elif defined(USE_MEM_BYTESWAP) && (defined(__clang__) || defined(__GNUC__))
101
  *(uint32*)mem = __builtin_bswap32(i);
101
  *(uint32*)mem = __builtin_bswap32(i);
102
#else
102
#else
103
  mem[0]=byte(i>>24);
103
  mem[0]=byte(i>>24);
Lines 112-118 Link Here
112
{
112
{
113
#ifdef _MSC_VER
113
#ifdef _MSC_VER
114
  return _byteswap_ulong(i);
114
  return _byteswap_ulong(i);
115
#elif (__GNUC__ > 3) && (__GNUC_MINOR__ > 2)
115
#elif defined(__clang__) || defined(__GNUC__)
116
  return  __builtin_bswap32(i);
116
  return  __builtin_bswap32(i);
117
#else
117
#else
118
  return (rotl32(i,24)&0xFF00FF00)|(rotl32(i,8)&0x00FF00FF);
118
  return (rotl32(i,24)&0xFF00FF00)|(rotl32(i,8)&0x00FF00FF);
(-)unrar-6.1.7/rdwrfn.cpp (-2 / +2 lines)
Lines 155-161 Link Here
155
{
155
{
156
156
157
#ifdef RARDLL
157
#ifdef RARDLL
158
  RAROptions *Cmd=((Archive *)SrcFile)->GetRAROptions();
158
  CommandData *Cmd=((Archive *)SrcFile)->GetCommandData();
159
  if (Cmd->DllOpMode!=RAR_SKIP)
159
  if (Cmd->DllOpMode!=RAR_SKIP)
160
  {
160
  {
161
    if (Cmd->Callback!=NULL &&
161
    if (Cmd->Callback!=NULL &&
Lines 204-210 Link Here
204
    ArcPos+=ProcessedArcSize;
204
    ArcPos+=ProcessedArcSize;
205
205
206
    Archive *SrcArc=(Archive *)SrcFile;
206
    Archive *SrcArc=(Archive *)SrcFile;
207
    RAROptions *Cmd=SrcArc->GetRAROptions();
207
    CommandData *Cmd=SrcArc->GetCommandData();
208
208
209
    int CurPercent=ToPercent(ArcPos,ArcSize);
209
    int CurPercent=ToPercent(ArcPos,ArcSize);
210
    if (!Cmd->DisablePercentage && CurPercent!=LastPercent)
210
    if (!Cmd->DisablePercentage && CurPercent!=LastPercent)
(-)unrar-6.1.7/recvol.cpp (-2 / +2 lines)
Lines 5-11 Link Here
5
5
6
6
7
7
8
bool RecVolumesRestore(RAROptions *Cmd,const wchar *Name,bool Silent)
8
bool RecVolumesRestore(CommandData *Cmd,const wchar *Name,bool Silent)
9
{
9
{
10
  Archive Arc(Cmd);
10
  Archive Arc(Cmd);
11
  if (!Arc.Open(Name))
11
  if (!Arc.Open(Name))
Lines 42-48 Link Here
42
}
42
}
43
43
44
44
45
void RecVolumesTest(RAROptions *Cmd,Archive *Arc,const wchar *Name)
45
void RecVolumesTest(CommandData *Cmd,Archive *Arc,const wchar *Name)
46
{
46
{
47
  wchar RevName[NM];
47
  wchar RevName[NM];
48
  *RevName=0;
48
  *RevName=0;
(-)unrar-6.1.7/recvol.hpp (-11 / +11 lines)
Lines 14-24 Link Here
14
    ThreadPool *RSThreadPool;
14
    ThreadPool *RSThreadPool;
15
#endif
15
#endif
16
  public:
16
  public:
17
    RecVolumes3(RAROptions *Cmd,bool TestOnly);
17
    RecVolumes3(CommandData *Cmd,bool TestOnly);
18
    ~RecVolumes3();
18
    ~RecVolumes3();
19
    void Make(RAROptions *Cmd,wchar *ArcName);
19
    void Make(CommandData *Cmd,wchar *ArcName);
20
    bool Restore(RAROptions *Cmd,const wchar *Name,bool Silent);
20
    bool Restore(CommandData *Cmd,const wchar *Name,bool Silent);
21
    void Test(RAROptions *Cmd,const wchar *Name);
21
    void Test(CommandData *Cmd,const wchar *Name);
22
};
22
};
23
23
24
24
Lines 48-55 Link Here
48
class RecVolumes5
48
class RecVolumes5
49
{
49
{
50
  private:
50
  private:
51
    void ProcessRS(RAROptions *Cmd,uint DataNum,const byte *Data,uint MaxRead,bool Encode);
51
    void ProcessRS(CommandData *Cmd,uint DataNum,const byte *Data,uint MaxRead,bool Encode);
52
    void ProcessRS(RAROptions *Cmd,uint MaxRead,bool Encode);
52
    void ProcessRS(CommandData *Cmd,uint MaxRead,bool Encode);
53
    uint ReadHeader(File *RecFile,bool FirstRev);
53
    uint ReadHeader(File *RecFile,bool FirstRev);
54
54
55
    Array<RecVolItem> RecItems;
55
    Array<RecVolItem> RecItems;
Lines 76-88 Link Here
76
  public: // 'public' only because called from thread functions.
76
  public: // 'public' only because called from thread functions.
77
    void ProcessAreaRS(RecRSThreadData *td);
77
    void ProcessAreaRS(RecRSThreadData *td);
78
  public:
78
  public:
79
    RecVolumes5(RAROptions *Cmd,bool TestOnly);
79
    RecVolumes5(CommandData *Cmd,bool TestOnly);
80
    ~RecVolumes5();
80
    ~RecVolumes5();
81
    bool Restore(RAROptions *Cmd,const wchar *Name,bool Silent);
81
    bool Restore(CommandData *Cmd,const wchar *Name,bool Silent);
82
    void Test(RAROptions *Cmd,const wchar *Name);
82
    void Test(CommandData *Cmd,const wchar *Name);
83
};
83
};
84
84
85
bool RecVolumesRestore(RAROptions *Cmd,const wchar *Name,bool Silent);
85
bool RecVolumesRestore(CommandData *Cmd,const wchar *Name,bool Silent);
86
void RecVolumesTest(RAROptions *Cmd,Archive *Arc,const wchar *Name);
86
void RecVolumesTest(CommandData *Cmd,Archive *Arc,const wchar *Name);
87
87
88
#endif
88
#endif
(-)unrar-6.1.7/recvol3.cpp (-3 / +3 lines)
Lines 36-42 Link Here
36
}
36
}
37
#endif
37
#endif
38
38
39
RecVolumes3::RecVolumes3(RAROptions *Cmd,bool TestOnly)
39
RecVolumes3::RecVolumes3(CommandData *Cmd,bool TestOnly)
40
{
40
{
41
  memset(SrcFile,0,sizeof(SrcFile));
41
  memset(SrcFile,0,sizeof(SrcFile));
42
  if (TestOnly)
42
  if (TestOnly)
Lines 99-105 Link Here
99
}
99
}
100
100
101
101
102
bool RecVolumes3::Restore(RAROptions *Cmd,const wchar *Name,bool Silent)
102
bool RecVolumes3::Restore(CommandData *Cmd,const wchar *Name,bool Silent)
103
{
103
{
104
  wchar ArcName[NM];
104
  wchar ArcName[NM];
105
  wcsncpyz(ArcName,Name,ASIZE(ArcName));
105
  wcsncpyz(ArcName,Name,ASIZE(ArcName));
Lines 497-503 Link Here
497
}
497
}
498
498
499
499
500
void RecVolumes3::Test(RAROptions *Cmd,const wchar *Name)
500
void RecVolumes3::Test(CommandData *Cmd,const wchar *Name)
501
{
501
{
502
  if (!IsNewStyleRev(Name)) // RAR 3.0 name#_#_#.rev do not include CRC32.
502
  if (!IsNewStyleRev(Name)) // RAR 3.0 name#_#_#.rev do not include CRC32.
503
  {
503
  {
(-)unrar-6.1.7/recvol5.cpp (-4 / +4 lines)
Lines 4-10 Link Here
4
// rev files by mistake.
4
// rev files by mistake.
5
#define MAX_REV_TO_DATA_RATIO 10 // 1000% of rev files.
5
#define MAX_REV_TO_DATA_RATIO 10 // 1000% of rev files.
6
6
7
RecVolumes5::RecVolumes5(RAROptions *Cmd,bool TestOnly)
7
RecVolumes5::RecVolumes5(CommandData *Cmd,bool TestOnly)
8
{
8
{
9
  RealBuf=NULL;
9
  RealBuf=NULL;
10
  RealReadBuffer=NULL;
10
  RealReadBuffer=NULL;
Lines 70-76 Link Here
70
#endif
70
#endif
71
71
72
72
73
void RecVolumes5::ProcessRS(RAROptions *Cmd,uint DataNum,const byte *Data,uint MaxRead,bool Encode)
73
void RecVolumes5::ProcessRS(CommandData *Cmd,uint DataNum,const byte *Data,uint MaxRead,bool Encode)
74
{
74
{
75
/*
75
/*
76
  RSCoder16 RS;
76
  RSCoder16 RS;
Lines 141-147 Link Here
141
141
142
142
143
143
144
bool RecVolumes5::Restore(RAROptions *Cmd,const wchar *Name,bool Silent)
144
bool RecVolumes5::Restore(CommandData *Cmd,const wchar *Name,bool Silent)
145
{
145
{
146
  wchar ArcName[NM];
146
  wchar ArcName[NM];
147
  wcsncpyz(ArcName,Name,ASIZE(ArcName));
147
  wcsncpyz(ArcName,Name,ASIZE(ArcName));
Lines 494-500 Link Here
494
}
494
}
495
495
496
496
497
void RecVolumes5::Test(RAROptions *Cmd,const wchar *Name)
497
void RecVolumes5::Test(CommandData *Cmd,const wchar *Name)
498
{
498
{
499
  wchar VolName[NM];
499
  wchar VolName[NM];
500
  wcsncpyz(VolName,Name,ASIZE(VolName));
500
  wcsncpyz(VolName,Name,ASIZE(VolName));
(-)unrar-6.1.7/rijndael.cpp (-7 / +91 lines)
Lines 90-107 Link Here
90
90
91
void Rijndael::Init(bool Encrypt,const byte *key,uint keyLen,const byte * initVector)
91
void Rijndael::Init(bool Encrypt,const byte *key,uint keyLen,const byte * initVector)
92
{
92
{
93
#ifdef USE_SSE
93
  // Check SIMD here instead of constructor, so if object is a part of some
94
  // Check SSE here instead of constructor, so if object is a part of some
94
  // structure memset'ed before use, these variables are not lost.
95
  // structure memset'ed before use, this variable is not lost.
95
#if defined(USE_SSE)
96
  int CPUInfo[4];
96
  int CPUInfo[4];
97
  __cpuid(CPUInfo, 0x80000000); // Get the maximum supported cpuid function.
97
  __cpuid(CPUInfo, 0);
98
  if ((CPUInfo[0] & 0x7fffffff)>=1)
98
  if (CPUInfo[0]>=1) // Check the maximum supported cpuid function.
99
  {
99
  {
100
    __cpuid(CPUInfo, 1);
100
    __cpuid(CPUInfo, 1);
101
    AES_NI=(CPUInfo[2] & 0x2000000)!=0;
101
    AES_NI=(CPUInfo[2] & 0x2000000)!=0;
102
  }
102
  }
103
  else
103
  else
104
    AES_NI=false;
104
    AES_NI=false;
105
#elif defined(USE_NEON)
106
  AES_Neon=(getauxval(AT_HWCAP) & HWCAP_AES)!=0;
105
#endif
107
#endif
106
108
107
  // Other developers asked us to initialize it to suppress "may be used
109
  // Other developers asked us to initialize it to suppress "may be used
Lines 141-158 Link Here
141
    keyEncToDec();
143
    keyEncToDec();
142
}
144
}
143
145
146
144
void Rijndael::blockEncrypt(const byte *input,size_t inputLen,byte *outBuffer)
147
void Rijndael::blockEncrypt(const byte *input,size_t inputLen,byte *outBuffer)
145
{
148
{
146
  if (inputLen <= 0)
149
  if (inputLen <= 0)
147
    return;
150
    return;
148
151
149
  size_t numBlocks = inputLen/16;
152
  size_t numBlocks = inputLen/16;
150
#ifdef USE_SSE
153
#if defined(USE_SSE)
151
  if (AES_NI)
154
  if (AES_NI)
152
  {
155
  {
153
    blockEncryptSSE(input,numBlocks,outBuffer);
156
    blockEncryptSSE(input,numBlocks,outBuffer);
154
    return;
157
    return;
155
  }
158
  }
159
#elif defined(USE_NEON)
160
  if (AES_Neon)
161
  {
162
    blockEncryptNeon(input,numBlocks,outBuffer);
163
    return;
164
  }
156
#endif
165
#endif
157
  
166
  
158
  byte *prevBlock = m_initVector;
167
  byte *prevBlock = m_initVector;
Lines 239-244 Link Here
239
}
248
}
240
#endif
249
#endif
241
250
251
252
#ifdef USE_NEON
253
void Rijndael::blockEncryptNeon(const byte *input,size_t numBlocks,byte *outBuffer)
254
{
255
  byte *prevBlock = m_initVector;
256
  while (numBlocks > 0)
257
  {
258
    byte block[16];
259
    if (CBCMode)
260
      vst1q_u8(block, veorq_u8(vld1q_u8(prevBlock), vld1q_u8(input)));
261
    else
262
      vst1q_u8(block, vld1q_u8(input));
263
264
    uint8x16_t data = vld1q_u8(block);
265
    for (uint i = 0; i < m_uRounds-1; i++)
266
    {
267
      data = vaeseq_u8(data, vld1q_u8((byte *)m_expandedKey[i]));
268
      data = vaesmcq_u8(data);
269
    }
270
    data = vaeseq_u8(data, vld1q_u8((byte *)(m_expandedKey[m_uRounds-1])));
271
    data = veorq_u8(data, vld1q_u8((byte *)(m_expandedKey[m_uRounds])));
272
    vst1q_u8(outBuffer, data);
273
274
    prevBlock=outBuffer;
275
276
    outBuffer += 16;
277
    input += 16;
278
    numBlocks--;
279
  }
280
  vst1q_u8(m_initVector, vld1q_u8(prevBlock));
281
  return;
282
}
283
#endif
284
242
  
285
  
243
void Rijndael::blockDecrypt(const byte *input, size_t inputLen, byte *outBuffer)
286
void Rijndael::blockDecrypt(const byte *input, size_t inputLen, byte *outBuffer)
244
{
287
{
Lines 246-257 Link Here
246
    return;
289
    return;
247
290
248
  size_t numBlocks=inputLen/16;
291
  size_t numBlocks=inputLen/16;
249
#ifdef USE_SSE
292
#if defined(USE_SSE)
250
  if (AES_NI)
293
  if (AES_NI)
251
  {
294
  {
252
    blockDecryptSSE(input,numBlocks,outBuffer);
295
    blockDecryptSSE(input,numBlocks,outBuffer);
253
    return;
296
    return;
254
  }
297
  }
298
#elif defined(USE_NEON)
299
  if (AES_Neon)
300
  {
301
    blockDecryptNeon(input,numBlocks,outBuffer);
302
    return;
303
  }
255
#endif
304
#endif
256
305
257
  byte block[16], iv[4][4];
306
  byte block[16], iv[4][4];
Lines 339-344 Link Here
339
    numBlocks--;
388
    numBlocks--;
340
  }
389
  }
341
  _mm_storeu_si128((__m128i*)m_initVector,initVector);
390
  _mm_storeu_si128((__m128i*)m_initVector,initVector);
391
}
392
#endif
393
394
395
#ifdef USE_NEON
396
void Rijndael::blockDecryptNeon(const byte *input, size_t numBlocks, byte *outBuffer)
397
{
398
  byte iv[16];
399
  memcpy(iv,m_initVector,16);
400
401
  while (numBlocks > 0)
402
  {
403
    uint8x16_t data = vld1q_u8(input);
404
405
    for (int i=m_uRounds-1; i>0; i--)
406
    {
407
      data = vaesdq_u8(data, vld1q_u8((byte *)m_expandedKey[i+1]));
408
      data = vaesimcq_u8(data);
409
    }
410
411
    data = vaesdq_u8(data, vld1q_u8((byte *)m_expandedKey[1]));
412
    data = veorq_u8(data, vld1q_u8((byte *)m_expandedKey[0]));
413
414
    if (CBCMode)
415
      data = veorq_u8(data, vld1q_u8(iv));
416
417
    vst1q_u8(iv, vld1q_u8(input));
418
    vst1q_u8(outBuffer, data);
419
420
    input += 16;
421
    outBuffer += 16;
422
    numBlocks--;
423
  }
424
425
  memcpy(m_initVector,iv,16);
342
}
426
}
343
#endif
427
#endif
344
428
(-)unrar-6.1.7/rijndael.hpp (+10 lines)
Lines 18-23 Link Here
18
18
19
    bool AES_NI;
19
    bool AES_NI;
20
#endif
20
#endif
21
#ifdef USE_NEON
22
    // Set "crypto" attribute as replacement of -march=armv8-a+crypto switch.
23
    __attribute__((target("crypto")))
24
    void blockEncryptNeon(const byte *input,size_t numBlocks,byte *outBuffer);
25
    __attribute__((target("crypto")))
26
    void blockDecryptNeon(const byte *input, size_t numBlocks, byte *outBuffer);
27
28
    bool AES_Neon;
29
#endif
30
21
    void keySched(byte key[_MAX_KEY_COLUMNS][4]);
31
    void keySched(byte key[_MAX_KEY_COLUMNS][4]);
22
    void keyEncToDec();
32
    void keyEncToDec();
23
    void GenerateTables();
33
    void GenerateTables();
(-)unrar-6.1.7/scantree.cpp (-4 / +15 lines)
Lines 215-224 Link Here
215
  UnixSlashToDos(CurMask,CurMask,ASIZE(CurMask));
215
  UnixSlashToDos(CurMask,CurMask,ASIZE(CurMask));
216
#endif
216
#endif
217
217
218
  // We wish to scan entire disk if mask like c:\ is specified
218
  // We prefer to scan entire disk if mask like \\server\share\ or c:\
219
  // regardless of recursion mode. Use c:\*.* mask when need to scan only 
219
  // is specified regardless of recursion mode. Use \\server\share\*.*
220
  // the root directory.
220
  // or c:\*.* mask to scan only the root directory.
221
  ScanEntireDisk=IsDriveLetter(CurMask) && IsPathDiv(CurMask[2]) && CurMask[3]==0;
221
  if (CurMask[0]=='\\' && CurMask[1]=='\\')
222
  {
223
    const wchar *Slash=wcschr(CurMask+2,'\\');
224
    if (Slash!=NULL)
225
    {
226
      Slash=wcschr(Slash+1,'\\');
227
      ScanEntireDisk=Slash!=NULL && *(Slash+1)==0;
228
    }
229
  }
230
  else
231
    ScanEntireDisk=IsDriveLetter(CurMask) && IsPathDiv(CurMask[2]) && CurMask[3]==0;
232
222
233
223
  wchar *Name=PointToName(CurMask);
234
  wchar *Name=PointToName(CurMask);
224
  if (*Name==0)
235
  if (*Name==0)
(-)unrar-6.1.7/secpassword.cpp (-11 / +13 lines)
Lines 56-62 Link Here
56
56
57
SecPassword::SecPassword()
57
SecPassword::SecPassword()
58
{
58
{
59
  CrossProcess=false;
60
  Set(L"");
59
  Set(L"");
61
}
60
}
62
61
Lines 70-76 Link Here
70
void SecPassword::Clean()
69
void SecPassword::Clean()
71
{
70
{
72
  PasswordSet=false;
71
  PasswordSet=false;
73
  cleandata(Password,sizeof(Password));
72
  if (Password.size()>0)
73
    cleandata(&Password[0],Password.size());
74
}
74
}
75
 
75
 
76
76
Lines 104-110 Link Here
104
  // Source string can be shorter than destination as in case when we process
104
  // Source string can be shorter than destination as in case when we process
105
  // -p<pwd> parameter, so we need to take into account both sizes.
105
  // -p<pwd> parameter, so we need to take into account both sizes.
106
  memcpy(Dst,Src,Min(SrcSize,DstSize)*sizeof(*Dst));
106
  memcpy(Dst,Src,Min(SrcSize,DstSize)*sizeof(*Dst));
107
  SecHideData(Dst,DstSize*sizeof(*Dst),Encode,CrossProcess);
107
  SecHideData(Dst,DstSize*sizeof(*Dst),Encode,false);
108
}
108
}
109
109
110
110
Lines 112-118 Link Here
112
{
112
{
113
  if (PasswordSet)
113
  if (PasswordSet)
114
  {
114
  {
115
    Process(Password,ASIZE(Password),Psw,MaxSize,false);
115
    Process(&Password[0],Password.size(),Psw,MaxSize,false);
116
    Psw[MaxSize-1]=0;
116
    Psw[MaxSize-1]=0;
117
  }
117
  }
118
  else
118
  else
Lines 124-138 Link Here
124
124
125
void SecPassword::Set(const wchar *Psw)
125
void SecPassword::Set(const wchar *Psw)
126
{
126
{
127
  if (*Psw==0)
127
  // Eliminate any traces of previously stored password for security reason
128
  // in case it was longer than new one.
129
  Clean();
130
131
  if (*Psw!=0)
128
  {
132
  {
129
    PasswordSet=false;
130
    memset(Password,0,sizeof(Password));
131
  }
132
  else
133
  {
134
    PasswordSet=true;
133
    PasswordSet=true;
135
    Process(Psw,wcslen(Psw)+1,Password,ASIZE(Password),true);
134
    Process(Psw,wcslen(Psw)+1,&Password[0],Password.size(),true);
136
  }
135
  }
137
}
136
}
138
137
Lines 163-168 Link Here
163
}
162
}
164
163
165
164
165
// Set CrossProcess to true if we need to pass a password to another process.
166
// We use CrossProcess when transferring parameters to UAC elevated WinRAR
167
// and Windows GUI SFX modules.
166
void SecHideData(void *Data,size_t DataSize,bool Encode,bool CrossProcess)
168
void SecHideData(void *Data,size_t DataSize,bool Encode,bool CrossProcess)
167
{
169
{
168
  // CryptProtectMemory is not available in UWP and CryptProtectData
170
  // CryptProtectMemory is not available in UWP and CryptProtectData
(-)unrar-6.1.7/secpassword.hpp (-8 / +1 lines)
Lines 8-17 Link Here
8
  private:
8
  private:
9
    void Process(const wchar *Src,size_t SrcSize,wchar *Dst,size_t DstSize,bool Encode);
9
    void Process(const wchar *Src,size_t SrcSize,wchar *Dst,size_t DstSize,bool Encode);
10
10
11
    wchar Password[MAXPASSWORD];
11
    std::vector<wchar> Password = std::vector<wchar>(MAXPASSWORD);
12
13
    // It is important to have this 'bool' value, so if our object is cleaned
14
    // with memset as a part of larger structure, it is handled correctly.
15
    bool PasswordSet;
12
    bool PasswordSet;
16
  public:
13
  public:
17
    SecPassword();
14
    SecPassword();
Lines 22-31 Link Here
22
    bool IsSet() {return PasswordSet;}
19
    bool IsSet() {return PasswordSet;}
23
    size_t Length();
20
    size_t Length();
24
    bool operator == (SecPassword &psw);
21
    bool operator == (SecPassword &psw);
25
26
    // Set to true if we need to pass a password to another process.
27
    // We use it when transferring parameters to UAC elevated WinRAR.
28
    bool CrossProcess;
29
};
22
};
30
23
31
24
(-)unrar-6.1.7/strfn.cpp (+26 lines)
Lines 357-362 Link Here
357
}
357
}
358
358
359
359
360
// Convert the number to string using thousand separators.
361
void fmtitoa(int64 n,wchar *Str,size_t MaxSize)
362
{
363
  static wchar ThSep=0; // Thousands separator.
364
#ifdef _WIN_ALL
365
  wchar Info[10];
366
  if (!ThSep!=0 && GetLocaleInfo(LOCALE_USER_DEFAULT,LOCALE_STHOUSAND,Info,ASIZE(Info))>0)
367
    ThSep=*Info;
368
#elif defined(_UNIX)
369
  ThSep=*localeconv()->thousands_sep;
370
#endif
371
  if (ThSep==0) // If failed to detect the actual separator value.
372
    ThSep=' ';
373
  wchar RawText[30]; // 20 characters are enough for largest unsigned 64 bit int.
374
  itoa(n,RawText,ASIZE(RawText));
375
  uint S=0,D=0,L=wcslen(RawText)%3;
376
  while (RawText[S]!=0 && D+1<MaxSize)
377
  {
378
    if (S!=0 && (S+3-L)%3==0)
379
      Str[D++]=ThSep;
380
    Str[D++]=RawText[S++];
381
  }
382
  Str[D]=0;
383
}
384
385
360
const wchar* GetWide(const char *Src)
386
const wchar* GetWide(const char *Src)
361
{
387
{
362
  const size_t MaxLength=NM;
388
  const size_t MaxLength=NM;
(-)unrar-6.1.7/strfn.hpp (+1 lines)
Lines 42-47 Link Here
42
42
43
void itoa(int64 n,char *Str,size_t MaxSize);
43
void itoa(int64 n,char *Str,size_t MaxSize);
44
void itoa(int64 n,wchar *Str,size_t MaxSize);
44
void itoa(int64 n,wchar *Str,size_t MaxSize);
45
void fmtitoa(int64 n,wchar *Str,size_t MaxSize);
45
const wchar* GetWide(const char *Src);
46
const wchar* GetWide(const char *Src);
46
const wchar* GetCmdParam(const wchar *CmdLine,wchar *Param,size_t MaxSize);
47
const wchar* GetCmdParam(const wchar *CmdLine,wchar *Param,size_t MaxSize);
47
#ifndef RARDLL
48
#ifndef RARDLL
(-)unrar-6.1.7/system.cpp (-3 / +3 lines)
Lines 187-196 Link Here
187
SSE_VERSION GetSSEVersion()
187
SSE_VERSION GetSSEVersion()
188
{
188
{
189
  int CPUInfo[4];
189
  int CPUInfo[4];
190
  __cpuid(CPUInfo, 0x80000000);
190
  __cpuid(CPUInfo, 0);
191
191
192
  // Maximum supported cpuid function. For example, Pentium M 755 returns 4 here.
192
  // Maximum supported cpuid function.
193
  uint MaxSupported=CPUInfo[0] & 0x7fffffff;
193
  uint MaxSupported=CPUInfo[0];
194
194
195
  if (MaxSupported>=7)
195
  if (MaxSupported>=7)
196
  {
196
  {
(-)unrar-6.1.7/threadmisc.cpp (+2 lines)
Lines 149-151 Link Here
149
  return NumCPU;
149
  return NumCPU;
150
}
150
}
151
151
152
153
(-)unrar-6.1.7/timefn.hpp (+11 lines)
Lines 22-27 Link Here
22
22
23
    // Internal time representation in 1/TICKS_PER_SECOND since 01.01.1601.
23
    // Internal time representation in 1/TICKS_PER_SECOND since 01.01.1601.
24
    // We use nanoseconds here to handle the high precision Unix time.
24
    // We use nanoseconds here to handle the high precision Unix time.
25
    // It allows dates up to July 2185.
26
    //
27
    // If we'll ever need to extend the date range, we can define a lower
28
    // precision Windows version of TICKS_PER_SECOND. But then Unix and Windows
29
    // versions can differ in least significant digits of "lt" time output
30
    // for Unix archives.
31
    // Alternatively we can introduce 'bool HighPrecision' set to true
32
    // in SetUnixNS() and TicksPerSecond() instead of constant above.
33
    // It might be more reliable than defining TicksPerSecond variable,
34
    // which wouldn't survive memset of any structure hosting RarTime.
35
    // We would need to eliminate all such memsets in the entire code first.
25
    uint64 itime;
36
    uint64 itime;
26
  public:
37
  public:
27
    // RarLocalTime::Reminder precision. Must be equal to TICKS_PER_SECOND.
38
    // RarLocalTime::Reminder precision. Must be equal to TICKS_PER_SECOND.
(-)unrar-6.1.7/ui.hpp (-18 / +19 lines)
Lines 49-55 Link Here
49
  UIMSG_CORRECTINGNAME, UIMSG_BADARCHIVE, UIMSG_CREATING, UIMSG_RENAMING,
49
  UIMSG_CORRECTINGNAME, UIMSG_BADARCHIVE, UIMSG_CREATING, UIMSG_RENAMING,
50
  UIMSG_RECVOLCALCCHECKSUM, UIMSG_RECVOLFOUND, UIMSG_RECVOLMISSING,
50
  UIMSG_RECVOLCALCCHECKSUM, UIMSG_RECVOLFOUND, UIMSG_RECVOLMISSING,
51
  UIMSG_MISSINGVOL, UIMSG_RECONSTRUCTING, UIMSG_CHECKSUM, UIMSG_FAT32SIZE,
51
  UIMSG_MISSINGVOL, UIMSG_RECONSTRUCTING, UIMSG_CHECKSUM, UIMSG_FAT32SIZE,
52
  UIMSG_SKIPENCARC,
52
  UIMSG_SKIPENCARC, UIMSG_FILERENAME,
53
53
54
  UIWAIT_FIRST,
54
  UIWAIT_FIRST,
55
  UIWAIT_DISKFULLNEXT, UIWAIT_FCREATEERROR, UIWAIT_BADPSW,
55
  UIWAIT_DISKFULLNEXT, UIWAIT_FCREATEERROR, UIWAIT_BADPSW,
Lines 77-83 Link Here
77
};
77
};
78
78
79
UIASKREP_RESULT uiAskReplace(wchar *Name,size_t MaxNameSize,int64 FileSize,RarTime *FileTime,uint Flags);
79
UIASKREP_RESULT uiAskReplace(wchar *Name,size_t MaxNameSize,int64 FileSize,RarTime *FileTime,uint Flags);
80
UIASKREP_RESULT uiAskReplaceEx(RAROptions *Cmd,wchar *Name,size_t MaxNameSize,int64 FileSize,RarTime *FileTime,uint Flags);
80
UIASKREP_RESULT uiAskReplaceEx(CommandData *Cmd,wchar *Name,size_t MaxNameSize,int64 FileSize,RarTime *FileTime,uint Flags);
81
81
82
void uiInit(SOUND_NOTIFY_MODE Sound);
82
void uiInit(SOUND_NOTIFY_MODE Sound);
83
83
Lines 88-94 Link Here
88
void uiProcessProgress(const char *Command,int64 CurSize,int64 TotalSize);
88
void uiProcessProgress(const char *Command,int64 CurSize,int64 TotalSize);
89
89
90
enum UIPASSWORD_TYPE {UIPASSWORD_GLOBAL,UIPASSWORD_FILE,UIPASSWORD_ARCHIVE};
90
enum UIPASSWORD_TYPE {UIPASSWORD_GLOBAL,UIPASSWORD_FILE,UIPASSWORD_ARCHIVE};
91
bool uiGetPassword(UIPASSWORD_TYPE Type,const wchar *FileName,SecPassword *Password);
91
bool uiGetPassword(UIPASSWORD_TYPE Type,const wchar *FileName,SecPassword *Password,CheckPassword *CheckPwd);
92
bool uiIsGlobalPasswordSet();
92
bool uiIsGlobalPasswordSet();
93
93
94
enum UIALARM_TYPE {UIALARM_ERROR, UIALARM_INFO, UIALARM_QUESTION};
94
enum UIALARM_TYPE {UIALARM_ERROR, UIALARM_INFO, UIALARM_QUESTION};
Lines 145-174 Link Here
145
// Templates recognize usual NULL as integer, not wchar*.
145
// Templates recognize usual NULL as integer, not wchar*.
146
#define UINULL ((wchar *)NULL)
146
#define UINULL ((wchar *)NULL)
147
147
148
inline void uiMsg(UIMESSAGE_CODE Code)
148
inline void uiMsgBase(uiMsgStore &Store)
149
{
149
{
150
  uiMsgStore Store(Code);
150
  // Called last, when no parameters are left.
151
  Store.Msg();
152
}
151
}
153
152
154
template<class T1> void uiMsg(UIMESSAGE_CODE Code,T1 a1)
153
template<class T1,class... TN> void uiMsgBase(uiMsgStore &Store,T1&& a1,TN&&... aN)
155
{
154
{
156
  uiMsgStore Store(Code);
155
  // Process first parameter and pass the rest to same uiMsgBase.
157
  Store<<a1;
156
  Store<<a1;
158
  Store.Msg();
157
  uiMsgBase(Store,aN...);
159
}
158
}
160
159
161
template<class T1,class T2> void uiMsg(UIMESSAGE_CODE Code,T1 a1,T2 a2)
162
{
163
  uiMsgStore Store(Code);
164
  Store<<a1<<a2;
165
  Store.Msg();
166
}
167
160
168
template<class T1,class T2,class T3> void uiMsg(UIMESSAGE_CODE code,T1 a1,T2 a2,T3 a3)
161
// Use variadic templates.
162
//
163
// We must pass variable parameters by reference, so no temporary copies are
164
// created for custom string objects like CStringBase in 7-Zip decompression
165
// code. Such temporary copies would be destroyed inside of recursive
166
// uiMsgBase calls, leaving us with Str[] items pointing at released memory.
167
// Since we pass integer values as well, we can't use & references
168
// and must resort to && rvalue references.
169
template<class... TN> void uiMsg(UIMESSAGE_CODE Code,TN&&... aN)
169
{
170
{
170
  uiMsgStore Store(code);
171
  uiMsgStore Store(Code);
171
  Store<<a1<<a2<<a3;
172
  uiMsgBase(Store,aN...);
172
  Store.Msg();
173
  Store.Msg();
173
}
174
}
174
175
(-)unrar-6.1.7/uicommon.cpp (-1 / +1 lines)
Lines 8-14 Link Here
8
8
9
// Additionally to handling user input, it analyzes and sets command options.
9
// Additionally to handling user input, it analyzes and sets command options.
10
// Returns only 'replace', 'skip' and 'cancel' codes.
10
// Returns only 'replace', 'skip' and 'cancel' codes.
11
UIASKREP_RESULT uiAskReplaceEx(RAROptions *Cmd,wchar *Name,size_t MaxNameSize,int64 FileSize,RarTime *FileTime,uint Flags)
11
UIASKREP_RESULT uiAskReplaceEx(CommandData *Cmd,wchar *Name,size_t MaxNameSize,int64 FileSize,RarTime *FileTime,uint Flags)
12
{
12
{
13
  if (Cmd->Overwrite==OVERWRITE_NONE)
13
  if (Cmd->Overwrite==OVERWRITE_NONE)
14
    return UIASKREP_R_SKIP;
14
    return UIASKREP_R_SKIP;
(-)unrar-6.1.7/uiconsole.cpp (-1 / +3 lines)
Lines 262-267 Link Here
262
      break;
262
      break;
263
    case UIERROR_MISSINGVOL:
263
    case UIERROR_MISSINGVOL:
264
      Log(Str[0],St(MAbsNextVol),Str[0]);
264
      Log(Str[0],St(MAbsNextVol),Str[0]);
265
      mprintf(L"     "); // For progress percent.
265
      break;
266
      break;
266
#ifndef SFX_MODULE
267
#ifndef SFX_MODULE
267
    case UIERROR_NEEDPREVVOL:
268
    case UIERROR_NEEDPREVVOL:
Lines 395-401 Link Here
395
}
396
}
396
397
397
398
398
bool uiGetPassword(UIPASSWORD_TYPE Type,const wchar *FileName,SecPassword *Password)
399
bool uiGetPassword(UIPASSWORD_TYPE Type,const wchar *FileName,
400
                   SecPassword *Password,CheckPassword *CheckPwd)
399
{
401
{
400
  // Unlike GUI we cannot provide Cancel button here, so we use the empty
402
  // Unlike GUI we cannot provide Cancel button here, so we use the empty
401
  // password to abort. Otherwise user not knowing a password would need to
403
  // password to abort. Otherwise user not knowing a password would need to
(-)unrar-6.1.7/uisilent.cpp (-1 / +2 lines)
Lines 33-39 Link Here
33
}
33
}
34
34
35
35
36
bool uiGetPassword(UIPASSWORD_TYPE Type,const wchar *FileName,SecPassword *Password)
36
bool uiGetPassword(UIPASSWORD_TYPE Type,const wchar *FileName,
37
                   SecPassword *Password,CheckPassword *CheckPwd)
37
{
38
{
38
  return false;
39
  return false;
39
}
40
}
(-)unrar-6.1.7/ulinks.cpp (-4 / +4 lines)
Lines 70-76 Link Here
70
}
70
}
71
71
72
72
73
bool ExtractUnixLink30(CommandData *Cmd,ComprDataIO &DataIO,Archive &Arc,const wchar *LinkName)
73
static bool ExtractUnixLink30(CommandData *Cmd,ComprDataIO &DataIO,Archive &Arc,
74
                              const wchar *LinkName,bool &UpLink)
74
{
75
{
75
  char Target[NM];
76
  char Target[NM];
76
  if (IsLink(Arc.FileHead.FileAttr))
77
  if (IsLink(Arc.FileHead.FileAttr))
Lines 100-112 Link Here
100
    if (!Cmd->AbsoluteLinks && (IsFullPath(TargetW) ||
101
    if (!Cmd->AbsoluteLinks && (IsFullPath(TargetW) ||
101
        !IsRelativeSymlinkSafe(Cmd,Arc.FileHead.FileName,LinkName,TargetW)))
102
        !IsRelativeSymlinkSafe(Cmd,Arc.FileHead.FileName,LinkName,TargetW)))
102
      return false;
103
      return false;
104
    UpLink=strstr(Target,"..")!=NULL;
103
    return UnixSymlink(Cmd,Target,LinkName,&Arc.FileHead.mtime,&Arc.FileHead.atime);
105
    return UnixSymlink(Cmd,Target,LinkName,&Arc.FileHead.mtime,&Arc.FileHead.atime);
104
  }
106
  }
105
  return false;
107
  return false;
106
}
108
}
107
109
108
110
109
bool ExtractUnixLink50(CommandData *Cmd,const wchar *Name,FileHeader *hd)
111
static bool ExtractUnixLink50(CommandData *Cmd,const wchar *Name,FileHeader *hd)
110
{
112
{
111
  char Target[NM];
113
  char Target[NM];
112
  WideToChar(hd->RedirName,Target,ASIZE(Target));
114
  WideToChar(hd->RedirName,Target,ASIZE(Target));
Lines 127-134 Link Here
127
  // Use hd->FileName instead of LinkName, since LinkName can include
129
  // Use hd->FileName instead of LinkName, since LinkName can include
128
  // the destination path as a prefix, which can confuse
130
  // the destination path as a prefix, which can confuse
129
  // IsRelativeSymlinkSafe algorithm.
131
  // IsRelativeSymlinkSafe algorithm.
130
  // 2022.05.04: Use TargetW instead of previously used hd->RedirName
131
  // for security reason.
132
  if (!Cmd->AbsoluteLinks && (IsFullPath(TargetW) ||
132
  if (!Cmd->AbsoluteLinks && (IsFullPath(TargetW) ||
133
      !IsRelativeSymlinkSafe(Cmd,hd->FileName,Name,TargetW)))
133
      !IsRelativeSymlinkSafe(Cmd,hd->FileName,Name,TargetW)))
134
    return false;
134
    return false;
(-)unrar-6.1.7/unicode.cpp (-3 / +4 lines)
Lines 229-238 Link Here
229
#endif
229
#endif
230
230
231
231
232
// SrcSize is in wide characters, not in bytes.
232
// SrcSize is source data size in wide characters, not in bytes.
233
byte* WideToRaw(const wchar *Src,byte *Dest,size_t SrcSize)
233
// DestSize is the maximum allowed destination size.
234
byte* WideToRaw(const wchar *Src,size_t SrcSize,byte *Dest,size_t DestSize)
234
{
235
{
235
  for (size_t I=0;I<SrcSize;I++,Src++)
236
  for (size_t I=0;I<SrcSize && I*2+1<DestSize;I++,Src++)
236
  {
237
  {
237
    Dest[I*2]=(byte)*Src;
238
    Dest[I*2]=(byte)*Src;
238
    Dest[I*2+1]=(byte)(*Src>>8);
239
    Dest[I*2+1]=(byte)(*Src>>8);
(-)unrar-6.1.7/unicode.hpp (-1 / +1 lines)
Lines 7-13 Link Here
7
7
8
bool WideToChar(const wchar *Src,char *Dest,size_t DestSize);
8
bool WideToChar(const wchar *Src,char *Dest,size_t DestSize);
9
bool CharToWide(const char *Src,wchar *Dest,size_t DestSize);
9
bool CharToWide(const char *Src,wchar *Dest,size_t DestSize);
10
byte* WideToRaw(const wchar *Src,byte *Dest,size_t SrcSize);
10
byte* WideToRaw(const wchar *Src,size_t SrcSize,byte *Dest,size_t DestSize);
11
wchar* RawToWide(const byte *Src,wchar *Dest,size_t DestSize);
11
wchar* RawToWide(const byte *Src,wchar *Dest,size_t DestSize);
12
void WideToUtf(const wchar *Src,char *Dest,size_t DestSize);
12
void WideToUtf(const wchar *Src,char *Dest,size_t DestSize);
13
size_t WideToUtfSize(const wchar *Src);
13
size_t WideToUtfSize(const wchar *Src);
(-)unrar-6.1.7/unpack.cpp (-1 / +1 lines)
Lines 309-315 Link Here
309
      Dec->QuickBits=MAX_QUICK_DECODE_BITS;
309
      Dec->QuickBits=MAX_QUICK_DECODE_BITS;
310
      break;
310
      break;
311
    default:
311
    default:
312
      Dec->QuickBits=MAX_QUICK_DECODE_BITS-3;
312
      Dec->QuickBits=MAX_QUICK_DECODE_BITS>3 ? MAX_QUICK_DECODE_BITS-3 : 0;
313
      break;
313
      break;
314
  }
314
  }
315
315
(-)unrar-6.1.7/unpack.hpp (-3 / +3 lines)
Lines 93-109 Link Here
93
93
94
#ifdef RAR_SMP
94
#ifdef RAR_SMP
95
enum UNP_DEC_TYPE {
95
enum UNP_DEC_TYPE {
96
  UNPDT_LITERAL,UNPDT_MATCH,UNPDT_FULLREP,UNPDT_REP,UNPDT_FILTER
96
  UNPDT_LITERAL=0,UNPDT_MATCH,UNPDT_FULLREP,UNPDT_REP,UNPDT_FILTER
97
};
97
};
98
98
99
struct UnpackDecodedItem
99
struct UnpackDecodedItem
100
{
100
{
101
  UNP_DEC_TYPE Type;
101
  byte Type; // 'byte' instead of enum type to reduce memory use.
102
  ushort Length;
102
  ushort Length;
103
  union
103
  union
104
  {
104
  {
105
    uint Distance;
105
    uint Distance;
106
    byte Literal[4];
106
    byte Literal[8]; // Store up to 8 chars here to speed up extraction.
107
  };
107
  };
108
};
108
};
109
109
(-)unrar-6.1.7/unpack30.cpp (-1 / +1 lines)
Lines 55-61 Link Here
55
      if (!UnpReadBuf30())
55
      if (!UnpReadBuf30())
56
        break;
56
        break;
57
    }
57
    }
58
    if (((WrPtr-UnpPtr) & MaxWinMask)<260 && WrPtr!=UnpPtr)
58
    if (((WrPtr-UnpPtr) & MaxWinMask)<=MAX3_INC_LZ_MATCH && WrPtr!=UnpPtr)
59
    {
59
    {
60
      UnpWriteBuf30();
60
      UnpWriteBuf30();
61
      if (WrittenFileSize>DestUnpSize)
61
      if (WrittenFileSize>DestUnpSize)
(-)unrar-6.1.7/unpack50.cpp (-2 / +2 lines)
Lines 42-48 Link Here
42
        break;
42
        break;
43
    }
43
    }
44
44
45
    if (((WriteBorder-UnpPtr) & MaxWinMask)<MAX_INC_LZ_MATCH && WriteBorder!=UnpPtr)
45
    if (((WriteBorder-UnpPtr) & MaxWinMask)<=MAX_INC_LZ_MATCH && WriteBorder!=UnpPtr)
46
    {
46
    {
47
      UnpWriteBuf();
47
      UnpWriteBuf();
48
      if (WrittenFileSize>DestUnpSize)
48
      if (WrittenFileSize>DestUnpSize)
Lines 93-99 Link Here
93
        }
93
        }
94
        else
94
        else
95
        {
95
        {
96
          Distance+=Inp.getbits32()>>(32-DBits);
96
          Distance+=Inp.getbits()>>(16-DBits);
97
          Inp.addbits(DBits);
97
          Inp.addbits(DBits);
98
        }
98
        }
99
      }
99
      }
(-)unrar-6.1.7/unpack50mt.cpp (-7 / +7 lines)
Lines 345-351 Link Here
345
      if (D.DecodedSize>1)
345
      if (D.DecodedSize>1)
346
      {
346
      {
347
        UnpackDecodedItem *PrevItem=CurItem-1;
347
        UnpackDecodedItem *PrevItem=CurItem-1;
348
        if (PrevItem->Type==UNPDT_LITERAL && PrevItem->Length<3)
348
        if (PrevItem->Type==UNPDT_LITERAL && PrevItem->Length<ASIZE(PrevItem->Literal)-1)
349
        {
349
        {
350
          PrevItem->Length++;
350
          PrevItem->Length++;
351
          PrevItem->Literal[PrevItem->Length]=(byte)MainSlot;
351
          PrevItem->Literal[PrevItem->Length]=(byte)MainSlot;
Lines 388-394 Link Here
388
        }
388
        }
389
        else
389
        else
390
        {
390
        {
391
          Distance+=D.Inp.getbits32()>>(32-DBits);
391
          Distance+=D.Inp.getbits()>>(16-DBits);
392
          D.Inp.addbits(DBits);
392
          D.Inp.addbits(DBits);
393
        }
393
        }
394
      }
394
      }
Lines 451-457 Link Here
451
  while (Item<Border)
451
  while (Item<Border)
452
  {
452
  {
453
    UnpPtr&=MaxWinMask;
453
    UnpPtr&=MaxWinMask;
454
    if (((WriteBorder-UnpPtr) & MaxWinMask)<MAX_INC_LZ_MATCH && WriteBorder!=UnpPtr)
454
    if (((WriteBorder-UnpPtr) & MaxWinMask)<=MAX_INC_LZ_MATCH && WriteBorder!=UnpPtr)
455
    {
455
    {
456
      UnpWriteBuf();
456
      UnpWriteBuf();
457
      if (WrittenFileSize>DestUnpSize)
457
      if (WrittenFileSize>DestUnpSize)
Lines 461-470 Link Here
461
    if (Item->Type==UNPDT_LITERAL)
461
    if (Item->Type==UNPDT_LITERAL)
462
    {
462
    {
463
#if defined(LITTLE_ENDIAN) && defined(ALLOW_MISALIGNED)
463
#if defined(LITTLE_ENDIAN) && defined(ALLOW_MISALIGNED)
464
      if (Item->Length==3 && UnpPtr<MaxWinSize-4)
464
      if (Item->Length==7 && UnpPtr<MaxWinSize-8)
465
      {
465
      {
466
        *(uint32 *)(Window+UnpPtr)=*(uint32 *)Item->Literal;
466
        *(uint64 *)(Window+UnpPtr)=*(uint64 *)(Item->Literal);
467
        UnpPtr+=4;
467
         UnpPtr+=8;
468
      }
468
      }
469
      else
469
      else
470
#endif
470
#endif
Lines 559-565 Link Here
559
        break;
559
        break;
560
      }
560
      }
561
    }
561
    }
562
    if (((WriteBorder-UnpPtr) & MaxWinMask)<MAX_INC_LZ_MATCH && WriteBorder!=UnpPtr)
562
    if (((WriteBorder-UnpPtr) & MaxWinMask)<=MAX_INC_LZ_MATCH && WriteBorder!=UnpPtr)
563
    {
563
    {
564
      UnpWriteBuf();
564
      UnpWriteBuf();
565
      if (WrittenFileSize>DestUnpSize)
565
      if (WrittenFileSize>DestUnpSize)
(-)unrar-6.1.7/version.hpp (-4 / +4 lines)
Lines 1-6 Link Here
1
#define RARVER_MAJOR     6
1
#define RARVER_MAJOR     6
2
#define RARVER_MINOR    12
2
#define RARVER_MINOR    22
3
#define RARVER_BETA      0
3
#define RARVER_BETA      1
4
#define RARVER_DAY       4
4
#define RARVER_DAY      14
5
#define RARVER_MONTH     5
5
#define RARVER_MONTH     5
6
#define RARVER_YEAR   2022
6
#define RARVER_YEAR   2023
(-)unrar-6.1.7/volume.cpp (-5 / +5 lines)
Lines 1-15 Link Here
1
#include "rar.hpp"
1
#include "rar.hpp"
2
2
3
#ifdef RARDLL
3
#ifdef RARDLL
4
static bool DllVolChange(RAROptions *Cmd,wchar *NextName,size_t NameSize);
4
static bool DllVolChange(CommandData *Cmd,wchar *NextName,size_t NameSize);
5
static bool DllVolNotify(RAROptions *Cmd,wchar *NextName);
5
static bool DllVolNotify(CommandData *Cmd,wchar *NextName);
6
#endif
6
#endif
7
7
8
8
9
9
10
bool MergeArchive(Archive &Arc,ComprDataIO *DataIO,bool ShowFileName,wchar Command)
10
bool MergeArchive(Archive &Arc,ComprDataIO *DataIO,bool ShowFileName,wchar Command)
11
{
11
{
12
  RAROptions *Cmd=Arc.GetRAROptions();
12
  CommandData *Cmd=Arc.GetCommandData();
13
13
14
  HEADER_TYPE HeaderType=Arc.GetHeaderType();
14
  HEADER_TYPE HeaderType=Arc.GetHeaderType();
15
  FileHeader *hd=HeaderType==HEAD_SERVICE ? &Arc.SubHead:&Arc.FileHead;
15
  FileHeader *hd=HeaderType==HEAD_SERVICE ? &Arc.SubHead:&Arc.FileHead;
Lines 190-196 Link Here
190
190
191
191
192
#ifdef RARDLL
192
#ifdef RARDLL
193
bool DllVolChange(RAROptions *Cmd,wchar *NextName,size_t NameSize)
193
bool DllVolChange(CommandData *Cmd,wchar *NextName,size_t NameSize)
194
{
194
{
195
  bool DllVolChanged=false,DllVolAborted=false;
195
  bool DllVolChanged=false,DllVolAborted=false;
196
196
Lines 246-252 Link Here
246
246
247
247
248
#ifdef RARDLL
248
#ifdef RARDLL
249
bool DllVolNotify(RAROptions *Cmd,wchar *NextName)
249
bool DllVolNotify(CommandData *Cmd,wchar *NextName)
250
{
250
{
251
  char NextNameA[NM];
251
  char NextNameA[NM];
252
  WideToChar(NextName,NextNameA,ASIZE(NextNameA));
252
  WideToChar(NextName,NextNameA,ASIZE(NextNameA));
(-)unrar-6.1.7/volume.hpp (-3 lines)
Lines 1-10 Link Here
1
#ifndef _RAR_VOLUME_
1
#ifndef _RAR_VOLUME_
2
#define _RAR_VOLUME_
2
#define _RAR_VOLUME_
3
3
4
void SplitArchive(Archive &Arc,FileHeader *fh,int64 *HeaderPos,
5
                  ComprDataIO *DataIO);
6
bool MergeArchive(Archive &Arc,ComprDataIO *DataIO,bool ShowFileName,
4
bool MergeArchive(Archive &Arc,ComprDataIO *DataIO,bool ShowFileName,
7
                  wchar Command);
5
                  wchar Command);
8
void SetVolWrite(Archive &Dest,int64 VolSize);
9
6
10
#endif
7
#endif
(-)unrar-6.1.7/win32stm.cpp (-4 / +11 lines)
Lines 111-126 Link Here
111
111
112
  wcsncatz(FullName,StreamName,ASIZE(FullName));
112
  wcsncatz(FullName,StreamName,ASIZE(FullName));
113
113
114
114
  FindData fd;
115
  FindData fd;
115
  bool Found=FindFile::FastFind(FileName,&fd);
116
  bool HostFound=FindFile::FastFind(FileName,&fd);
116
117
117
  if ((fd.FileAttr & FILE_ATTRIBUTE_READONLY)!=0)
118
  if ((fd.FileAttr & FILE_ATTRIBUTE_READONLY)!=0)
118
    SetFileAttr(FileName,fd.FileAttr & ~FILE_ATTRIBUTE_READONLY);
119
    SetFileAttr(FileName,fd.FileAttr & ~FILE_ATTRIBUTE_READONLY);
119
  File CurFile;
120
  File CurFile;
120
  if (CurFile.WCreate(FullName) && Arc.ReadSubData(NULL,&CurFile,false))
121
121
    CurFile.Close();
122
  if (CurFile.WCreate(FullName))
123
  {
124
    if (Arc.ReadSubData(NULL,&CurFile,false))
125
      CurFile.Close();
126
  }
127
128
  // Restoring original file timestamps.
122
  File HostFile;
129
  File HostFile;
123
  if (Found && HostFile.Open(FileName,FMF_OPENSHARED|FMF_UPDATE))
130
  if (HostFound && HostFile.Open(FileName,FMF_OPENSHARED|FMF_UPDATE))
124
    SetFileTime(HostFile.GetHandle(),&fd.ftCreationTime,&fd.ftLastAccessTime,
131
    SetFileTime(HostFile.GetHandle(),&fd.ftCreationTime,&fd.ftLastAccessTime,
125
                &fd.ftLastWriteTime);
132
                &fd.ftLastWriteTime);
126
133

Return to bug 46318