Skip to content

Commit

Permalink
Update UnRAR to v5.1.7
Browse files Browse the repository at this point in the history
  • Loading branch information
BrunoReX authored and Cyberbeing committed Oct 1, 2014
1 parent 04d5513 commit aa64859
Show file tree
Hide file tree
Showing 34 changed files with 290 additions and 338 deletions.
3 changes: 3 additions & 0 deletions src/thirdparty/unrar/arcread.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1049,6 +1049,9 @@ void Archive::ProcessExtra50(RawRead *Raw,size_t ExtraSize,BaseBlock *bb)
Raw->GetB(UtfName,NameSize);
UtfName[NameSize]=0;
}
#ifdef _WIN_ALL
UnixSlashToDos(UtfName,UtfName,ASIZE(UtfName));
#endif
UtfToWide(UtfName,hd->RedirName,ASIZE(hd->RedirName));
}
break;
Expand Down
5 changes: 5 additions & 0 deletions src/thirdparty/unrar/blake2s.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -57,6 +57,11 @@ static inline void blake2s_increment_counter( blake2s_state *S, const uint32 inc
/* init2 xors IV with input parameter block */
void blake2s_init_param( blake2s_state *S, uint32 node_offset, uint32 node_depth)
{
#ifdef USE_SSE
if (_SSE_Version>=SSE_SSE2)
blake2s_init_sse();
#endif

S->init(); // Clean data.
for( int i = 0; i < 8; ++i )
S->h[i] = blake2s_IV[i];
Expand Down
44 changes: 29 additions & 15 deletions src/thirdparty/unrar/blake2s_sse.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,35 @@

extern const byte blake2s_sigma[10][16];

// Initialization vector.
static __m128i blake2s_IV_0_3, blake2s_IV_4_7;

#ifdef _WIN_64
// Constants for cyclic rotation. Used in 64-bit mode in mm_rotr_epi32 macro.
static __m128i crotr8, crotr16;
#endif

static void blake2s_init_sse()
{
// We cannot initialize these 128 bit variables in place when declaring
// them globally, because global scope initialization is performed before
// our SSE check and it would make code incompatible with older non-SSE2
// CPUs. Also we cannot initialize them as static inside of function
// using these variables, because SSE static initialization is not thread
// safe: first thread starts initialization and sets "init done" flag even
// if it is not done yet, second thread can attempt to access half-init
// SSE data. So we moved init code here.

blake2s_IV_0_3 = _mm_setr_epi32( 0x6A09E667, 0xBB67AE85, 0x3C6EF372, 0xA54FF53A );
blake2s_IV_4_7 = _mm_setr_epi32( 0x510E527F, 0x9B05688C, 0x1F83D9AB, 0x5BE0CD19 );

#ifdef _WIN_64
crotr8 = _mm_set_epi8( 12, 15, 14, 13, 8, 11, 10, 9, 4, 7, 6, 5, 0, 3, 2, 1 );
crotr16 = _mm_set_epi8( 13, 12, 15, 14, 9, 8, 11, 10, 5, 4, 7, 6, 1, 0, 3, 2 );
#endif
}


#define LOAD(p) _mm_load_si128( (__m128i *)(p) )
#define STORE(p,r) _mm_store_si128((__m128i *)(p), r)

Expand Down Expand Up @@ -72,21 +101,6 @@ extern const byte blake2s_sigma[10][16];

static int blake2s_compress_sse( blake2s_state *S, const byte block[BLAKE2S_BLOCKBYTES] )
{
// Initialization vector. Moving them outside of function would provide
// ~5% speed gain in 32-bit mode, but would make code incompatible
// with older non-SSE2 compatible CPUs. Global static initialization
// is performed before our SSE check.
static const __m128i blake2s_IV_0_3 = _mm_setr_epi32( 0x6A09E667, 0xBB67AE85, 0x3C6EF372, 0xA54FF53A );
static const __m128i blake2s_IV_4_7 = _mm_setr_epi32( 0x510E527F, 0x9B05688C, 0x1F83D9AB, 0x5BE0CD19 );

#ifdef _WIN_64
// Constants for cyclic rotation. We use them in 64-bit mode
// in mm_rotr_epi32 macro above. We must not define in global scope
// to be compatible with non-SSE CPU.
static const __m128i crotr8 = _mm_set_epi8( 12, 15, 14, 13, 8, 11, 10, 9, 4, 7, 6, 5, 0, 3, 2, 1 );
static const __m128i crotr16 = _mm_set_epi8( 13, 12, 15, 14, 9, 8, 11, 10, 5, 4, 7, 6, 1, 0, 3, 2 );
#endif

__m128i row[4];
__m128i ff0, ff1;

Expand Down
4 changes: 4 additions & 0 deletions src/thirdparty/unrar/consio.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -243,6 +243,10 @@ bool getwstr(wchar *str,size_t n)


#ifndef SILENT
// We allow this function to return 0 in case of invalid input,
// because it might be convenient to press Enter to some not dangerous
// prompts like "insert disk with next volume". We should call this function
// again in case of 0 in dangerous prompt such as overwriting file.
int Ask(const wchar *AskStr)
{
uiAlarm(UIALARM_QUESTION);
Expand Down
16 changes: 10 additions & 6 deletions src/thirdparty/unrar/dll.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -311,21 +311,25 @@ int PASCAL ProcessFile(HANDLE hArcData,int Operation,char *DestPath,char *DestNa
if (DestPath!=NULL)
{
char ExtrPathA[NM];
#ifdef _WIN_ALL
OemToCharBuffA(DestPath,ExtrPathA,ASIZE(ExtrPathA)-2);
#else
strncpyz(ExtrPathA,DestPath,ASIZE(ExtrPathA)-2);
#ifdef _WIN_ALL
// We must not apply OemToCharBuffA directly to DestPath,
// because we do not know DestPath length and OemToCharBuffA
// does not stop at 0.
OemToCharA(ExtrPathA,ExtrPathA);
#endif
CharToWide(ExtrPathA,Data->Cmd.ExtrPath,ASIZE(Data->Cmd.ExtrPath));
AddEndSlash(Data->Cmd.ExtrPath,ASIZE(Data->Cmd.ExtrPath));
}
if (DestName!=NULL)
{
char DestNameA[NM];
#ifdef _WIN_ALL
OemToCharBuffA(DestName,DestNameA,ASIZE(DestNameA)-2);
#else
strncpyz(DestNameA,DestName,ASIZE(DestNameA)-2);
#ifdef _WIN_ALL
// We must not apply OemToCharBuffA directly to DestName,
// because we do not know DestName length and OemToCharBuffA
// does not stop at 0.
OemToCharA(DestNameA,DestNameA);
#endif
CharToWide(DestNameA,Data->Cmd.DllDestName,ASIZE(Data->Cmd.DllDestName));
}
Expand Down
8 changes: 4 additions & 4 deletions src/thirdparty/unrar/dll.rc
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,8 @@
#include <commctrl.h>

VS_VERSION_INFO VERSIONINFO
FILEVERSION 5, 10, 1, 1173
PRODUCTVERSION 5, 10, 1, 1173
FILEVERSION 5, 11, 1, 1315
PRODUCTVERSION 5, 11, 1, 1315
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.10.1\0"
VALUE "ProductVersion", "5.10.1\0"
VALUE "FileVersion", "5.11.1\0"
VALUE "ProductVersion", "5.11.1\0"
VALUE "LegalCopyright", "Copyright � Alexander Roshal 1993-2014\0"
VALUE "OriginalFilename", "Unrar.dll\0"
}
Expand Down
10 changes: 8 additions & 2 deletions src/thirdparty/unrar/extract.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -613,7 +613,13 @@ bool CmdExtract::ExtractCurrentFile(Archive &Arc,size_t HeaderSize,bool &Repeat)

Arc.SeekToNext();

bool ValidCRC=DataIO.UnpHash.Cmp(&Arc.FileHead.FileHash,Arc.FileHead.UseHashKey ? Arc.FileHead.HashKey:NULL);
// We check for "split after" flag to detect partially extracted files
// from incomplete volume sets. For them file header contains packed
// data hash, which must not be compared against unpacked data hash
// to prevent accidental match. Moreover, for -m0 volumes packed data
// hash would match truncated unpacked data hash and lead to fake "OK"
// in incomplete volume set.
bool ValidCRC=!Arc.FileHead.SplitAfter && DataIO.UnpHash.Cmp(&Arc.FileHead.FileHash,Arc.FileHead.UseHashKey ? Arc.FileHead.HashKey:NULL);

// We set AnySolidDataUnpackedWell to true if we found at least one
// valid non-zero solid file in preceding solid stream. If it is true
Expand Down Expand Up @@ -735,7 +741,7 @@ void CmdExtract::UnstoreFile(ComprDataIO &DataIO,int64 DestUnpSize)

bool CmdExtract::ExtractFileCopy(File &New,wchar *ArcName,wchar *NameNew,wchar *NameExisting,size_t NameExistingSize)
{
SlashToNative(NameExisting,NameExisting,NameExistingSize);
SlashToNative(NameExisting,NameExisting,NameExistingSize); // Not needed for RAR 5.1+ archives.

File Existing;
if (!Existing.WOpen(NameExisting))
Expand Down
20 changes: 18 additions & 2 deletions src/thirdparty/unrar/file.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -658,10 +658,26 @@ int64 File::Copy(File &Dest,int64 Length)
{
Wait();
size_t SizeToRead=(!CopyAll && Length<(int64)Buffer.Size()) ? (size_t)Length:Buffer.Size();
int ReadSize=Read(&Buffer[0],SizeToRead);
char *Buf=&Buffer[0];
int ReadSize=Read(Buf,SizeToRead);
if (ReadSize==0)
break;
Dest.Write(&Buffer[0],ReadSize);
size_t WriteSize=ReadSize;
#ifdef _WIN_ALL
// For FAT32 USB flash drives in Windows if first write is 4 KB or more,
// write caching is disabled and "write through" is enabled, resulting
// in bad performance, especially for many small files. It happens when
// we create SFX archive on USB drive, because SFX module is writetn first.
// So we split the first write to small 1 KB followed by rest of data.
if (CopySize==0 && WriteSize>=4096)
{
const size_t FirstWrite=1024;
Dest.Write(Buf,FirstWrite);
Buf+=FirstWrite;
WriteSize-=FirstWrite;
}
#endif
Dest.Write(Buf,WriteSize);
CopySize+=ReadSize;
if (!CopyAll)
Length-=ReadSize;
Expand Down
2 changes: 1 addition & 1 deletion src/thirdparty/unrar/filestr.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@ bool ReadTextFile(
wcsncpyz(FileName,Name,ASIZE(FileName));

File SrcFile;
if (FileName!=NULL && *FileName!=0)
if (*FileName!=0)
{
bool OpenCode=AbortOnError ? SrcFile.WOpen(FileName):SrcFile.Open(FileName,0);

Expand Down
6 changes: 2 additions & 4 deletions src/thirdparty/unrar/hardlinks.cpp
Original file line number Diff line number Diff line change
@@ -1,12 +1,12 @@
bool ExtractHardlink(wchar *NameNew,wchar *NameExisting,size_t NameExistingSize)
{
SlashToNative(NameExisting,NameExisting,NameExistingSize); // Not needed for RAR 5.1+ archives.

if (!FileExist(NameExisting))
return false;
CreatePath(NameNew,true);

#ifdef _WIN_ALL
UnixSlashToDos(NameExisting,NameExisting,NameExistingSize);

bool Success=CreateHardLink(NameNew,NameExisting,NULL)!=0;
if (!Success)
{
Expand All @@ -16,8 +16,6 @@ bool ExtractHardlink(wchar *NameNew,wchar *NameExisting,size_t NameExistingSize)
}
return Success;
#elif defined(_UNIX)
DosSlashToUnix(NameExisting,NameExisting,NameExistingSize);

char NameExistingA[NM],NameNewA[NM];
WideToChar(NameExisting,NameExistingA,ASIZE(NameExistingA));
WideToChar(NameNew,NameNewA,ASIZE(NameNewA));
Expand Down
5 changes: 5 additions & 0 deletions src/thirdparty/unrar/os.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -158,6 +158,11 @@
#define SAVE_LINKS
#endif

#if defined(__linux) && !defined (_ANDROID) || defined(__FreeBSD__)
#include <sys/time.h>
#define USE_LUTIMES
#endif

#define ENABLE_ACCESS

#define DefConfigName L".rarrc"
Expand Down
12 changes: 10 additions & 2 deletions src/thirdparty/unrar/pathfn.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -643,7 +643,7 @@ wchar* VolNameToFirstName(const wchar *VolName,wchar *FirstName,size_t MaxSize,b


#ifndef SFX_MODULE
static void GenArcName(wchar *ArcName,wchar *GenerateMask,uint ArcNumber,bool &ArcNumPresent)
static void GenArcName(wchar *ArcName,const wchar *GenerateMask,uint ArcNumber,bool &ArcNumPresent)
{
bool Prefix=false;
if (*GenerateMask=='+')
Expand Down Expand Up @@ -766,7 +766,15 @@ static void GenArcName(wchar *ArcName,wchar *GenerateMask,uint ArcNumber,bool &A
}
const wchar *ChPtr=wcschr(MaskChars,toupperw(Mask[I]));
if (ChPtr==NULL || QuoteMode)
{
DateText[J]=Mask[I];
#ifdef _WIN_ALL
// We do not allow ':' in Windows because of NTFS streams.
// Users had problems after specifying hh:mm mask.
if (DateText[J]==':')
DateText[J]='_';
#endif
}
else
{
size_t FieldPos=ChPtr-MaskChars;
Expand Down Expand Up @@ -801,7 +809,7 @@ static void GenArcName(wchar *ArcName,wchar *GenerateMask,uint ArcNumber,bool &A
}


void GenerateArchiveName(wchar *ArcName,size_t MaxSize,wchar *GenerateMask,bool Archiving)
void GenerateArchiveName(wchar *ArcName,size_t MaxSize,const wchar *GenerateMask,bool Archiving)
{
// Must be enough space for archive name plus all stuff in mask plus
// extra overhead produced by mask 'N' (archive number) characters.
Expand Down
2 changes: 1 addition & 1 deletion src/thirdparty/unrar/pathfn.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -58,7 +58,7 @@ wchar* VolNameToFirstName(const wchar *VolName,wchar *FirstName,size_t MaxSize,b
wchar* GetWideName(const char *Name,const wchar *NameW,wchar *DestW,size_t DestSize);

#ifndef SFX_MODULE
void GenerateArchiveName(wchar *ArcName,size_t MaxSize,wchar *GenerateMask,bool Archiving);
void GenerateArchiveName(wchar *ArcName,size_t MaxSize,const wchar *GenerateMask,bool Archiving);
#endif

#ifdef _WIN_ALL
Expand Down
2 changes: 1 addition & 1 deletion src/thirdparty/unrar/rarvm.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -984,7 +984,7 @@ void RarVM::ExecuteStandardFilter(VM_StandardFilters FilterType)
byte *SrcData=Mem,*DestData=SrcData+DataSize;
const int Channels=3;
SET_VALUE(false,&Mem[VM_GLOBALMEMADDR+0x20],DataSize);
if ((uint)DataSize>=VM_GLOBALMEMADDR/2 || PosR<0)
if ((uint)DataSize>=VM_GLOBALMEMADDR/2 || Width<0 || PosR<0)
break;
for (int CurChannel=0;CurChannel<Channels;CurChannel++)
{
Expand Down
8 changes: 8 additions & 0 deletions src/thirdparty/unrar/rawread.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -51,7 +51,11 @@ inline uint RawGet2(const void *Data)
inline uint RawGet4(const void *Data)
{
byte *D=(byte *)Data;
#if defined(BIG_ENDIAN) || !defined(ALLOW_MISALIGNED) || !defined(PRESENT_INT32)
return D[0]+(D[1]<<8)+(D[2]<<16)+(D[3]<<24);
#else
return GET_UINT32(*(uint32 *)D);
#endif
}

inline uint64 RawGet8(const void *Data)
Expand All @@ -74,10 +78,14 @@ inline void RawPut2(uint Field,void *Data)
inline void RawPut4(uint Field,void *Data)
{
byte *D=(byte *)Data;
#if defined(BIG_ENDIAN) || !defined(ALLOW_MISALIGNED) || !defined(PRESENT_INT32)
D[0]=(byte)(Field);
D[1]=(byte)(Field>>8);
D[2]=(byte)(Field>>16);
D[3]=(byte)(Field>>24);
#else
*(uint32 *)D=Field;
#endif
}


Expand Down
48 changes: 37 additions & 11 deletions src/thirdparty/unrar/rdwrfn.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -44,8 +44,9 @@ int ComprDataIO::UnpRead(byte *Addr,size_t Count)
// block size. We can do it by simple masking, because unpack read code
// always reads more than CRYPT_BLOCK_SIZE, so we do not risk to make it 0.
if (Decryption)
Count&=~CRYPT_BLOCK_MASK;
Count &= ~CRYPT_BLOCK_MASK;
#endif

int ReadSize=0,TotalRead=0;
byte *ReadAddr;
ReadAddr=Addr;
Expand All @@ -62,14 +63,30 @@ int ComprDataIO::UnpRead(byte *Addr,size_t Count)
else
{
size_t SizeToRead=((int64)Count>UnpPackedSize) ? (size_t)UnpPackedSize:Count;
if (SizeToRead==0)
return 0;
if (!SrcFile->IsOpened())
return(-1);
ReadSize=SrcFile->Read(ReadAddr,SizeToRead);
FileHeader *hd=SubHead!=NULL ? SubHead:&SrcArc->FileHead;
if (hd->SplitAfter)
PackedDataHash.Update(ReadAddr,ReadSize);
if (SizeToRead > 0)
{
if (UnpVolume && Decryption && (int64)Count>UnpPackedSize)
{
// We need aligned blocks for decryption and we want "Keep broken
// files" to work efficiently with missing encrypted volumes.
// So for last data block in volume we adjust the size to read to
// next equal or smaller block producing aligned total block size.
// So we'll ask for next volume only when processing few unaligned
// bytes left in the end, when most of data is already extracted.
size_t NewTotalRead = TotalRead + SizeToRead;
size_t Adjust = NewTotalRead - (NewTotalRead & ~CRYPT_BLOCK_MASK);
size_t NewSizeToRead = SizeToRead - Adjust;
if ((int)NewSizeToRead > 0)
SizeToRead = NewSizeToRead;
}

if (!SrcFile->IsOpened())
return -1;
ReadSize=SrcFile->Read(ReadAddr,SizeToRead);
FileHeader *hd=SubHead!=NULL ? SubHead:&SrcArc->FileHead;
if (hd->SplitAfter)
PackedDataHash.Update(ReadAddr,ReadSize);
}
}
CurUnpRead+=ReadSize;
TotalRead+=ReadSize;
Expand All @@ -80,14 +97,23 @@ int ComprDataIO::UnpRead(byte *Addr,size_t Count)
Count-=ReadSize;
#endif
UnpPackedSize-=ReadSize;
if (UnpPackedSize == 0 && UnpVolume)

// Do not ask for next volume if we read something from current volume.
// If next volume is missing, we need to process all data from current
// volume before aborting. It helps to recover all possible data
// in "Keep broken files" mode. But if we process encrypted data,
// we ask for next volume also if we have non-aligned encryption block.
// Since we adjust data size for decryption earlier above,
// it does not hurt "Keep broken files" mode efficiency.
if (UnpVolume && UnpPackedSize == 0 &&
(ReadSize==0 || Decryption && (TotalRead & CRYPT_BLOCK_MASK) != 0) )
{
#ifndef NOVOLUME
if (!MergeArchive(*SrcArc,this,true,CurrentCommand))
#endif
{
NextVolumeMissing=true;
return(-1);
return -1;
}
}
else
Expand Down
Loading

0 comments on commit aa64859

Please sign in to comment.