Welcome to mirror list, hosted at ThFree Co, Russian Federation.

github.com/mpc-hc/mpc-hc.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorXhmikosR <xhmikosr@gmail.com>2017-07-26 18:47:02 +0300
committerXhmikosR <xhmikosr@gmail.com>2017-07-29 20:57:51 +0300
commitb3a977bab439d711a3e4844b9aa70b7a661177a8 (patch)
tree5e27344afac3b3edd4264764aaaa9b12f50d6477
parentc63c4cc6b7b5958caf17c0cfcf5fa5e94b1ca0fb (diff)
Update Unrar to v5.5.7.
-rw-r--r--docs/Changelog.txt1
-rw-r--r--src/thirdparty/unrar/arccmt.cpp6
-rw-r--r--src/thirdparty/unrar/arcread.cpp10
-rw-r--r--src/thirdparty/unrar/dll.rc8
-rw-r--r--src/thirdparty/unrar/encname.cpp16
-rw-r--r--src/thirdparty/unrar/extinfo.cpp50
-rw-r--r--src/thirdparty/unrar/file.cpp2
-rw-r--r--src/thirdparty/unrar/file.hpp3
-rw-r--r--src/thirdparty/unrar/rarvm.cpp15
-rw-r--r--src/thirdparty/unrar/rawread.cpp4
-rw-r--r--src/thirdparty/unrar/unicode.cpp12
-rw-r--r--src/thirdparty/unrar/unpack.cpp3
-rw-r--r--src/thirdparty/unrar/unpack.hpp14
-rw-r--r--src/thirdparty/unrar/unpack15.cpp2
-rw-r--r--src/thirdparty/unrar/unpack20.cpp74
-rw-r--r--src/thirdparty/unrar/unpack30.cpp78
-rw-r--r--src/thirdparty/unrar/unpack50.cpp42
-rw-r--r--src/thirdparty/unrar/unpack50mt.cpp4
-rw-r--r--src/thirdparty/unrar/unpackinline.cpp2
-rw-r--r--src/thirdparty/unrar/version.hpp4
20 files changed, 229 insertions, 121 deletions
diff --git a/docs/Changelog.txt b/docs/Changelog.txt
index c1c05198b..746a05ede 100644
--- a/docs/Changelog.txt
+++ b/docs/Changelog.txt
@@ -14,6 +14,7 @@ next version - not released yet
+ Automatic encoding option for saving playlists. Uses UTF-8 encoding when applicable
* Updated Little CMS to v2.9 (4be486f)
* Updated sanear to v0.3
+* Updated Unrar to v5.5.7
* Split internal MPEG source filter option into a PS and TS variant
! Fixed text subtitle rendering in Avisynth
! Fixed DPI scaling of non-client areas in main window
diff --git a/src/thirdparty/unrar/arccmt.cpp b/src/thirdparty/unrar/arccmt.cpp
index 47b352b22..79963b27f 100644
--- a/src/thirdparty/unrar/arccmt.cpp
+++ b/src/thirdparty/unrar/arccmt.cpp
@@ -7,7 +7,7 @@ bool Archive::GetComment(Array<wchar> *CmtData)
SaveFilePos SavePos(*this);
#ifndef SFX_MODULE
- ushort CmtLength;
+ uint CmtLength;
if (Format==RARFMT14)
{
Seek(SFXSize+SIZEOF_MAINHEAD14,SEEK_SET);
@@ -52,7 +52,7 @@ bool Archive::GetComment(Array<wchar> *CmtData)
if (Format==RARFMT14)
{
#ifdef RAR_NOCRYPT
- return(false);
+ return false;
#else
UnpCmtLength=GetByte();
UnpCmtLength+=(GetByte()<<8);
@@ -96,6 +96,8 @@ bool Archive::GetComment(Array<wchar> *CmtData)
}
else
{
+ if (CmtLength==0)
+ return false;
Array<byte> CmtRaw(CmtLength);
Read(&CmtRaw[0],CmtLength);
diff --git a/src/thirdparty/unrar/arcread.cpp b/src/thirdparty/unrar/arcread.cpp
index 08f3628cd..1120f6822 100644
--- a/src/thirdparty/unrar/arcread.cpp
+++ b/src/thirdparty/unrar/arcread.cpp
@@ -308,17 +308,17 @@ size_t Archive::ReadHeader15()
if (FileBlock)
{
+ *hd->FileName=0;
if ((hd->Flags & LHD_UNICODE)!=0)
{
EncodeFileName NameCoder;
size_t Length=strlen(FileName);
Length++;
- NameCoder.Decode(FileName,(byte *)FileName+Length,
- NameSize-Length,hd->FileName,
- ASIZE(hd->FileName));
+ if (ReadNameSize>Length)
+ NameCoder.Decode(FileName,(byte *)FileName+Length,
+ ReadNameSize-Length,hd->FileName,
+ ASIZE(hd->FileName));
}
- else
- *hd->FileName=0;
if (*hd->FileName==0)
ArcCharToWide(FileName,hd->FileName,ASIZE(hd->FileName),ACTW_OEM);
diff --git a/src/thirdparty/unrar/dll.rc b/src/thirdparty/unrar/dll.rc
index dd689562c..9c79e9cb1 100644
--- a/src/thirdparty/unrar/dll.rc
+++ b/src/thirdparty/unrar/dll.rc
@@ -2,8 +2,8 @@
#include <commctrl.h>
VS_VERSION_INFO VERSIONINFO
-FILEVERSION 5, 50, 5, 2378
-PRODUCTVERSION 5, 50, 5, 2378
+FILEVERSION 5, 50, 6, 2401
+PRODUCTVERSION 5, 50, 6, 2401
FILEOS VOS__WINDOWS32
FILETYPE VFT_APP
{
@@ -14,8 +14,8 @@ FILETYPE VFT_APP
VALUE "CompanyName", "Alexander Roshal\0"
VALUE "ProductName", "RAR decompression library\0"
VALUE "FileDescription", "RAR decompression library\0"
- VALUE "FileVersion", "5.50.5\0"
- VALUE "ProductVersion", "5.50.5\0"
+ VALUE "FileVersion", "5.50.6\0"
+ VALUE "ProductVersion", "5.50.6\0"
VALUE "LegalCopyright", "Copyright © Alexander Roshal 1993-2017\0"
VALUE "OriginalFilename", "Unrar.dll\0"
}
diff --git a/src/thirdparty/unrar/encname.cpp b/src/thirdparty/unrar/encname.cpp
index 4e42a759b..5556af3e0 100644
--- a/src/thirdparty/unrar/encname.cpp
+++ b/src/thirdparty/unrar/encname.cpp
@@ -15,31 +15,43 @@ void EncodeFileName::Decode(char *Name,byte *EncName,size_t EncSize,wchar *NameW
size_t MaxDecSize)
{
size_t EncPos=0,DecPos=0;
- byte HighByte=EncName[EncPos++];
+ byte HighByte=EncPos<EncSize ? EncName[EncPos++] : 0;
while (EncPos<EncSize && DecPos<MaxDecSize)
{
if (FlagBits==0)
{
+ if (EncPos>=EncSize)
+ break;
Flags=EncName[EncPos++];
FlagBits=8;
}
switch(Flags>>6)
{
case 0:
+ if (EncPos>=EncSize)
+ break;
NameW[DecPos++]=EncName[EncPos++];
break;
case 1:
+ if (EncPos>=EncSize)
+ break;
NameW[DecPos++]=EncName[EncPos++]+(HighByte<<8);
break;
case 2:
+ if (EncPos+1>=EncSize)
+ break;
NameW[DecPos++]=EncName[EncPos]+(EncName[EncPos+1]<<8);
EncPos+=2;
break;
case 3:
{
+ if (EncPos>=EncSize)
+ break;
int Length=EncName[EncPos++];
- if (Length & 0x80)
+ if ((Length & 0x80)!=0)
{
+ if (EncPos>=EncSize)
+ break;
byte Correction=EncName[EncPos++];
for (Length=(Length&0x7f)+2;Length>0 && DecPos<MaxDecSize;Length--,DecPos++)
NameW[DecPos]=((Name[DecPos]+Correction)&0xff)+(HighByte<<8);
diff --git a/src/thirdparty/unrar/extinfo.cpp b/src/thirdparty/unrar/extinfo.cpp
index fd6bd1340..5cb90a408 100644
--- a/src/thirdparty/unrar/extinfo.cpp
+++ b/src/thirdparty/unrar/extinfo.cpp
@@ -93,6 +93,25 @@ static int CalcAllowedDepth(const wchar *Name)
}
+// Check if all existing path components are directories and not links.
+static bool LinkInPath(const wchar *Name)
+{
+ wchar Path[NM];
+ if (wcslen(Name)>=ASIZE(Path))
+ return true; // It should not be that long, skip.
+ wcsncpyz(Path,Name,ASIZE(Path));
+ for (wchar *s=Path+wcslen(Path)-1;s>Path;s--)
+ if (IsPathDiv(*s))
+ {
+ *s=0;
+ FindData FD;
+ if (FindFile::FastFind(Path,&FD,true) && (FD.IsLink || !FD.IsDir))
+ return true;
+ }
+ return false;
+}
+
+
bool IsRelativeSymlinkSafe(CommandData *Cmd,const wchar *SrcName,const wchar *PrepSrcName,const wchar *TargetName)
{
// Catch root dir based /path/file paths also as stuff like \\?\.
@@ -100,7 +119,25 @@ bool IsRelativeSymlinkSafe(CommandData *Cmd,const wchar *SrcName,const wchar *Pr
// is a root based.
if (IsFullRootPath(SrcName) || IsFullRootPath(TargetName))
return false;
-
+
+ // Number of ".." in link target.
+ int UpLevels=0;
+ for (int Pos=0;*TargetName!=0;Pos++)
+ {
+ bool Dot2=TargetName[0]=='.' && TargetName[1]=='.' &&
+ (IsPathDiv(TargetName[2]) || TargetName[2]==0) &&
+ (Pos==0 || IsPathDiv(*(TargetName-1)));
+ if (Dot2)
+ UpLevels++;
+ TargetName++;
+ }
+ // If link target includes "..", it must not have another links
+ // in the path, because they can bypass our safety check. For example,
+ // suppose we extracted "lnk1" -> "." first and "lnk1/lnk2" -> ".." next
+ // or "dir/lnk1" -> ".." first and "dir/lnk1/lnk2" -> ".." next.
+ if (UpLevels>0 && LinkInPath(PrepSrcName))
+ return false;
+
// We could check just prepared src name, but for extra safety
// we check both original (as from archive header) and prepared
// (after applying the destination path and -ep switches) names.
@@ -119,17 +156,6 @@ bool IsRelativeSymlinkSafe(CommandData *Cmd,const wchar *SrcName,const wchar *Pr
}
int PrepAllowedDepth=CalcAllowedDepth(PrepSrcName);
- // Number of ".." in link target.
- int UpLevels=0;
- for (int Pos=0;*TargetName!=0;Pos++)
- {
- bool Dot2=TargetName[0]=='.' && TargetName[1]=='.' &&
- (IsPathDiv(TargetName[2]) || TargetName[2]==0) &&
- (Pos==0 || IsPathDiv(*(TargetName-1)));
- if (Dot2)
- UpLevels++;
- TargetName++;
- }
return AllowedDepth>=UpLevels && PrepAllowedDepth>=UpLevels;
}
diff --git a/src/thirdparty/unrar/file.cpp b/src/thirdparty/unrar/file.cpp
index ed3eaee2f..5e6235a75 100644
--- a/src/thirdparty/unrar/file.cpp
+++ b/src/thirdparty/unrar/file.cpp
@@ -173,7 +173,7 @@ bool File::Create(const wchar *Name,uint Mode)
wchar *LastChar=PointToLastChar(Name);
bool Special=*LastChar=='.' || *LastChar==' ';
- if (Special)
+ if (Special && (Mode & FMF_STANDARDNAMES)==0)
hFile=FILE_BAD_HANDLE;
else
hFile=CreateFile(Name,Access,ShareMode,NULL,CREATE_ALWAYS,0,NULL);
diff --git a/src/thirdparty/unrar/file.hpp b/src/thirdparty/unrar/file.hpp
index 9d8193edc..8a7631e3e 100644
--- a/src/thirdparty/unrar/file.hpp
+++ b/src/thirdparty/unrar/file.hpp
@@ -39,6 +39,9 @@ enum FILE_MODE_FLAGS {
// Provide read access to created file for other programs.
FMF_SHAREREAD=16,
+ // Use standard NTFS names without trailing dots and spaces.
+ FMF_STANDARDNAMES=32,
+
// Mode flags are not defined yet.
FMF_UNDEFINED=256
};
diff --git a/src/thirdparty/unrar/rarvm.cpp b/src/thirdparty/unrar/rarvm.cpp
index 2975e2358..8d8675a39 100644
--- a/src/thirdparty/unrar/rarvm.cpp
+++ b/src/thirdparty/unrar/rarvm.cpp
@@ -22,6 +22,7 @@ void RarVM::Init()
void RarVM::Execute(VM_PreparedProgram *Prg)
{
memcpy(R,Prg->InitR,sizeof(Prg->InitR));
+ Prg->FilteredData=NULL;
if (Prg->Type!=VMSF_NONE)
{
bool Success=ExecuteStandardFilter(Prg->Type);
@@ -107,7 +108,14 @@ uint RarVM::ReadData(BitInput &Inp)
void RarVM::SetMemory(size_t Pos,byte *Data,size_t DataSize)
{
if (Pos<VM_MEMSIZE && Data!=Mem+Pos)
- memmove(Mem+Pos,Data,Min(DataSize,VM_MEMSIZE-Pos));
+ {
+ // We can have NULL Data for invalid filters with DataSize==0. While most
+ // sensible memmove implementations do not care about data if size is 0,
+ // let's follow the standard and check the size first.
+ size_t CopySize=Min(DataSize,VM_MEMSIZE-Pos);
+ if (CopySize!=0)
+ memmove(Mem+Pos,Data,CopySize);
+ }
}
@@ -279,7 +287,10 @@ bool RarVM::ExecuteStandardFilter(VM_StandardFilters FilterType)
PrevDelta=(signed char)(Predicted-PrevByte);
PrevByte=Predicted;
- int D=((signed char)CurByte)<<3;
+ int D=(signed char)CurByte;
+ // Left shift of negative value is undefined behavior in C++,
+ // so we cast it to unsigned to follow the standard.
+ D=(uint)D<<3;
Dif[0]+=abs(D);
Dif[1]+=abs(D-D1);
diff --git a/src/thirdparty/unrar/rawread.cpp b/src/thirdparty/unrar/rawread.cpp
index a6e5fdefb..d99bac84c 100644
--- a/src/thirdparty/unrar/rawread.cpp
+++ b/src/thirdparty/unrar/rawread.cpp
@@ -115,7 +115,9 @@ uint64 RawRead::Get8()
uint64 RawRead::GetV()
{
uint64 Result=0;
- for (uint Shift=0;ReadPos<DataSize;Shift+=7)
+ // Need to check Shift<64, because for shift greater than or equal to
+ // the width of the promoted left operand, the behavior is undefined.
+ for (uint Shift=0;ReadPos<DataSize && Shift<64;Shift+=7)
{
byte CurByte=Data[ReadPos++];
Result+=uint64(CurByte & 0x7f)<<Shift;
diff --git a/src/thirdparty/unrar/unicode.cpp b/src/thirdparty/unrar/unicode.cpp
index e462906b6..5a24edc12 100644
--- a/src/thirdparty/unrar/unicode.cpp
+++ b/src/thirdparty/unrar/unicode.cpp
@@ -510,19 +510,23 @@ int atoiw(const wchar *s)
int64 atoilw(const wchar *s)
{
- int sign=1;
+ bool sign=false;
if (*s=='-')
{
s++;
- sign=-1;
+ sign=true;
}
- int64 n=0;
+ // Use unsigned type here, since long string can overflow the variable
+ // and signed integer overflow is undefined behavior in C++.
+ uint64 n=0;
while (*s>='0' && *s<='9')
{
n=n*10+(*s-'0');
s++;
}
- return sign*n;
+ // Check int64(n)>=0 to avoid the signed overflow with undefined behavior
+ // when negating 0x8000000000000000.
+ return sign && int64(n)>=0 ? -int64(n) : int64(n);
}
diff --git a/src/thirdparty/unrar/unpack.cpp b/src/thirdparty/unrar/unpack.cpp
index 6ee158bd0..0163c49fe 100644
--- a/src/thirdparty/unrar/unpack.cpp
+++ b/src/thirdparty/unrar/unpack.cpp
@@ -135,7 +135,7 @@ void Unpack::Init(size_t WinSize,bool Solid)
}
-void Unpack::DoUnpack(int Method,bool Solid)
+void Unpack::DoUnpack(uint Method,bool Solid)
{
// Methods <50 will crash in Fragmented mode when accessing NULL Window.
// They cannot be called in such mode now, but we check it below anyway
@@ -206,6 +206,7 @@ void Unpack::UnpInitData(bool Solid)
UnpInitData20(Solid);
#endif
UnpInitData30(Solid);
+ UnpInitData50(Solid);
}
diff --git a/src/thirdparty/unrar/unpack.hpp b/src/thirdparty/unrar/unpack.hpp
index ab15554ea..cd7110640 100644
--- a/src/thirdparty/unrar/unpack.hpp
+++ b/src/thirdparty/unrar/unpack.hpp
@@ -211,6 +211,7 @@ class Unpack:PackDef
void UnpWriteArea(size_t StartPtr,size_t EndPtr);
void UnpWriteData(byte *Data,size_t Size);
_forceinline uint SlotToLength(BitInput &Inp,uint Slot);
+ void UnpInitData50(bool Solid);
bool ReadBlockHeader(BitInput &Inp,UnpackBlockHeader &Header);
bool ReadTables(BitInput &Inp,UnpackBlockHeader &Header,UnpackBlockTables &Tables);
void MakeDecodeTables(byte *LengthTable,DecodeTable *Dec,uint Size);
@@ -307,7 +308,9 @@ class Unpack:PackDef
DecodeTable MD[4]; // Decode multimedia data, up to 4 channels.
unsigned char UnpOldTable20[MC20*4];
- int UnpAudioBlock,UnpChannels,UnpCurChannel,UnpChannelDelta;
+ bool UnpAudioBlock;
+ uint UnpChannels,UnpCurChannel;
+ int UnpChannelDelta;
void CopyString20(uint Length,uint Distance);
bool ReadTables20();
void UnpWriteBuf20();
@@ -341,7 +344,12 @@ class Unpack:PackDef
byte UnpOldTable[HUFF_TABLE_SIZE30];
int UnpBlockType;
- bool TablesRead;
+ // If we already read decoding tables for Unpack v2,v3,v5.
+ // We should not use a single variable for all algorithm versions,
+ // because we can have a corrupt archive with one algorithm file
+ // followed by another algorithm file with "solid" flag and we do not
+ // want to reuse tables from one algorithm in another.
+ bool TablesRead2,TablesRead3,TablesRead5;
// Virtual machine to execute filters code.
RarVM VM;
@@ -368,7 +376,7 @@ class Unpack:PackDef
Unpack(ComprDataIO *DataIO);
~Unpack();
void Init(size_t WinSize,bool Solid);
- void DoUnpack(int Method,bool Solid);
+ void DoUnpack(uint Method,bool Solid);
bool IsFileExtracted() {return(FileExtracted);}
void SetDestSize(int64 DestSize) {DestUnpSize=DestSize;FileExtracted=false;}
void SetSuspended(bool Suspended) {Unpack::Suspended=Suspended;}
diff --git a/src/thirdparty/unrar/unpack15.cpp b/src/thirdparty/unrar/unpack15.cpp
index 0bcb31454..1e7cf76c2 100644
--- a/src/thirdparty/unrar/unpack15.cpp
+++ b/src/thirdparty/unrar/unpack15.cpp
@@ -285,7 +285,7 @@ void Unpack::LongLZ()
break;
}
- ChSetB[DistancePlace]=ChSetB[NewDistancePlace];
+ ChSetB[DistancePlace & 0xff]=ChSetB[NewDistancePlace];
ChSetB[NewDistancePlace]=Distance;
Distance=((Distance & 0xff00) | (Inp.fgetbits() >> 8)) >> 1;
diff --git a/src/thirdparty/unrar/unpack20.cpp b/src/thirdparty/unrar/unpack20.cpp
index aca520935..7ace2e43c 100644
--- a/src/thirdparty/unrar/unpack20.cpp
+++ b/src/thirdparty/unrar/unpack20.cpp
@@ -13,11 +13,11 @@ void Unpack::Unpack20(bool Solid)
{
static unsigned char LDecode[]={0,1,2,3,4,5,6,7,8,10,12,14,16,20,24,28,32,40,48,56,64,80,96,112,128,160,192,224};
static unsigned char LBits[]= {0,0,0,0,0,0,0,0,1, 1, 1, 1, 2, 2, 2, 2, 3, 3, 3, 3, 4, 4, 4, 4, 5, 5, 5, 5};
- static int DDecode[]={0,1,2,3,4,6,8,12,16,24,32,48,64,96,128,192,256,384,512,768,1024,1536,2048,3072,4096,6144,8192,12288,16384,24576,32768U,49152U,65536,98304,131072,196608,262144,327680,393216,458752,524288,589824,655360,720896,786432,851968,917504,983040};
+ static uint DDecode[]={0,1,2,3,4,6,8,12,16,24,32,48,64,96,128,192,256,384,512,768,1024,1536,2048,3072,4096,6144,8192,12288,16384,24576,32768U,49152U,65536,98304,131072,196608,262144,327680,393216,458752,524288,589824,655360,720896,786432,851968,917504,983040};
static unsigned char DBits[]= {0,0,0,0,1,1,2, 2, 3, 3, 4, 4, 5, 5, 6, 6, 7, 7, 8, 8, 9, 9, 10, 10, 11, 11, 12, 12, 13, 13, 14, 14, 15, 15, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16};
static unsigned char SDDecode[]={0,4,8,16,32,64,128,192};
static unsigned char SDBits[]= {2,2,3, 4, 5, 6, 6, 6};
- unsigned int Bits;
+ uint Bits;
if (Suspended)
UnpPtr=WrPtr;
@@ -26,9 +26,8 @@ void Unpack::Unpack20(bool Solid)
UnpInitData(Solid);
if (!UnpReadBuf())
return;
- if (!Solid)
- if (!ReadTables20())
- return;
+ if ((!Solid || !TablesRead2) && !ReadTables20())
+ return;
--DestUnpSize;
}
@@ -47,7 +46,7 @@ void Unpack::Unpack20(bool Solid)
}
if (UnpAudioBlock)
{
- int AudioNumber=DecodeNumber(Inp,&MD[UnpCurChannel]);
+ uint AudioNumber=DecodeNumber(Inp,&MD[UnpCurChannel]);
if (AudioNumber==256)
{
@@ -55,14 +54,14 @@ void Unpack::Unpack20(bool Solid)
break;
continue;
}
- Window[UnpPtr++]=DecodeAudio(AudioNumber);
+ Window[UnpPtr++]=DecodeAudio((int)AudioNumber);
if (++UnpCurChannel==UnpChannels)
UnpCurChannel=0;
--DestUnpSize;
continue;
}
- int Number=DecodeNumber(Inp,&BlockTables.LD);
+ uint Number=DecodeNumber(Inp,&BlockTables.LD);
if (Number<256)
{
Window[UnpPtr++]=(byte)Number;
@@ -71,15 +70,15 @@ void Unpack::Unpack20(bool Solid)
}
if (Number>269)
{
- int Length=LDecode[Number-=270]+3;
+ uint Length=LDecode[Number-=270]+3;
if ((Bits=LBits[Number])>0)
{
Length+=Inp.getbits()>>(16-Bits);
Inp.addbits(Bits);
}
- int DistNumber=DecodeNumber(Inp,&BlockTables.DD);
- unsigned int Distance=DDecode[DistNumber]+1;
+ uint DistNumber=DecodeNumber(Inp,&BlockTables.DD);
+ uint Distance=DDecode[DistNumber]+1;
if ((Bits=DBits[DistNumber])>0)
{
Distance+=Inp.getbits()>>(16-Bits);
@@ -109,9 +108,9 @@ void Unpack::Unpack20(bool Solid)
}
if (Number<261)
{
- unsigned int Distance=OldDist[(OldDistPtr-(Number-256)) & 3];
- int LengthNumber=DecodeNumber(Inp,&BlockTables.RD);
- int Length=LDecode[LengthNumber]+2;
+ uint Distance=OldDist[(OldDistPtr-(Number-256)) & 3];
+ uint LengthNumber=DecodeNumber(Inp,&BlockTables.RD);
+ uint Length=LDecode[LengthNumber]+2;
if ((Bits=LBits[LengthNumber])>0)
{
Length+=Inp.getbits()>>(16-Bits);
@@ -132,7 +131,7 @@ void Unpack::Unpack20(bool Solid)
}
if (Number<270)
{
- unsigned int Distance=SDDecode[Number-=261]+1;
+ uint Distance=SDDecode[Number-=261]+1;
if ((Bits=SDBits[Number])>0)
{
Distance+=Inp.getbits()>>(16-Bits);
@@ -167,17 +166,17 @@ bool Unpack::ReadTables20()
{
byte BitLength[BC20];
byte Table[MC20*4];
- int TableSize,N,I;
if (Inp.InAddr>ReadTop-25)
if (!UnpReadBuf())
- return(false);
+ return false;
uint BitField=Inp.getbits();
- UnpAudioBlock=(BitField & 0x8000);
+ UnpAudioBlock=(BitField & 0x8000)!=0;
if (!(BitField & 0x4000))
memset(UnpOldTable20,0,sizeof(UnpOldTable20));
Inp.addbits(2);
+ uint TableSize;
if (UnpAudioBlock)
{
UnpChannels=((BitField>>12) & 3)+1;
@@ -189,19 +188,18 @@ bool Unpack::ReadTables20()
else
TableSize=NC20+DC20+RC20;
- for (I=0;I<BC20;I++)
+ for (uint I=0;I<BC20;I++)
{
BitLength[I]=(byte)(Inp.getbits() >> 12);
Inp.addbits(4);
}
MakeDecodeTables(BitLength,&BlockTables.BD,BC20);
- I=0;
- while (I<TableSize)
+ for (uint I=0;I<TableSize;)
{
if (Inp.InAddr>ReadTop-5)
if (!UnpReadBuf())
return false;
- int Number=DecodeNumber(Inp,&BlockTables.BD);
+ uint Number=DecodeNumber(Inp,&BlockTables.BD);
if (Number<16)
{
Table[I]=(Number+UnpOldTable20[I]) & 0xf;
@@ -210,9 +208,11 @@ bool Unpack::ReadTables20()
else
if (Number==16)
{
- N=(Inp.getbits() >> 14)+3;
+ uint N=(Inp.getbits() >> 14)+3;
Inp.addbits(2);
- if (I>0)
+ if (I==0)
+ return false; // We cannot have "repeat previous" code at the first position.
+ else
while (N-- > 0 && I<TableSize)
{
Table[I]=Table[I-1];
@@ -221,6 +221,7 @@ bool Unpack::ReadTables20()
}
else
{
+ uint N;
if (Number==17)
{
N=(Inp.getbits() >> 13)+3;
@@ -235,10 +236,11 @@ bool Unpack::ReadTables20()
Table[I++]=0;
}
}
+ TablesRead2=true;
if (Inp.InAddr>ReadTop)
- return(true);
+ return true;
if (UnpAudioBlock)
- for (I=0;I<UnpChannels;I++)
+ for (uint I=0;I<UnpChannels;I++)
MakeDecodeTables(&Table[I*MC20],&MD[I],MC20);
else
{
@@ -247,7 +249,7 @@ bool Unpack::ReadTables20()
MakeDecodeTables(&Table[NC20+DC20],&BlockTables.RD,RC20);
}
memcpy(UnpOldTable20,Table,sizeof(UnpOldTable20));
- return(true);
+ return true;
}
@@ -269,7 +271,10 @@ void Unpack::UnpInitData20(int Solid)
{
if (!Solid)
{
- UnpAudioBlock=UnpChannelDelta=UnpCurChannel=0;
+ TablesRead2=false;
+ UnpAudioBlock=false;
+ UnpChannelDelta=0;
+ UnpCurChannel=0;
UnpChannels=1;
memset(AudV,0,sizeof(AudV));
@@ -290,9 +295,12 @@ byte Unpack::DecodeAudio(int Delta)
int PCh=8*V->LastChar+V->K1*V->D1+V->K2*V->D2+V->K3*V->D3+V->K4*V->D4+V->K5*UnpChannelDelta;
PCh=(PCh>>3) & 0xFF;
- unsigned int Ch=PCh-Delta;
+ uint Ch=PCh-Delta;
- int D=((signed char)Delta)<<3;
+ int D=(signed char)Delta;
+ // Left shift of negative value is undefined behavior in C++,
+ // so we cast it to unsigned to follow the standard.
+ D=(uint)D<<3;
V->Dif[0]+=abs(D);
V->Dif[1]+=abs(D-V->D1);
@@ -311,9 +319,9 @@ byte Unpack::DecodeAudio(int Delta)
if ((V->ByteCount & 0x1F)==0)
{
- unsigned int MinDif=V->Dif[0],NumMinDif=0;
+ uint MinDif=V->Dif[0],NumMinDif=0;
V->Dif[0]=0;
- for (int I=1;I<sizeof(V->Dif)/sizeof(V->Dif[0]);I++)
+ for (uint I=1;I<ASIZE(V->Dif);I++)
{
if (V->Dif[I]<MinDif)
{
@@ -366,5 +374,5 @@ byte Unpack::DecodeAudio(int Delta)
break;
}
}
- return((byte)Ch);
+ return (byte)Ch;
}
diff --git a/src/thirdparty/unrar/unpack30.cpp b/src/thirdparty/unrar/unpack30.cpp
index d558806a3..515fff1df 100644
--- a/src/thirdparty/unrar/unpack30.cpp
+++ b/src/thirdparty/unrar/unpack30.cpp
@@ -42,7 +42,7 @@ void Unpack::Unpack29(bool Solid)
UnpInitData(Solid);
if (!UnpReadBuf30())
return;
- if ((!Solid || !TablesRead) && !ReadTables30())
+ if ((!Solid || !TablesRead3) && !ReadTables30())
return;
}
@@ -133,7 +133,7 @@ void Unpack::Unpack29(bool Solid)
continue;
}
- int Number=DecodeNumber(Inp,&BlockTables.LD);
+ uint Number=DecodeNumber(Inp,&BlockTables.LD);
if (Number<256)
{
Window[UnpPtr++]=(byte)Number;
@@ -141,15 +141,15 @@ void Unpack::Unpack29(bool Solid)
}
if (Number>=271)
{
- int Length=LDecode[Number-=271]+3;
+ uint Length=LDecode[Number-=271]+3;
if ((Bits=LBits[Number])>0)
{
Length+=Inp.getbits()>>(16-Bits);
Inp.addbits(Bits);
}
- int DistNumber=DecodeNumber(Inp,&BlockTables.DD);
- unsigned int Distance=DDecode[DistNumber]+1;
+ uint DistNumber=DecodeNumber(Inp,&BlockTables.DD);
+ uint Distance=DDecode[DistNumber]+1;
if ((Bits=DBits[DistNumber])>0)
{
if (DistNumber>9)
@@ -166,7 +166,7 @@ void Unpack::Unpack29(bool Solid)
}
else
{
- int LowDist=DecodeNumber(Inp,&BlockTables.LDD);
+ uint LowDist=DecodeNumber(Inp,&BlockTables.LDD);
if (LowDist==16)
{
LowDistRepCount=LOW_DIST_REP_COUNT-1;
@@ -189,7 +189,7 @@ void Unpack::Unpack29(bool Solid)
if (Distance>=0x2000)
{
Length++;
- if (Distance>=0x40000L)
+ if (Distance>=0x40000)
Length++;
}
@@ -218,13 +218,13 @@ void Unpack::Unpack29(bool Solid)
}
if (Number<263)
{
- int DistNum=Number-259;
- unsigned int Distance=OldDist[DistNum];
- for (int I=DistNum;I>0;I--)
+ uint DistNum=Number-259;
+ uint Distance=OldDist[DistNum];
+ for (uint I=DistNum;I>0;I--)
OldDist[I]=OldDist[I-1];
OldDist[0]=Distance;
- int LengthNumber=DecodeNumber(Inp,&BlockTables.RD);
+ uint LengthNumber=DecodeNumber(Inp,&BlockTables.RD);
int Length=LDecode[LengthNumber]+2;
if ((Bits=LBits[LengthNumber])>0)
{
@@ -237,7 +237,7 @@ void Unpack::Unpack29(bool Solid)
}
if (Number<272)
{
- unsigned int Distance=SDDecode[Number-=263]+1;
+ uint Distance=SDDecode[Number-=263]+1;
if ((Bits=SDBits[Number])>0)
{
Distance+=Inp.getbits()>>(16-Bits);
@@ -274,11 +274,11 @@ bool Unpack::ReadEndOfBlock()
NewTable=(BitField & 0x4000)!=0;
Inp.addbits(2);
}
- TablesRead=!NewTable;
+ TablesRead3=!NewTable;
// Quit immediately if "new file" flag is set. If "new table" flag
// is present, we'll read the table in beginning of next file
- // based on 'TablesRead' 'false' value.
+ // based on 'TablesRead3' 'false' value.
if (NewFile)
return false;
return ReadTables30(); // Quit only if we failed to read tables.
@@ -290,9 +290,9 @@ bool Unpack::ReadVMCode()
// Entire VM code is guaranteed to fully present in block defined
// by current Huffman table. Compressor checks that VM code does not cross
// Huffman block boundaries.
- unsigned int FirstByte=Inp.getbits()>>8;
+ uint FirstByte=Inp.getbits()>>8;
Inp.addbits(8);
- int Length=(FirstByte & 7)+1;
+ uint Length=(FirstByte & 7)+1;
if (Length==7)
{
Length=(Inp.getbits()>>8)+7;
@@ -304,8 +304,10 @@ bool Unpack::ReadVMCode()
Length=Inp.getbits();
Inp.addbits(16);
}
+ if (Length==0)
+ return false;
Array<byte> VMCode(Length);
- for (int I=0;I<Length;I++)
+ for (uint I=0;I<Length;I++)
{
// Try to read the new buffer if only one byte is left.
// But if we read all bytes except the last, one byte is enough.
@@ -320,15 +322,15 @@ bool Unpack::ReadVMCode()
bool Unpack::ReadVMCodePPM()
{
- unsigned int FirstByte=SafePPMDecodeChar();
+ uint FirstByte=SafePPMDecodeChar();
if ((int)FirstByte==-1)
return false;
- int Length=(FirstByte & 7)+1;
+ uint Length=(FirstByte & 7)+1;
if (Length==7)
{
int B1=SafePPMDecodeChar();
if (B1==-1)
- return(false);
+ return false;
Length=B1+7;
}
else
@@ -342,12 +344,14 @@ bool Unpack::ReadVMCodePPM()
return false;
Length=B1*256+B2;
}
+ if (Length==0)
+ return false;
Array<byte> VMCode(Length);
- for (int I=0;I<Length;I++)
+ for (uint I=0;I<Length;I++)
{
int Ch=SafePPMDecodeChar();
if (Ch==-1)
- return(false);
+ return false;
VMCode[I]=Ch;
}
return AddVMCode(FirstByte,&VMCode[0],Length);
@@ -405,7 +409,7 @@ bool Unpack::AddVMCode(uint FirstByte,byte *Code,int CodeSize)
StackFilter->ParentFilter=FiltPos;
}
- int EmptyCount=0;
+ uint EmptyCount=0;
for (uint I=0;I<PrgStack.Size();I++)
{
PrgStack[I-EmptyCount]=PrgStack[I];
@@ -424,7 +428,7 @@ bool Unpack::AddVMCode(uint FirstByte,byte *Code,int CodeSize)
PrgStack.Add(1);
EmptyCount=1;
}
- int StackPos=(int)(PrgStack.Size()-EmptyCount);
+ size_t StackPos=PrgStack.Size()-EmptyCount;
PrgStack[StackPos]=StackFilter;
uint BlockStart=RarVM::ReadData(VMCodeInp);
@@ -458,7 +462,7 @@ bool Unpack::AddVMCode(uint FirstByte,byte *Code,int CodeSize)
{
uint InitMask=VMCodeInp.fgetbits()>>9;
VMCodeInp.faddbits(7);
- for (int I=0;I<7;I++)
+ for (uint I=0;I<7;I++)
if (InitMask & (1<<I))
StackFilter->Prg.InitR[I]=RarVM::ReadData(VMCodeInp);
}
@@ -644,13 +648,13 @@ bool Unpack::ReadTables30()
memset(UnpOldTable,0,sizeof(UnpOldTable));
Inp.faddbits(2);
- for (int I=0;I<BC;I++)
+ for (uint I=0;I<BC;I++)
{
- int Length=(byte)(Inp.fgetbits() >> 12);
+ uint Length=(byte)(Inp.fgetbits() >> 12);
Inp.faddbits(4);
if (Length==15)
{
- int ZeroCount=(byte)(Inp.fgetbits() >> 12);
+ uint ZeroCount=(byte)(Inp.fgetbits() >> 12);
Inp.faddbits(4);
if (ZeroCount==0)
BitLength[I]=15;
@@ -667,13 +671,13 @@ bool Unpack::ReadTables30()
}
MakeDecodeTables(BitLength,&BlockTables.BD,BC30);
- const int TableSize=HUFF_TABLE_SIZE30;
- for (int I=0;I<TableSize;)
+ const uint TableSize=HUFF_TABLE_SIZE30;
+ for (uint I=0;I<TableSize;)
{
if (Inp.InAddr>ReadTop-5)
if (!UnpReadBuf30())
return(false);
- int Number=DecodeNumber(Inp,&BlockTables.BD);
+ uint Number=DecodeNumber(Inp,&BlockTables.BD);
if (Number<16)
{
Table[I]=(Number+UnpOldTable[I]) & 0xf;
@@ -682,7 +686,7 @@ bool Unpack::ReadTables30()
else
if (Number<18)
{
- int N;
+ uint N;
if (Number==16)
{
N=(Inp.fgetbits() >> 13)+3;
@@ -693,7 +697,9 @@ bool Unpack::ReadTables30()
N=(Inp.fgetbits() >> 9)+11;
Inp.faddbits(7);
}
- if (I>0)
+ if (I==0)
+ return false; // We cannot have "repeat previous" code at the first position.
+ else
while (N-- > 0 && I<TableSize)
{
Table[I]=Table[I-1];
@@ -702,7 +708,7 @@ bool Unpack::ReadTables30()
}
else
{
- int N;
+ uint N;
if (Number==18)
{
N=(Inp.fgetbits() >> 13)+3;
@@ -717,7 +723,7 @@ bool Unpack::ReadTables30()
Table[I++]=0;
}
}
- TablesRead=true;
+ TablesRead3=true;
if (Inp.InAddr>ReadTop)
return false;
MakeDecodeTables(&Table[0],&BlockTables.LD,NC30);
@@ -733,7 +739,7 @@ void Unpack::UnpInitData30(bool Solid)
{
if (!Solid)
{
- TablesRead=false;
+ TablesRead3=false;
memset(UnpOldTable,0,sizeof(UnpOldTable));
PPMEscChar=2;
UnpBlockType=BLOCK_LZ;
diff --git a/src/thirdparty/unrar/unpack50.cpp b/src/thirdparty/unrar/unpack50.cpp
index aaa8c2b98..d8a595923 100644
--- a/src/thirdparty/unrar/unpack50.cpp
+++ b/src/thirdparty/unrar/unpack50.cpp
@@ -7,7 +7,12 @@ void Unpack::Unpack5(bool Solid)
UnpInitData(Solid);
if (!UnpReadBuf())
return;
- if (!ReadBlockHeader(Inp,BlockHeader) || !ReadTables(Inp,BlockHeader,BlockTables))
+
+ // Check TablesRead5 to be sure that we read tables at least once
+ // regardless of current block header TablePresent flag.
+ // So we can safefly use these tables below.
+ if (!ReadBlockHeader(Inp,BlockHeader) ||
+ !ReadTables(Inp,BlockHeader,BlockTables) || !TablesRead5)
return;
}
@@ -516,6 +521,13 @@ void Unpack::UnpWriteData(byte *Data,size_t Size)
}
+void Unpack::UnpInitData50(bool Solid)
+{
+ if (!Solid)
+ TablesRead5=false;
+}
+
+
bool Unpack::ReadBlockHeader(BitInput &Inp,UnpackBlockHeader &Header)
{
Header.HeaderSize=0;
@@ -570,13 +582,13 @@ bool Unpack::ReadTables(BitInput &Inp,UnpackBlockHeader &Header,UnpackBlockTable
return false;
byte BitLength[BC];
- for (int I=0;I<BC;I++)
+ for (uint I=0;I<BC;I++)
{
- int Length=(byte)(Inp.fgetbits() >> 12);
+ uint Length=(byte)(Inp.fgetbits() >> 12);
Inp.faddbits(4);
if (Length==15)
{
- int ZeroCount=(byte)(Inp.fgetbits() >> 12);
+ uint ZeroCount=(byte)(Inp.fgetbits() >> 12);
Inp.faddbits(4);
if (ZeroCount==0)
BitLength[I]=15;
@@ -595,13 +607,13 @@ bool Unpack::ReadTables(BitInput &Inp,UnpackBlockHeader &Header,UnpackBlockTable
MakeDecodeTables(BitLength,&Tables.BD,BC);
byte Table[HUFF_TABLE_SIZE];
- const int TableSize=HUFF_TABLE_SIZE;
- for (int I=0;I<TableSize;)
+ const uint TableSize=HUFF_TABLE_SIZE;
+ for (uint I=0;I<TableSize;)
{
if (!Inp.ExternalBuffer && Inp.InAddr>ReadTop-5)
if (!UnpReadBuf())
return false;
- int Number=DecodeNumber(Inp,&Tables.BD);
+ uint Number=DecodeNumber(Inp,&Tables.BD);
if (Number<16)
{
Table[I]=Number;
@@ -610,7 +622,7 @@ bool Unpack::ReadTables(BitInput &Inp,UnpackBlockHeader &Header,UnpackBlockTable
else
if (Number<18)
{
- int N;
+ uint N;
if (Number==16)
{
N=(Inp.fgetbits() >> 13)+3;
@@ -621,7 +633,16 @@ bool Unpack::ReadTables(BitInput &Inp,UnpackBlockHeader &Header,UnpackBlockTable
N=(Inp.fgetbits() >> 9)+11;
Inp.faddbits(7);
}
- if (I>0)
+ if (I==0)
+ {
+ // We cannot have "repeat previous" code at the first position.
+ // Multiple such codes would shift Inp position without changing I,
+ // which can lead to reading beyond of Inp boundary in mutithreading
+ // mode, where Inp.ExternalBuffer disables bounds check and we just
+ // reserve a lot of buffer space to not need such check normally.
+ return false;
+ }
+ else
while (N-- > 0 && I<TableSize)
{
Table[I]=Table[I-1];
@@ -630,7 +651,7 @@ bool Unpack::ReadTables(BitInput &Inp,UnpackBlockHeader &Header,UnpackBlockTable
}
else
{
- int N;
+ uint N;
if (Number==18)
{
N=(Inp.fgetbits() >> 13)+3;
@@ -645,6 +666,7 @@ bool Unpack::ReadTables(BitInput &Inp,UnpackBlockHeader &Header,UnpackBlockTable
Table[I++]=0;
}
}
+ TablesRead5=true;
if (!Inp.ExternalBuffer && Inp.InAddr>ReadTop)
return false;
MakeDecodeTables(&Table[0],&Tables.LD,NC);
diff --git a/src/thirdparty/unrar/unpack50mt.cpp b/src/thirdparty/unrar/unpack50mt.cpp
index 6f786adc9..c4acaf10c 100644
--- a/src/thirdparty/unrar/unpack50mt.cpp
+++ b/src/thirdparty/unrar/unpack50mt.cpp
@@ -133,11 +133,13 @@ void Unpack::Unpack5MT(bool Solid)
if (!CurData->HeaderRead)
{
CurData->HeaderRead=true;
- if (!ReadBlockHeader(CurData->Inp,CurData->BlockHeader))
+ if (!ReadBlockHeader(CurData->Inp,CurData->BlockHeader) ||
+ !CurData->BlockHeader.TablePresent && !TablesRead5)
{
Done=true;
break;
}
+ TablesRead5=true;
}
// To prevent too high memory use we switch to single threaded mode
diff --git a/src/thirdparty/unrar/unpackinline.cpp b/src/thirdparty/unrar/unpackinline.cpp
index 1dc6980c5..c12c77db2 100644
--- a/src/thirdparty/unrar/unpackinline.cpp
+++ b/src/thirdparty/unrar/unpackinline.cpp
@@ -120,7 +120,7 @@ _forceinline uint Unpack::DecodeNumber(BitInput &Inp,DecodeTable *Dec)
// Convert the position in the code list to position in alphabet
// and return it.
- return(Dec->DecodeNum[Pos]);
+ return Dec->DecodeNum[Pos];
}
diff --git a/src/thirdparty/unrar/version.hpp b/src/thirdparty/unrar/version.hpp
index 0730921bc..e15b2e7b7 100644
--- a/src/thirdparty/unrar/version.hpp
+++ b/src/thirdparty/unrar/version.hpp
@@ -1,6 +1,6 @@
#define RARVER_MAJOR 5
#define RARVER_MINOR 50
-#define RARVER_BETA 5
-#define RARVER_DAY 2
+#define RARVER_BETA 6
+#define RARVER_DAY 25
#define RARVER_MONTH 7
#define RARVER_YEAR 2017