diff --git a/Classes/URKArchive.h b/Classes/URKArchive.h index afc923d6..cf92ae12 100644 --- a/Classes/URKArchive.h +++ b/Classes/URKArchive.h @@ -228,6 +228,15 @@ extern NSString *URKErrorDomain; */ + (BOOL)urlIsARAR:(NSURL *)fileURL; +/** + * Lists the names/paths of the volume parts + * + * @param error Contains an NSError object when there was an error reading the archive + * + * @return Returns a list of NSString containing the paths of the volume parts, or nil if an error was encountered + */ +- (NSArray *)listVolumePaths:(NSError **)error; + /** * Lists the names of the files in the archive * diff --git a/Classes/URKArchive.mm b/Classes/URKArchive.mm index f8440f46..b9817cef 100644 --- a/Classes/URKArchive.mm +++ b/Classes/URKArchive.mm @@ -273,6 +273,22 @@ + (BOOL)urlIsARAR:(NSURL *)fileURL #pragma mark - Public Methods +- (NSArray *)listVolumePaths:(NSError **)error +{ + __block NSMutableArray *volumePaths = [NSMutableArray new]; + + NSArray *listFileInfo = [self listFileInfo:error]; + + if (listFileInfo == nil) + return nil; + + for (URKFileInfo* info in listFileInfo) { + if (![volumePaths containsObject:info.archiveName]) + [volumePaths addObject:info.archiveName]; + } + + return [NSArray arrayWithArray:volumePaths]; +} - (NSArray *)listFilenames:(NSError **)error { diff --git a/Libraries/unrar/UnRAR.vcproj b/Libraries/unrar/UnRAR.vcproj deleted file mode 100644 index 74ff2c44..00000000 --- a/Libraries/unrar/UnRAR.vcproj +++ /dev/null @@ -1,643 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/Libraries/unrar/UnRAR.vcxproj b/Libraries/unrar/UnRAR.vcxproj new file mode 100644 index 00000000..512bcf15 --- /dev/null +++ b/Libraries/unrar/UnRAR.vcxproj @@ -0,0 +1,279 @@ + + + + + Debug + Win32 + + + Debug + x64 + + + Release + Win32 + + + Release + x64 + + + + {95CC809B-03FC-4EDB-BB20-FD07A698C05F} + UnRAR + Win32Proj + 8.1 + + + + Application + v140_xp + MultiByte + true + + + Application + v140_xp + MultiByte + + + Application + v140_xp + MultiByte + false + + + Application + v140_xp + MultiByte + + + + + + + + + + + + + + + + + + + <_ProjectFileVersion>14.0.24720.0 + + + build\unrar32\$(Configuration)\ + build\unrar32\$(Configuration)\obj\ + true + false + + + build\unrar64\$(Configuration)\ + build\unrar64\$(Configuration)\obj\ + true + false + + + build\unrar32\$(Configuration)\ + build\unrar32\$(Configuration)\obj\ + false + false + + + build\unrar64\$(Configuration)\ + build\unrar64\$(Configuration)\obj\ + false + false + + + + /MP %(AdditionalOptions) + Disabled + UNRAR;%(PreprocessorDefinitions) + false + EnableFastChecks + MultiThreadedDebug + false + Use + rar.hpp + Level3 + ProgramDatabase + StdCall + 4007;4996;%(DisableSpecificWarnings) + NoExtensions + + + true + Console + MachineX86 + + + + + X64 + + + /MP %(AdditionalOptions) + Disabled + UNRAR;%(PreprocessorDefinitions) + false + EnableFastChecks + MultiThreadedDebug + false + Use + rar.hpp + Level3 + ProgramDatabase + StdCall + 4007;4996;%(DisableSpecificWarnings) + NotSet + + + true + Console + MachineX64 + + + + + /MP %(AdditionalOptions) + MaxSpeed + true + Neither + true + false + UNRAR;%(PreprocessorDefinitions) + false + MultiThreaded + Default + true + true + NoExtensions + Precise + false + Use + rar.hpp + Level3 + ProgramDatabase + StdCall + 4007;4996;%(DisableSpecificWarnings) + + + true + Console + true + true + + MachineX86 + + + + + X64 + + + /MP %(AdditionalOptions) + MinSpace + true + Neither + true + false + UNRAR;%(PreprocessorDefinitions) + false + false + MultiThreaded + true + true + false + Use + rar.hpp + Level3 + ProgramDatabase + StdCall + 4007;4996;%(DisableSpecificWarnings) + NotSet + + + true + Console + true + true + + MachineX64 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + Create + Create + Create + Create + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/Libraries/unrar/UnRARDll.vcproj b/Libraries/unrar/UnRARDll.vcproj deleted file mode 100644 index 56dcdc31..00000000 --- a/Libraries/unrar/UnRARDll.vcproj +++ /dev/null @@ -1,876 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/Libraries/unrar/UnRARDll.vcxproj b/Libraries/unrar/UnRARDll.vcxproj new file mode 100644 index 00000000..ec5c17b0 --- /dev/null +++ b/Libraries/unrar/UnRARDll.vcxproj @@ -0,0 +1,420 @@ + + + + + Debug + Win32 + + + Debug + x64 + + + release_nocrypt + Win32 + + + release_nocrypt + x64 + + + Release + Win32 + + + Release + x64 + + + + UnRAR + {E815C46C-36C4-499F-BBC2-E772C6B17971} + UnRAR + Win32Proj + 8.1 + + + + DynamicLibrary + v140_xp + MultiByte + true + + + DynamicLibrary + v140_xp + MultiByte + true + + + DynamicLibrary + v140_xp + MultiByte + + + DynamicLibrary + v140_xp + MultiByte + false + + + DynamicLibrary + v140_xp + MultiByte + false + + + DynamicLibrary + v140_xp + MultiByte + + + + + + + + + + + + + + + + + + + + + + + + + <_ProjectFileVersion>14.0.24720.0 + + + build\unrardll32\$(Configuration)\ + build\unrardll32\$(Configuration)\obj\ + true + true + + + build\unrardll64\$(Configuration)\ + build\unrardll64\$(Configuration)\obj\ + true + true + + + build\unrardll32\$(Configuration)\ + build\unrardll32\$(Configuration)\obj\ + false + true + + + build\unrardll64\$(Configuration)\ + build\unrardll64\$(Configuration)\obj\ + false + true + + + build\unrardll32\$(Configuration)\ + build\unrardll32\$(Configuration)\obj\ + false + true + + + build\unrardll64\$(Configuration)\ + build\unrardll64\$(Configuration)\obj\ + false + true + + + + /MP %(AdditionalOptions) + Disabled + RARDLL;UNRAR;SILENT;%(PreprocessorDefinitions) + false + Sync + EnableFastChecks + MultiThreadedDebug + 4Bytes + false + Use + rar.hpp + Level3 + ProgramDatabase + Cdecl + 4007;4996;%(DisableSpecificWarnings) + NoExtensions + + + $(OutDir)unrar.dll + dll.def + true + Console + MachineX86 + + + + + X64 + + + /MP %(AdditionalOptions) + Disabled + RARDLL;UNRAR;SILENT;%(PreprocessorDefinitions) + false + Sync + EnableFastChecks + MultiThreadedDebug + 4Bytes + false + Use + rar.hpp + Level3 + ProgramDatabase + Cdecl + 4007;4996;%(DisableSpecificWarnings) + NotSet + + + $(OutDir)unrar.dll + dll.def + true + Console + MachineX64 + + + + + /MP %(AdditionalOptions) + MaxSpeed + true + Neither + true + false + RARDLL;UNRAR;SILENT;%(PreprocessorDefinitions) + false + Sync + MultiThreaded + 4Bytes + true + true + NoExtensions + Precise + false + Use + rar.hpp + Level3 + ProgramDatabase + Cdecl + 4007;4996;%(DisableSpecificWarnings) + + + /SAFESEH %(AdditionalOptions) + $(OutDir)unrar.dll + dll.def + true + Console + true + true + + MachineX86 + + + + + X64 + + + /MP %(AdditionalOptions) + MaxSpeed + true + Neither + true + false + RARDLL;UNRAR;SILENT;%(PreprocessorDefinitions) + false + false + Sync + MultiThreaded + 4Bytes + true + true + false + Use + rar.hpp + Level3 + ProgramDatabase + Cdecl + 4007;4996;%(DisableSpecificWarnings) + NotSet + + + $(OutDir)unrar.dll + dll.def + true + Console + true + true + + MachineX64 + + + + + /MP %(AdditionalOptions) + MaxSpeed + true + Neither + true + false + RARDLL;UNRAR;SILENT;RAR_NOCRYPT;%(PreprocessorDefinitions) + false + Sync + MultiThreaded + 4Bytes + true + true + NoExtensions + Precise + false + Use + rar.hpp + Level3 + ProgramDatabase + Cdecl + 4007;4996;%(DisableSpecificWarnings) + + + /SAFESEH %(AdditionalOptions) + $(OutDir)unrar.dll + dll_nocrypt.def + true + Console + true + true + + MachineX86 + + + + + X64 + + + /MP %(AdditionalOptions) + MaxSpeed + true + Neither + true + false + RARDLL;UNRAR;SILENT;RAR_NOCRYPT;%(PreprocessorDefinitions) + false + false + Sync + MultiThreaded + 4Bytes + true + true + false + Use + rar.hpp + Level3 + ProgramDatabase + StdCall + 4007;4996;%(DisableSpecificWarnings) + NotSet + + + $(OutDir)unrar.dll + dll_nocrypt.def + true + Console + true + true + + MachineX64 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + Create + Create + Create + Create + Create + Create + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/Libraries/unrar/arcread.cpp b/Libraries/unrar/arcread.cpp index 03ea611d..14639387 100644 --- a/Libraries/unrar/arcread.cpp +++ b/Libraries/unrar/arcread.cpp @@ -53,9 +53,11 @@ size_t Archive::SearchBlock(HEADER_TYPE HeaderType) size_t Archive::SearchSubBlock(const wchar *Type) { - size_t Size; + size_t Size,Count=0; while ((Size=ReadHeader())!=0 && GetHeaderType()!=HEAD_ENDARC) { + if ((++Count & 127)==0) + Wait(); if (GetHeaderType()==HEAD_SERVICE && SubHead.CmpName(Type)) return Size; SeekToNext(); @@ -318,9 +320,8 @@ size_t Archive::ReadHeader15() else *hd->FileName=0; - char AnsiName[NM]; - IntToExt(FileName,AnsiName,ASIZE(AnsiName)); - GetWideName(AnsiName,hd->FileName,hd->FileName,ASIZE(hd->FileName)); + if (*hd->FileName==0) + ArcCharToWide(FileName,hd->FileName,ASIZE(hd->FileName),ACTW_OEM); #ifndef SFX_MODULE ConvertNameCase(hd->FileName); diff --git a/Libraries/unrar/blake2s.cpp b/Libraries/unrar/blake2s.cpp index d481bc63..a7207d33 100644 --- a/Libraries/unrar/blake2s.cpp +++ b/Libraries/unrar/blake2s.cpp @@ -162,7 +162,7 @@ void blake2s_update( blake2s_state *S, const byte *in, size_t inlen ) memcpy( S->buf + left, in, (size_t)inlen ); S->buflen += (size_t)inlen; // Be lazy, do not compress in += inlen; - inlen -= inlen; + inlen = 0; } } } diff --git a/Libraries/unrar/cmddata.cpp b/Libraries/unrar/cmddata.cpp index 02c4f2f2..8502210f 100644 --- a/Libraries/unrar/cmddata.cpp +++ b/Libraries/unrar/cmddata.cpp @@ -467,6 +467,11 @@ void CommandData::ProcessSwitch(const wchar *Switch) Shutdown=true; break; } + if (wcsicomp(Switch+1,L"VER")==0) + { + PrintVersion=true; + break; + } break; case 'K': switch(toupperw(Switch[1])) @@ -620,6 +625,12 @@ void CommandData::ProcessSwitch(const wchar *Switch) if (toupperw(Switch[2])=='A') AbsoluteLinks=true; break; +#endif +#ifdef _WIN_ALL + case 'N': + if (toupperw(Switch[2])=='I') + AllowIncompatNames=true; + break; #endif case 'R': Overwrite=OVERWRITE_AUTORENAME; @@ -920,12 +931,26 @@ void CommandData::OutTitle() if (TitleShown) return; TitleShown=true; - wchar Version[50]; - int Beta=RARVER_BETA; - if (Beta!=0) + + wchar Version[80]; + if (RARVER_BETA!=0) swprintf(Version,ASIZE(Version),L"%d.%02d %ls %d",RARVER_MAJOR,RARVER_MINOR,St(MBeta),RARVER_BETA); else swprintf(Version,ASIZE(Version),L"%d.%02d",RARVER_MAJOR,RARVER_MINOR); +#if defined(_WIN_32) || defined(_WIN_64) + wcsncatz(Version,L" ",ASIZE(Version)); +#endif +#ifdef _WIN_32 + wcsncatz(Version,St(Mx86),ASIZE(Version)); +#endif +#ifdef _WIN_64 + wcsncatz(Version,St(Mx64),ASIZE(Version)); +#endif + if (PrintVersion) + { + mprintf(L"%s",Version); + exit(0); + } #ifdef UNRAR mprintf(St(MUCopyright),Version,RARVER_YEAR); #else @@ -981,7 +1006,7 @@ void CommandData::OutHelp(RAR_EXIT ExitCode) #ifndef _WIN_ALL static MSGID Win32Only[]={ MCHelpSwIEML,MCHelpSwVD,MCHelpSwAO,MCHelpSwOS,MCHelpSwIOFF, - MCHelpSwEP2,MCHelpSwOC,MCHelpSwDR,MCHelpSwRI + MCHelpSwEP2,MCHelpSwOC,MCHelpSwONI,MCHelpSwDR,MCHelpSwRI }; bool Found=false; for (int J=0;JRewind(); - while (Args->GetString(CurMask,ASIZE(CurMask)-1)) + while (Args->GetString(CurMask,ASIZE(CurMask))) { wchar *LastMaskChar=PointToLastChar(CurMask); bool DirMask=IsPathDiv(*LastMaskChar); // Mask for directories only. @@ -1057,11 +1082,12 @@ bool CommandData::CheckArgs(StringList *Args,bool Dir,const wchar *CheckName,boo } else { + // REMOVED, we want -npath\* to match empty folders too. // If mask has wildcards in name part and does not have the trailing // '\' character, we cannot use it for directories. - if (IsWildcard(PointToName(CurMask))) - continue; + // if (IsWildcard(PointToName(CurMask))) + // continue; } } else @@ -1073,7 +1099,7 @@ bool CommandData::CheckArgs(StringList *Args,bool Dir,const wchar *CheckName,boo // is excluded from further scanning. if (DirMask) - wcscat(CurMask,L"*"); + wcsncatz(CurMask,L"*",ASIZE(CurMask)); } #ifndef SFX_MODULE @@ -1210,13 +1236,24 @@ void CommandData::ProcessCommand() if (Command[0]!=0 && Command[1]!=0 && wcschr(SingleCharCommands,Command[0])!=NULL || *ArcName==0) OutHelp(*Command==0 ? RARX_SUCCESS:RARX_USERERROR); // Return 'success' for 'rar' without parameters. + const wchar *ArcExt=GetExt(ArcName); #ifdef _UNIX - if (GetExt(ArcName)==NULL && (!FileExist(ArcName) || IsDir(GetFileAttr(ArcName)))) + if (ArcExt==NULL && (!FileExist(ArcName) || IsDir(GetFileAttr(ArcName)))) wcsncatz(ArcName,L".rar",ASIZE(ArcName)); #else - if (GetExt(ArcName)==NULL) + if (ArcExt==NULL) wcsncatz(ArcName,L".rar",ASIZE(ArcName)); #endif + // Treat arcname.part1 as arcname.part1.rar. + if (ArcExt!=NULL && wcsnicomp(ArcExt,L".part",5)==0 && IsDigit(ArcExt[5]) && + !FileExist(ArcName)) + { + wchar Name[NM]; + wcsncpyz(Name,ArcName,ASIZE(Name)); + wcsncatz(Name,L".rar",ASIZE(Name)); + if (FileExist(Name)) + wcsncpyz(ArcName,Name,ASIZE(ArcName)); + } if (wcschr(L"AFUMD",*Command)==NULL) { diff --git a/Libraries/unrar/consio.cpp b/Libraries/unrar/consio.cpp index 243ebbc2..7f39a2b1 100644 --- a/Libraries/unrar/consio.cpp +++ b/Libraries/unrar/consio.cpp @@ -6,10 +6,7 @@ static RAR_CHARSET RedirectCharset=RCH_DEFAULT; const int MaxMsgSize=2*NM+2048; -#ifdef _WIN_ALL static bool StdoutRedirected=false,StderrRedirected=false,StdinRedirected=false; -#endif - #ifdef _WIN_ALL static bool IsRedirected(DWORD nStdHandle) @@ -44,6 +41,10 @@ void InitConsole() if (!StderrRedirected) _setmode(_fileno(stderr), _O_U16TEXT); #endif +#elif defined(_UNIX) + StdoutRedirected=!isatty(fileno(stdout)); + StderrRedirected=!isatty(fileno(stderr)); + StdinRedirected=!isatty(fileno(stdin)); #endif } @@ -136,32 +137,37 @@ static void GetPasswordText(wchar *Str,uint MaxLength) { if (MaxLength==0) return; + if (StdinRedirected) + getwstr(Str,MaxLength); // Read from pipe or redirected file. + else + { #ifdef _WIN_ALL - HANDLE hConIn=GetStdHandle(STD_INPUT_HANDLE); - HANDLE hConOut=GetStdHandle(STD_OUTPUT_HANDLE); - DWORD ConInMode,ConOutMode; - DWORD Read=0; - GetConsoleMode(hConIn,&ConInMode); - GetConsoleMode(hConOut,&ConOutMode); - SetConsoleMode(hConIn,ENABLE_LINE_INPUT); - SetConsoleMode(hConOut,ENABLE_PROCESSED_OUTPUT|ENABLE_WRAP_AT_EOL_OUTPUT); - - ReadConsole(hConIn,Str,MaxLength-1,&Read,NULL); - Str[Read]=0; - SetConsoleMode(hConIn,ConInMode); - SetConsoleMode(hConOut,ConOutMode); + HANDLE hConIn=GetStdHandle(STD_INPUT_HANDLE); + HANDLE hConOut=GetStdHandle(STD_OUTPUT_HANDLE); + DWORD ConInMode,ConOutMode; + DWORD Read=0; + GetConsoleMode(hConIn,&ConInMode); + GetConsoleMode(hConOut,&ConOutMode); + SetConsoleMode(hConIn,ENABLE_LINE_INPUT); + SetConsoleMode(hConOut,ENABLE_PROCESSED_OUTPUT|ENABLE_WRAP_AT_EOL_OUTPUT); + + ReadConsole(hConIn,Str,MaxLength-1,&Read,NULL); + Str[Read]=0; + SetConsoleMode(hConIn,ConInMode); + SetConsoleMode(hConOut,ConOutMode); #else - char StrA[MAXPASSWORD]; + char StrA[MAXPASSWORD]; #if defined(_EMX) || defined (__VMS) - fgets(StrA,ASIZE(StrA)-1,stdin); + fgets(StrA,ASIZE(StrA)-1,stdin); #elif defined(__sun) - strncpyz(StrA,getpassphrase(""),ASIZE(StrA)); + strncpyz(StrA,getpassphrase(""),ASIZE(StrA)); #else - strncpyz(StrA,getpass(""),ASIZE(StrA)); + strncpyz(StrA,getpass(""),ASIZE(StrA)); #endif - CharToWide(StrA,Str,MaxLength); - cleandata(StrA,sizeof(StrA)); + CharToWide(StrA,Str,MaxLength); + cleandata(StrA,sizeof(StrA)); #endif + } Str[MaxLength-1]=0; RemoveLF(Str); } @@ -171,20 +177,22 @@ static void GetPasswordText(wchar *Str,uint MaxLength) #ifndef SILENT bool GetConsolePassword(UIPASSWORD_TYPE Type,const wchar *FileName,SecPassword *Password) { - uiAlarm(UIALARM_QUESTION); + if (!StdinRedirected) + uiAlarm(UIALARM_QUESTION); while (true) { - if (Type==UIPASSWORD_GLOBAL) - eprintf(L"\n%s: ",St(MAskPsw)); - else - eprintf(St(MAskPswFor),FileName); + if (!StdinRedirected) + if (Type==UIPASSWORD_GLOBAL) + eprintf(L"\n%s: ",St(MAskPsw)); + else + eprintf(St(MAskPswFor),FileName); wchar PlainPsw[MAXPASSWORD]; GetPasswordText(PlainPsw,ASIZE(PlainPsw)); if (*PlainPsw==0 && Type==UIPASSWORD_GLOBAL) return false; - if (Type==UIPASSWORD_GLOBAL) + if (!StdinRedirected && Type==UIPASSWORD_GLOBAL) { eprintf(St(MReAskPsw)); wchar CmpStr[MAXPASSWORD]; @@ -231,8 +239,9 @@ bool getwstr(wchar *str,size_t n) // calling Ask(), so let's better exit. ErrHandler.Exit(RARX_USERBREAK); } - StrA[ReadSize-1]=0; + StrA[ReadSize]=0; CharToWide(&StrA[0],str,n); + cleandata(&StrA[0],StrA.Size()); // We can use this function to enter passwords. } else { diff --git a/Libraries/unrar/crc.cpp b/Libraries/unrar/crc.cpp index d593281e..d77fa030 100644 --- a/Libraries/unrar/crc.cpp +++ b/Libraries/unrar/crc.cpp @@ -37,15 +37,15 @@ static void InitTables() { InitCRC32(crc_tables[0]); - for (uint I=0;I<256;I++) // Build additional lookup tables. + for (uint I=0;I<256;I++) // Build additional lookup tables. { - uint C=crc_tables[0][I]; - for (uint J=1;J<8;J++) + uint C=crc_tables[0][I]; + for (uint J=1;J<8;J++) { - C=crc_tables[0][(byte)C]^(C>>8); - crc_tables[J][I]=C; - } - } + C=crc_tables[0][(byte)C]^(C>>8); + crc_tables[J][I]=C; + } + } } @@ -62,13 +62,13 @@ uint CRC32(uint StartCRC,const void *Addr,size_t Size) for (;Size>=8;Size-=8,Data+=8) { #ifdef BIG_ENDIAN - StartCRC ^= Data[0]|(Data[1] << 8)|(Data[2] << 16)|(Data[3] << 24); + StartCRC ^= Data[0]|(Data[1] << 8)|(Data[2] << 16)|(Data[3] << 24); uint NextData = Data[4]|(Data[5] << 8)|(Data[6] << 16)|(Data[7] << 24); #else - StartCRC ^= *(uint32 *) Data; + StartCRC ^= *(uint32 *) Data; uint NextData = *(uint32 *) (Data +4); #endif - StartCRC = crc_tables[7][(byte) StartCRC ] ^ + StartCRC = crc_tables[7][(byte) StartCRC ] ^ crc_tables[6][(byte)(StartCRC >> 8) ] ^ crc_tables[5][(byte)(StartCRC >> 16)] ^ crc_tables[4][(byte)(StartCRC >> 24)] ^ @@ -76,7 +76,7 @@ uint CRC32(uint StartCRC,const void *Addr,size_t Size) crc_tables[2][(byte)(NextData >>8 ) ] ^ crc_tables[1][(byte)(NextData >> 16)] ^ crc_tables[0][(byte)(NextData >> 24)]; - } + } for (;Size>0;Size--,Data++) // Process left data. StartCRC=crc_tables[0][(byte)(StartCRC^Data[0])]^(StartCRC>>8); diff --git a/Libraries/unrar/dll.rc b/Libraries/unrar/dll.rc index b40d886f..757f3f0e 100644 --- a/Libraries/unrar/dll.rc +++ b/Libraries/unrar/dll.rc @@ -2,8 +2,8 @@ #include VS_VERSION_INFO VERSIONINFO -FILEVERSION 5, 31, 100, 1864 -PRODUCTVERSION 5, 31, 100, 1864 +FILEVERSION 5, 40, 100, 2057 +PRODUCTVERSION 5, 40, 100, 2057 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.31.0\0" - VALUE "ProductVersion", "5.31.0\0" + VALUE "FileVersion", "5.40.0\0" + VALUE "ProductVersion", "5.40.0\0" VALUE "LegalCopyright", "Copyright © Alexander Roshal 1993-2016\0" VALUE "OriginalFilename", "Unrar.dll\0" } diff --git a/Libraries/unrar/extract.cpp b/Libraries/unrar/extract.cpp index 2f6964ed..c77de809 100644 --- a/Libraries/unrar/extract.cpp +++ b/Libraries/unrar/extract.cpp @@ -106,10 +106,31 @@ EXTRACT_ARC_CODE CmdExtract::ExtractArchive() if (!Arc.IsArchive(true)) { +#if !defined(SFX_MODULE) && !defined(RARDLL) + if (CmpExt(ArcName,L"rev")) + { + wchar FirstVolName[NM]; + VolNameToFirstName(ArcName,FirstVolName,ASIZE(FirstVolName),true); + + // If several volume names from same volume set are specified + // and current volume is not first in set and first volume is present + // and specified too, let's skip the current volume. + if (wcsicomp(ArcName,FirstVolName)!=0 && FileExist(FirstVolName) && + Cmd->ArcNames.Search(FirstVolName,false)) + return EXTRACT_ARC_NEXT; + RecVolumesTest(Cmd,NULL,ArcName); + TotalFileCount++; // Suppress "No files to extract" message. + return EXTRACT_ARC_NEXT; + } +#endif + #ifndef GUI mprintf(St(MNotRAR),ArcName); #endif + +#ifndef SFX_MODULE if (CmpExt(ArcName,L"rar")) +#endif ErrHandler.SetErrorCode(RARX_WARNING); return EXTRACT_ARC_NEXT; } @@ -200,6 +221,11 @@ EXTRACT_ARC_CODE CmdExtract::ExtractArchive() } +#if !defined(SFX_MODULE) && !defined(RARDLL) + if (Cmd->Test && Arc.Volume) + RecVolumesTest(Cmd,&Arc,ArcName); +#endif + return EXTRACT_ARC_NEXT; } @@ -319,6 +345,10 @@ bool CmdExtract::ExtractCurrentFile(Archive &Arc,size_t HeaderSize,bool &Repeat) wchar ArcFileName[NM]; ConvertPath(Arc.FileHead.FileName,ArcFileName); +#ifdef _WIN_ALL + if (!Cmd->AllowIncompatNames) + MakeNameCompatible(ArcFileName); +#endif if (Arc.FileHead.Version) { diff --git a/Libraries/unrar/file.cpp b/Libraries/unrar/file.cpp index 044eddf0..7fbfb6e6 100644 --- a/Libraries/unrar/file.cpp +++ b/Libraries/unrar/file.cpp @@ -549,7 +549,7 @@ void File::Prealloc(int64 Size) #if defined(_UNIX) && defined(USE_FALLOCATE) // fallocate is rather new call. Only latest kernels support it. // So we are not using it by default yet. - int fd = GetFD(hFile); + int fd = GetFD(); if (fd >= 0) fallocate(fd, 0, 0, Size); #endif diff --git a/Libraries/unrar/filefn.cpp b/Libraries/unrar/filefn.cpp index c344d3d7..0c2b03dd 100644 --- a/Libraries/unrar/filefn.cpp +++ b/Libraries/unrar/filefn.cpp @@ -335,11 +335,11 @@ void CalcFileSum(File *SrcFile,uint *CRC32,byte *Blake2,uint Threads,int64 Size, { SaveFilePos SavePos(*SrcFile); #ifndef SILENT - int64 FileLength=SrcFile->FileLength(); + int64 FileLength=Size==INT64NDF ? SrcFile->FileLength() : Size; #endif #ifndef GUI - if ((Flags & (CALCFSUM_SHOWTEXT|CALCFSUM_SHOWALL))!=0) + if ((Flags & (CALCFSUM_SHOWTEXT|CALCFSUM_SHOWPERCENT))!=0) #endif uiMsg(UIEVENT_FILESUMSTART); @@ -355,6 +355,7 @@ void CalcFileSum(File *SrcFile,uint *CRC32,byte *Blake2,uint Threads,int64 Size, HashBlake2.Init(HASH_BLAKE2,Threads); int64 BlockCount=0; + int64 TotalRead=0; while (true) { size_t SizeToRead; @@ -365,14 +366,20 @@ void CalcFileSum(File *SrcFile,uint *CRC32,byte *Blake2,uint Threads,int64 Size, int ReadSize=SrcFile->Read(&Data[0],SizeToRead); if (ReadSize==0) break; + TotalRead+=ReadSize; if ((++BlockCount & 0xf)==0) { #ifndef SILENT + if ((Flags & CALCFSUM_SHOWPROGRESS)!=0) + uiExtractProgress(TotalRead,FileLength,TotalRead,FileLength); + else + { #ifndef GUI - if ((Flags & CALCFSUM_SHOWALL)!=0) + if ((Flags & CALCFSUM_SHOWPERCENT)!=0) #endif - uiMsg(UIEVENT_FILESUMPROGRESS,ToPercent(BlockCount*int64(BufSize),FileLength)); + uiMsg(UIEVENT_FILESUMPROGRESS,ToPercent(TotalRead,FileLength)); + } #endif Wait(); } @@ -386,7 +393,7 @@ void CalcFileSum(File *SrcFile,uint *CRC32,byte *Blake2,uint Threads,int64 Size, Size-=ReadSize; } #ifndef GUI - if ((Flags & CALCFSUM_SHOWALL)!=0) + if ((Flags & CALCFSUM_SHOWPERCENT)!=0) #endif uiMsg(UIEVENT_FILESUMEND); diff --git a/Libraries/unrar/filefn.hpp b/Libraries/unrar/filefn.hpp index b06cc64e..3a0c7a79 100644 --- a/Libraries/unrar/filefn.hpp +++ b/Libraries/unrar/filefn.hpp @@ -28,7 +28,7 @@ void PrepareToDelete(const wchar *Name); uint GetFileAttr(const wchar *Name); bool SetFileAttr(const wchar *Name,uint Attr); -enum CALCFSUM_FLAGS {CALCFSUM_SHOWTEXT=1,CALCFSUM_SHOWALL=2,CALCFSUM_CURPOS=4}; +enum CALCFSUM_FLAGS {CALCFSUM_SHOWTEXT=1,CALCFSUM_SHOWPERCENT=2,CALCFSUM_SHOWPROGRESS=4,CALCFSUM_CURPOS=8}; void CalcFileSum(File *SrcFile,uint *CRC32,byte *Blake2,uint Threads,int64 Size=INT64NDF,uint Flags=0); diff --git a/Libraries/unrar/filestr.cpp b/Libraries/unrar/filestr.cpp index 5fa946a4..d8ac36da 100644 --- a/Libraries/unrar/filestr.cpp +++ b/Libraries/unrar/filestr.cpp @@ -1,7 +1,5 @@ #include "rar.hpp" -static bool IsUnicode(byte *Data,int Size); - bool ReadTextFile( const wchar *Name, StringList *List, @@ -36,7 +34,7 @@ bool ReadTextFile( else SrcFile.SetHandleType(FILE_HANDLESTD); - unsigned int DataSize=0,ReadSize; + uint DataSize=0,ReadSize; const int ReadBlock=4096; // Our algorithm below needs at least two trailing zeroes after data. @@ -44,7 +42,7 @@ bool ReadTextFile( // in case read Unicode data contains uneven number of bytes. const size_t ZeroPadding=5; - Array Data(ReadBlock+ZeroPadding); + Array Data(ReadBlock+ZeroPadding); while ((ReadSize=SrcFile.Read(&Data[DataSize],ReadBlock))!=0) { DataSize+=ReadSize; @@ -55,17 +53,30 @@ bool ReadTextFile( Array WideStr; - if (SrcCharset==RCH_UNICODE || - SrcCharset==RCH_DEFAULT && IsUnicode((byte *)&Data[0],DataSize)) + int LowEndian=Data[0]==255 && Data[1]==254 ? 1:0; + int BigEndian=Data[0]==254 && Data[1]==255 ? 1:0; + + bool IsUnicode=false; + if (LowEndian || BigEndian) + for (size_t I=2;I DataW(Data.Size()/2+1); - for (size_t I=2;I DataW(Data.Size()/2+1); + for (size_t I=Start;I>= (8-InBit); - return(BitField & 0xffff); + return BitField & 0xffff; } // Return 32 bits from current position in the buffer. @@ -50,7 +50,7 @@ class BitInput BitField|=(uint)InBuf[InAddr+3]; BitField <<= InBit; BitField|=(uint)InBuf[InAddr+4] >> (8-InBit); - return(BitField & 0xffffffff); + return BitField & 0xffffffff; } void faddbits(uint Bits); @@ -60,7 +60,7 @@ class BitInput // if buffer will be overflown. bool Overflow(uint IncPtr) { - return(InAddr+IncPtr>=MAX_SIZE); + return InAddr+IncPtr>=MAX_SIZE; } void SetExternalBuffer(byte *Buf); diff --git a/Libraries/unrar/hash.cpp b/Libraries/unrar/hash.cpp index 578e32fa..42791f4f 100644 --- a/Libraries/unrar/hash.cpp +++ b/Libraries/unrar/hash.cpp @@ -41,6 +41,7 @@ bool HashValue::operator == (const HashValue &cmp) DataHash::DataHash() { + blake2ctx=NULL; HashType=HASH_NONE; #ifdef RAR_SMP ThPool=NULL; @@ -54,20 +55,26 @@ DataHash::~DataHash() #ifdef RAR_SMP DestroyThreadPool(ThPool); #endif - cleandata(&blake2ctx, sizeof(blake2ctx)); cleandata(&CurCRC32, sizeof(CurCRC32)); + if (blake2ctx!=NULL) + { + cleandata(blake2ctx, sizeof(blake2sp_state)); + delete blake2ctx; + } } void DataHash::Init(HASH_TYPE Type,uint MaxThreads) { + if (blake2ctx==NULL) + blake2ctx=new blake2sp_state; HashType=Type; if (Type==HASH_RAR14) CurCRC32=0; if (Type==HASH_CRC32) CurCRC32=0xffffffff; // Initial CRC32 value. if (Type==HASH_BLAKE2) - blake2sp_init( &blake2ctx ); + blake2sp_init(blake2ctx); #ifdef RAR_SMP DataHash::MaxThreads=Min(MaxThreads,MaxHashThreads); #endif @@ -88,10 +95,10 @@ void DataHash::Update(const void *Data,size_t DataSize) #ifdef RAR_SMP if (MaxThreads>1 && ThPool==NULL) ThPool=CreateThreadPool(); - blake2ctx.ThPool=ThPool; - blake2ctx.MaxThreads=MaxThreads; + blake2ctx->ThPool=ThPool; + blake2ctx->MaxThreads=MaxThreads; #endif - blake2sp_update( &blake2ctx, (byte *)Data, DataSize); + blake2sp_update( blake2ctx, (byte *)Data, DataSize); } } @@ -106,8 +113,8 @@ void DataHash::Result(HashValue *Result) if (HashType==HASH_BLAKE2) { // Preserve the original context, so we can continue hashing if necessary. - blake2sp_state res=blake2ctx; - blake2sp_final( &res, Result->Digest ); + blake2sp_state res=*blake2ctx; + blake2sp_final(&res,Result->Digest); } } diff --git a/Libraries/unrar/hash.hpp b/Libraries/unrar/hash.hpp index dae31d1b..b7d879f6 100644 --- a/Libraries/unrar/hash.hpp +++ b/Libraries/unrar/hash.hpp @@ -29,7 +29,7 @@ class DataHash private: HASH_TYPE HashType; uint CurCRC32; - blake2sp_state blake2ctx; + blake2sp_state *blake2ctx; #ifdef RAR_SMP ThreadPool *ThPool; diff --git a/Libraries/unrar/list.cpp b/Libraries/unrar/list.cpp index 9e69ef7a..561122b4 100644 --- a/Libraries/unrar/list.cpp +++ b/Libraries/unrar/list.cpp @@ -77,7 +77,7 @@ void ListArchive(CommandData *Cmd) #ifndef SFX_MODULE // Only RAR 1.5 archives store the volume number in end record. if (Arc.EndArcHead.StoreVolNumber && Arc.Format==RARFMT15) - swprintf(VolNumText,ASIZE(VolNumText),L"%.10ls %d",St(MListVolume),Arc.VolNumber+1); + swprintf(VolNumText,ASIZE(VolNumText),L"%.10ls %u",St(MListVolume),Arc.VolNumber+1); #endif if (Technical && ShowService) { @@ -149,9 +149,7 @@ void ListArchive(CommandData *Cmd) if (Cmd->VolSize!=0 && (Arc.FileHead.SplitAfter || Arc.GetHeaderType()==HEAD_ENDARC && Arc.EndArcHead.NextVolume) && MergeArchive(Arc,NULL,false,Cmd->Command[0])) - { Arc.Seek(0,SEEK_SET); - } else #endif break; diff --git a/Libraries/unrar/loclang.hpp b/Libraries/unrar/loclang.hpp index 077be72d..71b8985d 100644 --- a/Libraries/unrar/loclang.hpp +++ b/Libraries/unrar/loclang.hpp @@ -9,6 +9,8 @@ #define MShare L"\nTrial version Type RAR -? for help\n" #define MUCopyright L"\nUNRAR %s freeware Copyright (c) 1993-%d Alexander Roshal\n" #define MBeta L"beta" +#define Mx86 L"x86" +#define Mx64 L"x64" #define MMonthJan L"Jan" #define MMonthFeb L"Feb" #define MMonthMar L"Mar" @@ -83,6 +85,7 @@ #define MCHelpSwINUL L"\n inul Disable all messages" #define MCHelpSwIOFF L"\n ioff Turn PC off after completing an operation" #define MCHelpSwISND L"\n isnd Enable sound" +#define MCHelpSwIVER L"\n iver Display the version number" #define MCHelpSwK L"\n k Lock archive" #define MCHelpSwKB L"\n kb Keep broken extracted files" #define MCHelpSwLog L"\n log[f][=name] Write names to log file" @@ -100,6 +103,7 @@ #define MCHelpSwOH L"\n oh Save hard links as the link instead of the file" #define MCHelpSwOI L"\n oi[0-4][:min] Save identical files as references" #define MCHelpSwOL L"\n ol[a] Process symbolic links as the link [absolute paths]" +#define MCHelpSwONI L"\n oni Allow potentially incompatible names" #define MCHelpSwOR L"\n or Rename files automatically" #define MCHelpSwOS L"\n os Save NTFS streams" #define MCHelpSwOW L"\n ow Save or restore file owner and group" diff --git a/Libraries/unrar/makefile b/Libraries/unrar/makefile index 3c380270..83c07132 100644 --- a/Libraries/unrar/makefile +++ b/Libraries/unrar/makefile @@ -2,7 +2,7 @@ # Makefile for UNIX - unrar # Linux using GCC -CXX=g++ +CXX=c++ CXXFLAGS=-O2 LIBFLAGS=-fPIC DEFINES=-D_FILE_OFFSET_BITS=64 -D_LARGEFILE_SOURCE -DRAR_SMP diff --git a/Libraries/unrar/options.hpp b/Libraries/unrar/options.hpp index 878fe0e8..05d9e10c 100644 --- a/Libraries/unrar/options.hpp +++ b/Libraries/unrar/options.hpp @@ -114,6 +114,7 @@ class RAROptions bool DisablePercentage; bool DisableCopyright; bool DisableDone; + bool PrintVersion; int Solid; int SolidCount; bool ClearArc; @@ -140,6 +141,10 @@ class RAROptions bool OpenShared; bool DeleteFiles; +#ifdef _WIN_ALL + bool AllowIncompatNames; // Allow names with trailing dots and spaces. +#endif + #ifndef SFX_MODULE bool GenerateArcName; diff --git a/Libraries/unrar/pathfn.cpp b/Libraries/unrar/pathfn.cpp index de5585d8..1fe6b98d 100644 --- a/Libraries/unrar/pathfn.cpp +++ b/Libraries/unrar/pathfn.cpp @@ -733,16 +733,16 @@ static void GenArcName(wchar *ArcName,const wchar *GenerateMask,uint ArcNumber,b char Field[10][6]; - sprintf(Field[0],"%04d",rlt.Year); - sprintf(Field[1],"%02d",rlt.Month); - sprintf(Field[2],"%02d",rlt.Day); - sprintf(Field[3],"%02d",rlt.Hour); - sprintf(Field[4],"%02d",rlt.Minute); - sprintf(Field[5],"%02d",rlt.Second); - sprintf(Field[6],"%02d",CurWeek); - sprintf(Field[7],"%d",WeekDay+1); - sprintf(Field[8],"%03d",rlt.yDay+1); - sprintf(Field[9],"%05d",ArcNumber); + sprintf(Field[0],"%04u",rlt.Year); + sprintf(Field[1],"%02u",rlt.Month); + sprintf(Field[2],"%02u",rlt.Day); + sprintf(Field[3],"%02u",rlt.Hour); + sprintf(Field[4],"%02u",rlt.Minute); + sprintf(Field[5],"%02u",rlt.Second); + sprintf(Field[6],"%02u",(uint)CurWeek); + sprintf(Field[7],"%u",(uint)WeekDay+1); + sprintf(Field[8],"%03u",rlt.yDay+1); + sprintf(Field[9],"%05u",ArcNumber); const wchar *MaskChars=L"YMDHISWAEN"; @@ -873,7 +873,7 @@ wchar* GetWideName(const char *Name,const wchar *NameW,wchar *DestW,size_t DestS if (DestSize>0) DestW[DestSize-1]=0; - return(DestW); + return DestW; } @@ -958,4 +958,26 @@ void ConvertToPrecomposed(wchar *Name,size_t NameSize) wcsncpyz(Name,FileName,NameSize); } } + + +// Remove trailing spaces and dots in file name and in dir names in path. +void MakeNameCompatible(wchar *Name) +{ + int Src=0,Dest=0; + while (true) + { + if (IsPathDiv(Name[Src]) || Name[Src]==0) + for (int I=Dest-1;I>0 && (Name[I]==' ' || Name[I]=='.');I--) + { + if (IsPathDiv(Name[I-1])) // Permit path1/./path2 paths. + break; + Dest--; + } + Name[Dest]=Name[Src]; + if (Name[Src]==0) + break; + Src++; + Dest++; + } +} #endif diff --git a/Libraries/unrar/pathfn.hpp b/Libraries/unrar/pathfn.hpp index fe28112f..f0826946 100644 --- a/Libraries/unrar/pathfn.hpp +++ b/Libraries/unrar/pathfn.hpp @@ -70,6 +70,7 @@ void GenerateArchiveName(wchar *ArcName,size_t MaxSize,const wchar *GenerateMask #ifdef _WIN_ALL bool GetWinLongPath(const wchar *Src,wchar *Dest,size_t MaxSize); void ConvertToPrecomposed(wchar *Name,size_t NameSize); +void MakeNameCompatible(wchar *Name); #endif #endif diff --git a/Libraries/unrar/rardefs.hpp b/Libraries/unrar/rardefs.hpp index 93276233..80f39b12 100644 --- a/Libraries/unrar/rardefs.hpp +++ b/Libraries/unrar/rardefs.hpp @@ -13,7 +13,9 @@ // for CryptProtectMemory in SecPassword. #define MAXPASSWORD 128 -#define MAXSFXSIZE 0x100000 +#define MAXSFXSIZE 0x200000 + +#define MAXCMTSIZE 0x40000 #define DefSFXName L"default.sfx" #define DefSortListName L"rarfiles.lst" diff --git a/Libraries/unrar/rdwrfn.cpp b/Libraries/unrar/rdwrfn.cpp index 9bb0094f..5d2598e4 100644 --- a/Libraries/unrar/rdwrfn.cpp +++ b/Libraries/unrar/rdwrfn.cpp @@ -2,6 +2,10 @@ ComprDataIO::ComprDataIO() { +#ifndef RAR_NOCRYPT + Crypt=new CryptData; + Decrypt=new CryptData; +#endif Init(); } @@ -33,6 +37,13 @@ void ComprDataIO::Init() } +ComprDataIO::~ComprDataIO() +{ +#ifndef RAR_NOCRYPT + delete Crypt; + delete Decrypt; +#endif +} @@ -127,7 +138,7 @@ int ComprDataIO::UnpRead(byte *Addr,size_t Count) ReadSize=TotalRead; #ifndef RAR_NOCRYPT if (Decryption) - Decrypt.DecryptBlock(Addr,ReadSize); + Decrypt->DecryptBlock(Addr,ReadSize); #endif } Wait(); @@ -273,9 +284,9 @@ void ComprDataIO::SetEncryption(bool Encrypt,CRYPT_METHOD Method, { #ifndef RAR_NOCRYPT if (Encrypt) - Encryption=Crypt.SetCryptKeys(true,Method,Password,Salt,InitV,Lg2Cnt,HashKey,PswCheck); + Encryption=Crypt->SetCryptKeys(true,Method,Password,Salt,InitV,Lg2Cnt,HashKey,PswCheck); else - Decryption=Decrypt.SetCryptKeys(false,Method,Password,Salt,InitV,Lg2Cnt,HashKey,PswCheck); + Decryption=Decrypt->SetCryptKeys(false,Method,Password,Salt,InitV,Lg2Cnt,HashKey,PswCheck); #endif } @@ -284,7 +295,7 @@ void ComprDataIO::SetEncryption(bool Encrypt,CRYPT_METHOD Method, void ComprDataIO::SetAV15Encryption() { Decryption=true; - Decrypt.SetAV15Encryption(); + Decrypt->SetAV15Encryption(); } #endif @@ -293,7 +304,7 @@ void ComprDataIO::SetAV15Encryption() void ComprDataIO::SetCmt13Encryption() { Decryption=true; - Decrypt.SetCmt13Encryption(); + Decrypt->SetCmt13Encryption(); } #endif diff --git a/Libraries/unrar/rdwrfn.hpp b/Libraries/unrar/rdwrfn.hpp index 11ab5129..a8508d60 100644 --- a/Libraries/unrar/rdwrfn.hpp +++ b/Libraries/unrar/rdwrfn.hpp @@ -38,8 +38,8 @@ class ComprDataIO int64 *SubHeadPos; #ifndef RAR_NOCRYPT - CryptData Crypt; - CryptData Decrypt; + CryptData *Crypt; + CryptData *Decrypt; #endif @@ -49,6 +49,7 @@ class ComprDataIO public: ComprDataIO(); + ~ComprDataIO(); void Init(); int UnpRead(byte *Addr,size_t Count); void UnpWrite(byte *Addr,size_t Count); diff --git a/Libraries/unrar/recvol.cpp b/Libraries/unrar/recvol.cpp index beb2ce57..c1586342 100644 --- a/Libraries/unrar/recvol.cpp +++ b/Libraries/unrar/recvol.cpp @@ -31,12 +31,83 @@ bool RecVolumesRestore(RAROptions *Cmd,const wchar *Name,bool Silent) // handling exceptions. So it can close and delete files on Cancel. if (Fmt==RARFMT15) { - RecVolumes3 RecVol; + RecVolumes3 RecVol(false); return RecVol.Restore(Cmd,Name,Silent); } else { - RecVolumes5 RecVol; + RecVolumes5 RecVol(false); return RecVol.Restore(Cmd,Name,Silent); } } + + +void RecVolumesTest(RAROptions *Cmd,Archive *Arc,const wchar *Name) +{ + wchar RevName[NM]; + *RevName=0; + if (Arc!=NULL) + { + // We received .rar or .exe volume as a parameter, trying to find + // the matching .rev file number 1. + bool NewNumbering=Arc->NewNumbering; + + wchar ArcName[NM]; + wcsncpyz(ArcName,Name,ASIZE(ArcName)); + + wchar *VolNumStart=VolNameToFirstName(ArcName,ArcName,ASIZE(ArcName),NewNumbering); + wchar RecVolMask[NM]; + wcsncpyz(RecVolMask,ArcName,ASIZE(RecVolMask)); + size_t BaseNamePartLength=VolNumStart-ArcName; + wcsncpyz(RecVolMask+BaseNamePartLength,L"*.rev",ASIZE(RecVolMask)-BaseNamePartLength); + + FindFile Find; + Find.SetMask(RecVolMask); + FindData RecData; + + while (Find.Next(&RecData)) + { + wchar *Num=GetVolNumPart(RecData.Name); + if (*Num!='1') // Name must have "0...01" numeric part. + continue; + bool FirstVol=true; + while (--Num>=RecData.Name && IsDigit(*Num)) + if (*Num!='0') + { + FirstVol=false; + break; + } + if (FirstVol) + { + wcsncpyz(RevName,RecData.Name,ASIZE(RevName)); + Name=RevName; + break; + } + } + if (*RevName==0) // First .rev file not found. + return; + } + + File RevFile; + if (!RevFile.Open(Name)) + { + ErrHandler.OpenErrorMsg(Name); // It also sets RARX_OPEN. + return; + } +#ifndef GUI + mprintf(L"\n"); +#endif + byte Sign[REV5_SIGN_SIZE]; + bool Rev5=RevFile.Read(Sign,REV5_SIGN_SIZE)==REV5_SIGN_SIZE && memcmp(Sign,REV5_SIGN,REV5_SIGN_SIZE)==0; + RevFile.Close(); + if (Rev5) + { + RecVolumes5 RecVol(true); + RecVol.Test(Cmd,Name); + } + else + { + RecVolumes3 RecVol(true); + RecVol.Test(Cmd,Name); + } +} diff --git a/Libraries/unrar/recvol.hpp b/Libraries/unrar/recvol.hpp index 5956d7bb..7f2f1adb 100644 --- a/Libraries/unrar/recvol.hpp +++ b/Libraries/unrar/recvol.hpp @@ -14,10 +14,11 @@ class RecVolumes3 ThreadPool *RSThreadPool; #endif public: - RecVolumes3(); + RecVolumes3(bool TestOnly); ~RecVolumes3(); void Make(RAROptions *Cmd,wchar *ArcName); bool Restore(RAROptions *Cmd,const wchar *Name,bool Silent); + void Test(RAROptions *Cmd,const wchar *Name); }; @@ -74,11 +75,13 @@ class RecVolumes5 public: // 'public' only because called from thread functions. void ProcessAreaRS(RecRSThreadData *td); public: - RecVolumes5(); + RecVolumes5(bool TestOnly); ~RecVolumes5(); bool Restore(RAROptions *Cmd,const wchar *Name,bool Silent); + void Test(RAROptions *Cmd,const wchar *Name); }; bool RecVolumesRestore(RAROptions *Cmd,const wchar *Name,bool Silent); +void RecVolumesTest(RAROptions *Cmd,Archive *Arc,const wchar *Name); #endif diff --git a/Libraries/unrar/recvol3.cpp b/Libraries/unrar/recvol3.cpp index 3c77eba3..4cbc39c8 100644 --- a/Libraries/unrar/recvol3.cpp +++ b/Libraries/unrar/recvol3.cpp @@ -38,13 +38,23 @@ THREAD_PROC(RSDecodeThread) } #endif -RecVolumes3::RecVolumes3() +RecVolumes3::RecVolumes3(bool TestOnly) { - Buf.Alloc(TotalBufferSize); memset(SrcFile,0,sizeof(SrcFile)); + if (TestOnly) + { +#ifdef RAR_SMP + RSThreadPool=NULL; +#endif + } + else + { + Buf.Alloc(TotalBufferSize); + memset(SrcFile,0,sizeof(SrcFile)); #ifdef RAR_SMP - RSThreadPool=CreateThreadPool(); + RSThreadPool=CreateThreadPool(); #endif + } } @@ -74,26 +84,34 @@ void RSEncode::EncodeBuf() } +// Check for names like arc5_3_1.rev created by RAR 3.0. +static bool IsNewStyleRev(const wchar *Name) +{ + wchar *Ext=GetExt(Name); + if (Ext==NULL) + return true; + int DigitGroup=0; + for (Ext--;Ext>Name;Ext--) + if (!IsDigit(*Ext)) + if (*Ext=='_' && IsDigit(*(Ext-1))) + DigitGroup++; + else + break; + return DigitGroup<2; +} + + bool RecVolumes3::Restore(RAROptions *Cmd,const wchar *Name,bool Silent) { wchar ArcName[NM]; wcsncpyz(ArcName,Name,ASIZE(ArcName)); wchar *Ext=GetExt(ArcName); - bool NewStyle=false; + bool NewStyle=false; // New style .rev volumes are supported since RAR 3.10. bool RevName=Ext!=NULL && wcsicomp(Ext,L".rev")==0; if (RevName) { - for (int DigitGroup=0;Ext>ArcName && DigitGroup<3;Ext--) - if (!IsDigit(*Ext)) - if (IsDigit(*(Ext-1)) && (*Ext=='_' || DigitGroup<2)) - DigitGroup++; - else - if (DigitGroup<2) - { - NewStyle=true; - break; - } - while (IsDigit(*Ext) && Ext>ArcName+1) + NewStyle=IsNewStyleRev(ArcName); + while (Ext>ArcName+1 && (IsDigit(*(Ext-1)) || *(Ext-1)=='_')) Ext--; wcscpy(Ext,L"*.*"); @@ -480,3 +498,54 @@ void RSEncode::DecodeBuf() Buf[Erasures[I]*RecBufferSize+BufPos]=Data[Erasures[I]]; } } + + +void RecVolumes3::Test(RAROptions *Cmd,const wchar *Name) +{ + if (!IsNewStyleRev(Name)) // RAR 3.0 name#_#_#.rev do not include CRC32. + { + ErrHandler.UnknownMethodMsg(Name,Name); + return; + } + + wchar VolName[NM]; + wcsncpyz(VolName,Name,ASIZE(VolName)); + + while (FileExist(VolName)) + { + File CurFile; + if (!CurFile.Open(VolName)) + { + ErrHandler.OpenErrorMsg(VolName); // It also sets RARX_OPEN. + continue; + } + if (!uiStartFileExtract(VolName,false,true,false)) + return; +#ifndef GUI + mprintf(St(MExtrTestFile),VolName); + mprintf(L" "); +#endif + CurFile.Seek(0,SEEK_END); + int64 Length=CurFile.Tell(); + CurFile.Seek(Length-4,SEEK_SET); + uint FileCRC=0; + for (int I=0;I<4;I++) + FileCRC|=CurFile.GetByte()<<(I*8); + + uint CalcCRC; + CalcFileSum(&CurFile,&CalcCRC,NULL,1,Length-4,Cmd->DisablePercentage ? 0 : CALCFSUM_SHOWPROGRESS); + if (FileCRC==CalcCRC) + { +#ifndef GUI + mprintf(L"%s%s ",L"\b\b\b\b\b ",St(MOk)); +#endif + } + else + { + uiMsg(UIERROR_CHECKSUM,VolName,VolName); + ErrHandler.SetErrorCode(RARX_CRC); + } + + NextVolumeName(VolName,ASIZE(VolName),false); + } +} diff --git a/Libraries/unrar/recvol5.cpp b/Libraries/unrar/recvol5.cpp index 4cb0fc72..bd5534ed 100644 --- a/Libraries/unrar/recvol5.cpp +++ b/Libraries/unrar/recvol5.cpp @@ -2,8 +2,9 @@ static const uint MaxVolumes=65535; -RecVolumes5::RecVolumes5() +RecVolumes5::RecVolumes5(bool TestOnly) { + RealBuf=NULL; RealReadBuffer=NULL; DataCount=0; @@ -16,13 +17,21 @@ RecVolumes5::RecVolumes5() ThreadData[I].RecRSPtr=this; ThreadData[I].RS=NULL; } + + if (TestOnly) + { #ifdef RAR_SMP - RecThreadPool=CreateThreadPool(); + RecThreadPool=NULL; #endif - - RealBuf=NULL; // Might be needed in case of exception. - RealBuf=new byte[TotalBufferSize+SSE_ALIGNMENT]; - Buf=(byte *)ALIGN_VALUE(RealBuf,SSE_ALIGNMENT); + } + else + { +#ifdef RAR_SMP + RecThreadPool=CreateThreadPool(); +#endif + RealBuf=new byte[TotalBufferSize+SSE_ALIGNMENT]; + Buf=(byte *)ALIGN_VALUE(RealBuf,SSE_ALIGNMENT); + } } @@ -129,7 +138,7 @@ void RecVolumes5::ProcessAreaRS(RecRSThreadData *td) bool RecVolumes5::Restore(RAROptions *Cmd,const wchar *Name,bool Silent) { wchar ArcName[NM]; - wcscpy(ArcName,Name); + wcsncpyz(ArcName,Name,ASIZE(ArcName)); wchar *Num=GetVolNumPart(ArcName); while (Num>ArcName && IsDigit(*(Num-1))) @@ -288,7 +297,7 @@ bool RecVolumes5::Restore(RAROptions *Cmd,const wchar *Name,bool Silent) Item->f=NULL; } - if (Item->New=(Item->f==NULL)) + if ((Item->New=(Item->f==NULL))) // Additional parentheses to avoid GCC warning. { wcsncpyz(Item->Name,FirstVolName,ASIZE(Item->Name)); uiMsg(UIMSG_CREATING,Item->Name); @@ -339,7 +348,11 @@ bool RecVolumes5::Restore(RAROptions *Cmd,const wchar *Name,bool Silent) RSCoder16 RS; if (!RS.Init(DataCount,RecCount,ValidFlags)) + { + delete[] ValidFlags; + delete[] Data; return false; // Should not happen, we check parameter validity above. + } RealReadBuffer=new byte[RecBufferSize+SSE_ALIGNMENT]; byte *ReadBuf=(byte *)ALIGN_VALUE(RealReadBuffer,SSE_ALIGNMENT); @@ -462,3 +475,51 @@ uint RecVolumes5::ReadHeader(File *RecFile,bool FirstRev) return RecNum; } + + +void RecVolumes5::Test(RAROptions *Cmd,const wchar *Name) +{ + wchar VolName[NM]; + wcsncpyz(VolName,Name,ASIZE(VolName)); + + uint FoundRecVolumes=0; + while (FileExist(VolName)) + { + File CurFile; + if (!CurFile.Open(VolName)) + { + ErrHandler.OpenErrorMsg(VolName); // It also sets RARX_OPEN. + continue; + } + if (!uiStartFileExtract(VolName,false,true,false)) + return; +#ifndef GUI + mprintf(St(MExtrTestFile),VolName); + mprintf(L" "); +#endif + bool Valid=false; + uint RecNum=ReadHeader(&CurFile,FoundRecVolumes==0); + if (RecNum!=0) + { + FoundRecVolumes++; + + uint RevCRC; + CalcFileSum(&CurFile,&RevCRC,NULL,1,INT64NDF,CALCFSUM_CURPOS|(Cmd->DisablePercentage ? 0 : CALCFSUM_SHOWPROGRESS)); + Valid=RevCRC==RecItems[RecNum].CRC; + } + + if (Valid) + { +#ifndef GUI + mprintf(L"%s%s ",L"\b\b\b\b\b ",St(MOk)); +#endif + } + else + { + uiMsg(UIERROR_CHECKSUM,VolName,VolName); + ErrHandler.SetErrorCode(RARX_CRC); + } + + NextVolumeName(VolName,ASIZE(VolName),false); + } +} diff --git a/Libraries/unrar/rs16.cpp b/Libraries/unrar/rs16.cpp index 082ab83f..e1b4af1d 100644 --- a/Libraries/unrar/rs16.cpp +++ b/Libraries/unrar/rs16.cpp @@ -215,6 +215,7 @@ void RSCoder16::InvertDecoderMatrix() } +#if 0 // Multiply matrix to data vector. When encoding, it contains data in Data // and stores error correction codes in Out. When decoding it contains // broken data followed by ECC in Data and stores recovered data to Out. @@ -252,6 +253,7 @@ void RSCoder16::Process(const uint *Data, uint *Out) Out[I] = R; } } +#endif // We update ECC in blocks by applying every data block to all ECC blocks. diff --git a/Libraries/unrar/rs16.hpp b/Libraries/unrar/rs16.hpp index ba518ac1..b67a7ca8 100644 --- a/Libraries/unrar/rs16.hpp +++ b/Libraries/unrar/rs16.hpp @@ -35,7 +35,9 @@ class RSCoder16 ~RSCoder16(); bool Init(uint DataCount, uint RecCount, bool *ValidityFlags); +#if 0 // We use only UpdateECC now. void Process(const uint *Data, uint *Out); +#endif void UpdateECC(uint DataNum, uint ECCNum, const byte *Data, byte *ECC, size_t BlockSize); }; diff --git a/Libraries/unrar/scantree.cpp b/Libraries/unrar/scantree.cpp index 36bb5708..ed48efe4 100644 --- a/Libraries/unrar/scantree.cpp +++ b/Libraries/unrar/scantree.cpp @@ -17,6 +17,8 @@ ScanTree::ScanTree(StringList *FileMasks,RECURSE_MODE Recurse,bool GetLinks,SCAN Errors=0; *ErrArcName=0; Cmd=NULL; + ErrDirList=NULL; + ErrDirSpecPathLength=NULL; } @@ -467,6 +469,10 @@ void ScanTree::ScanError(bool &Error) if (Error) { + if (ErrDirList!=NULL) + ErrDirList->AddString(CurMask); + if (ErrDirSpecPathLength!=NULL) + ErrDirSpecPathLength->Push((uint)SpecPathLength); wchar FullName[NM]; // This conversion works for wildcard masks too. ConvertNameToFull(CurMask,FullName,ASIZE(FullName)); diff --git a/Libraries/unrar/scantree.hpp b/Libraries/unrar/scantree.hpp index ed627ee7..40a6d849 100644 --- a/Libraries/unrar/scantree.hpp +++ b/Libraries/unrar/scantree.hpp @@ -47,6 +47,10 @@ class ScanTree // Store a filter string for folder wildcard in recursive mode. StringList FilterList; + // Save the list of unreadable dirs here. + StringList *ErrDirList; + Array *ErrDirSpecPathLength; + // Set if processing a folder wildcard mask. bool FolderWildcards; @@ -64,6 +68,11 @@ class ScanTree int GetErrors() {return Errors;}; void SetErrArcName(const wchar *Name) {wcsncpyz(ErrArcName,Name,ASIZE(ErrArcName));} void SetCommandData(CommandData *Cmd) {ScanTree::Cmd=Cmd;} + void SetErrDirList(StringList *List,Array *Lengths) + { + ErrDirList=List; + ErrDirSpecPathLength=Lengths; + } }; #endif diff --git a/Libraries/unrar/smallfn.cpp b/Libraries/unrar/smallfn.cpp index fe7cb1dc..81259d02 100644 --- a/Libraries/unrar/smallfn.cpp +++ b/Libraries/unrar/smallfn.cpp @@ -3,7 +3,7 @@ int ToPercent(int64 N1,int64 N2) { if (N20) + Dest[DestSize-1]=0; +} + + int stricomp(const char *s1,const char *s2) { #ifdef _WIN_ALL @@ -87,7 +102,7 @@ wchar* RemoveLF(wchar *Str) { for (int I=(int)wcslen(Str)-1;I>=0 && (Str[I]=='\r' || Str[I]=='\n');I--) Str[I]=0; - return(Str); + return Str; } @@ -95,9 +110,9 @@ unsigned char loctolower(unsigned char ch) { #ifdef _WIN_ALL // Convert to LPARAM first to avoid a warning in 64 bit mode. - return((int)(LPARAM)CharLowerA((LPSTR)ch)); + return (int)(LPARAM)CharLowerA((LPSTR)ch); #else - return(tolower(ch)); + return tolower(ch); #endif } @@ -106,9 +121,9 @@ unsigned char loctoupper(unsigned char ch) { #ifdef _WIN_ALL // Convert to LPARAM first to avoid a warning in 64 bit mode. - return((int)(LPARAM)CharUpperA((LPSTR)ch)); + return (int)(LPARAM)CharUpperA((LPSTR)ch); #else - return(toupper(ch)); + return toupper(ch); #endif } @@ -120,8 +135,8 @@ unsigned char loctoupper(unsigned char ch) unsigned char etoupper(unsigned char ch) { if (ch=='i') - return('I'); - return(toupper(ch)); + return 'I'; + return toupper(ch); } @@ -129,8 +144,8 @@ unsigned char etoupper(unsigned char ch) wchar etoupperw(wchar ch) { if (ch=='i') - return('I'); - return(toupperw(ch)); + return 'I'; + return toupperw(ch); } @@ -140,7 +155,7 @@ wchar etoupperw(wchar ch) // values, resulting in undefined behavior in standard isdigit. bool IsDigit(int ch) { - return(ch>='0' && ch<='9'); + return ch>='0' && ch<='9'; } @@ -150,7 +165,7 @@ bool IsDigit(int ch) // values, resulting in undefined behavior in standard isspace. bool IsSpace(int ch) { - return(ch==' ' || ch=='\t'); + return ch==' ' || ch=='\t'; } @@ -160,7 +175,7 @@ bool IsSpace(int ch) // values, resulting in undefined behavior in standard function. bool IsAlpha(int ch) { - return(ch>='A' && ch<='Z' || ch>='a' && ch<='z'); + return ch>='A' && ch<='Z' || ch>='a' && ch<='z'; } diff --git a/Libraries/unrar/strfn.hpp b/Libraries/unrar/strfn.hpp index cf26e4ea..d6d8d124 100644 --- a/Libraries/unrar/strfn.hpp +++ b/Libraries/unrar/strfn.hpp @@ -4,6 +4,10 @@ const char* NullToEmpty(const char *Str); const wchar* NullToEmpty(const wchar *Str); void IntToExt(const char *Src,char *Dest,size_t DestSize); + +enum ACTW_ENCODING { ACTW_DEFAULT, ACTW_OEM, ACTW_UTF8}; +void ArcCharToWide(const char *Src,wchar *Dest,size_t DestSize,ACTW_ENCODING Encoding); + int stricomp(const char *s1,const char *s2); int strnicomp(const char *s1,const char *s2,size_t n); wchar* RemoveEOL(wchar *Str); diff --git a/Libraries/unrar/suballoc.cpp b/Libraries/unrar/suballoc.cpp index 4bc07bf9..d1fb690d 100644 --- a/Libraries/unrar/suballoc.cpp +++ b/Libraries/unrar/suballoc.cpp @@ -66,8 +66,6 @@ inline void SubAllocator::SplitBlock(void* pv,int OldIndx,int NewIndx) } - - void SubAllocator::StopSubAllocator() { if ( SubAllocatorSize ) diff --git a/Libraries/unrar/suballoc.hpp b/Libraries/unrar/suballoc.hpp index 0280289c..5989e82e 100644 --- a/Libraries/unrar/suballoc.hpp +++ b/Libraries/unrar/suballoc.hpp @@ -57,7 +57,6 @@ class SubAllocator inline void* RemoveNode(int indx); inline uint U2B(int NU); inline void SplitBlock(void* pv,int OldIndx,int NewIndx); - uint GetUsedMemory(); inline void GlueFreeBlocks(); void* AllocUnitsRare(int indx); inline RARPPM_MEM_BLK* MBPtr(RARPPM_MEM_BLK *BasePtr,int Items); diff --git a/Libraries/unrar/threadmisc.cpp b/Libraries/unrar/threadmisc.cpp index 0075f7c2..4ad5af2e 100644 --- a/Libraries/unrar/threadmisc.cpp +++ b/Libraries/unrar/threadmisc.cpp @@ -77,17 +77,20 @@ ThreadPool* CreateThreadPool() void DestroyThreadPool(ThreadPool *Pool) { - CriticalSectionStart(&PoolCreateSync.CritSection); + if (Pool!=NULL) + { + CriticalSectionStart(&PoolCreateSync.CritSection); - if (Pool!=NULL && Pool==GlobalPool && GlobalPoolUseCount > 0 && --GlobalPoolUseCount == 0) - delete GlobalPool; + if (Pool==GlobalPool && GlobalPoolUseCount > 0 && --GlobalPoolUseCount == 0) + delete GlobalPool; - // To correctly work in multithreaded environment UnRAR.dll creates - // new pools if global pool is already in use. We delete such pools here. - if (Pool!=NULL && Pool!=GlobalPool) - delete Pool; + // To correctly work in multithreaded environment UnRAR.dll creates + // new pools if global pool is already in use. We delete such pools here. + if (Pool!=GlobalPool) + delete Pool; - CriticalSectionEnd(&PoolCreateSync.CritSection); + CriticalSectionEnd(&PoolCreateSync.CritSection); + } } diff --git a/Libraries/unrar/timefn.cpp b/Libraries/unrar/timefn.cpp index f0d38161..b524f774 100644 --- a/Libraries/unrar/timefn.cpp +++ b/Libraries/unrar/timefn.cpp @@ -175,6 +175,51 @@ void RarTime::SetLocal(RarLocalTime *lt) } +void RarTime::SetUTC(RarLocalTime *lt) // Input is in UTC format. +{ +#ifdef _WIN_ALL + SYSTEMTIME st; + st.wYear=lt->Year; + st.wMonth=lt->Month; + st.wDay=lt->Day; + st.wHour=lt->Hour; + st.wMinute=lt->Minute; + st.wSecond=lt->Second; + st.wMilliseconds=0; + st.wDayOfWeek=0; + FILETIME ft; + if (SystemTimeToFileTime(&st,&ft)) + *this=ft; + else + Reset(); +#else + struct tm t; + + t.tm_sec=lt->Second; + t.tm_min=lt->Minute; + t.tm_hour=lt->Hour; + t.tm_mday=lt->Day; + t.tm_mon=lt->Month-1; + t.tm_year=lt->Year-1900; + t.tm_isdst=-1; + + /* get the local time for Jan 2, 1900 00:00 UTC */ + time_t zero = 24*60*60L; + struct tm *timeptr = localtime( &zero ); + int gmtime_hours = timeptr->tm_hour; + + /* if the local time is the "day before" the UTC, subtract 24 hours + from the hours to get the UTC offset */ + if( timeptr->tm_mday < 2 ) + gmtime_hours -= 24; + + *this=mktime(&t)+gmtime_hours*3600; + itime+=lt->Reminder; + +#endif +} + + // Return the stored time as 64-bit number of 100-nanosecond intervals since // 01.01.1601. Actually we do not care since which date this time starts from // as long as this date is the same for GetRaw and SetRaw. We use the value diff --git a/Libraries/unrar/timefn.hpp b/Libraries/unrar/timefn.hpp index 39767170..e9d77586 100644 --- a/Libraries/unrar/timefn.hpp +++ b/Libraries/unrar/timefn.hpp @@ -17,6 +17,8 @@ struct RarLocalTime class RarTime { + public: + static const uint TICKS_PER_SECOND = 10000000; // Raw time items per second. private: // Internal FILETIME like time representation in 100 nanoseconds // since 01.01.1601. @@ -39,6 +41,7 @@ class RarTime bool operator >= (RarTime &rt) {return itime>rt.itime || itime==rt.itime;} void GetLocal(RarLocalTime *lt); void SetLocal(RarLocalTime *lt); + void SetUTC(RarLocalTime *lt); uint64 GetRaw(); void SetRaw(uint64 RawTime); uint GetDos(); diff --git a/Libraries/unrar/unicode.cpp b/Libraries/unrar/unicode.cpp index d854bcd0..be336329 100644 --- a/Libraries/unrar/unicode.cpp +++ b/Libraries/unrar/unicode.cpp @@ -359,7 +359,7 @@ bool UtfToWide(const char *Src,wchar *Dest,size_t DestSize) continue; } if (Dest!=NULL) - if (sizeof(*Dest)==2) // Use the surrogate pair for 2 byte Unicode. + if (sizeof(*Dest)==2) // Use the surrogate pair. { *(Dest++)=((d-0x10000)>>10)+0xd800; *(Dest++)=(d&0x3ff)+0xdc00; @@ -476,7 +476,7 @@ int toupperw(int ch) // CharUpper is more reliable than towupper in Windows, which seems to be // C locale dependent even in Unicode version. For example, towupper failed // to convert lowercase Russian characters. - return (int)CharUpper((wchar *)ch); + return (int)(INT_PTR)CharUpper((wchar *)(INT_PTR)ch); #else return towupper(ch); #endif @@ -488,7 +488,7 @@ int tolowerw(int ch) #ifdef _WIN_ALL // CharLower is more reliable than towlower in Windows. // See comment for towupper above. - return (int)CharLower((wchar *)ch); + return (int)(INT_PTR)CharLower((wchar *)(INT_PTR)ch); #else return towlower(ch); #endif diff --git a/Libraries/unrar/unpack.cpp b/Libraries/unrar/unpack.cpp index 2046e104..9b4c8540 100644 --- a/Libraries/unrar/unpack.cpp +++ b/Libraries/unrar/unpack.cpp @@ -319,7 +319,7 @@ void Unpack::MakeDecodeTables(byte *LengthTable,DecodeTable *Dec,uint Size) // Find the upper limit for current bit field and adjust the bit length // accordingly if necessary. - while (BitField>=Dec->DecodeLen[CurBitLength] && CurBitLengthDecodeLen)) + while (CurBitLengthDecodeLen) && BitField>=Dec->DecodeLen[CurBitLength]) CurBitLength++; // Translation of right aligned bit string to bit length. diff --git a/Libraries/unrar/unpack30.cpp b/Libraries/unrar/unpack30.cpp index cee67b66..c5b72e2c 100644 --- a/Libraries/unrar/unpack30.cpp +++ b/Libraries/unrar/unpack30.cpp @@ -419,7 +419,10 @@ bool Unpack::AddVMCode(uint FirstByte,byte *Code,int CodeSize) if (EmptyCount==0) { if (PrgStack.Size()>MAX3_UNPACK_FILTERS) + { + delete StackFilter; return false; + } PrgStack.Add(1); EmptyCount=1; } diff --git a/Libraries/unrar/unpack50mt.cpp b/Libraries/unrar/unpack50mt.cpp index 9925cf2b..ce31f0a3 100644 --- a/Libraries/unrar/unpack50mt.cpp +++ b/Libraries/unrar/unpack50mt.cpp @@ -43,6 +43,7 @@ void Unpack::InitMT() { // Typical number of items in RAR blocks does not exceed 0x4000. CurData->DecodedAllocated=0x4100; + // It will be freed in the object destructor, not in this file. CurData->Decoded=(UnpackDecodedItem *)malloc(CurData->DecodedAllocated*sizeof(UnpackDecodedItem)); if (CurData->Decoded==NULL) ErrHandler.MemoryError(); @@ -96,7 +97,6 @@ void Unpack::Unpack5MT(bool Solid) if (ReadSize>0 && DataSize MaxWinMask here. UnpWriteBuf(); BlockHeader=UnpThreadData[LastBlockNum].BlockHeader; @@ -328,9 +329,10 @@ void Unpack::UnpackDecode(UnpackThreadData &D) if (D.DecodedSize>D.DecodedAllocated-8) // Filter can use several slots. { D.DecodedAllocated=D.DecodedAllocated*2; - D.Decoded=(UnpackDecodedItem *)realloc(D.Decoded,D.DecodedAllocated*sizeof(UnpackDecodedItem)); - if (D.Decoded==NULL) - ErrHandler.MemoryError(); + void *Decoded=realloc(D.Decoded,D.DecodedAllocated*sizeof(UnpackDecodedItem)); + if (Decoded==NULL) + ErrHandler.MemoryError(); // D.Decoded will be freed in the destructor. + D.Decoded=(UnpackDecodedItem *)Decoded; } UnpackDecodedItem *CurItem=D.Decoded+D.DecodedSize++; diff --git a/Libraries/unrar/version.hpp b/Libraries/unrar/version.hpp index cab6ad63..f9085307 100644 --- a/Libraries/unrar/version.hpp +++ b/Libraries/unrar/version.hpp @@ -1,6 +1,6 @@ #define RARVER_MAJOR 5 -#define RARVER_MINOR 31 +#define RARVER_MINOR 40 #define RARVER_BETA 0 -#define RARVER_DAY 4 -#define RARVER_MONTH 2 +#define RARVER_DAY 15 +#define RARVER_MONTH 8 #define RARVER_YEAR 2016 diff --git a/Libraries/unrar/win32acl.cpp b/Libraries/unrar/win32acl.cpp index 315d4db5..44d0bfa4 100644 --- a/Libraries/unrar/win32acl.cpp +++ b/Libraries/unrar/win32acl.cpp @@ -49,7 +49,7 @@ void ExtractACL20(Archive &Arc,const wchar *FileName) si|=SACL_SECURITY_INFORMATION; SECURITY_DESCRIPTOR *sd=(SECURITY_DESCRIPTOR *)&UnpData[0]; - int SetCode=SetFileSecurityW(FileName,si,sd); + int SetCode=SetFileSecurity(FileName,si,sd); if (!SetCode) { diff --git a/Libraries/unrar/win32stm.cpp b/Libraries/unrar/win32stm.cpp index c176d7d4..9e24c13e 100644 --- a/Libraries/unrar/win32stm.cpp +++ b/Libraries/unrar/win32stm.cpp @@ -89,9 +89,6 @@ void ExtractStreams(Archive &Arc,const wchar *FileName,bool TestMode) else wcsncpyz(FullName,FileName,ASIZE(FullName)); - byte *Data=&Arc.SubHead.SubData[0]; - size_t DataSize=Arc.SubHead.SubData.Size(); - wchar StreamName[NM]; GetStreamNameNTFS(Arc,StreamName,ASIZE(StreamName)); if (*StreamName!=':')