Skip to content

Commit

Permalink
Browse files Browse the repository at this point in the history
Updated to 5.5.7
  • Loading branch information
pmachapman committed Jul 27, 2017
1 parent f517336 commit a7b2005
Show file tree
Hide file tree
Showing 19 changed files with 228 additions and 121 deletions.
6 changes: 4 additions & 2 deletions arccmt.cpp
Expand Up @@ -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);
Expand Down Expand Up @@ -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);
Expand Down Expand Up @@ -96,6 +96,8 @@ bool Archive::GetComment(Array<wchar> *CmtData)
}
else
{
if (CmtLength==0)
return false;
Array<byte> CmtRaw(CmtLength);
Read(&CmtRaw[0],CmtLength);

Expand Down
10 changes: 5 additions & 5 deletions arcread.cpp
Expand Up @@ -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);
Expand Down
8 changes: 4 additions & 4 deletions dll.rc
Expand Up @@ -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
{
Expand All @@ -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"
}
Expand Down
16 changes: 14 additions & 2 deletions encname.cpp
Expand Up @@ -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);
Expand Down
50 changes: 38 additions & 12 deletions extinfo.cpp
Expand Up @@ -93,14 +93,51 @@ 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 \\?\.
// Do not check PrepSrcName here, it can be root based if destination path
// 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.
Expand All @@ -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;
}

Expand Down
2 changes: 1 addition & 1 deletion file.cpp
Expand Up @@ -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);
Expand Down
3 changes: 3 additions & 0 deletions file.hpp
Expand Up @@ -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
};
Expand Down
15 changes: 13 additions & 2 deletions rarvm.cpp
Expand Up @@ -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);
Expand Down Expand Up @@ -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);
}
}


Expand Down Expand Up @@ -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);
Expand Down
4 changes: 3 additions & 1 deletion rawread.cpp
Expand Up @@ -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;
Expand Down
12 changes: 8 additions & 4 deletions unicode.cpp
Expand Up @@ -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);
}


Expand Down
3 changes: 2 additions & 1 deletion unpack.cpp
Expand Up @@ -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
Expand Down Expand Up @@ -206,6 +206,7 @@ void Unpack::UnpInitData(bool Solid)
UnpInitData20(Solid);
#endif
UnpInitData30(Solid);
UnpInitData50(Solid);
}


Expand Down
14 changes: 11 additions & 3 deletions unpack.hpp
Expand Up @@ -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);
Expand Down Expand Up @@ -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();
Expand Down Expand Up @@ -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;
Expand All @@ -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;}
Expand Down
2 changes: 1 addition & 1 deletion unpack15.cpp
Expand Up @@ -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;
Expand Down

0 comments on commit a7b2005

Please sign in to comment.