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;
