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));


Reply via email to