Skip to content

Commit 9565df5

Browse files
committed
update unrar to 7.1.6 (fixes #4936)
1 parent d7b6b66 commit 9565df5

143 files changed

Lines changed: 5686 additions & 3764 deletions

File tree

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

ext/unrar/UnRAR.vcxproj

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -238,8 +238,10 @@
238238
<ClCompile Include="hash.cpp" />
239239
<ClCompile Include="headers.cpp" />
240240
<ClCompile Include="isnt.cpp" />
241+
<ClCompile Include="largepage.cpp" />
241242
<ClCompile Include="list.cpp" />
242243
<ClCompile Include="match.cpp" />
244+
<ClCompile Include="motw.cpp" />
243245
<ClCompile Include="options.cpp" />
244246
<ClCompile Include="pathfn.cpp" />
245247
<ClCompile Include="qopen.cpp" />

ext/unrar/UnRARDll.vcxproj

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -374,7 +374,9 @@
374374
<ClCompile Include="hash.cpp" />
375375
<ClCompile Include="headers.cpp" />
376376
<ClCompile Include="isnt.cpp" />
377+
<ClCompile Include="largepage.cpp" />
377378
<ClCompile Include="match.cpp" />
379+
<ClCompile Include="motw.cpp" />
378380
<ClCompile Include="options.cpp" />
379381
<ClCompile Include="pathfn.cpp" />
380382
<ClCompile Include="qopen.cpp" />

ext/unrar/arccmt.cpp

Lines changed: 37 additions & 35 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
static bool IsAnsiEscComment(const wchar *Data,size_t Size);
22

3-
bool Archive::GetComment(Array<wchar> *CmtData)
3+
bool Archive::GetComment(std::wstring &CmtData)
44
{
55
if (!MainComment)
66
return false;
@@ -11,7 +11,7 @@ bool Archive::GetComment(Array<wchar> *CmtData)
1111
}
1212

1313

14-
bool Archive::DoGetComment(Array<wchar> *CmtData)
14+
bool Archive::DoGetComment(std::wstring &CmtData)
1515
{
1616
#ifndef SFX_MODULE
1717
uint CmtLength;
@@ -36,7 +36,12 @@ bool Archive::DoGetComment(Array<wchar> *CmtData)
3636
{
3737
// Current (RAR 3.0+) version of archive comment.
3838
Seek(GetStartPos(),SEEK_SET);
39-
return SearchSubBlock(SUBHEAD_TYPE_CMT)!=0 && ReadCommentData(CmtData);
39+
if (SearchSubBlock(SUBHEAD_TYPE_CMT)!=0)
40+
if (ReadCommentData(CmtData))
41+
return true;
42+
else
43+
uiMsg(UIERROR_CMTBROKEN,FileName);
44+
return false;
4045
}
4146
#ifndef SFX_MODULE
4247
// Old style (RAR 2.9) comment header embedded into the main
@@ -101,67 +106,63 @@ bool Archive::DoGetComment(Array<wchar> *CmtData)
101106
// 4x memory for OEM to UTF-8 output here.
102107
OemToCharBuffA((char *)UnpData,(char *)UnpData,(DWORD)UnpDataSize);
103108
#endif
104-
CmtData->Alloc(UnpDataSize+1);
105-
memset(CmtData->Addr(0),0,CmtData->Size()*sizeof(wchar));
106-
CharToWide((char *)UnpData,CmtData->Addr(0),CmtData->Size());
107-
CmtData->Alloc(wcslen(CmtData->Addr(0)));
109+
std::string UnpStr((char*)UnpData,UnpDataSize);
110+
CharToWide(UnpStr,CmtData);
108111
}
109112
}
110113
}
111114
else
112115
{
113116
if (CmtLength==0)
114117
return false;
115-
Array<byte> CmtRaw(CmtLength);
116-
int ReadSize=Read(&CmtRaw[0],CmtLength);
118+
std::vector<byte> CmtRaw(CmtLength);
119+
int ReadSize=Read(CmtRaw.data(),CmtLength);
117120
if (ReadSize>=0 && (uint)ReadSize<CmtLength) // Comment is shorter than declared.
118121
{
119122
CmtLength=ReadSize;
120-
CmtRaw.Alloc(CmtLength);
123+
CmtRaw.resize(CmtLength);
121124
}
122125

123126
if (Format!=RARFMT14 && CommHead.CommCRC!=(~CRC32(0xffffffff,&CmtRaw[0],CmtLength)&0xffff))
124127
{
125128
uiMsg(UIERROR_CMTBROKEN,FileName);
126129
return false;
127130
}
128-
CmtData->Alloc(CmtLength+1);
129-
CmtRaw.Push(0);
131+
// CmtData.resize(CmtLength+1);
132+
CmtRaw.push_back(0);
130133
#ifdef _WIN_ALL
131134
// If we ever decide to extend it to Android, we'll need to alloc
132135
// 4x memory for OEM to UTF-8 output here.
133-
OemToCharA((char *)&CmtRaw[0],(char *)&CmtRaw[0]);
136+
OemToCharA((char *)CmtRaw.data(),(char *)CmtRaw.data());
134137
#endif
135-
CharToWide((char *)&CmtRaw[0],CmtData->Addr(0),CmtData->Size());
136-
CmtData->Alloc(wcslen(CmtData->Addr(0)));
138+
CharToWide((const char *)CmtRaw.data(),CmtData);
139+
// CmtData->resize(wcslen(CmtData->data()));
137140
}
138141
#endif
139-
return CmtData->Size() > 0;
142+
return CmtData.size() > 0;
140143
}
141144

142145

143-
bool Archive::ReadCommentData(Array<wchar> *CmtData)
146+
bool Archive::ReadCommentData(std::wstring &CmtData)
144147
{
145-
Array<byte> CmtRaw;
148+
std::vector<byte> CmtRaw;
146149
if (!ReadSubData(&CmtRaw,NULL,false))
147150
return false;
148-
size_t CmtSize=CmtRaw.Size();
149-
CmtRaw.Push(0);
150-
CmtData->Alloc(CmtSize+1);
151+
size_t CmtSize=CmtRaw.size();
152+
CmtRaw.push_back(0);
153+
// CmtData->resize(CmtSize+1);
151154
if (Format==RARFMT50)
152-
UtfToWide((char *)&CmtRaw[0],CmtData->Addr(0),CmtData->Size());
155+
UtfToWide((char *)CmtRaw.data(),CmtData);
153156
else
154157
if ((SubHead.SubFlags & SUBHEAD_FLAGS_CMT_UNICODE)!=0)
155158
{
156-
RawToWide(&CmtRaw[0],CmtData->Addr(0),CmtSize/2);
157-
(*CmtData)[CmtSize/2]=0;
158-
159+
CmtData=RawToWide(CmtRaw);
159160
}
160161
else
161162
{
162-
CharToWide((char *)&CmtRaw[0],CmtData->Addr(0),CmtData->Size());
163+
CharToWide((const char *)CmtRaw.data(),CmtData);
163164
}
164-
CmtData->Alloc(wcslen(CmtData->Addr(0))); // Set buffer size to actual comment length.
165+
// CmtData->resize(wcslen(CmtData->data())); // Set buffer size to actual comment length.
165166
return true;
166167
}
167168

@@ -170,15 +171,16 @@ void Archive::ViewComment()
170171
{
171172
if (Cmd->DisableComment)
172173
return;
173-
Array<wchar> CmtBuf;
174-
if (GetComment(&CmtBuf)) // In GUI too, so "Test" command detects broken comments.
174+
std::wstring CmtBuf;
175+
if (GetComment(CmtBuf)) // In GUI too, so "Test" command detects broken comments.
175176
{
176-
size_t CmtSize=CmtBuf.Size();
177-
wchar *ChPtr=wcschr(&CmtBuf[0],0x1A);
178-
if (ChPtr!=NULL)
179-
CmtSize=ChPtr-&CmtBuf[0];
180-
mprintf(L"\n");
181-
OutComment(&CmtBuf[0],CmtSize);
177+
size_t CmtSize=CmtBuf.size();
178+
auto EndPos=CmtBuf.find(0x1A);
179+
if (EndPos!=std::wstring::npos)
180+
CmtSize=EndPos;
181+
mprintf(St(MArcComment));
182+
mprintf(L":\n");
183+
OutComment(CmtBuf);
182184
}
183185
}
184186

ext/unrar/archive.cpp

Lines changed: 31 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -26,10 +26,12 @@ Archive::Archive(CommandData *InitCmd)
2626
FailedHeaderDecryption=false;
2727
BrokenHeader=false;
2828
LastReadBlock=0;
29+
CurHeaderType=HEAD_UNKNOWN;
2930

3031
CurBlockPos=0;
3132
NextBlockPos=0;
3233

34+
RecoveryPercent=-1;
3335

3436
MainHead.Reset();
3537
CryptHead={};
@@ -39,7 +41,6 @@ Archive::Archive(CommandData *InitCmd)
3941
VolWrite=0;
4042
AddingFilesSize=0;
4143
AddingHeadersSize=0;
42-
*FirstVolumeName=0;
4344

4445
Splitting=false;
4546
NewArchive=false;
@@ -68,21 +69,21 @@ void Archive::CheckArc(bool EnableBroken)
6869
// password is incorrect.
6970
if (!FailedHeaderDecryption)
7071
uiMsg(UIERROR_BADARCHIVE,FileName);
71-
ErrHandler.Exit(RARX_FATAL);
72+
ErrHandler.Exit(RARX_BADARC);
7273
}
7374
}
7475

7576

7677
#if !defined(SFX_MODULE)
77-
void Archive::CheckOpen(const wchar *Name)
78+
void Archive::CheckOpen(const std::wstring &Name)
7879
{
7980
TOpen(Name);
8081
CheckArc(false);
8182
}
8283
#endif
8384

8485

85-
bool Archive::WCheckOpen(const wchar *Name)
86+
bool Archive::WCheckOpen(const std::wstring &Name)
8687
{
8788
if (!WOpen(Name))
8889
return false;
@@ -110,9 +111,11 @@ RARFORMAT Archive::IsSignature(const byte *D,size_t Size)
110111
// We check the last signature byte, so we can return a sensible
111112
// warning in case we'll want to change the archive format
112113
// sometimes in the future.
114+
#ifndef SFX_MODULE
113115
if (D[6]==0)
114116
Type=RARFMT15;
115117
else
118+
#endif
116119
if (D[6]==1)
117120
Type=RARFMT50;
118121
else
@@ -148,9 +151,9 @@ bool Archive::IsArchive(bool EnableBroken)
148151
}
149152
else
150153
{
151-
Array<char> Buffer(MAXSFXSIZE);
154+
std::vector<char> Buffer(MAXSFXSIZE);
152155
long CurPos=(long)Tell();
153-
int ReadSize=Read(&Buffer[0],Buffer.Size()-16);
156+
int ReadSize=Read(Buffer.data(),Buffer.size()-16);
154157
for (int I=0;I<ReadSize;I++)
155158
if (Buffer[I]==0x52 && (Type=IsSignature((byte *)&Buffer[I],ReadSize-I))!=RARFMT_NONE)
156159
{
@@ -265,7 +268,7 @@ bool Archive::IsArchive(bool EnableBroken)
265268
Seek(SavePos,SEEK_SET);
266269
}
267270
if (!Volume || FirstVolume)
268-
wcsncpyz(FirstVolumeName,FileName,ASIZE(FirstVolumeName));
271+
FirstVolumeName=FileName;
269272

270273
return true;
271274
}
@@ -301,7 +304,7 @@ uint Archive::FullHeaderSize(size_t Size)
301304

302305

303306
#ifdef USE_QOPEN
304-
bool Archive::Open(const wchar *Name,uint Mode)
307+
bool Archive::Open(const std::wstring &Name,uint Mode)
305308
{
306309
// Important if we reuse Archive object and it has virtual QOpen
307310
// file position not matching real. For example, for 'l -v volname'.
@@ -336,3 +339,23 @@ int64 Archive::Tell()
336339
}
337340
#endif
338341

342+
343+
// Return 0 if dictionary size is invalid. If size is RAR7 only, return
344+
// the adjusted nearest bottom value. Return header flags in Flags.
345+
uint64 Archive::GetWinSize(uint64 Size,uint &Flags)
346+
{
347+
Flags=0;
348+
// Allow 128 KB - 1 TB range.
349+
if (Size<0x20000 || Size>0x10000000000ULL)
350+
return 0;
351+
uint64 Pow2=0x20000; // Power of 2 dictionary size.
352+
for (;2*Pow2<=Size;Pow2*=2)
353+
Flags+=FCI_DICT_BIT0;
354+
if (Size==Pow2)
355+
return Size; // If 'Size' is the power of 2, return it as is.
356+
357+
// Get the number of Pow2/32 to add to Pow2 for nearest value not exceeding 'Size'.
358+
uint64 Fraction=(Size-Pow2)/(Pow2/32);
359+
Flags+=(uint)Fraction*FCI_DICT_FRACT0;
360+
return Pow2+Fraction*(Pow2/32);
361+
}

ext/unrar/archive.hpp

Lines changed: 29 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -27,7 +27,7 @@ class Archive:public File
2727
{
2828
private:
2929
void UpdateLatestTime(FileHeader *CurBlock);
30-
void ConvertNameCase(wchar *Name);
30+
void ConvertNameCase(std::wstring &Name);
3131
void ConvertFileHeader(FileHeader *hd);
3232
size_t ReadHeader14();
3333
size_t ReadHeader15();
@@ -36,9 +36,9 @@ class Archive:public File
3636
void RequestArcPassword(RarCheckPassword *SelPwd);
3737
void UnexpEndArcMsg();
3838
void BrokenHeaderMsg();
39-
void UnkEncVerMsg(const wchar *Name,const wchar *Info);
40-
bool DoGetComment(Array<wchar> *CmtData);
41-
bool ReadCommentData(Array<wchar> *CmtData);
39+
void UnkEncVerMsg(const std::wstring &Name,const std::wstring &Info);
40+
bool DoGetComment(std::wstring &CmtData);
41+
bool ReadCommentData(std::wstring &CmtData);
4242

4343
#if !defined(RAR_NOCRYPT)
4444
CryptData HeadersCrypt;
@@ -47,6 +47,7 @@ class Archive:public File
4747
bool DummyCmd;
4848
CommandData *Cmd;
4949

50+
int RecoveryPercent;
5051

5152
RarTime LatestTime;
5253
int LastReadBlock;
@@ -58,18 +59,19 @@ class Archive:public File
5859
bool ProhibitQOpen;
5960
#endif
6061
public:
61-
Archive(CommandData *InitCmd=NULL);
62+
Archive(CommandData *InitCmd=nullptr);
6263
~Archive();
6364
static RARFORMAT IsSignature(const byte *D,size_t Size);
6465
bool IsArchive(bool EnableBroken);
6566
size_t SearchBlock(HEADER_TYPE HeaderType);
6667
size_t SearchSubBlock(const wchar *Type);
6768
size_t SearchRR();
69+
int GetRecoveryPercent() {return RecoveryPercent;}
6870
size_t ReadHeader();
6971
void CheckArc(bool EnableBroken);
70-
void CheckOpen(const wchar *Name);
71-
bool WCheckOpen(const wchar *Name);
72-
bool GetComment(Array<wchar> *CmtData);
72+
void CheckOpen(const std::wstring &Name);
73+
bool WCheckOpen(const std::wstring &Name);
74+
bool GetComment(std::wstring &CmtData);
7375
void ViewComment();
7476
void SetLatestTime(RarTime *NewTime);
7577
void SeekToNext();
@@ -79,23 +81,25 @@ class Archive:public File
7981
void VolSubtractHeaderSize(size_t SubSize);
8082
uint FullHeaderSize(size_t Size);
8183
int64 GetStartPos();
82-
void AddSubData(byte *SrcData,uint64 DataSize,File *SrcFile,
84+
void AddSubData(const byte *SrcData,uint64 DataSize,File *SrcFile,
8385
const wchar *Name,uint Flags);
84-
bool ReadSubData(Array<byte> *UnpData,File *DestFile,bool TestMode);
86+
bool ReadSubData(std::vector<byte> *UnpData,File *DestFile,bool TestMode);
8587
HEADER_TYPE GetHeaderType() {return CurHeaderType;}
8688
CommandData* GetCommandData() {return Cmd;}
8789
void SetSilentOpen(bool Mode) {SilentOpen=Mode;}
88-
#if 0
89-
void GetRecoveryInfo(bool Required,int64 *Size,int *Percent);
90-
#endif
9190
#ifdef USE_QOPEN
92-
bool Open(const wchar *Name,uint Mode=FMF_READ);
93-
int Read(void *Data,size_t Size);
94-
void Seek(int64 Offset,int Method);
95-
int64 Tell();
91+
bool Open(const std::wstring &Name,uint Mode=FMF_READ) override;
92+
int Read(void *Data,size_t Size) override;
93+
void Seek(int64 Offset,int Method) override;
94+
int64 Tell() override;
9695
void QOpenUnload() {QOpen.Unload();}
9796
void SetProhibitQOpen(bool Mode) {ProhibitQOpen=Mode;}
9897
#endif
98+
static uint64 GetWinSize(uint64 Size,uint &Flags);
99+
100+
// Needed to see wstring based Open from File. Otherwise compiler finds
101+
// Open in Archive and doesn't check the base class overloads.
102+
using File::Open;
99103

100104
BaseBlock ShortBlock;
101105
MarkHeader MarkHead;
@@ -107,7 +111,6 @@ class Archive:public File
107111
FileHeader SubHead;
108112
CommentHeader CommHead;
109113
ProtectHeader ProtectHead;
110-
UnixOwnersHeader UOHead;
111114
EAHeader EAHead;
112115
StreamHeader StreamHead;
113116

@@ -136,12 +139,19 @@ class Archive:public File
136139

137140
uint VolNumber;
138141
int64 VolWrite;
142+
143+
// Total size of files adding to archive. Might also include the size of
144+
// files repacked in solid archive.
139145
uint64 AddingFilesSize;
146+
140147
uint64 AddingHeadersSize;
141148

142149
bool NewArchive;
143150

144-
wchar FirstVolumeName[NM];
151+
std::wstring FirstVolumeName;
152+
#ifdef PROPAGATE_MOTW
153+
MarkOfTheWeb Motw;
154+
#endif
145155
};
146156

147157

0 commit comments

Comments
 (0)