Hello community, here is the log from the commit of package unrar for openSUSE:Factory:NonFree checked in at 2019-02-01 11:48:48 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ Comparing /work/SRC/openSUSE:Factory:NonFree/unrar (Old) and /work/SRC/openSUSE:Factory:NonFree/.unrar.new.28833 (New) ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Package is "unrar" Fri Feb 1 11:48:48 2019 rev:75 rq:670434 version:5.7.1 Changes: -------- --- /work/SRC/openSUSE:Factory:NonFree/unrar/unrar.changes 2018-10-15 09:48:13.323051273 +0200 +++ /work/SRC/openSUSE:Factory:NonFree/.unrar.new.28833/unrar.changes 2019-02-01 11:49:06.092327219 +0100 @@ -1,0 +2,6 @@ +Wed Jan 30 10:51:39 UTC 2019 - i...@paolostivanin.com + +- Update to 5.7.1 + * No upstream changelog + +------------------------------------------------------------------- Old: ---- unrarsrc-5.6.8.tar.gz New: ---- unrarsrc-5.7.1.tar.gz ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ Other differences: ------------------ ++++++ unrar.spec ++++++ --- /var/tmp/diff_new_pack.MrYYVW/_old 2019-02-01 11:49:06.668326628 +0100 +++ /var/tmp/diff_new_pack.MrYYVW/_new 2019-02-01 11:49:06.668326628 +0100 @@ -18,10 +18,10 @@ # majorversion should match the major version number. %define majorversion 5 -%define libsuffix 5_6_8 +%define libsuffix 5_7_1 Name: unrar -Version: 5.6.8 +Version: 5.7.1 Release: 0 Summary: A program to extract, test, and view RAR archives License: NonFree ++++++ unrarsrc-5.6.8.tar.gz -> unrarsrc-5.7.1.tar.gz ++++++ diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/unrar/arccmt.cpp new/unrar/arccmt.cpp --- old/unrar/arccmt.cpp 2018-10-03 19:07:08.000000000 +0200 +++ new/unrar/arccmt.cpp 2019-01-28 11:39:40.000000000 +0100 @@ -85,15 +85,18 @@ byte *UnpData; size_t UnpDataSize; DataIO.GetUnpackedData(&UnpData,&UnpDataSize); + if (UnpDataSize>0) + { #ifdef _WIN_ALL - // If we ever decide to extend it to Android, we'll need to alloc - // 4x memory for OEM to UTF-8 output here. - OemToCharBuffA((char *)UnpData,(char *)UnpData,(DWORD)UnpDataSize); + // If we ever decide to extend it to Android, we'll need to alloc + // 4x memory for OEM to UTF-8 output here. + OemToCharBuffA((char *)UnpData,(char *)UnpData,(DWORD)UnpDataSize); #endif - CmtData->Alloc(UnpDataSize+1); - memset(CmtData->Addr(0),0,CmtData->Size()*sizeof(wchar)); - CharToWide((char *)UnpData,CmtData->Addr(0),CmtData->Size()); - CmtData->Alloc(wcslen(CmtData->Addr(0))); + CmtData->Alloc(UnpDataSize+1); + memset(CmtData->Addr(0),0,CmtData->Size()*sizeof(wchar)); + CharToWide((char *)UnpData,CmtData->Addr(0),CmtData->Size()); + CmtData->Alloc(wcslen(CmtData->Addr(0))); + } } } else diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/unrar/archive.hpp new/unrar/archive.hpp --- old/unrar/archive.hpp 2018-10-03 19:07:09.000000000 +0200 +++ new/unrar/archive.hpp 2019-01-28 11:39:40.000000000 +0100 @@ -37,8 +37,7 @@ void RequestArcPassword(); void UnexpEndArcMsg(); void BrokenHeaderMsg(); - void UnkEncVerMsg(const wchar *Name); - void UnkEncVerMsg(); + void UnkEncVerMsg(const wchar *Name,const wchar *Info); bool ReadCommentData(Array<wchar> *CmtData); #if !defined(RAR_NOCRYPT) diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/unrar/arcread.cpp new/unrar/arcread.cpp --- old/unrar/arcread.cpp 2018-10-03 19:07:09.000000000 +0200 +++ new/unrar/arcread.cpp 2019-01-28 11:39:40.000000000 +0100 @@ -10,7 +10,10 @@ CurBlockPos=Tell(); - size_t ReadSize; + // Other developers asked us to initialize it to suppress "may be used + // uninitialized" warning in code below in some compilers. + size_t ReadSize=0; + switch(Format) { #ifndef SFX_MODULE @@ -113,9 +116,9 @@ } -void Archive::UnkEncVerMsg(const wchar *Name) +void Archive::UnkEncVerMsg(const wchar *Name,const wchar *Info) { - uiMsg(UIERROR_UNKNOWNENCMETHOD,FileName,Name); + uiMsg(UIERROR_UNKNOWNENCMETHOD,FileName,Name,Info); ErrHandler.SetErrorCode(RARX_WARNING); } @@ -702,7 +705,9 @@ uint CryptVersion=(uint)Raw.GetV(); if (CryptVersion>CRYPT_VERSION) { - UnkEncVerMsg(FileName); + wchar Info[20]; + swprintf(Info,ASIZE(Info),L"h%u",CryptVersion); + UnkEncVerMsg(FileName,Info); return 0; } uint EncFlags=(uint)Raw.GetV(); @@ -710,7 +715,9 @@ CryptHead.Lg2Count=Raw.Get1(); if (CryptHead.Lg2Count>CRYPT5_KDF_LG2_COUNT_MAX) { - UnkEncVerMsg(FileName); + wchar Info[20]; + swprintf(Info,ASIZE(Info),L"hc%u",CryptHead.Lg2Count); + UnkEncVerMsg(FileName,Info); return 0; } Raw.GetB(CryptHead.Salt,SIZE_SALT50); @@ -991,8 +998,12 @@ { FileHeader *hd=(FileHeader *)bb; uint EncVersion=(uint)Raw->GetV(); - if (EncVersion > CRYPT_VERSION) - UnkEncVerMsg(hd->FileName); + if (EncVersion>CRYPT_VERSION) + { + wchar Info[20]; + swprintf(Info,ASIZE(Info),L"x%u",EncVersion); + UnkEncVerMsg(hd->FileName,Info); + } else { uint Flags=(uint)Raw->GetV(); @@ -1000,7 +1011,11 @@ hd->UseHashKey=(Flags & FHEXTRA_CRYPT_HASHMAC)!=0; hd->Lg2Count=Raw->Get1(); if (hd->Lg2Count>CRYPT5_KDF_LG2_COUNT_MAX) - UnkEncVerMsg(hd->FileName); + { + wchar Info[20]; + swprintf(Info,ASIZE(Info),L"xc%u",hd->Lg2Count); + UnkEncVerMsg(hd->FileName,Info); + } Raw->GetB(hd->Salt,SIZE_SALT50); Raw->GetB(hd->InitV,SIZE_INITV); if (hd->UsePswCheck) diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/unrar/cmddata.cpp new/unrar/cmddata.cpp --- old/unrar/cmddata.cpp 2018-10-03 19:07:09.000000000 +0200 +++ new/unrar/cmddata.cpp 2019-01-28 11:39:40.000000000 +0100 @@ -280,7 +280,11 @@ ClearArc=true; break; case 'D': - AppendArcNameToPath=true; + if (Switch[2]==0) + AppendArcNameToPath=APPENDARCNAME_DESTPATH; + else + if (Switch[2]=='1') + AppendArcNameToPath=APPENDARCNAME_OWNDIR; break; #ifndef SFX_MODULE case 'G': @@ -302,7 +306,7 @@ AddArcOnly=true; break; case 'P': - wcscpy(ArcPath,Switch+2); + wcsncpyz(ArcPath,Switch+2,ASIZE(ArcPath)); break; case 'S': SyncFiles=true; @@ -805,16 +809,40 @@ ArcTime=ARCTIME_LATEST; break; case 'O': - FileTimeBefore.SetAgeText(Switch+2); + switch(toupperw(Switch[2])) + { + case 'M': FileMtimeBefore.SetAgeText(Switch+3); break; + case 'C': FileCtimeBefore.SetAgeText(Switch+3); break; + case 'A': FileAtimeBefore.SetAgeText(Switch+3); break; + default: FileMtimeBefore.SetAgeText(Switch+2); break; + } break; case 'N': - FileTimeAfter.SetAgeText(Switch+2); + switch(toupperw(Switch[2])) + { + case 'M': FileMtimeAfter.SetAgeText(Switch+3); break; + case 'C': FileCtimeAfter.SetAgeText(Switch+3); break; + case 'A': FileAtimeAfter.SetAgeText(Switch+3); break; + default: FileMtimeAfter.SetAgeText(Switch+2); break; + } break; case 'B': - FileTimeBefore.SetIsoText(Switch+2); + switch(toupperw(Switch[2])) + { + case 'M': FileMtimeBefore.SetIsoText(Switch+3); break; + case 'C': FileCtimeBefore.SetIsoText(Switch+3); break; + case 'A': FileAtimeBefore.SetIsoText(Switch+3); break; + default: FileMtimeBefore.SetIsoText(Switch+2); break; + } break; case 'A': - FileTimeAfter.SetIsoText(Switch+2); + switch(toupperw(Switch[2])) + { + case 'M': FileMtimeAfter.SetIsoText(Switch+3); break; + case 'C': FileCtimeAfter.SetIsoText(Switch+3); break; + case 'A': FileAtimeAfter.SetIsoText(Switch+3); break; + default: FileMtimeAfter.SetIsoText(Switch+2); break; + } break; case 'S': { @@ -897,7 +925,7 @@ if (Switch[1]==0) { // If comment file is not specified, we read data from stdin. - wcscpy(CommentFile,L"stdin"); + wcsncpyz(CommentFile,L"stdin",ASIZE(CommentFile)); } else wcsncpyz(CommentFile,Switch+1,ASIZE(CommentFile)); @@ -1058,7 +1086,7 @@ bool CommandData::CheckArgs(StringList *Args,bool Dir,const wchar *CheckName,bool CheckFullPath,int MatchMode) { - wchar *Name=ConvertPath(CheckName,NULL); + wchar *Name=ConvertPath(CheckName,NULL,0); wchar FullName[NM]; wchar CurMask[NM]; *FullName=0; @@ -1121,7 +1149,7 @@ // Important to convert before "*\" check below, so masks like // d:*\something are processed properly. - wchar *CmpMask=ConvertPath(CurMask,NULL); + wchar *CmpMask=ConvertPath(CurMask,NULL,0); if (CmpMask[0]=='*' && IsPathDiv(CmpMask[1])) { @@ -1166,11 +1194,19 @@ #ifndef SFX_MODULE // Return 'true' if we need to exclude the file from processing. -bool CommandData::TimeCheck(RarTime &ft) +bool CommandData::TimeCheck(RarTime &ftm,RarTime &ftc,RarTime &fta) { - if (FileTimeBefore.IsSet() && ft>=FileTimeBefore) + if (FileMtimeBefore.IsSet() && ftm>=FileMtimeBefore) + return true; + if (FileMtimeAfter.IsSet() && ftm<=FileMtimeAfter) + return true; + if (FileCtimeBefore.IsSet() && ftc>=FileCtimeBefore) + return true; + if (FileCtimeAfter.IsSet() && ftc<=FileCtimeAfter) + return true; + if (FileAtimeBefore.IsSet() && fta>=FileAtimeBefore) return true; - if (FileTimeAfter.IsSet() && ft<=FileTimeAfter) + if (FileAtimeAfter.IsSet() && fta<=FileAtimeAfter) return true; return false; } @@ -1203,7 +1239,7 @@ if (ExclCheck(FileHead.FileName,Dir,false,true)) return 0; #ifndef SFX_MODULE - if (TimeCheck(FileHead.mtime)) + if (TimeCheck(FileHead.mtime,FileHead.ctime,FileHead.atime)) return 0; if ((FileHead.FileAttr & ExclFileAttr)!=0 || InclAttrSet && (FileHead.FileAttr & InclFileAttr)==0) return 0; diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/unrar/cmddata.hpp new/unrar/cmddata.hpp --- old/unrar/cmddata.hpp 2018-10-03 19:07:09.000000000 +0200 +++ new/unrar/cmddata.hpp 2019-01-28 11:39:40.000000000 +0100 @@ -34,7 +34,7 @@ bool ExclCheck(const wchar *CheckName,bool Dir,bool CheckFullPath,bool CheckInclList); static bool CheckArgs(StringList *Args,bool Dir,const wchar *CheckName,bool CheckFullPath,int MatchMode); bool ExclDirByAttr(uint FileAttr); - bool TimeCheck(RarTime &ft); + bool TimeCheck(RarTime &ftm,RarTime &ftc,RarTime &fta); bool SizeCheck(int64 Size); bool AnyFiltersActive(); int IsProcessFile(FileHeader &FileHead,bool *ExactMatch=NULL,int MatchType=MATCH_WILDSUBPATH, diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/unrar/crypt3.cpp new/unrar/crypt3.cpp --- old/unrar/crypt3.cpp 2018-10-03 19:07:09.000000000 +0200 +++ new/unrar/crypt3.cpp 2019-01-28 11:39:41.000000000 +0100 @@ -28,8 +28,8 @@ sha1_context c; sha1_init(&c); - const int HashRounds=0x40000; - for (int I=0;I<HashRounds;I++) + const uint HashRounds=0x40000; + for (uint I=0;I<HashRounds;I++) { sha1_process_rar29( &c, RawPsw, RawLength ); byte PswNum[3]; @@ -47,8 +47,8 @@ } uint32 digest[5]; sha1_done( &c, digest ); - for (int I=0;I<4;I++) - for (int J=0;J<4;J++) + for (uint I=0;I<4;I++) + for (uint J=0;J<4;J++) AESKey[I*4+J]=(byte)(digest[I]>>(J*8)); KDF3Cache[KDF3CachePos].Pwd=*Password; diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/unrar/dll.cpp new/unrar/dll.cpp --- old/unrar/dll.cpp 2018-10-03 19:07:10.000000000 +0200 +++ new/unrar/dll.cpp 2019-01-28 11:39:41.000000000 +0100 @@ -42,6 +42,7 @@ Data->Cmd.DllError=0; Data->OpenMode=r->OpenMode; Data->Cmd.FileArgs.AddString(L"*"); + Data->Cmd.KeepBroken=(r->OpFlags&ROADOF_KEEPBROKEN)!=0; char AnsiArcName[NM]; *AnsiArcName=0; @@ -369,7 +370,7 @@ if (DestNameW!=NULL) wcsncpyz(Data->Cmd.DllDestName,DestNameW,ASIZE(Data->Cmd.DllDestName)); - wcscpy(Data->Cmd.Command,Operation==RAR_EXTRACT ? L"X":L"T"); + wcsncpyz(Data->Cmd.Command,Operation==RAR_EXTRACT ? L"X":L"T",ASIZE(Data->Cmd.Command)); Data->Cmd.Test=Operation!=RAR_EXTRACT; bool Repeat=false; Data->Extract.ExtractCurrentFile(Data->Arc,Data->HeaderSize,Repeat); diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/unrar/dll.hpp new/unrar/dll.hpp --- old/unrar/dll.hpp 2018-10-03 19:07:10.000000000 +0200 +++ new/unrar/dll.hpp 2019-01-28 11:39:41.000000000 +0100 @@ -135,6 +135,8 @@ #define ROADF_ENCHEADERS 0x0080 #define ROADF_FIRSTVOLUME 0x0100 +#define ROADOF_KEEPBROKEN 0x0001 + struct RAROpenArchiveDataEx { char *ArcName; @@ -148,7 +150,8 @@ unsigned int Flags; UNRARCALLBACK Callback; LPARAM UserData; - unsigned int Reserved[28]; + unsigned int OpFlags; + unsigned int Reserved[27]; }; enum UNRARCALLBACK_MESSAGES { diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/unrar/dll.rc new/unrar/dll.rc --- old/unrar/dll.rc 2018-10-03 09:30:49.000000000 +0200 +++ new/unrar/dll.rc 2019-01-28 11:01:39.000000000 +0100 @@ -2,8 +2,8 @@ #include <commctrl.h> VS_VERSION_INFO VERSIONINFO -FILEVERSION 5, 61, 100, 2835 -PRODUCTVERSION 5, 61, 100, 2835 +FILEVERSION 5, 70, 1, 2955 +PRODUCTVERSION 5, 70, 1, 2955 FILEOS VOS__WINDOWS32 FILETYPE VFT_APP { @@ -14,9 +14,9 @@ VALUE "CompanyName", "Alexander Roshal\0" VALUE "ProductName", "RAR decompression library\0" VALUE "FileDescription", "RAR decompression library\0" - VALUE "FileVersion", "5.61.0\0" - VALUE "ProductVersion", "5.61.0\0" - VALUE "LegalCopyright", "Copyright � Alexander Roshal 1993-2018\0" + VALUE "FileVersion", "5.70.1\0" + VALUE "ProductVersion", "5.70.1\0" + VALUE "LegalCopyright", "Copyright � Alexander Roshal 1993-2019\0" VALUE "OriginalFilename", "Unrar.dll\0" } } diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/unrar/extract.cpp new/unrar/extract.cpp --- old/unrar/extract.cpp 2018-10-03 19:07:10.000000000 +0200 +++ new/unrar/extract.cpp 2019-01-28 11:39:41.000000000 +0100 @@ -345,7 +345,7 @@ #endif wchar ArcFileName[NM]; - ConvertPath(Arc.FileHead.FileName,ArcFileName); + ConvertPath(Arc.FileHead.FileName,ArcFileName,ASIZE(ArcFileName)); if (Arc.FileHead.Version) { @@ -851,9 +851,12 @@ } #ifndef SFX_MODULE - if (Cmd->AppendArcNameToPath) + if (Cmd->AppendArcNameToPath!=APPENDARCNAME_NONE) { - wcsncatz(DestName,PointToName(Arc.FirstVolumeName),DestSize); + if (Cmd->AppendArcNameToPath==APPENDARCNAME_DESTPATH) + wcsncatz(DestName,PointToName(Arc.FirstVolumeName),DestSize); + else + wcsncpyz(DestName,Arc.FirstVolumeName,DestSize); // To archive own dir. SetExt(DestName,NULL,DestSize); AddEndSlash(DestName,DestSize); } diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/unrar/file.cpp new/unrar/file.cpp --- old/unrar/file.cpp 2018-10-03 19:07:10.000000000 +0200 +++ new/unrar/file.cpp 2019-01-28 11:39:41.000000000 +0100 @@ -271,7 +271,7 @@ Success=RenameFile(FileName,NewName); if (Success) - wcscpy(FileName,NewName); + wcsncpyz(FileName,NewName,ASIZE(FileName)); return Success; } diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/unrar/filefn.cpp new/unrar/filefn.cpp --- old/unrar/filefn.cpp 2018-10-03 19:07:10.000000000 +0200 +++ new/unrar/filefn.cpp 2019-01-28 11:39:41.000000000 +0100 @@ -348,7 +348,7 @@ swprintf(RndText,ASIZE(RndText),L"%u.%03u",PID,Ext); if (Length+wcslen(RndText)>=MaxSize || Attempt==1000) return NULL; - wcscpy(Name+Length,RndText); + wcsncpyz(Name+Length,RndText,MaxSize-Length); if (!FileExist(Name)) break; } diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/unrar/find.cpp new/unrar/find.cpp --- old/unrar/find.cpp 2018-10-03 19:07:11.000000000 +0200 +++ new/unrar/find.cpp 2019-01-28 11:39:41.000000000 +0100 @@ -26,7 +26,7 @@ void FindFile::SetMask(const wchar *Mask) { - wcscpy(FindMask,Mask); + wcsncpyz(FindMask,Mask,ASIZE(FindMask)); FirstCall=true; } @@ -52,7 +52,7 @@ wcsncpyz(DirName,FindMask,ASIZE(DirName)); RemoveNameFromPath(DirName); if (*DirName==0) - wcscpy(DirName,L"."); + wcsncpyz(DirName,L".",ASIZE(DirName)); char DirNameA[NM]; WideToChar(DirName,DirNameA,ASIZE(DirNameA)); if ((dirp=opendir(DirNameA))==NULL) @@ -75,20 +75,20 @@ if (CmpName(FindMask,Name,MATCH_NAMES)) { wchar FullName[NM]; - wcscpy(FullName,FindMask); + wcsncpyz(FullName,FindMask,ASIZE(FullName)); *PointToName(FullName)=0; if (wcslen(FullName)+wcslen(Name)>=ASIZE(FullName)-1) { uiMsg(UIERROR_PATHTOOLONG,FullName,L"",Name); return false; } - wcscat(FullName,Name); + wcsncatz(FullName,Name,ASIZE(FullName)); if (!FastFind(FullName,fd,GetSymLink)) { ErrHandler.OpenErrorMsg(FullName); continue; } - wcscpy(fd->Name,FullName); + wcsncpyz(fd->Name,FullName,ASIZE(fd->Name)); break; } } diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/unrar/list.cpp new/unrar/list.cpp --- old/unrar/list.cpp 2018-10-03 19:07:11.000000000 +0200 +++ new/unrar/list.cpp 2019-01-28 11:39:42.000000000 +0100 @@ -215,7 +215,7 @@ wchar UnpSizeText[30],PackSizeText[30]; if (hd.UnpSize==INT64NDF) - wcscpy(UnpSizeText,L"?"); + wcsncpyz(UnpSizeText,L"?",ASIZE(UnpSizeText)); else itoa(hd.UnpSize,UnpSizeText,ASIZE(UnpSizeText)); itoa(hd.PackSize,PackSizeText,ASIZE(PackSizeText)); @@ -229,13 +229,13 @@ wchar RatioStr[10]; if (hd.SplitBefore && hd.SplitAfter) - wcscpy(RatioStr,L"<->"); + wcsncpyz(RatioStr,L"<->",ASIZE(RatioStr)); else if (hd.SplitBefore) - wcscpy(RatioStr,L"<--"); + wcsncpyz(RatioStr,L"<--",ASIZE(RatioStr)); else if (hd.SplitAfter) - wcscpy(RatioStr,L"-->"); + wcsncpyz(RatioStr,L"-->",ASIZE(RatioStr)); else swprintf(RatioStr,ASIZE(RatioStr),L"%d%%",ToPercentUnlim(hd.PackSize,hd.UnpSize)); @@ -467,7 +467,7 @@ (A & 0x0001) ? ((A & 0x200)!=0 ? 't' : 'x') : '-'); break; case HSYS_UNKNOWN: - wcscpy(AttrStr,L"?"); + wcsncpyz(AttrStr,L"?",AttrSize); break; } } diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/unrar/loclang.hpp new/unrar/loclang.hpp --- old/unrar/loclang.hpp 2018-10-03 19:07:11.000000000 +0200 +++ new/unrar/loclang.hpp 2019-01-28 11:39:42.000000000 +0100 @@ -127,11 +127,11 @@ #define MCHelpSwT L"\n t Test files after archiving" #define MCHelpSwTK L"\n tk Keep original archive time" #define MCHelpSwTL L"\n tl Set archive time to latest file" -#define MCHelpSwTN L"\n tn<time> Process files newer than <time>" -#define MCHelpSwTO L"\n to<time> Process files older than <time>" -#define MCHelpSwTA L"\n ta<date> Process files modified after <date> in YYYYMMDDHHMMSS format" -#define MCHelpSwTB L"\n tb<date> Process files modified before <date> in YYYYMMDDHHMMSS format" -#define MCHelpSwTS L"\n ts[m|c|a] Save or restore file time (modification, creation, access)" +#define MCHelpSwTN L"\n tn[m,c,a]<t> Process files newer than <t> time" +#define MCHelpSwTO L"\n to[m,c,a]<t> Process files older than <t> time" +#define MCHelpSwTA L"\n ta[m,c,a]<d> Process files modified after <d> YYYYMMDDHHMMSS date" +#define MCHelpSwTB L"\n tb[m,c,a]<d> Process files modified before <d> YYYYMMDDHHMMSS date" +#define MCHelpSwTS L"\n ts[m,c,a] Save or restore file time (modification, creation, access)" #define MCHelpSwU L"\n u Update files" #define MCHelpSwV L"\n v Create volumes with size autodetection or list all volumes" #define MCHelpSwVUnr L"\n v List all volumes" @@ -354,7 +354,7 @@ #define MCannotDelete L"\nCannot delete %s" #define MRecycleFailed L"\nCannot move some files and folders to Recycle Bin" #define MCalcCRC L"\nCalculating the checksum" -#define MTooLargeSFXArc L"\nWARNING: Too large SFX archive. Windows cannot run the executable file exceeding 4 GB." +#define MTooLargeSFXArc L"\nToo large SFX archive. Windows cannot run the executable file exceeding 4 GB." #define MCalcCRCAllVol L"\nCalculating checksums of all volumes." #define MNotEnoughDisk L"\nERROR: Not enough disk space for %s." #define MNewerRAR L"\nYou may need a newer version of RAR." diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/unrar/options.hpp new/unrar/options.hpp --- old/unrar/options.hpp 2018-10-03 19:07:11.000000000 +0200 +++ new/unrar/options.hpp 2019-01-28 11:39:42.000000000 +0100 @@ -59,6 +59,11 @@ SAVECOPY_DUPLISTEXIT }; +enum APPENDARCNAME_MODE +{ + APPENDARCNAME_NONE=0,APPENDARCNAME_DESTPATH,APPENDARCNAME_OWNDIR +}; + enum POWER_MODE { POWERMODE_KEEP=0,POWERMODE_OFF,POWERMODE_HIBERNATE,POWERMODE_SLEEP, POWERMODE_RESTART @@ -159,8 +164,12 @@ bool SaveStreams; bool SetCompressedAttr; bool IgnoreGeneralAttr; - RarTime FileTimeBefore; - RarTime FileTimeAfter; + RarTime FileMtimeBefore; + RarTime FileMtimeAfter; + RarTime FileCtimeBefore; + RarTime FileCtimeAfter; + RarTime FileAtimeBefore; + RarTime FileAtimeAfter; int64 FileSizeLess; int64 FileSizeMore; bool Lock; @@ -169,9 +178,9 @@ FilterMode FilterModes[MAX_FILTER_TYPES]; wchar EmailTo[NM]; uint VersionControl; - bool AppendArcNameToPath; + APPENDARCNAME_MODE AppendArcNameToPath; POWER_MODE Shutdown; - EXTTIME_MODE xmtime; + EXTTIME_MODE xmtime; // Extended time modes (time precision to store). EXTTIME_MODE xctime; EXTTIME_MODE xatime; wchar CompressStdin[NM]; diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/unrar/pathfn.cpp new/unrar/pathfn.cpp --- old/unrar/pathfn.cpp 2018-10-03 19:07:12.000000000 +0200 +++ new/unrar/pathfn.cpp 2019-01-28 11:39:42.000000000 +0100 @@ -16,7 +16,7 @@ } -wchar* ConvertPath(const wchar *SrcPath,wchar *DestPath) +wchar* ConvertPath(const wchar *SrcPath,wchar *DestPath,size_t DestSize) { const wchar *DestPtr=SrcPath; @@ -25,7 +25,7 @@ if (IsPathDiv(s[0]) && s[1]=='.' && s[2]=='.' && IsPathDiv(s[3])) DestPtr=s+4; - // Remove <d>:\ and any sequence of . and \ in the beginning of path string. + // Remove any amount of <d>:\ and any sequence of . and \ in the beginning of path string. while (*DestPtr!=0) { const wchar *s=DestPtr; @@ -58,7 +58,7 @@ // so we use the temporary buffer for copying. wchar TmpStr[NM]; wcsncpyz(TmpStr,DestPtr,ASIZE(TmpStr)); - wcscpy(DestPath,TmpStr); + wcsncpyz(DestPath,TmpStr,DestSize); } return (wchar *)DestPtr; } @@ -163,8 +163,8 @@ void AddEndSlash(wchar *Path,size_t MaxLength) { size_t Length=wcslen(Path); - if (Length>0 && Path[Length-1]!=CPATHDIVIDER && Length+1<MaxLength) - wcscat(Path,SPATHDIVIDER); + if (Length>0 && Path[Length-1]!=CPATHDIVIDER) + wcsncatz(Path,SPATHDIVIDER,MaxLength); } @@ -303,9 +303,13 @@ #endif -// Returns a pointer to rightmost digit of volume number. +// Returns a pointer to rightmost digit of volume number or to beginning +// of file name if numeric part is missing. wchar* GetVolNumPart(const wchar *ArcName) { + if (*ArcName==0) + return (wchar *)ArcName; + // Pointing to last name character. const wchar *ChPtr=ArcName+wcslen(ArcName)-1; @@ -346,18 +350,33 @@ ChPtr=GetExt(ArcName); } else - if (ChPtr[1]==0 && wcslen(ArcName)<MaxLength-3 || wcsicomp(ChPtr+1,L"exe")==0 || wcsicomp(ChPtr+1,L"sfx")==0) - wcscpy(ChPtr+1,L"rar"); + if (ChPtr[1]==0 || wcsicomp(ChPtr,L".exe")==0 || wcsicomp(ChPtr,L".sfx")==0) + wcsncpyz(ChPtr,L".rar",MaxLength-(ChPtr-ArcName)); + + if (ChPtr==NULL || *ChPtr!='.' || ChPtr[1]==0) + { + // Normally we shall have some extension here. If we don't, it means + // the name has no extension and buffer has no free space to append one. + // Let's clear the name to prevent a new call with same name and return. + *ArcName=0; + return; + } + if (!OldNumbering) { ChPtr=GetVolNumPart(ArcName); + // We should not check for IsDigit(*ChPtr) here and should increment + // even non-digits. If we got a corrupt archive with volume flag, + // but without numeric part, we still need to modify its name somehow, + // so while (exist(name)) {NextVolumeName()} loops do not run infinitely. while ((++(*ChPtr))=='9'+1) { *ChPtr='0'; ChPtr--; if (ChPtr<ArcName || !IsDigit(*ChPtr)) { + // Convert .part:.rar (.part9.rar after increment) to part10.rar. for (wchar *EndPtr=ArcName+wcslen(ArcName);EndPtr!=ChPtr;EndPtr--) *(EndPtr+1)=*EndPtr; *(ChPtr+1)='1'; @@ -366,15 +385,15 @@ } } else - if (!IsDigit(*(ChPtr+2)) || !IsDigit(*(ChPtr+3))) - wcscpy(ChPtr+2,L"00"); + if (!IsDigit(ChPtr[2]) || !IsDigit(ChPtr[3])) + wcsncpyz(ChPtr+2,L"00",MaxLength-(ChPtr-ArcName)-2); // From .rar to .r00. else { - ChPtr+=3; - while ((++(*ChPtr))=='9'+1) - if (*(ChPtr-1)=='.') + ChPtr+=wcslen(ChPtr)-1; // Set to last character. + while (++(*ChPtr)=='9'+1) + if (ChPtr<=ArcName || *(ChPtr-1)=='.') { - *ChPtr='A'; + *ChPtr='a'; // From .999 to .a00 if started from .001 or for too short names. break; } else @@ -585,8 +604,7 @@ wchar *VerText=wcsrchr(Name,';'); if (VerText!=NULL) { - if (Version==0) - Version=atoiw(VerText+1); + Version=atoiw(VerText+1); if (Truncate) *VerText=0; } @@ -652,7 +670,7 @@ #ifndef SFX_MODULE -static void GenArcName(wchar *ArcName,const wchar *GenerateMask,uint ArcNumber,bool &ArcNumPresent) +static void GenArcName(wchar *ArcName,size_t MaxSize,const wchar *GenerateMask,uint ArcNumber,bool &ArcNumPresent) { bool Prefix=false; if (*GenerateMask=='+') @@ -713,7 +731,7 @@ wchar Ext[NM],*Dot=GetExt(ArcName); *Ext=0; if (Dot==NULL) - wcscpy(Ext,*PointToName(ArcName)==0 ? L".rar":L""); + wcsncpyz(Ext,*PointToName(ArcName)==0 ? L".rar":L"",ASIZE(Ext)); else { wcsncpyz(Ext,Dot,ASIZE(Ext)); @@ -749,7 +767,7 @@ int CField[sizeof(Field)/sizeof(Field[0])]; memset(CField,0,sizeof(CField)); QuoteMode=false; - for (int I=0;Mask[I]!=0;I++) + for (uint I=0;Mask[I]!=0;I++) { if (Mask[I]=='{' || Mask[I]=='}') { @@ -810,21 +828,17 @@ AddEndSlash(NewName,ASIZE(NewName)); wcsncatz(NewName,DateText,ASIZE(NewName)); wcsncatz(NewName,PointToName(ArcName),ASIZE(NewName)); - wcscpy(ArcName,NewName); + wcsncpyz(ArcName,NewName,MaxSize); } else - wcscat(ArcName,DateText); - wcscat(ArcName,Ext); + wcsncatz(ArcName,DateText,MaxSize); + wcsncatz(ArcName,Ext,MaxSize); } 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. - // One 'N' character can result in several numbers if we process more - // than 9 archives. - wchar NewName[NM+MAX_GENERATE_MASK+20]; + wchar NewName[NM]; uint ArcNumber=1; while (true) // Loop for 'N' (archive number) processing. @@ -833,7 +847,7 @@ bool ArcNumPresent=false; - GenArcName(NewName,GenerateMask,ArcNumber,ArcNumPresent); + GenArcName(NewName,ASIZE(NewName),GenerateMask,ArcNumber,ArcNumPresent); if (!ArcNumPresent) break; @@ -845,7 +859,7 @@ // existing archive before the first unused name. So we generate // the name for (ArcNumber-1) below. wcsncpyz(NewName,NullToEmpty(ArcName),ASIZE(NewName)); - GenArcName(NewName,GenerateMask,ArcNumber-1,ArcNumPresent); + GenArcName(NewName,ASIZE(NewName),GenerateMask,ArcNumber-1,ArcNumPresent); } break; } @@ -895,8 +909,8 @@ { if (MaxSize<=PrefixLength+SrcLength) return false; - wcsncpy(Dest,Prefix,PrefixLength); - wcscpy(Dest+PrefixLength,Src); + wcsncpyz(Dest,Prefix,MaxSize); + wcsncatz(Dest,Src,MaxSize); // "\\?\D:\very long path". return true; } else @@ -904,9 +918,9 @@ { if (MaxSize<=PrefixLength+SrcLength+2) return false; - wcsncpy(Dest,Prefix,PrefixLength); - wcscpy(Dest+PrefixLength,L"UNC"); - wcscpy(Dest+PrefixLength+3,Src+1); + wcsncpyz(Dest,Prefix,MaxSize); + wcsncatz(Dest,L"UNC",MaxSize); + wcsncatz(Dest,Src+1,MaxSize); // "\\?\UNC\server\share". return true; } // We may be here only if we modify IsFullPath in the future. @@ -923,9 +937,10 @@ { if (MaxSize<=PrefixLength+SrcLength+2) return false; - wcsncpy(Dest,Prefix,PrefixLength); - wcsncpy(Dest+PrefixLength,CurDir,2); // Copy drive letter 'd:'. - wcscpy(Dest+PrefixLength+2,Src); + wcsncpyz(Dest,Prefix,MaxSize); + CurDir[2]=0; + wcsncatz(Dest,CurDir,MaxSize); // Copy drive letter 'd:'. + wcsncatz(Dest,Src,MaxSize); return true; } else // Paths in path\name format. @@ -933,8 +948,8 @@ AddEndSlash(CurDir,ASIZE(CurDir)); if (MaxSize<=PrefixLength+wcslen(CurDir)+SrcLength) return false; - wcsncpy(Dest,Prefix,PrefixLength); - wcscpy(Dest+PrefixLength,CurDir); + wcsncpyz(Dest,Prefix,MaxSize); + wcsncatz(Dest,CurDir,MaxSize); if (Src[0]=='.' && IsPathDiv(Src[1])) // Remove leading .\ in pathname. Src+=2; diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/unrar/pathfn.hpp new/unrar/pathfn.hpp --- old/unrar/pathfn.hpp 2018-10-03 19:07:12.000000000 +0200 +++ new/unrar/pathfn.hpp 2019-01-28 11:39:42.000000000 +0100 @@ -3,7 +3,7 @@ wchar* PointToName(const wchar *Path); wchar* PointToLastChar(const wchar *Path); -wchar* ConvertPath(const wchar *SrcPath,wchar *DestPath); +wchar* ConvertPath(const wchar *SrcPath,wchar *DestPath,size_t DestSize); void SetName(wchar *FullName,const wchar *Name,size_t MaxSize); void SetExt(wchar *Name,const wchar *NewExt,size_t MaxSize); void SetSFXExt(wchar *SFXName,size_t MaxSize); diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/unrar/rar.cpp new/unrar/rar.cpp --- old/unrar/rar.cpp 2018-10-03 19:07:12.000000000 +0200 +++ new/unrar/rar.cpp 2019-01-28 11:39:42.000000000 +0100 @@ -37,7 +37,7 @@ CommandData *Cmd=new CommandData; #ifdef SFX_MODULE - wcscpy(Cmd->Command,L"X"); + wcsncpyz(Cmd->Command,L"X",ASIZE(Cmd->Command)); char *Switch=argc>1 ? argv[1]:NULL; if (Switch!=NULL && Cmd->IsSwitch(Switch[0])) { @@ -68,6 +68,8 @@ #if defined(_WIN_ALL) && !defined(SFX_MODULE) ShutdownOnClose=Cmd->Shutdown; + if (ShutdownOnClose) + ShutdownCheckAnother(true); #endif uiInit(Cmd->Sound); @@ -93,7 +95,8 @@ } #if defined(_WIN_ALL) && !defined(SFX_MODULE) - if (ShutdownOnClose!=POWERMODE_KEEP && ErrHandler.IsShutdownEnabled()) + if (ShutdownOnClose!=POWERMODE_KEEP && ErrHandler.IsShutdownEnabled() && + !ShutdownCheckAnother(false)) Shutdown(ShutdownOnClose); #endif ErrHandler.MainExit=true; diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/unrar/rdwrfn.cpp new/unrar/rdwrfn.cpp --- old/unrar/rdwrfn.cpp 2018-10-03 19:07:12.000000000 +0200 +++ new/unrar/rdwrfn.cpp 2019-01-28 11:39:42.000000000 +0100 @@ -25,6 +25,7 @@ NextVolumeMissing=false; SrcFile=NULL; DestFile=NULL; + UnpWrAddr=NULL; UnpWrSize=0; Command=NULL; Encryption=false; diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/unrar/recvol3.cpp new/unrar/recvol3.cpp --- old/unrar/recvol3.cpp 2018-10-03 19:07:12.000000000 +0200 +++ new/unrar/recvol3.cpp 2019-01-28 11:39:42.000000000 +0100 @@ -111,7 +111,7 @@ NewStyle=IsNewStyleRev(ArcName); while (Ext>ArcName+1 && (IsDigit(*(Ext-1)) || *(Ext-1)=='_')) Ext--; - wcscpy(Ext,L"*.*"); + wcsncpyz(Ext,L"*.*",ASIZE(ArcName)-(Ext-ArcName)); FindFile Find; Find.SetMask(ArcName); @@ -235,7 +235,7 @@ } RecVolNumber=P[1]; FileNumber=P[2]; - wcscpy(PrevName,CurName); + wcsncpyz(PrevName,CurName,ASIZE(PrevName)); File *NewFile=new File; NewFile->TOpen(CurName); SrcFile[FileNumber+P[0]-1]=NewFile; @@ -247,7 +247,7 @@ if (!Silent || FoundRecVolumes!=0) uiMsg(UIMSG_RECVOLFOUND,FoundRecVolumes); if (FoundRecVolumes==0) - return(false); + return false; bool WriteFlags[256]; memset(WriteFlags,0,sizeof(WriteFlags)); @@ -290,8 +290,8 @@ { NewFile->Close(); wchar NewName[NM]; - wcscpy(NewName,ArcName); - wcscat(NewName,L".bad"); + wcsncpyz(NewName,ArcName,ASIZE(NewName)); + wcsncatz(NewName,L".bad",ASIZE(NewName)); uiMsg(UIMSG_BADARCHIVE,ArcName); uiMsg(UIMSG_RENAMING,ArcName,NewName); @@ -322,7 +322,7 @@ MissingVolumes++; if (CurArcNum==FileNumber-1) - wcscpy(LastVolName,ArcName); + wcsncpyz(LastVolName,ArcName,ASIZE(LastVolName)); uiMsg(UIMSG_MISSINGVOL,ArcName); uiMsg(UIEVENT_NEWARCHIVE,ArcName); diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/unrar/recvol5.cpp new/unrar/recvol5.cpp --- old/unrar/recvol5.cpp 2018-10-03 19:07:12.000000000 +0200 +++ new/unrar/recvol5.cpp 2019-01-28 11:39:42.000000000 +0100 @@ -139,12 +139,10 @@ wcsncpyz(ArcName,Name,ASIZE(ArcName)); wchar *Num=GetVolNumPart(ArcName); - if (Num==ArcName) - return false; // Number part is missing in the name. while (Num>ArcName && IsDigit(*(Num-1))) Num--; if (Num==ArcName) - return false; // Entire volume name is numeric, not possible for REV file. + return false; // Numeric part is missing or entire volume name is numeric, not possible for RAR or REV volume. wcsncpyz(Num,L"*.*",ASIZE(ArcName)-(Num-ArcName)); wchar FirstVolName[NM]; @@ -289,8 +287,8 @@ Item->f->Close(); wchar NewName[NM]; - wcscpy(NewName,Item->Name); - wcscat(NewName,L".bad"); + wcsncpyz(NewName,Item->Name,ASIZE(NewName)); + wcsncatz(NewName,L".bad",ASIZE(NewName)); uiMsg(UIMSG_BADARCHIVE,Item->Name); uiMsg(UIMSG_RENAMING,Item->Name,NewName); diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/unrar/rijndael.cpp new/unrar/rijndael.cpp --- old/unrar/rijndael.cpp 2018-10-03 19:07:12.000000000 +0200 +++ new/unrar/rijndael.cpp 2019-01-28 11:39:42.000000000 +0100 @@ -79,7 +79,10 @@ AES_NI=(CPUInfo[2] & 0x2000000)!=0; #endif - uint uKeyLenInBytes; + // Other developers asked us to initialize it to suppress "may be used + // uninitialized" warning in code below in some compilers. + uint uKeyLenInBytes=0; + switch(keyLen) { case 128: diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/unrar/scantree.cpp new/unrar/scantree.cpp --- old/unrar/scantree.cpp 2018-10-03 19:07:13.000000000 +0200 +++ new/unrar/scantree.cpp 2019-01-28 11:39:43.000000000 +0100 @@ -142,7 +142,7 @@ bool WildcardFound=false; uint FolderWildcardCount=0; uint SlashPos=0; - for (int I=0;CurMask[I]!=0;I++) + for (uint I=0;CurMask[I]!=0;I++) { if (CurMask[I]=='?' || CurMask[I]=='*') WildcardFound=true; @@ -171,7 +171,7 @@ wchar Filter[NM]; // Convert path\dir*\ to *\dir filter to search for 'dir' in all 'path' subfolders. - wcscpy(Filter,L"*"); + wcsncpyz(Filter,L"*",ASIZE(Filter)); AddEndSlash(Filter,ASIZE(Filter)); // SlashPos might point or not point to path separator for masks like 'dir*', '\dir*' or 'd:dir*' wchar *WildName=IsPathDiv(CurMask[SlashPos]) || IsDriveDiv(CurMask[SlashPos]) ? CurMask+SlashPos+1 : CurMask+SlashPos; @@ -360,7 +360,7 @@ wcsncpyz(CurMask,Mask+1,ASIZE(CurMask)); else { - *(PrevSlash+1)=0; + *PrevSlash=0; wcsncatz(CurMask,Mask,ASIZE(CurMask)); } } diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/unrar/strfn.cpp new/unrar/strfn.cpp --- old/unrar/strfn.cpp 2018-10-03 19:07:13.000000000 +0200 +++ new/unrar/strfn.cpp 2019-01-28 11:39:43.000000000 +0100 @@ -281,53 +281,49 @@ } -// Safe strncpy: copies maxlen-1 max and always returns zero terminated dest. -char* strncpyz(char *dest, const char *src, size_t maxlen) +// Safe copy: copies maxlen-1 max and for maxlen>0 returns zero terminated dest. +void strncpyz(char *dest, const char *src, size_t maxlen) { if (maxlen>0) { - strncpy(dest,src,maxlen-1); - dest[maxlen-1]=0; + while (--maxlen>0 && *src!=0) + *dest++=*src++; + *dest=0; } - return dest; } -// Safe wcsncpy: copies maxlen-1 max and always returns zero terminated dest. -wchar* wcsncpyz(wchar *dest, const wchar *src, size_t maxlen) +// Safe copy: copies maxlen-1 max and for maxlen>0 returns zero terminated dest. +void wcsncpyz(wchar *dest, const wchar *src, size_t maxlen) { if (maxlen>0) { - wcsncpy(dest,src,maxlen-1); - dest[maxlen-1]=0; + while (--maxlen>0 && *src!=0) + *dest++=*src++; + *dest=0; } - return dest; } -// Safe strncat: resulting dest length cannot exceed maxlen and dest -// is always zero terminated. Note that 'maxlen' parameter defines the entire -// dest buffer size and is not compatible with standard strncat. -char* strncatz(char* dest, const char* src, size_t maxlen) +// Safe append: resulting dest length cannot exceed maxlen and dest +// is always zero terminated. 'maxlen' parameter defines the entire +// dest buffer size and is not compatible with wcsncat. +void strncatz(char* dest, const char* src, size_t maxlen) { - size_t Length = strlen(dest); - int avail=int(maxlen - Length - 1); - if (avail > 0) - strncat(dest, src, avail); - return dest; + size_t length = strlen(dest); + if (maxlen > length) + strncpyz(dest + length, src, maxlen - length); } -// Safe wcsncat: resulting dest length cannot exceed maxlen and dest -// is always zero terminated. Note that 'maxlen' parameter defines the entire -// dest buffer size and is not compatible with standard wcsncat. -wchar* wcsncatz(wchar* dest, const wchar* src, size_t maxlen) +// Safe append: resulting dest length cannot exceed maxlen and dest +// is always zero terminated. 'maxlen' parameter defines the entire +// dest buffer size and is not compatible with wcsncat. +void wcsncatz(wchar* dest, const wchar* src, size_t maxlen) { - size_t Length = wcslen(dest); - int avail=int(maxlen - Length - 1); - if (avail > 0) - wcsncat(dest, src, avail); - return dest; + size_t length = wcslen(dest); + if (maxlen > length) + wcsncpyz(dest + length, src, maxlen - length); } diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/unrar/strfn.hpp new/unrar/strfn.hpp --- old/unrar/strfn.hpp 2018-10-03 19:07:13.000000000 +0200 +++ new/unrar/strfn.hpp 2019-01-28 11:39:43.000000000 +0100 @@ -16,10 +16,10 @@ unsigned char loctolower(unsigned char ch); unsigned char loctoupper(unsigned char ch); -char* strncpyz(char *dest, const char *src, size_t maxlen); -wchar* wcsncpyz(wchar *dest, const wchar *src, size_t maxlen); -char* strncatz(char* dest, const char* src, size_t maxlen); -wchar* wcsncatz(wchar* dest, const wchar* src, size_t maxlen); +void strncpyz(char *dest, const char *src, size_t maxlen); +void wcsncpyz(wchar *dest, const wchar *src, size_t maxlen); +void strncatz(char* dest, const char* src, size_t maxlen); +void wcsncatz(wchar* dest, const wchar* src, size_t maxlen); unsigned char etoupper(unsigned char ch); wchar etoupperw(wchar ch); diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/unrar/system.cpp new/unrar/system.cpp --- old/unrar/system.cpp 2018-10-03 19:07:14.000000000 +0200 +++ new/unrar/system.cpp 2019-01-28 11:39:43.000000000 +0100 @@ -123,6 +123,28 @@ if (Mode==POWERMODE_RESTART) ExitWindowsEx(EWX_REBOOT|EWX_FORCE,SHTDN_REASON_FLAG_PLANNED); } + + +bool ShutdownCheckAnother(bool Open) +{ + const wchar *EventName=L"rar -ioff"; + static HANDLE hEvent=NULL; + bool Result=false; // Return false if no other RAR -ioff are running. + if (Open) // Create or open the event. + hEvent=CreateEvent(NULL,FALSE,FALSE,EventName); + else + { + if (hEvent!=NULL) + CloseHandle(hEvent); // Close our event. + // Check if other copies still own the event. While race conditions + // are possible, they are improbable and their harm is minimal. + hEvent=CreateEvent(NULL,FALSE,FALSE,EventName); + Result=GetLastError()==ERROR_ALREADY_EXISTS; + if (hEvent!=NULL) + CloseHandle(hEvent); + } + return Result; +} #endif diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/unrar/system.hpp new/unrar/system.hpp --- old/unrar/system.hpp 2018-10-03 19:07:14.000000000 +0200 +++ new/unrar/system.hpp 2019-01-28 11:39:43.000000000 +0100 @@ -23,6 +23,7 @@ void Wait(); bool EmailFile(const wchar *FileName,const wchar *MailToW); void Shutdown(POWER_MODE Mode); +bool ShutdownCheckAnother(bool Open); #ifdef _WIN_ALL HMODULE WINAPI LoadSysLibrary(const wchar *Name); diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/unrar/timefn.cpp new/unrar/timefn.cpp --- old/unrar/timefn.cpp 2018-10-03 19:07:14.000000000 +0200 +++ new/unrar/timefn.cpp 2019-01-28 11:39:43.000000000 +0100 @@ -236,7 +236,7 @@ else { // We use escape before '?' to avoid weird C trigraph characters. - wcscpy(DateStr,L"\?\?\?\?-\?\?-\?\? \?\?:\?\?"); + wcsncpyz(DateStr,L"\?\?\?\?-\?\?-\?\? \?\?:\?\?",MaxSize); } } diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/unrar/ui.hpp new/unrar/ui.hpp --- old/unrar/ui.hpp 2018-10-03 19:07:14.000000000 +0200 +++ new/unrar/ui.hpp 2019-01-28 11:39:43.000000000 +0100 @@ -18,7 +18,8 @@ UIERROR_HEADERBROKEN, UIERROR_MHEADERBROKEN, UIERROR_FHEADERBROKEN, UIERROR_SUBHEADERBROKEN, UIERROR_SUBHEADERUNKNOWN, UIERROR_SUBHEADERDATABROKEN, UIERROR_RRDAMAGED, UIERROR_UNKNOWNMETHOD, - UIERROR_UNKNOWNENCMETHOD, UIERROR_RENAMING, UIERROR_NEWERRAR, UIERROR_NOTSFX, UIERROR_OLDTOSFX, + UIERROR_UNKNOWNENCMETHOD, UIERROR_RENAMING, UIERROR_NEWERRAR, + UIERROR_NOTSFX, UIERROR_OLDTOSFX, UIERROR_WRONGSFXVER, UIERROR_ALREADYENC, UIERROR_DICTOUTMEM, UIERROR_USESMALLERDICT, UIERROR_MODIFYUNKNOWN, UIERROR_MODIFYOLD, UIERROR_MODIFYLOCKED, UIERROR_MODIFYVOLUME, UIERROR_NOTVOLUME, @@ -31,12 +32,12 @@ UIERROR_NOFILESTOADD, UIERROR_NOFILESTODELETE, UIERROR_NOFILESTOEXTRACT, UIERROR_MISSINGVOL, UIERROR_NEEDPREVVOL, UIERROR_UNKNOWNEXTRA, UIERROR_CORRUPTEXTRA, UIERROR_NTFSREQUIRED, UIERROR_ZIPVOLSFX, - UIERROR_FILERO, UIERROR_TOOLARGESFX, UIERROR_EMAIL, UIERROR_ACLGET, - UIERROR_ACLBROKEN, UIERROR_ACLUNKNOWN, UIERROR_ACLSET, UIERROR_STREAMBROKEN, - UIERROR_STREAMUNKNOWN, UIERROR_INCOMPATSWITCH, UIERROR_PATHTOOLONG, - UIERROR_DIRSCAN, UIERROR_UOWNERGET, UIERROR_UOWNERBROKEN, - UIERROR_UOWNERGETOWNERID, UIERROR_UOWNERGETGROUPID, UIERROR_UOWNERSET, - UIERROR_ULINKREAD, UIERROR_ULINKEXIST, + UIERROR_FILERO, UIERROR_TOOLARGESFX, UIERROR_NOZIPSFX, UIERROR_EMAIL, + UIERROR_ACLGET, UIERROR_ACLBROKEN, UIERROR_ACLUNKNOWN, UIERROR_ACLSET, + UIERROR_STREAMBROKEN, UIERROR_STREAMUNKNOWN, UIERROR_INCOMPATSWITCH, + UIERROR_PATHTOOLONG, UIERROR_DIRSCAN, UIERROR_UOWNERGET, + UIERROR_UOWNERBROKEN, UIERROR_UOWNERGETOWNERID, UIERROR_UOWNERGETGROUPID, + UIERROR_UOWNERSET, UIERROR_ULINKREAD, UIERROR_ULINKEXIST, UIMSG_FIRST, UIMSG_STRING, UIMSG_BUILD, UIMSG_RRSEARCH, UIMSG_ANALYZEFILEDATA, @@ -111,6 +112,11 @@ public: uiMsgStore(UIMESSAGE_CODE Code) { + // Init arrays in case a caller passes fewer parameters than expected. + for (uint I=0;I<ASIZE(Str);I++) + Str[I]=L""; + memset(Num,0,sizeof(Num)); + NumSize=StrSize=0; this->Code=Code; } diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/unrar/uiconsole.cpp new/unrar/uiconsole.cpp --- old/unrar/uiconsole.cpp 2018-10-03 19:07:14.000000000 +0200 +++ new/unrar/uiconsole.cpp 2019-01-28 11:39:43.000000000 +0100 @@ -18,7 +18,10 @@ { itoa(FileSize,SizeText2,ASIZE(SizeText2)); FileTime->GetText(DateStr2,ASIZE(DateStr2),false); - eprintf(St(MAskReplace),Name,SizeText1,DateStr1,SizeText2,DateStr2); + if ((Flags & UIASKREP_F_EXCHSRCDEST)==0) + eprintf(St(MAskReplace),Name,SizeText1,DateStr1,SizeText2,DateStr2); + else + eprintf(St(MAskReplace),Name,SizeText2,DateStr2,SizeText1,DateStr1); } bool AllowRename=(Flags & UIASKREP_F_NORENAME)==0; @@ -186,7 +189,11 @@ Log(Str[0],St(MUnknownMeth),Str[1]); break; case UIERROR_UNKNOWNENCMETHOD: - Log(Str[0],St(MUnkEncMethod),Str[1]); + { + wchar Msg[256]; + swprintf(Msg,ASIZE(Msg),St(MUnkEncMethod),Str[1]); + Log(Str[0],L"%s: %s",Msg,Str[2]); + } break; #ifndef SFX_MODULE case UIERROR_RENAMING: diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/unrar/version.hpp new/unrar/version.hpp --- old/unrar/version.hpp 2018-10-03 19:07:15.000000000 +0200 +++ new/unrar/version.hpp 2019-01-28 11:39:44.000000000 +0100 @@ -1,6 +1,6 @@ #define RARVER_MAJOR 5 -#define RARVER_MINOR 61 -#define RARVER_BETA 0 -#define RARVER_DAY 30 -#define RARVER_MONTH 9 -#define RARVER_YEAR 2018 +#define RARVER_MINOR 70 +#define RARVER_BETA 1 +#define RARVER_DAY 28 +#define RARVER_MONTH 1 +#define RARVER_YEAR 2019 diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/unrar/volume.cpp new/unrar/volume.cpp --- old/unrar/volume.cpp 2018-10-03 19:07:15.000000000 +0200 +++ new/unrar/volume.cpp 2019-01-28 11:39:44.000000000 +0100 @@ -34,7 +34,7 @@ Arc.Close(); wchar NextName[NM]; - wcscpy(NextName,Arc.FileName); + wcsncpyz(NextName,Arc.FileName,ASIZE(NextName)); NextVolumeName(NextName,ASIZE(NextName),!Arc.NewNumbering); #if !defined(SFX_MODULE) && !defined(RARDLL) @@ -67,12 +67,12 @@ // Checking for new style volumes renamed by user to old style // name format. Some users did it for unknown reason. wchar AltNextName[NM]; - wcscpy(AltNextName,Arc.FileName); + wcsncpyz(AltNextName,Arc.FileName,ASIZE(AltNextName)); NextVolumeName(AltNextName,ASIZE(AltNextName),true); OldSchemeTested=true; if (Arc.Open(AltNextName,OpenMode)) { - wcscpy(NextName,AltNextName); + wcsncpyz(NextName,AltNextName,ASIZE(NextName)); break; } } @@ -185,7 +185,7 @@ if (Cmd->Callback!=NULL) { wchar OrgNextName[NM]; - wcscpy(OrgNextName,NextName); + wcsncpyz(OrgNextName,NextName,ASIZE(OrgNextName)); if (Cmd->Callback(UCM_CHANGEVOLUMEW,Cmd->UserData,(LPARAM)NextName,RAR_VOL_ASK)==-1) DllVolAborted=true; else @@ -195,7 +195,7 @@ { char NextNameA[NM],OrgNextNameA[NM]; WideToChar(NextName,NextNameA,ASIZE(NextNameA)); - strcpy(OrgNextNameA,NextNameA); + strncpyz(OrgNextNameA,NextNameA,ASIZE(OrgNextNameA)); if (Cmd->Callback(UCM_CHANGEVOLUME,Cmd->UserData,(LPARAM)NextNameA,RAR_VOL_ASK)==-1) DllVolAborted=true; else diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/unrar/win32stm.cpp new/unrar/win32stm.cpp --- old/unrar/win32stm.cpp 2018-10-03 19:07:15.000000000 +0200 +++ new/unrar/win32stm.cpp 2019-01-28 11:39:44.000000000 +0100 @@ -20,11 +20,13 @@ wchar StreamName[NM+2]; if (FileName[0]!=0 && FileName[1]==0) { - wcscpy(StreamName,L".\\"); - wcscpy(StreamName+2,FileName); + // Convert single character names like f:stream to .\f:stream to + // resolve the ambiguity with drive letters. + wcsncpyz(StreamName,L".\\",ASIZE(StreamName)); + wcsncatz(StreamName,FileName,ASIZE(StreamName)); } else - wcscpy(StreamName,FileName); + wcsncpyz(StreamName,FileName,ASIZE(StreamName)); if (wcslen(StreamName)+strlen(Arc.StreamHead.StreamName)>=ASIZE(StreamName) || Arc.StreamHead.StreamName[0]!=':') { @@ -35,7 +37,7 @@ wchar StoredName[NM]; CharToWide(Arc.StreamHead.StreamName,StoredName,ASIZE(StoredName)); - ConvertPath(StoredName+1,StoredName+1); + ConvertPath(StoredName+1,StoredName+1,ASIZE(StoredName)-1); wcsncatz(StreamName,StoredName,ASIZE(StreamName)); @@ -83,8 +85,10 @@ wchar FullName[NM+2]; if (FileName[0]!=0 && FileName[1]==0) { - wcscpy(FullName,L".\\"); - wcsncpyz(FullName+2,FileName,ASIZE(FullName)-2); + // Convert single character names like f:stream to .\f:stream to + // resolve the ambiguity with drive letters. + wcsncpyz(FullName,L".\\",ASIZE(FullName)); + wcsncatz(FullName,FileName,ASIZE(FullName)); } else wcsncpyz(FullName,FileName,ASIZE(FullName));