Script 'mail_helper' called by obssrc
Hello community,

here is the log from the commit of package unrar for openSUSE:Factory:NonFree 
checked in at 2023-02-08 17:19:03
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Comparing /work/SRC/openSUSE:Factory:NonFree/unrar (Old)
 and      /work/SRC/openSUSE:Factory:NonFree/.unrar.new.4462 (New)
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

Package is "unrar"

Wed Feb  8 17:19:03 2023 rev:103 rq:1063741 version:6.2.5

Changes:
--------
--- /work/SRC/openSUSE:Factory:NonFree/unrar/unrar.changes      2022-11-25 
13:10:32.507472939 +0100
+++ /work/SRC/openSUSE:Factory:NonFree/.unrar.new.4462/unrar.changes    
2023-02-08 17:19:04.209582949 +0100
@@ -1,0 +2,6 @@
+Tue Feb  7 11:33:49 UTC 2023 - Andrea Manzini <[email protected]>
+
+- Update to version 6.2.5:
+  * no upstream changelog available
+
+-------------------------------------------------------------------

Old:
----
  unrarsrc-6.2.2.tar.gz

New:
----
  unrarsrc-6.2.5.tar.gz

++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

Other differences:
------------------
++++++ unrar.spec ++++++
--- /var/tmp/diff_new_pack.7CzACm/_old  2023-02-08 17:19:04.877586229 +0100
+++ /var/tmp/diff_new_pack.7CzACm/_new  2023-02-08 17:19:04.881586248 +0100
@@ -18,9 +18,9 @@
 
 # majorversion should match the major version number.
 %define majorversion 6
-%define libsuffix 6_2_2
+%define libsuffix 6_2_5
 Name:           unrar
-Version:        6.2.2
+Version:        6.2.5
 Release:        0
 Summary:        A program to extract, test, and view RAR archives
 License:        NonFree

++++++ unrarsrc-6.2.2.tar.gz -> unrarsrc-6.2.5.tar.gz ++++++
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/unrar/arcread.cpp new/unrar/arcread.cpp
--- old/unrar/arcread.cpp       2022-11-12 12:06:48.000000000 +0100
+++ new/unrar/arcread.cpp       2023-01-24 17:25:30.000000000 +0100
@@ -1000,7 +1000,7 @@
               {
                 std::vector<char> NameU((size_t)NameSize); // UTF-8 name.
                 Raw->GetB(&NameU[0],(size_t)NameSize);
-                // If starts from 0, the name was longer han reserved space
+                // If starts from 0, the name was longer than reserved space
                 // when saving this extra field.
                 if (NameU[0]!=0)
                 {
@@ -1014,11 +1014,11 @@
             if ((Flags & MHEXTRA_METADATA_CTIME)!=0)
               if ((Flags & MHEXTRA_METADATA_UNIXTIME)!=0)
                 if ((Flags & MHEXTRA_METADATA_UNIX_NS)!=0)
-                  hd->OrigCtime.SetUnixNS(Raw->Get8());
+                  hd->OrigTime.SetUnixNS(Raw->Get8());
                 else
-                  hd->OrigCtime.SetUnix((time_t)Raw->Get4());
+                  hd->OrigTime.SetUnix((time_t)Raw->Get4());
               else
-                hd->OrigCtime.SetWin(Raw->Get8());
+                hd->OrigTime.SetWin(Raw->Get8());
           }
           break;
       }
@@ -1476,7 +1476,9 @@
   {
     if (SubHead.UnpSize>0x1000000)
     {
-      // So huge allocation must never happen in valid archives.
+      // Prevent the excessive allocation. When reading to memory, normally
+      // this function operates with reasonably small blocks, such as
+      // the archive comment, NTFS ACL or "Zone.Identifier" NTFS stream.
       uiMsg(UIERROR_SUBHEADERUNKNOWN,FileName);
       return false;
     }
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/unrar/cmdfilter.cpp new/unrar/cmdfilter.cpp
--- old/unrar/cmdfilter.cpp     2022-11-12 12:06:48.000000000 +0100
+++ new/unrar/cmdfilter.cpp     2023-01-24 17:25:30.000000000 +0100
@@ -289,8 +289,8 @@
     return 0;
   if ((FileHead.FileAttr & ExclFileAttr)!=0 || FileHead.Dir && ExclDir)
     return 0;
-  if (InclAttrSet && (!FileHead.Dir && (FileHead.FileAttr & InclFileAttr)==0 ||
-      FileHead.Dir && !InclDir))
+  if (InclAttrSet && (FileHead.FileAttr & InclFileAttr)==0 &&
+      (!FileHead.Dir || !InclDir))
     return 0;
   if (!Dir && SizeCheck(FileHead.UnpSize))
     return 0;
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/unrar/crypt.cpp new/unrar/crypt.cpp
--- old/unrar/crypt.cpp 2022-11-12 12:06:48.000000000 +0100
+++ new/unrar/crypt.cpp 2023-01-24 17:25:30.000000000 +0100
@@ -47,7 +47,7 @@
      SecPassword *Password,const byte *Salt,
      const byte *InitV,uint Lg2Cnt,byte *HashKey,byte *PswCheck)
 {
-  if (!Password->IsSet() || Method==CRYPT_NONE)
+  if (Method==CRYPT_NONE || !Password->IsSet())
     return false;
 
   CryptData::Method=Method;
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/unrar/crypt.hpp new/unrar/crypt.hpp
--- old/unrar/crypt.hpp 2022-11-12 12:06:48.000000000 +0100
+++ new/unrar/crypt.hpp 2023-01-24 17:25:30.000000000 +0100
@@ -15,10 +15,7 @@
 #define CRYPT_BLOCK_SIZE         16
 #define CRYPT_BLOCK_MASK         (CRYPT_BLOCK_SIZE-1) // 0xf
 
-// 2013.04.29: set to 15 for RAR 5.00 beta 1.
-// 2022.09.07: changed to 16 for upcoming RAR 6.20.
-#define CRYPT5_KDF_LG2_COUNT     16 // LOG2 of PDKDF2 iteration count.
-
+#define CRYPT5_KDF_LG2_COUNT     15 // LOG2 of PDKDF2 iteration count.
 #define CRYPT5_KDF_LG2_COUNT_MAX 24 // LOG2 of maximum accepted iteration 
count.
 #define CRYPT_VERSION             0 // Supported encryption version.
 
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/unrar/dll.rc new/unrar/dll.rc
--- old/unrar/dll.rc    2022-11-12 11:16:12.000000000 +0100
+++ new/unrar/dll.rc    2023-01-24 17:12:32.000000000 +0100
@@ -2,8 +2,8 @@
 #include <commctrl.h>
 
 VS_VERSION_INFO VERSIONINFO
-FILEVERSION 6, 20, 2, 681
-PRODUCTVERSION 6, 20, 2, 681
+FILEVERSION 6, 21, 1, 755
+PRODUCTVERSION 6, 21, 1, 755
 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", "6.20.2\0"
-      VALUE "ProductVersion", "6.20.2\0"
-      VALUE "LegalCopyright", "Copyright © Alexander Roshal 1993-2022\0"
+      VALUE "FileVersion", "6.21.1\0"
+      VALUE "ProductVersion", "6.21.1\0"
+      VALUE "LegalCopyright", "Copyright © Alexander Roshal 1993-2023\0"
       VALUE "OriginalFilename", "Unrar.dll\0"
     }
   }
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/unrar/errhnd.cpp new/unrar/errhnd.cpp
--- old/unrar/errhnd.cpp        2022-11-12 12:06:48.000000000 +0100
+++ new/unrar/errhnd.cpp        2023-01-24 17:25:30.000000000 +0100
@@ -169,10 +169,13 @@
 
 void ErrorHandler::OpenErrorMsg(const wchar *ArcName,const wchar *FileName)
 {
-  Wait(); // Keep GUI responsive if many files cannot be opened when archiving.
   uiMsg(UIERROR_FILEOPEN,ArcName,FileName);
   SysErrMsg();
   SetErrorCode(RARX_OPEN);
+
+  // Keep GUI responsive if many files cannot be opened when archiving.
+  // Call after SysErrMsg to avoid modifying the error code and SysErrMsg text.
+  Wait();
 }
 
 
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/unrar/extinfo.cpp new/unrar/extinfo.cpp
--- old/unrar/extinfo.cpp       2022-11-12 12:06:48.000000000 +0100
+++ new/unrar/extinfo.cpp       2023-01-24 17:25:30.000000000 +0100
@@ -112,6 +112,68 @@
 }
 
 
+// Delete symbolic links in file path, if any, and replace them by directories.
+// Prevents extracting files outside of destination folder with symlink chains.
+bool LinksToDirs(const wchar *SrcName,const wchar *SkipPart,std::wstring 
&LastChecked)
+{
+  // Unlike Unix, Windows doesn't expand lnk1 in symlink targets like
+  // "lnk1/../dir", but converts the path to "dir". In Unix we need to call
+  // this function to prevent placing unpacked files outside of destination
+  // folder if previously we unpacked "dir/lnk1" -> "..",
+  // "dir/lnk2" -> "lnk1/.." and "dir/lnk2/anypath/poc.txt".
+  // We may still need this function to prevent abusing symlink chains
+  // in link source path if we remove detection of such chains
+  // in IsRelativeSymlinkSafe. This function seems to make other symlink
+  // related safety checks redundant, but for now we prefer to keep them too.
+  //
+  // 2022.12.01: the performance impact is minimized after adding the check
+  // against the previous path and enabling this verification only after
+  // extracting a symlink with ".." in target. So we enabled it for Windows
+  // as well for extra safety.
+//#ifdef _UNIX
+  wchar Path[NM];
+  if (wcslen(SrcName)>=ASIZE(Path))
+    return false;  // It should not be that long, skip.
+  wcsncpyz(Path,SrcName,ASIZE(Path));
+
+  size_t SkipLength=wcslen(SkipPart);
+
+  if (SkipLength>0 && wcsncmp(Path,SkipPart,SkipLength)!=0)
+    SkipLength=0; // Parameter validation, not really needed now.
+
+  // Do not check parts already checked in previous path to improve 
performance.
+  for (uint I=0;Path[I]!=0 && I<LastChecked.size() && 
Path[I]==LastChecked[I];I++)
+    if (IsPathDiv(Path[I]) && I>SkipLength)
+      SkipLength=I;
+
+  wchar *Name=Path;
+  if (SkipLength>0)
+  {
+    // Avoid converting symlinks in destination path part specified by user.
+    Name+=SkipLength;
+    while (IsPathDiv(*Name))
+      Name++;
+  }
+
+  for (wchar *s=Path+wcslen(Path)-1;s>Name;s--)
+    if (IsPathDiv(*s))
+    {
+      *s=0;
+      FindData FD;
+      if (FindFile::FastFind(Path,&FD,true) && FD.IsLink)
+#ifdef _WIN_ALL
+        if (!DelDir(Path))
+#else
+        if (!DelFile(Path))
+#endif
+          return false; // Couldn't delete the symlink to replace it with 
directory.
+    }
+  LastChecked=SrcName;
+//#endif
+  return true;
+}
+
+
 bool IsRelativeSymlinkSafe(CommandData *Cmd,const wchar *SrcName,const wchar 
*PrepSrcName,const wchar *TargetName)
 {
   // Catch root dir based /path/file paths also as stuff like \\?\.
@@ -131,10 +193,14 @@
       UpLevels++;
     TargetName++;
   }
-  // If link target includes "..", it must not have another links
-  // in the path, because they can bypass our safety check. For example,
+  // If link target includes "..", it must not have another links in its
+  // source path, because they can bypass our safety check. For example,
   // suppose we extracted "lnk1" -> "." first and "lnk1/lnk2" -> ".." next
-  // or "dir/lnk1" -> ".." first and "dir/lnk1/lnk2" -> ".." next.
+  // or "dir/lnk1" -> ".." first, "dir/lnk1/lnk2" -> ".." next and
+  // file "dir/lnk1/lnk2/poc.txt" last.
+  // Do not confuse with link chains in target, this is in link source path.
+  // It is important for Windows too, though this check can be omitted
+  // if LinksToDirs is invoked in Windows as well.
   if (UpLevels>0 && LinkInPath(PrepSrcName))
     return false;
     
@@ -160,15 +226,26 @@
 }
 
 
-bool ExtractSymlink(CommandData *Cmd,ComprDataIO &DataIO,Archive &Arc,const 
wchar *LinkName)
+bool ExtractSymlink(CommandData *Cmd,ComprDataIO &DataIO,Archive &Arc,const 
wchar *LinkName,bool &UpLink)
 {
+  // Returning true in Uplink indicates that link target might include ".."
+  // and enables additional checks. It is ok to falsely return true here,
+  // as it implies only the minor performance penalty. But we shall always
+  // return true for links with ".." in target for security reason.
+
+  UpLink=true; // Assume the target might include potentially unsafe "..".
+#if defined(SAVE_LINKS) && defined(_UNIX) || defined(_WIN_ALL)
+  if (Arc.Format==RARFMT50) // For RAR5 archives we can check RedirName for 
both Unix and Windows.
+    UpLink=wcsstr(Arc.FileHead.RedirName,L"..")!=NULL;
+#endif
+
 #if defined(SAVE_LINKS) && defined(_UNIX)
   // For RAR 3.x archives we process links even in test mode to skip link data.
   if (Arc.Format==RARFMT15)
-    return ExtractUnixLink30(Cmd,DataIO,Arc,LinkName);
+    return ExtractUnixLink30(Cmd,DataIO,Arc,LinkName,UpLink);
   if (Arc.Format==RARFMT50)
     return ExtractUnixLink50(Cmd,LinkName,&Arc.FileHead);
-#elif defined _WIN_ALL
+#elif defined(_WIN_ALL)
   // RAR 5.0 archives store link information in file header, so there is
   // no need to additionally test it if we do not create a file.
   if (Arc.Format==RARFMT50)
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/unrar/extinfo.hpp new/unrar/extinfo.hpp
--- old/unrar/extinfo.hpp       2022-11-12 12:06:48.000000000 +0100
+++ new/unrar/extinfo.hpp       2023-01-24 17:25:30.000000000 +0100
@@ -1,8 +1,9 @@
 #ifndef _RAR_EXTINFO_
 #define _RAR_EXTINFO_
 
+bool LinksToDirs(const wchar *SrcName,const wchar *SkipPart,std::wstring 
&LastChecked);
 bool IsRelativeSymlinkSafe(CommandData *Cmd,const wchar *SrcName,const wchar 
*PrepSrcName,const wchar *TargetName);
-bool ExtractSymlink(CommandData *Cmd,ComprDataIO &DataIO,Archive &Arc,const 
wchar *LinkName);
+bool ExtractSymlink(CommandData *Cmd,ComprDataIO &DataIO,Archive &Arc,const 
wchar *LinkName,bool &UpLink);
 #ifdef _UNIX
 void SetUnixOwner(Archive &Arc,const wchar *FileName);
 #endif
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/unrar/extract.cpp new/unrar/extract.cpp
--- old/unrar/extract.cpp       2022-11-12 12:06:48.000000000 +0100
+++ new/unrar/extract.cpp       2023-01-24 17:25:30.000000000 +0100
@@ -12,6 +12,23 @@
   memset(Analyze,0,sizeof(*Analyze));
 
   TotalFileCount=0;
+
+  // Common for all archives involved. Set here instead of DoExtract()
+  // to use in unrar.dll too. Allows to avoid LinksToDirs() calls
+  // and save CPU time in no symlinks including ".." in target were extracted.
+#if defined(_WIN_ALL)
+  // We can't expand symlink path components in another symlink target
+  // in Windows. We can't create symlinks in Android now. Even though we do not
+  // really need LinksToDirs() calls in these systems, we still call it
+  // for extra safety, but only if symlink with ".." in target was extracted.
+  ConvertSymlinkPaths=false;
+#else
+  // We enable it by default in Unix to care about the case when several
+  // archives are unpacked to same directory with several independent RAR runs.
+  // Worst case performance penalty for a lot of small files seems to be ~3%.
+  ConvertSymlinkPaths=true;
+#endif
+
   Unp=new Unpack(&DataIO);
 #ifdef RAR_SMP
   Unp->SetThreads(Cmd->Threads);
@@ -125,6 +142,8 @@
   ArcAnalyzed=false;
 
   StartTime.SetCurrentTime();
+
+  LastCheckedSymlink.clear();
 }
 
 
@@ -478,6 +497,13 @@
       
         if (!Cmd->Test) // While harmless, it is useless for 't'.
         {
+          // If reference source isn't selected, but target is selected,
+          // we unpack the source under the temporary name and then rename
+          // or copy it to target name. We do not unpack it under the target
+          // name immediately, because the same source can be used by multiple
+          // targets and it is possible that first target isn't unpacked
+          // for some reason. Also targets might have associated service blocks
+          // like ACLs. All this would complicate processing a lot.
           wcsncpyz(DestFileName,*Cmd->TempPath!=0 ? 
Cmd->TempPath:Cmd->ExtrPath,ASIZE(DestFileName));
           AddEndSlash(DestFileName,ASIZE(DestFileName));
           
wcsncatz(DestFileName,L"__tmp_reference_source_",ASIZE(DestFileName));
@@ -612,12 +638,18 @@
         break;
       }
     }
+    else
+      DataIO.SetEncryption(false,CRYPT_NONE,NULL,NULL,NULL,0,NULL,NULL);
 
 #ifdef RARDLL
     if (*Cmd->DllDestName!=0)
       wcsncpyz(DestFileName,Cmd->DllDestName,ASIZE(DestFileName));
 #endif
 
+    if (ExtrFile && Command!='P' && !Cmd->Test && !Cmd->AbsoluteLinks &&
+        ConvertSymlinkPaths)
+      ExtrFile=LinksToDirs(DestFileName,Cmd->ExtrPath,LastCheckedSymlink);
+
     File CurFile;
 
     bool LinkEntry=Arc.FileHead.RedirType!=FSREDIR_NONE;
@@ -747,7 +779,17 @@
         if (Type==FSREDIR_HARDLINK || Type==FSREDIR_FILECOPY)
         {
           wchar RedirName[NM];
-          ConvertPath(Arc.FileHead.RedirName,RedirName,ASIZE(RedirName));
+        
+          // 2022.11.15: Might be needed when unpacking WinRAR 5.0 links with
+          // Unix RAR. WinRAR 5.0 used \ path separators here, when beginning
+          // from 5.10 even Windows version uses / internally and converts
+          // them to \ when reading FHEXTRA_REDIR.
+          // We must perform this conversion before ConvertPath call,
+          // so paths mixing different slashes like \dir1/dir2\file are
+          // processed correctly.
+          SlashToNative(Arc.FileHead.RedirName,RedirName,ASIZE(RedirName));
+
+          ConvertPath(RedirName,RedirName,ASIZE(RedirName));
 
           wchar NameExisting[NM];
           ExtrPrepareName(Arc,RedirName,NameExisting,ASIZE(NameExisting));
@@ -761,7 +803,22 @@
           if (Type==FSREDIR_UNIXSYMLINK || Type==FSREDIR_WINSYMLINK || 
Type==FSREDIR_JUNCTION)
           {
             if (FileCreateMode)
-              LinkSuccess=ExtractSymlink(Cmd,DataIO,Arc,DestFileName);
+            {
+              bool UpLink;
+              LinkSuccess=ExtractSymlink(Cmd,DataIO,Arc,DestFileName,UpLink);
+              ConvertSymlinkPaths|=LinkSuccess && UpLink;
+
+              // We do not actually need to reset the cache here if we cache
+              // only the single last checked path, because at this point
+              // it will always contain the link own path and link can't
+              // overwrite its parent folder. But if we ever decide to cache
+              // several already checked paths, we'll need to reset them here.
+              // Otherwise if no files were created in one of such paths,
+              // let's say because of file create error, it might be possible
+              // to overwrite the path with link and avoid checks. We keep this
+              // code here as a reminder in case of possible modifications.
+              LastCheckedSymlink.clear(); // Reset cache for safety reason.
+            }
           }
           else
           {
@@ -948,8 +1005,6 @@
 
 bool CmdExtract::ExtractFileCopy(File &New,wchar *ArcName,const wchar 
*RedirName,wchar *NameNew,wchar *NameExisting,size_t NameExistingSize,int64 
UnpSize)
 {
-  SlashToNative(NameExisting,NameExisting,NameExistingSize); // Not needed for 
RAR 5.1+ archives.
-
   File Existing;
   if (!Existing.Open(NameExisting))
   {
@@ -1269,6 +1324,8 @@
         DirExist=FileExist(DestFileName) && IsDir(GetFileAttr(DestFileName));
         if (!DirExist)
         {
+          if (!Cmd->AbsoluteLinks && ConvertSymlinkPaths)
+            LinksToDirs(DestFileName,Cmd->ExtrPath,LastCheckedSymlink);
           CreatePath(DestFileName,true,Cmd->DisableNames);
           
MDCode=MakeDir(DestFileName,!Cmd->IgnoreGeneralAttr,Arc.FileHead.FileAttr);
         }
@@ -1350,6 +1407,8 @@
 
           MakeNameUsable(DestFileName,true);
 
+          if (!Cmd->AbsoluteLinks && ConvertSymlinkPaths)
+            LinksToDirs(DestFileName,Cmd->ExtrPath,LastCheckedSymlink);
           CreatePath(DestFileName,true,Cmd->DisableNames);
           if 
(FileCreate(Cmd,&CurFile,DestFileName,ASIZE(DestFileName),&UserReject,Arc.FileHead.UnpSize,&Arc.FileHead.mtime,true))
           {
@@ -1460,6 +1519,8 @@
         {
           if (!MatchFound && !Arc.FileHead.Solid) // Can start extraction from 
here.
           {
+            // We would gain nothing and unnecessarily complicate extraction
+            // by setting these values for first volume or first archived file.
             if (!FirstVolume)
               wcsncpyz(Analyze->StartName,NextName,ASIZE(Analyze->StartName));
             if (!FirstFile)
@@ -1472,6 +1533,10 @@
             MatchFound = true;
             PrevMatched = true;
 
+            // Reset the previously set early exit position, if any, because
+            // we found a new matched file.
+            Analyze->EndPos=0;
+
             // Matched file reference pointing at maybe non-matched source 
file.
             // Even though we know RedirName, we can't check if source file
             // is certainly non-matched, because it can be filtered out by
@@ -1506,6 +1571,8 @@
           {
             if (PrevMatched) // First non-matched item after matched.
             {
+              // We would gain nothing and unnecessarily complicate extraction
+              // by setting these values for first volume or first archived 
file.
               if (!FirstVolume)
                 wcsncpyz(Analyze->EndName,NextName,ASIZE(Analyze->EndName));
               if (!FirstFile)
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/unrar/extract.hpp new/unrar/extract.hpp
--- old/unrar/extract.hpp       2022-11-12 12:06:48.000000000 +0100
+++ new/unrar/extract.hpp       2023-01-24 17:25:30.000000000 +0100
@@ -71,6 +71,15 @@
     bool PrevProcessed; // If previous file was successfully extracted or 
tested.
     wchar DestFileName[NM];
     bool PasswordCancelled;
+
+    // In Windows it is set to true if at least one symlink with ".."
+    // in target was extracted.
+    bool ConvertSymlinkPaths;
+
+    // Last path checked for symlinks. We use it to improve the performance,
+    // so we do not check recently checked folders again.
+    std::wstring LastCheckedSymlink;
+
 #if defined(_WIN_ALL) && !defined(SFX_MODULE) && !defined(SILENT)
     bool Fat32,NotFat32;
 #endif
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/unrar/hardlinks.cpp new/unrar/hardlinks.cpp
--- old/unrar/hardlinks.cpp     2022-11-12 12:06:48.000000000 +0100
+++ new/unrar/hardlinks.cpp     2023-01-24 17:25:31.000000000 +0100
@@ -1,7 +1,5 @@
 bool ExtractHardlink(CommandData *Cmd,wchar *NameNew,wchar 
*NameExisting,size_t NameExistingSize)
 {
-  SlashToNative(NameExisting,NameExisting,NameExistingSize); // Not needed for 
RAR 5.1+ archives.
-
   if (!FileExist(NameExisting))
   {
     uiMsg(UIERROR_HLINKCREATE,NameNew);
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/unrar/headers.hpp new/unrar/headers.hpp
--- old/unrar/headers.hpp       2022-11-12 12:06:48.000000000 +0100
+++ new/unrar/headers.hpp       2023-01-24 17:25:31.000000000 +0100
@@ -170,7 +170,7 @@
   uint64 RRMaxSize;     // Maximum size of RR offset in locator extra field.
   size_t MetaNameMaxSize; // Maximum size of archive name in metadata extra 
field.
   std::wstring OrigName;  // Original archive name.
-  RarTime OrigCtime;      // Original archive creation time.
+  RarTime OrigTime;       // Original archive time.
 
   void Reset();
 };
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/unrar/list.cpp new/unrar/list.cpp
--- old/unrar/list.cpp  2022-11-12 12:06:48.000000000 +0100
+++ new/unrar/list.cpp  2023-01-24 17:25:31.000000000 +0100
@@ -65,10 +65,10 @@
 
           if (!Arc.MainHead.OrigName.empty())
             mprintf(L"\n%s: %s",St(MOrigName),Arc.MainHead.OrigName.c_str());
-          if (Arc.MainHead.OrigCtime.IsSet())
+          if (Arc.MainHead.OrigTime.IsSet())
           {
             wchar DateStr[50];
-            Arc.MainHead.OrigCtime.GetText(DateStr,ASIZE(DateStr),Technical);
+            Arc.MainHead.OrigTime.GetText(DateStr,ASIZE(DateStr),Technical);
             mprintf(L"\n%s: %s",St(MOriginalTime),DateStr);
           }
 
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/unrar/model.cpp new/unrar/model.cpp
--- old/unrar/model.cpp 2022-11-12 12:06:48.000000000 +0100
+++ new/unrar/model.cpp 2023-01-24 17:25:31.000000000 +0100
@@ -532,13 +532,15 @@
     Model->Coder.SubRange.LowCount=HiCnt;
     Model->Coder.SubRange.HighCount=Model->Coder.SubRange.scale;
     i=NumStats-Model->NumMasked;
-    pps--;
+
+    // 2022.12.02: we removed pps-- here and changed the code below to avoid
+    // "array subscript -1 is outside array bounds" warning in some compilers.
     do 
     { 
-      pps++;
       if (pps>=ps+ASIZE(ps)) // Extra safety check.
         return false;
       Model->CharMask[(*pps)->Symbol]=Model->EscCount; 
+      pps++;
     } while ( --i );
     psee2c->Summ += Model->Coder.SubRange.scale;
     Model->NumMasked = NumStats;
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/unrar/pathfn.cpp new/unrar/pathfn.cpp
--- old/unrar/pathfn.cpp        2022-11-12 12:06:48.000000000 +0100
+++ new/unrar/pathfn.cpp        2023-01-24 17:25:31.000000000 +0100
@@ -31,11 +31,17 @@
     const wchar *s=DestPtr;
     if (s[0]!=0 && IsDriveDiv(s[1]))
       s+=2;
-    if (s[0]=='\\' && s[1]=='\\')
+
+    // Skip UNC Windows \\server\share\ or Unix //server/share/
+    if (IsPathDiv(s[0]) && IsPathDiv(s[1]))
     {
-      const wchar *Slash=wcschr(s+2,'\\');
-      if (Slash!=NULL && (Slash=wcschr(Slash+1,'\\'))!=NULL)
-        s=Slash+1;
+      uint SlashCount=0;
+      for (const wchar *t=s+2;*t!=0;t++)
+        if (IsPathDiv(*t) && ++SlashCount==2)
+        {
+          s=t+1; // Found two more path separators after leading two.
+          break;
+        }
     }
     for (const wchar *t=s;*t!=0;t++)
       if (IsPathDiv(*t))
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/unrar/timefn.hpp new/unrar/timefn.hpp
--- old/unrar/timefn.hpp        2022-11-12 12:06:49.000000000 +0100
+++ new/unrar/timefn.hpp        2023-01-24 17:25:31.000000000 +0100
@@ -22,6 +22,17 @@
 
     // Internal time representation in 1/TICKS_PER_SECOND since 01.01.1601.
     // We use nanoseconds here to handle the high precision Unix time.
+    // It allows dates up to July 2185.
+    //
+    // If we'll ever need to extend the date range, we can define a lower
+    // precision Windows version of TICKS_PER_SECOND. But then Unix and Windows
+    // versions can differ in least significant digits of "lt" time output
+    // for Unix archives.
+    // Alternatively we can introduce 'bool HighPrecision' set to true
+    // in SetUnixNS() and TicksPerSecond() instead of constant above.
+    // It might be more reliable than defining TicksPerSecond variable,
+    // which wouldn't survive memset of any structure hosting RarTime.
+    // We would need to eliminate all such memsets in the entire code first.
     uint64 itime;
   public:
     // RarLocalTime::Reminder precision. Must be equal to TICKS_PER_SECOND.
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/unrar/ulinks.cpp new/unrar/ulinks.cpp
--- old/unrar/ulinks.cpp        2022-11-12 12:06:49.000000000 +0100
+++ new/unrar/ulinks.cpp        2023-01-24 17:25:32.000000000 +0100
@@ -70,7 +70,8 @@
 }
 
 
-bool ExtractUnixLink30(CommandData *Cmd,ComprDataIO &DataIO,Archive &Arc,const 
wchar *LinkName)
+static bool ExtractUnixLink30(CommandData *Cmd,ComprDataIO &DataIO,Archive 
&Arc,
+                              const wchar *LinkName,bool &UpLink)
 {
   char Target[NM];
   if (IsLink(Arc.FileHead.FileAttr))
@@ -100,13 +101,14 @@
     if (!Cmd->AbsoluteLinks && (IsFullPath(TargetW) ||
         !IsRelativeSymlinkSafe(Cmd,Arc.FileHead.FileName,LinkName,TargetW)))
       return false;
+    UpLink=strstr(Target,"..")!=NULL;
     return 
UnixSymlink(Cmd,Target,LinkName,&Arc.FileHead.mtime,&Arc.FileHead.atime);
   }
   return false;
 }
 
 
-bool ExtractUnixLink50(CommandData *Cmd,const wchar *Name,FileHeader *hd)
+static bool ExtractUnixLink50(CommandData *Cmd,const wchar *Name,FileHeader 
*hd)
 {
   char Target[NM];
   WideToChar(hd->RedirName,Target,ASIZE(Target));
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/unrar/version.hpp new/unrar/version.hpp
--- old/unrar/version.hpp       2022-11-12 12:06:49.000000000 +0100
+++ new/unrar/version.hpp       2023-01-24 17:25:32.000000000 +0100
@@ -1,6 +1,6 @@
 #define RARVER_MAJOR     6
-#define RARVER_MINOR    20
-#define RARVER_BETA      2
-#define RARVER_DAY      12
-#define RARVER_MONTH    11
-#define RARVER_YEAR   2022
+#define RARVER_MINOR    21
+#define RARVER_BETA      1
+#define RARVER_DAY      24
+#define RARVER_MONTH     1
+#define RARVER_YEAR   2023
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/unrar/win32stm.cpp new/unrar/win32stm.cpp
--- old/unrar/win32stm.cpp      2022-11-12 12:06:49.000000000 +0100
+++ new/unrar/win32stm.cpp      2023-01-24 17:25:32.000000000 +0100
@@ -118,8 +118,12 @@
   if ((fd.FileAttr & FILE_ATTRIBUTE_READONLY)!=0)
     SetFileAttr(FileName,fd.FileAttr & ~FILE_ATTRIBUTE_READONLY);
   File CurFile;
-  if (CurFile.WCreate(FullName) && Arc.ReadSubData(NULL,&CurFile,false))
-    CurFile.Close();
+
+  if (CurFile.WCreate(FullName))
+  {
+    if (Arc.ReadSubData(NULL,&CurFile,false))
+      CurFile.Close();
+  }
 
   // Restoring original file timestamps.
   File HostFile;

Reply via email to