diff options
author | XhmikosR <xhmikosr@users.sourceforge.net> | 2013-09-30 15:31:13 +0400 |
---|---|---|
committer | XhmikosR <xhmikosr@users.sourceforge.net> | 2013-10-03 21:02:48 +0400 |
commit | f765df54f07a945f38bc31a59a90b8c7be5487d6 (patch) | |
tree | b3317b2256dd842d5617143c7882aebc4d4b60c6 /src/thirdparty/unrar | |
parent | 6322d201ba9112791142fac705478f127327a932 (diff) |
Update Unrar to unrarsrc-5.0.12.tar.gz.
Diffstat (limited to 'src/thirdparty/unrar')
-rw-r--r-- | src/thirdparty/unrar/archive.cpp | 26 | ||||
-rw-r--r-- | src/thirdparty/unrar/arcread.cpp | 24 | ||||
-rw-r--r-- | src/thirdparty/unrar/blake2s_sse.cpp | 22 | ||||
-rw-r--r-- | src/thirdparty/unrar/dll.cpp | 5 | ||||
-rw-r--r-- | src/thirdparty/unrar/extract.cpp | 4 | ||||
-rw-r--r-- | src/thirdparty/unrar/strfn.cpp | 8 | ||||
-rw-r--r-- | src/thirdparty/unrar/unpack.cpp | 16 | ||||
-rw-r--r-- | src/thirdparty/unrar/win32acl.cpp | 8 |
8 files changed, 81 insertions, 32 deletions
diff --git a/src/thirdparty/unrar/archive.cpp b/src/thirdparty/unrar/archive.cpp index bf54c89e1..5b7ef7a67 100644 --- a/src/thirdparty/unrar/archive.cpp +++ b/src/thirdparty/unrar/archive.cpp @@ -202,8 +202,15 @@ bool Archive::IsArchive(bool EnableBroken) MarkHead.HeadSize=SIZEOF_MARKHEAD3; // Skip the archive encryption header if any and read the main header. - while (ReadHeader()!=0 && GetHeaderType()!=HEAD_MAIN) + while (ReadHeader()!=0) + { + HEADER_TYPE Type=GetHeaderType(); + // In RAR 5.0 we need to quit after reading HEAD_CRYPT if we wish to + // avoid the password prompt. + if (Type==HEAD_MAIN || SilentOpen && Type==HEAD_CRYPT) + break; SeekToNext(); + } // This check allows to make RS based recovery even if password is incorrect. // But we should not do it for EnableBroken or we'll get 'not RAR archive' @@ -248,18 +255,13 @@ bool Archive::IsArchive(bool EnableBroken) MainComment=MainHead.CommentInHeader; -#ifdef USE_QOPEN - if (MainHead.Locator && MainHead.QOpenOffset>0 && Cmd->QOpenMode!=QOPEN_NONE) - { - QOpen.Init(this,false); - QOpen.Load(MainHead.QOpenOffset); - } -#endif - // If we process non-encrypted archive or can request a password, // we set 'first volume' flag based on file attributes below. // It is necessary for RAR 2.x archives, which did not have 'first volume' - // flag in main header. + // flag in main header. Also for all RAR formats we need to scan until + // first file header to set "comment" flag when reading service header. + // Unless we are in silent mode, we need to know about presence of comment + // immediately after IsArchive call. if (!SilentOpen || !Encrypted) { SaveFilePos SavePos(*this); @@ -269,11 +271,7 @@ bool Archive::IsArchive(bool EnableBroken) { HEADER_TYPE HeaderType=GetHeaderType(); if (HeaderType==HEAD_SERVICE) - { - if (SubHead.CmpName(SUBHEAD_TYPE_CMT)) - MainComment=true; FirstVolume=!SubHead.SplitBefore; - } else { FirstVolume=HeaderType==HEAD_FILE && !FileHead.SplitBefore; diff --git a/src/thirdparty/unrar/arcread.cpp b/src/thirdparty/unrar/arcread.cpp index 166c2f2ef..69a371e8e 100644 --- a/src/thirdparty/unrar/arcread.cpp +++ b/src/thirdparty/unrar/arcread.cpp @@ -365,6 +365,9 @@ size_t Archive::ReadHeader15() RecoveryPercent++; } } + + if (hd->CmpName(SUBHEAD_TYPE_CMT)) + MainComment=true; } if ((hd->Flags & LHD_SALT)!=0) Raw.GetB(hd->Salt,SIZE_SALT30); @@ -741,6 +744,24 @@ size_t Archive::ReadHeader50() if (ExtraSize!=0) ProcessExtra50(&Raw,(size_t)ExtraSize,&MainHead); + +#ifdef USE_QOPEN + if (MainHead.Locator && MainHead.QOpenOffset>0 && Cmd->QOpenMode!=QOPEN_NONE) + { + // We seek to QO block in the end of archive when processing + // QOpen.Load, so we need to preserve current block positions + // to not break normal archive processing by calling function. + int64 SaveCurBlockPos=CurBlockPos,SaveNextBlockPos=NextBlockPos; + HEADER_TYPE SaveCurHeaderType=CurHeaderType; + + QOpen.Init(this,false); + QOpen.Load(MainHead.QOpenOffset); + + CurBlockPos=SaveCurBlockPos; + NextBlockPos=SaveNextBlockPos; + CurHeaderType=SaveCurHeaderType; + } +#endif } break; case HEAD_FILE: @@ -820,6 +841,9 @@ size_t Archive::ReadHeader50() ConvertFileHeader(hd); } + if (!FileBlock && hd->CmpName(SUBHEAD_TYPE_CMT)) + MainComment=true; + if (BadCRC) { diff --git a/src/thirdparty/unrar/blake2s_sse.cpp b/src/thirdparty/unrar/blake2s_sse.cpp index 93b28b07d..a44fb62f1 100644 --- a/src/thirdparty/unrar/blake2s_sse.cpp +++ b/src/thirdparty/unrar/blake2s_sse.cpp @@ -11,9 +11,6 @@ extern const byte blake2s_sigma[10][16]; #define mm_rotr_epi32(r, c) ( \ _mm_xor_si128(_mm_srli_epi32( (r), c ),_mm_slli_epi32( (r), 32-c )) ) #else -// Constants for cyclic rotation. -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 ); #define mm_rotr_epi32(r, c) ( \ c==8 ? _mm_shuffle_epi8(r,crotr8) \ : c==16 ? _mm_shuffle_epi8(r,crotr16) \ @@ -73,12 +70,23 @@ static const __m128i crotr16 = _mm_set_epi8( 13, 12, 15, 14, 9, 8, 11, 10, 5, 4, } -// Initialization vector. -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 ); - 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; diff --git a/src/thirdparty/unrar/dll.cpp b/src/thirdparty/unrar/dll.cpp index f44e7fdc1..f8c598270 100644 --- a/src/thirdparty/unrar/dll.cpp +++ b/src/thirdparty/unrar/dll.cpp @@ -1,5 +1,4 @@ #include "rar.hpp" -#include "dll.hpp" static int RarErrorToDll(RAR_EXIT ErrCode); @@ -340,6 +339,10 @@ int PASCAL ProcessFile(HANDLE hArcData,int Operation,char *DestPath,char *DestNa Data->Arc.Seek(Data->Arc.CurBlockPos,SEEK_SET); } } + catch (std::bad_alloc) + { + return ERAR_NO_MEMORY; + } catch (RAR_EXIT ErrCode) { return Data->Cmd.DllError!=0 ? Data->Cmd.DllError : RarErrorToDll(ErrCode); diff --git a/src/thirdparty/unrar/extract.cpp b/src/thirdparty/unrar/extract.cpp index a909de167..d6d600019 100644 --- a/src/thirdparty/unrar/extract.cpp +++ b/src/thirdparty/unrar/extract.cpp @@ -542,11 +542,11 @@ bool CmdExtract::ExtractCurrentFile(CommandData *Cmd,Archive &Arc,size_t HeaderS bool FileCreateMode=!TestMode && !SkipSolid && Command!='P';
bool ShowChecksum=true; // Display checksum verification result.
+ bool LinkSuccess=true; // Assume success for test mode.
if (LinkEntry)
{
FILE_SYSTEM_REDIRECT Type=Arc.FileHead.RedirType;
- bool LinkSuccess=true; // Assume success for test mode.
if (Type==FSREDIR_HARDLINK || Type==FSREDIR_FILECOPY)
{
wchar NameExisting[NM];
@@ -653,7 +653,7 @@ bool CmdExtract::ExtractCurrentFile(CommandData *Cmd,Archive &Arc,size_t HeaderS #endif
if (!TestMode && !WrongPassword && (Command=='X' || Command=='E') &&
- (!LinkEntry || Arc.FileHead.RedirType==FSREDIR_FILECOPY) &&
+ (!LinkEntry || Arc.FileHead.RedirType==FSREDIR_FILECOPY && LinkSuccess) &&
(!BrokenFile || Cmd->KeepBroken))
{
// We could preallocate more space that really written to broken file.
diff --git a/src/thirdparty/unrar/strfn.cpp b/src/thirdparty/unrar/strfn.cpp index eb72348bf..b180890b1 100644 --- a/src/thirdparty/unrar/strfn.cpp +++ b/src/thirdparty/unrar/strfn.cpp @@ -47,9 +47,11 @@ int strnicomp(const char *s1,const char *s2,size_t n) // If we specify 'n' exceeding the actual string length, CompareString goes // beyond the trailing zero and compares garbage. So we need to limit 'n' // to real string length. - size_t l1=Min(strlen(s1)+1,n); - size_t l2=Min(strlen(s2)+1,n); - return(CompareStringA(LOCALE_USER_DEFAULT,NORM_IGNORECASE|SORT_STRINGSORT,s1,(int)l1,s2,(int)l2)-2); + // It is important to use strnlen (or memchr(...,0)) instead of strlen, + // because data can be not zero terminated. + size_t l1=Min(strnlen(s1,n),n); + size_t l2=Min(strnlen(s2,n),n); + return CompareStringA(LOCALE_USER_DEFAULT,NORM_IGNORECASE|SORT_STRINGSORT,s1,(int)l1,s2,(int)l2)-2; #else if (n==0) return 0; diff --git a/src/thirdparty/unrar/unpack.cpp b/src/thirdparty/unrar/unpack.cpp index df9259c61..af82ff13e 100644 --- a/src/thirdparty/unrar/unpack.cpp +++ b/src/thirdparty/unrar/unpack.cpp @@ -145,10 +145,18 @@ void Unpack::DoUnpack(int Method,bool Solid) case 0: // RAR 5.0 compression algorithm 0. #ifdef RAR_SMP if (MaxUserThreads>1) - { - Unpack5MT(Solid); - break; - } + { +// We do not use the multithreaded unpack routine to repack RAR archives +// in 'suspended' mode, because unlike the single threaded code it can +// write more than one dictionary for same loop pass. So we would need +// larger buffers of unknown size. Also we do not support multithreading +// in fragmented window mode. + if (!Fragmented) + { + Unpack5MT(Solid); + break; + } + } #endif Unpack5(Solid); break; diff --git a/src/thirdparty/unrar/win32acl.cpp b/src/thirdparty/unrar/win32acl.cpp index 966542006..28215c9ed 100644 --- a/src/thirdparty/unrar/win32acl.cpp +++ b/src/thirdparty/unrar/win32acl.cpp @@ -75,7 +75,13 @@ void ExtractACL(Archive &Arc,const wchar *FileName) si|=SACL_SECURITY_INFORMATION; SECURITY_DESCRIPTOR *sd=(SECURITY_DESCRIPTOR *)&SubData[0]; - int SetCode=SetFileSecurityW(FileName,si,sd); + int SetCode=SetFileSecurity(FileName,si,sd); + if (!SetCode) + { + wchar LongName[NM]; + if (GetWinLongPath(FileName,LongName,ASIZE(LongName))) + SetCode=SetFileSecurity(LongName,si,sd); + } if (!SetCode) { |