From: <sv...@op...> - 2024-03-02 22:29:23
|
Author: sagamusix Date: Sat Mar 2 23:29:05 2024 New Revision: 20181 URL: https://source.openmpt.org/browse/openmpt/?op=revision&rev=20181 Log: [Var] unrar: Update to v7.0.7. Modified: trunk/OpenMPT/include/unrar/OpenMPT.txt trunk/OpenMPT/include/unrar/arccmt.cpp trunk/OpenMPT/include/unrar/archive.cpp trunk/OpenMPT/include/unrar/archive.hpp trunk/OpenMPT/include/unrar/arcread.cpp trunk/OpenMPT/include/unrar/blake2s.cpp trunk/OpenMPT/include/unrar/blake2s_sse.cpp trunk/OpenMPT/include/unrar/blake2sp.cpp trunk/OpenMPT/include/unrar/cmddata.cpp trunk/OpenMPT/include/unrar/cmddata.hpp trunk/OpenMPT/include/unrar/cmdfilter.cpp trunk/OpenMPT/include/unrar/cmdmix.cpp trunk/OpenMPT/include/unrar/coder.cpp trunk/OpenMPT/include/unrar/coder.hpp trunk/OpenMPT/include/unrar/compress.hpp trunk/OpenMPT/include/unrar/consio.cpp trunk/OpenMPT/include/unrar/consio.hpp trunk/OpenMPT/include/unrar/crc.cpp trunk/OpenMPT/include/unrar/crc.hpp trunk/OpenMPT/include/unrar/crypt.cpp trunk/OpenMPT/include/unrar/crypt.hpp trunk/OpenMPT/include/unrar/crypt1.cpp trunk/OpenMPT/include/unrar/crypt5.cpp trunk/OpenMPT/include/unrar/dll.cpp trunk/OpenMPT/include/unrar/dll.hpp trunk/OpenMPT/include/unrar/encname.cpp trunk/OpenMPT/include/unrar/encname.hpp trunk/OpenMPT/include/unrar/errhnd.cpp trunk/OpenMPT/include/unrar/errhnd.hpp trunk/OpenMPT/include/unrar/extinfo.cpp trunk/OpenMPT/include/unrar/extinfo.hpp trunk/OpenMPT/include/unrar/extract.cpp trunk/OpenMPT/include/unrar/extract.hpp trunk/OpenMPT/include/unrar/filcreat.cpp trunk/OpenMPT/include/unrar/filcreat.hpp trunk/OpenMPT/include/unrar/file.cpp trunk/OpenMPT/include/unrar/file.hpp trunk/OpenMPT/include/unrar/filefn.cpp trunk/OpenMPT/include/unrar/filefn.hpp trunk/OpenMPT/include/unrar/filestr.cpp trunk/OpenMPT/include/unrar/filestr.hpp trunk/OpenMPT/include/unrar/find.cpp trunk/OpenMPT/include/unrar/find.hpp trunk/OpenMPT/include/unrar/getbits.cpp trunk/OpenMPT/include/unrar/getbits.hpp trunk/OpenMPT/include/unrar/hardlinks.cpp trunk/OpenMPT/include/unrar/hash.cpp trunk/OpenMPT/include/unrar/hash.hpp trunk/OpenMPT/include/unrar/headers.cpp trunk/OpenMPT/include/unrar/headers.hpp trunk/OpenMPT/include/unrar/headers5.hpp trunk/OpenMPT/include/unrar/isnt.cpp trunk/OpenMPT/include/unrar/list.cpp trunk/OpenMPT/include/unrar/loclang.hpp trunk/OpenMPT/include/unrar/log.cpp trunk/OpenMPT/include/unrar/log.hpp trunk/OpenMPT/include/unrar/match.cpp trunk/OpenMPT/include/unrar/match.hpp trunk/OpenMPT/include/unrar/model.cpp trunk/OpenMPT/include/unrar/model.hpp trunk/OpenMPT/include/unrar/options.cpp trunk/OpenMPT/include/unrar/options.hpp trunk/OpenMPT/include/unrar/os.hpp trunk/OpenMPT/include/unrar/pathfn.cpp trunk/OpenMPT/include/unrar/pathfn.hpp trunk/OpenMPT/include/unrar/qopen.cpp trunk/OpenMPT/include/unrar/qopen.hpp trunk/OpenMPT/include/unrar/rar.cpp trunk/OpenMPT/include/unrar/rar.hpp trunk/OpenMPT/include/unrar/rardefs.hpp trunk/OpenMPT/include/unrar/raros.hpp trunk/OpenMPT/include/unrar/rartypes.hpp trunk/OpenMPT/include/unrar/rarvm.cpp trunk/OpenMPT/include/unrar/rawint.hpp trunk/OpenMPT/include/unrar/rawread.cpp trunk/OpenMPT/include/unrar/rawread.hpp trunk/OpenMPT/include/unrar/rdwrfn.cpp trunk/OpenMPT/include/unrar/rdwrfn.hpp trunk/OpenMPT/include/unrar/recvol.cpp trunk/OpenMPT/include/unrar/recvol.hpp trunk/OpenMPT/include/unrar/recvol3.cpp trunk/OpenMPT/include/unrar/recvol5.cpp trunk/OpenMPT/include/unrar/resource.cpp trunk/OpenMPT/include/unrar/resource.hpp trunk/OpenMPT/include/unrar/rijndael.cpp trunk/OpenMPT/include/unrar/rijndael.hpp trunk/OpenMPT/include/unrar/rs16.cpp trunk/OpenMPT/include/unrar/rs16.hpp trunk/OpenMPT/include/unrar/scantree.cpp trunk/OpenMPT/include/unrar/scantree.hpp trunk/OpenMPT/include/unrar/secpassword.cpp trunk/OpenMPT/include/unrar/secpassword.hpp trunk/OpenMPT/include/unrar/sha256.cpp trunk/OpenMPT/include/unrar/sha256.hpp trunk/OpenMPT/include/unrar/strfn.cpp trunk/OpenMPT/include/unrar/strfn.hpp trunk/OpenMPT/include/unrar/strlist.cpp trunk/OpenMPT/include/unrar/strlist.hpp trunk/OpenMPT/include/unrar/system.cpp trunk/OpenMPT/include/unrar/system.hpp trunk/OpenMPT/include/unrar/timefn.cpp trunk/OpenMPT/include/unrar/timefn.hpp trunk/OpenMPT/include/unrar/ui.hpp trunk/OpenMPT/include/unrar/uicommon.cpp trunk/OpenMPT/include/unrar/uiconsole.cpp trunk/OpenMPT/include/unrar/uisilent.cpp trunk/OpenMPT/include/unrar/ulinks.cpp trunk/OpenMPT/include/unrar/unicode.cpp trunk/OpenMPT/include/unrar/unicode.hpp trunk/OpenMPT/include/unrar/unpack.cpp trunk/OpenMPT/include/unrar/unpack.hpp trunk/OpenMPT/include/unrar/unpack15.cpp trunk/OpenMPT/include/unrar/unpack20.cpp trunk/OpenMPT/include/unrar/unpack30.cpp trunk/OpenMPT/include/unrar/unpack50.cpp trunk/OpenMPT/include/unrar/unpack50frag.cpp trunk/OpenMPT/include/unrar/unpack50mt.cpp trunk/OpenMPT/include/unrar/unpackinline.cpp trunk/OpenMPT/include/unrar/uowners.cpp trunk/OpenMPT/include/unrar/version.hpp trunk/OpenMPT/include/unrar/volume.cpp trunk/OpenMPT/include/unrar/win32acl.cpp trunk/OpenMPT/include/unrar/win32lnk.cpp trunk/OpenMPT/include/unrar/win32stm.cpp Modified: trunk/OpenMPT/include/unrar/OpenMPT.txt ============================================================================== --- trunk/OpenMPT/include/unrar/OpenMPT.txt Sat Mar 2 22:17:07 2024 (r20180) +++ trunk/OpenMPT/include/unrar/OpenMPT.txt Sat Mar 2 23:29:05 2024 (r20181) @@ -1,4 +1,4 @@ -This folder is based on https://rarlab.com/rar/unrarsrc-6.2.10.tar.gz +This folder is based on https://rarlab.com/rar/unrarsrc-7.0.7.tar.gz All modifications to existing files have been done in a manner so that no existing lines were edited; only new lines were added. @@ -10,9 +10,9 @@ never be used in OpenMPT's context. The following files have been modified: -arcread.cpp, extract.cpp, filcreat.cpp, file.cpp, filefn.cpp, find.cpp, -match.cpp, os.hpp, pathfn.cpp, rdwrfn.cpp, secpassword.cpp, system.cpp, -volume.cpp, win32acl.cpp, win32lnk.cpp +extract.cpp, filcreat.cpp, file.cpp, filefn.cpp, find.cpp, match.cpp, +os.hpp, pathfn.cpp, rdwrfn.cpp, secpassword.cpp, volume.cpp, +win32acl.cpp, win32lnk.cpp For building, premake is used to generate Visual Studio project files. See ../build/premake/ for details. Modified: trunk/OpenMPT/include/unrar/arccmt.cpp ============================================================================== --- trunk/OpenMPT/include/unrar/arccmt.cpp Sat Mar 2 22:17:07 2024 (r20180) +++ trunk/OpenMPT/include/unrar/arccmt.cpp Sat Mar 2 23:29:05 2024 (r20181) @@ -1,6 +1,6 @@ static bool IsAnsiEscComment(const wchar *Data,size_t Size); -bool Archive::GetComment(Array<wchar> *CmtData) +bool Archive::GetComment(std::wstring &CmtData) { if (!MainComment) return false; @@ -11,7 +11,7 @@ } -bool Archive::DoGetComment(Array<wchar> *CmtData) +bool Archive::DoGetComment(std::wstring &CmtData) { #ifndef SFX_MODULE uint CmtLength; @@ -101,10 +101,9 @@ // 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.resize(UnpDataSize+1); + CharToWide((const char *)UnpData,CmtData); +// CmtData.resize(wcslen(CmtData->data())); } } } @@ -112,12 +111,12 @@ { if (CmtLength==0) return false; - Array<byte> CmtRaw(CmtLength); - int ReadSize=Read(&CmtRaw[0],CmtLength); + std::vector<byte> CmtRaw(CmtLength); + int ReadSize=Read(CmtRaw.data(),CmtLength); if (ReadSize>=0 && (uint)ReadSize<CmtLength) // Comment is shorter than declared. { CmtLength=ReadSize; - CmtRaw.Alloc(CmtLength); + CmtRaw.resize(CmtLength); } if (Format!=RARFMT14 && CommHead.CommCRC!=(~CRC32(0xffffffff,&CmtRaw[0],CmtLength)&0xffff)) @@ -125,43 +124,41 @@ uiMsg(UIERROR_CMTBROKEN,FileName); return false; } - CmtData->Alloc(CmtLength+1); - CmtRaw.Push(0); +// CmtData.resize(CmtLength+1); + CmtRaw.push_back(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. - OemToCharA((char *)&CmtRaw[0],(char *)&CmtRaw[0]); + OemToCharA((char *)CmtRaw.data(),(char *)CmtRaw.data()); #endif - CharToWide((char *)&CmtRaw[0],CmtData->Addr(0),CmtData->Size()); - CmtData->Alloc(wcslen(CmtData->Addr(0))); + CharToWide((const char *)CmtRaw.data(),CmtData); +// CmtData->resize(wcslen(CmtData->data())); } #endif - return CmtData->Size() > 0; + return CmtData.size() > 0; } -bool Archive::ReadCommentData(Array<wchar> *CmtData) +bool Archive::ReadCommentData(std::wstring &CmtData) { - Array<byte> CmtRaw; + std::vector<byte> CmtRaw; if (!ReadSubData(&CmtRaw,NULL,false)) return false; - size_t CmtSize=CmtRaw.Size(); - CmtRaw.Push(0); - CmtData->Alloc(CmtSize+1); + size_t CmtSize=CmtRaw.size(); + CmtRaw.push_back(0); +// CmtData->resize(CmtSize+1); if (Format==RARFMT50) - UtfToWide((char *)&CmtRaw[0],CmtData->Addr(0),CmtData->Size()); + UtfToWide((char *)CmtRaw.data(),CmtData); else if ((SubHead.SubFlags & SUBHEAD_FLAGS_CMT_UNICODE)!=0) { - RawToWide(&CmtRaw[0],CmtData->Addr(0),CmtSize/2); - (*CmtData)[CmtSize/2]=0; - + CmtData=RawToWide(CmtRaw); } else { - CharToWide((char *)&CmtRaw[0],CmtData->Addr(0),CmtData->Size()); + CharToWide((const char *)CmtRaw.data(),CmtData); } - CmtData->Alloc(wcslen(CmtData->Addr(0))); // Set buffer size to actual comment length. +// CmtData->resize(wcslen(CmtData->data())); // Set buffer size to actual comment length. return true; } @@ -170,15 +167,16 @@ { if (Cmd->DisableComment) return; - Array<wchar> CmtBuf; - if (GetComment(&CmtBuf)) // In GUI too, so "Test" command detects broken comments. + std::wstring CmtBuf; + if (GetComment(CmtBuf)) // In GUI too, so "Test" command detects broken comments. { - size_t CmtSize=CmtBuf.Size(); - wchar *ChPtr=wcschr(&CmtBuf[0],0x1A); - if (ChPtr!=NULL) - CmtSize=ChPtr-&CmtBuf[0]; - mprintf(L"\n"); - OutComment(&CmtBuf[0],CmtSize); + size_t CmtSize=CmtBuf.size(); + auto EndPos=CmtBuf.find(0x1A); + if (EndPos!=std::wstring::npos) + CmtSize=EndPos; + mprintf(St(MArcComment)); + mprintf(L":\n"); + OutComment(CmtBuf); } } Modified: trunk/OpenMPT/include/unrar/archive.cpp ============================================================================== --- trunk/OpenMPT/include/unrar/archive.cpp Sat Mar 2 22:17:07 2024 (r20180) +++ trunk/OpenMPT/include/unrar/archive.cpp Sat Mar 2 23:29:05 2024 (r20181) @@ -39,7 +39,6 @@ VolWrite=0; AddingFilesSize=0; AddingHeadersSize=0; - *FirstVolumeName=0; Splitting=false; NewArchive=false; @@ -74,7 +73,7 @@ #if !defined(SFX_MODULE) -void Archive::CheckOpen(const wchar *Name) +void Archive::CheckOpen(const std::wstring &Name) { TOpen(Name); CheckArc(false); @@ -82,7 +81,7 @@ #endif -bool Archive::WCheckOpen(const wchar *Name) +bool Archive::WCheckOpen(const std::wstring &Name) { if (!WOpen(Name)) return false; @@ -148,9 +147,9 @@ } else { - Array<char> Buffer(MAXSFXSIZE); + std::vector<char> Buffer(MAXSFXSIZE); long CurPos=(long)Tell(); - int ReadSize=Read(&Buffer[0],Buffer.Size()-16); + int ReadSize=Read(Buffer.data(),Buffer.size()-16); for (int I=0;I<ReadSize;I++) if (Buffer[I]==0x52 && (Type=IsSignature((byte *)&Buffer[I],ReadSize-I))!=RARFMT_NONE) { @@ -265,7 +264,7 @@ Seek(SavePos,SEEK_SET); } if (!Volume || FirstVolume) - wcsncpyz(FirstVolumeName,FileName,ASIZE(FirstVolumeName)); + FirstVolumeName=FileName; return true; } @@ -301,7 +300,7 @@ #ifdef USE_QOPEN -bool Archive::Open(const wchar *Name,uint Mode) +bool Archive::Open(const std::wstring &Name,uint Mode) { // Important if we reuse Archive object and it has virtual QOpen // file position not matching real. For example, for 'l -v volname'. @@ -336,3 +335,23 @@ } #endif + +// Return 0 if dictionary size is invalid. If size is RAR7 only, return +// the adjusted nearest bottom value. Return header flags in Flags. +uint64 Archive::GetWinSize(uint64 Size,uint &Flags) +{ + Flags=0; + // Allow 128 KB - 1 TB range. + if (Size<0x20000 || Size>0x10000000000ULL) + return 0; + uint64 Pow2=0x20000; // Power of 2 dictionary size. + for (;2*Pow2<=Size;Pow2*=2) + Flags+=FCI_DICT_BIT0; + if (Size==Pow2) + return Size; // If 'Size' is the power of 2, return it as is. + + // Get the number of Pow2/32 to add to Pow2 for nearest value not exceeding 'Size'. + uint64 Fraction=(Size-Pow2)/(Pow2/32); + Flags+=(uint)Fraction*FCI_DICT_FRACT0; + return Pow2+Fraction*(Pow2/32); +} Modified: trunk/OpenMPT/include/unrar/archive.hpp ============================================================================== --- trunk/OpenMPT/include/unrar/archive.hpp Sat Mar 2 22:17:07 2024 (r20180) +++ trunk/OpenMPT/include/unrar/archive.hpp Sat Mar 2 23:29:05 2024 (r20181) @@ -27,7 +27,7 @@ { private: void UpdateLatestTime(FileHeader *CurBlock); - void ConvertNameCase(wchar *Name); + void ConvertNameCase(std::wstring &Name); void ConvertFileHeader(FileHeader *hd); size_t ReadHeader14(); size_t ReadHeader15(); @@ -36,9 +36,9 @@ void RequestArcPassword(RarCheckPassword *SelPwd); void UnexpEndArcMsg(); void BrokenHeaderMsg(); - void UnkEncVerMsg(const wchar *Name,const wchar *Info); - bool DoGetComment(Array<wchar> *CmtData); - bool ReadCommentData(Array<wchar> *CmtData); + void UnkEncVerMsg(const std::wstring &Name,const std::wstring &Info); + bool DoGetComment(std::wstring &CmtData); + bool ReadCommentData(std::wstring &CmtData); #if !defined(RAR_NOCRYPT) CryptData HeadersCrypt; @@ -67,9 +67,9 @@ size_t SearchRR(); size_t ReadHeader(); void CheckArc(bool EnableBroken); - void CheckOpen(const wchar *Name); - bool WCheckOpen(const wchar *Name); - bool GetComment(Array<wchar> *CmtData); + void CheckOpen(const std::wstring &Name); + bool WCheckOpen(const std::wstring &Name); + bool GetComment(std::wstring &CmtData); void ViewComment(); void SetLatestTime(RarTime *NewTime); void SeekToNext(); @@ -79,23 +79,25 @@ void VolSubtractHeaderSize(size_t SubSize); uint FullHeaderSize(size_t Size); int64 GetStartPos(); - void AddSubData(byte *SrcData,uint64 DataSize,File *SrcFile, + void AddSubData(const byte *SrcData,uint64 DataSize,File *SrcFile, const wchar *Name,uint Flags); - bool ReadSubData(Array<byte> *UnpData,File *DestFile,bool TestMode); + bool ReadSubData(std::vector<byte> *UnpData,File *DestFile,bool TestMode); HEADER_TYPE GetHeaderType() {return CurHeaderType;} CommandData* GetCommandData() {return Cmd;} void SetSilentOpen(bool Mode) {SilentOpen=Mode;} -#if 0 - void GetRecoveryInfo(bool Required,int64 *Size,int *Percent); -#endif #ifdef USE_QOPEN - bool Open(const wchar *Name,uint Mode=FMF_READ); - int Read(void *Data,size_t Size); - void Seek(int64 Offset,int Method); - int64 Tell(); + bool Open(const std::wstring &Name,uint Mode=FMF_READ) override; + int Read(void *Data,size_t Size) override; + void Seek(int64 Offset,int Method) override; + int64 Tell() override; void QOpenUnload() {QOpen.Unload();} void SetProhibitQOpen(bool Mode) {ProhibitQOpen=Mode;} #endif + static uint64 GetWinSize(uint64 Size,uint &Flags); + + // Needed to see wstring based Open from File. Otherwise compiler finds + // Open in Archive and doesn't check the base class overloads. + using File::Open; BaseBlock ShortBlock; MarkHeader MarkHead; @@ -135,12 +137,16 @@ uint VolNumber; int64 VolWrite; + + // Total size of files adding to archive. Might also include the size of + // files repacked in solid archive. uint64 AddingFilesSize; + uint64 AddingHeadersSize; bool NewArchive; - wchar FirstVolumeName[NM]; + std::wstring FirstVolumeName; }; Modified: trunk/OpenMPT/include/unrar/arcread.cpp ============================================================================== --- trunk/OpenMPT/include/unrar/arcread.cpp Sat Mar 2 22:17:07 2024 (r20180) +++ trunk/OpenMPT/include/unrar/arcread.cpp Sat Mar 2 23:29:05 2024 (r20181) @@ -119,7 +119,7 @@ } -void Archive::UnkEncVerMsg(const wchar *Name,const wchar *Info) +void Archive::UnkEncVerMsg(const std::wstring &Name,const std::wstring &Info) { uiMsg(UIERROR_UNKNOWNENCMETHOD,FileName,Name,Info); ErrHandler.SetErrorCode(RARX_WARNING); @@ -222,7 +222,7 @@ { case HEAD_MAIN: MainHead.Reset(); - *(BaseBlock *)&MainHead=ShortBlock; + MainHead.SetBaseBlock(ShortBlock); MainHead.HighPosAV=Raw.Get2(); MainHead.PosAV=Raw.Get4(); @@ -248,7 +248,7 @@ FileHeader *hd=FileBlock ? &FileHead:&SubHead; hd->Reset(); - *(BaseBlock *)hd=ShortBlock; + hd->SetBaseBlock(ShortBlock); hd->SplitBefore=(hd->Flags & LHD_SPLIT_BEFORE)!=0; hd->SplitAfter=(hd->Flags & LHD_SPLIT_AFTER)!=0; @@ -307,7 +307,7 @@ if (hd->HostOS==HOST_UNIX && (hd->FileAttr & 0xF000)==0xA000) { hd->RedirType=FSREDIR_UNIXSYMLINK; - *hd->RedirName=0; + hd->RedirName.clear(); } hd->Inherited=!FileBlock && (hd->SubFlags & SUBHEAD_FLAGS_INHERITED)!=0; @@ -334,27 +334,26 @@ if (hd->UnknownUnpSize) hd->UnpSize=INT64NDF; - char FileName[NM*4]; - size_t ReadNameSize=Min(NameSize,ASIZE(FileName)-1); - Raw.GetB((byte *)FileName,ReadNameSize); - FileName[ReadNameSize]=0; + size_t ReadNameSize=Min(NameSize,MAXPATHSIZE); + std::string FileName(ReadNameSize,0); + Raw.GetB((byte *)&FileName[0],ReadNameSize); if (FileBlock) { - *hd->FileName=0; + hd->FileName.clear(); if ((hd->Flags & LHD_UNICODE)!=0) { EncodeFileName NameCoder; - size_t Length=strlen(FileName); + size_t Length=strlen(FileName.data()); Length++; if (ReadNameSize>Length) - NameCoder.Decode(FileName,ReadNameSize,(byte *)FileName+Length, - ReadNameSize-Length,hd->FileName, - ASIZE(hd->FileName)); + NameCoder.Decode(FileName.data(),ReadNameSize, + (byte *)&FileName[Length], + ReadNameSize-Length,hd->FileName); } - if (*hd->FileName==0) - ArcCharToWide(FileName,hd->FileName,ASIZE(hd->FileName),ACTW_OEM); + if (hd->FileName.empty()) + ArcCharToWide(FileName.data(),hd->FileName,ACTW_OEM); #ifndef SFX_MODULE ConvertNameCase(hd->FileName); @@ -363,7 +362,7 @@ } else { - CharToWide(FileName,hd->FileName,ASIZE(hd->FileName)); + CharToWide(FileName.data(),hd->FileName); // Calculate the size of optional data. int DataSize=int(hd->HeadSize-NameSize-SIZEOF_FILEHEAD3); @@ -374,14 +373,15 @@ { // Here we read optional additional fields for subheaders. // They are stored after the file name and before salt. - hd->SubData.Alloc(DataSize); - Raw.GetB(&hd->SubData[0],DataSize); + hd->SubData.resize(DataSize); + Raw.GetB(hd->SubData.data(),DataSize); } if (hd->CmpName(SUBHEAD_TYPE_CMT)) MainComment=true; } + if ((hd->Flags & LHD_SALT)!=0) Raw.GetB(hd->Salt,SIZE_SALT30); hd->mtime.SetDos(FileTime); @@ -424,7 +424,7 @@ NextBlockPos=SafeAdd(NextBlockPos,hd->PackSize,0); bool CRCProcessedOnly=hd->CommentInHeader; - ushort HeaderCRC=Raw.GetCRC15(CRCProcessedOnly); + uint HeaderCRC=Raw.GetCRC15(CRCProcessedOnly); if (hd->HeadCRC!=HeaderCRC) { BrokenHeader=true; @@ -441,7 +441,7 @@ } break; case HEAD_ENDARC: - *(BaseBlock *)&EndArcHead=ShortBlock; + EndArcHead.SetBaseBlock(ShortBlock); EndArcHead.NextVolume=(EndArcHead.Flags & EARC_NEXT_VOLUME)!=0; EndArcHead.DataCRC=(EndArcHead.Flags & EARC_DATACRC)!=0; EndArcHead.RevSpace=(EndArcHead.Flags & EARC_REVSPACE)!=0; @@ -453,14 +453,14 @@ break; #ifndef SFX_MODULE case HEAD3_CMT: - *(BaseBlock *)&CommHead=ShortBlock; + CommHead.SetBaseBlock(ShortBlock); CommHead.UnpSize=Raw.Get2(); CommHead.UnpVer=Raw.Get1(); CommHead.Method=Raw.Get1(); CommHead.CommCRC=Raw.Get2(); break; case HEAD3_PROTECT: - *(BaseBlock *)&ProtectHead=ShortBlock; + ProtectHead.SetBaseBlock(ShortBlock); ProtectHead.DataSize=Raw.Get4(); ProtectHead.Version=Raw.Get1(); ProtectHead.RecSectors=Raw.Get2(); @@ -469,7 +469,7 @@ NextBlockPos+=ProtectHead.DataSize; break; case HEAD3_OLDSERVICE: // RAR 2.9 and earlier. - *(BaseBlock *)&SubBlockHead=ShortBlock; + SubBlockHead.SetBaseBlock(ShortBlock); SubBlockHead.DataSize=Raw.Get4(); NextBlockPos+=SubBlockHead.DataSize; SubBlockHead.SubType=Raw.Get2(); @@ -490,10 +490,13 @@ StreamHead.Method=Raw.Get1(); StreamHead.StreamCRC=Raw.Get4(); StreamHead.StreamNameSize=Raw.Get2(); - if (StreamHead.StreamNameSize>=ASIZE(StreamHead.StreamName)) - StreamHead.StreamNameSize=ASIZE(StreamHead.StreamName)-1; - Raw.GetB(StreamHead.StreamName,StreamHead.StreamNameSize); - StreamHead.StreamName[StreamHead.StreamNameSize]=0; + + const size_t MaxStreamName20=260; // Maximum allowed stream name in RAR 2.x format. + if (StreamHead.StreamNameSize>MaxStreamName20) + StreamHead.StreamNameSize=MaxStreamName20; + + StreamHead.StreamName.resize(StreamHead.StreamNameSize); + Raw.GetB(&StreamHead.StreamName[0],StreamHead.StreamNameSize); break; } break; @@ -504,7 +507,7 @@ break; } - ushort HeaderCRC=Raw.GetCRC15(false); + uint HeaderCRC=Raw.GetCRC15(false); // Old AV header does not have header CRC properly set. // Old Unix owners header didn't include string fields into header size, @@ -646,7 +649,7 @@ } int SizeToRead=int(BlockSize); - SizeToRead-=FirstReadSize-SizeBytes-4; // Adjust overread size bytes if any. + SizeToRead-=int(FirstReadSize-SizeBytes-4); // Adjust overread size bytes if any. uint HeaderSize=4+SizeBytes+(uint)BlockSize; if (SizeToRead<0 || HeaderSize<SIZEOF_SHORTBLOCKHEAD5) @@ -711,13 +714,12 @@ { case HEAD_CRYPT: { - *(BaseBlock *)&CryptHead=ShortBlock; + CryptHead.SetBaseBlock(ShortBlock); uint CryptVersion=(uint)Raw.GetV(); if (CryptVersion>CRYPT_VERSION) { - wchar Info[20]; - swprintf(Info,ASIZE(Info),L"h%u",CryptVersion); - UnkEncVerMsg(FileName,Info); + UnkEncVerMsg(FileName,L"h" + std::to_wstring(CryptVersion)); + FailedHeaderDecryption=true; return 0; } uint EncFlags=(uint)Raw.GetV(); @@ -725,9 +727,8 @@ CryptHead.Lg2Count=Raw.Get1(); if (CryptHead.Lg2Count>CRYPT5_KDF_LG2_COUNT_MAX) { - wchar Info[20]; - swprintf(Info,ASIZE(Info),L"hc%u",CryptHead.Lg2Count); - UnkEncVerMsg(FileName,Info); + UnkEncVerMsg(FileName,L"hc" + std::to_wstring(CryptHead.Lg2Count)); + FailedHeaderDecryption=true; return 0; } @@ -739,12 +740,8 @@ byte csum[SIZE_PSWCHECK_CSUM]; Raw.GetB(csum,SIZE_PSWCHECK_CSUM); - sha256_context ctx; - sha256_init(&ctx); - sha256_process(&ctx, CryptHead.PswCheck, SIZE_PSWCHECK); - byte Digest[SHA256_DIGEST_SIZE]; - sha256_done(&ctx, Digest); + sha256_get(CryptHead.PswCheck, SIZE_PSWCHECK, Digest); CryptHead.UsePswCheck=memcmp(csum,Digest,SIZE_PSWCHECK_CSUM)==0; } @@ -754,7 +751,7 @@ case HEAD_MAIN: { MainHead.Reset(); - *(BaseBlock *)&MainHead=ShortBlock; + MainHead.SetBaseBlock(ShortBlock); uint ArcFlags=(uint)Raw.GetV(); Volume=(ArcFlags & MHFL_VOLUME)!=0; @@ -832,9 +829,14 @@ // we may need to use the compression algorithm 15 in the future, // but it was already used in RAR 1.5 and Unpack needs to distinguish // them. - hd->UnpVer=(CompInfo & 0x3f) + 50; - if (hd->UnpVer!=50) // Only 5.0 compression is known now. - hd->UnpVer=VER_UNKNOWN; + uint UnpVer=(CompInfo & 0x3f); + if (UnpVer==0) + hd->UnpVer=VER_PACK5; + else + if (UnpVer==1) + hd->UnpVer=VER_PACK7; + else + hd->UnpVer=VER_UNKNOWN; hd->HostOS=(byte)Raw.GetV(); size_t NameSize=(size_t)Raw.GetV(); @@ -852,14 +854,29 @@ hd->SubBlock=(hd->Flags & HFL_CHILD)!=0; hd->Solid=FileBlock && (CompInfo & FCI_SOLID)!=0; hd->Dir=(hd->FileFlags & FHFL_DIRECTORY)!=0; - hd->WinSize=hd->Dir ? 0:size_t(0x20000)<<((CompInfo>>10)&0xf); + if (hd->Dir || UnpVer>1) + hd->WinSize=0; + else + { + hd->WinSize=0x20000ULL<<((CompInfo>>10)&(UnpVer==0 ? 0x0f:0x1f)); + if (UnpVer==1) + { + hd->WinSize+=hd->WinSize/32*((CompInfo>>15)&0x1f); - char FileName[NM*4]; - size_t ReadNameSize=Min(NameSize,ASIZE(FileName)-1); - Raw.GetB((byte *)FileName,ReadNameSize); - FileName[ReadNameSize]=0; + // RAR7 header with RAR5 compression. Needed to append RAR7 files + // to RAR5 solid stream if new dictionary is larger than existing. + if ((CompInfo & FCI_RAR5_COMPAT)!=0) + hd->UnpVer=VER_PACK5; + if (hd->WinSize>UNPACK_MAX_DICT) + hd->UnpVer=VER_UNKNOWN; + } + } - UtfToWide(FileName,hd->FileName,ASIZE(hd->FileName)); + size_t ReadNameSize=Min(NameSize,MAXPATHSIZE); + std::string FileName(ReadNameSize,0); + Raw.GetB((byte *)&FileName[0],ReadNameSize); + + UtfToWide(FileName.data(),hd->FileName); // Should do it before converting names, because extra fields can // affect name processing, like in case of NTFS streams. @@ -884,7 +901,7 @@ break; case HEAD_ENDARC: { - *(BaseBlock *)&EndArcHead=ShortBlock; + EndArcHead.SetBaseBlock(ShortBlock); uint ArcFlags=(uint)Raw.GetV(); EndArcHead.NextVolume=(ArcFlags & EHFL_NEXTVOLUME)!=0; EndArcHead.StoreVolNumber=false; @@ -916,7 +933,7 @@ *PasswordA=0; if (Cmd->Callback(UCM_NEEDPASSWORD,Cmd->UserData,(LPARAM)PasswordA,ASIZE(PasswordA))==-1) *PasswordA=0; - GetWideName(PasswordA,NULL,PasswordW,ASIZE(PasswordW)); + CharToWide(PasswordA,PasswordW,ASIZE(PasswordW)); cleandata(PasswordA,sizeof(PasswordA)); } Cmd->Password.Set(PasswordW); @@ -991,19 +1008,14 @@ if ((Flags & MHEXTRA_METADATA_NAME)!=0) { uint64 NameSize=Raw->GetV(); - if (NameSize<0x10000) // Prevent excessive allocation. + if (NameSize>0 && NameSize<MAXPATHSIZE) // Prevent excessive allocation. { - std::vector<char> NameU((size_t)NameSize); // UTF-8 name. + std::string NameU((size_t)NameSize,0); // UTF-8 name. Raw->GetB(&NameU[0],(size_t)NameSize); // If starts from 0, the name was longer than reserved space // when saving this extra field. if (NameU[0]!=0) - { - NameU.push_back(0); - std::vector<wchar> NameW(NameU.size()*4); - UtfToWide(&NameU[0],&NameW[0],NameW.size()); - hd->OrigName.assign(&NameW[0]); - } + UtfToWide(&NameU[0],hd->OrigName); } } if ((Flags & MHEXTRA_METADATA_CTIME)!=0) @@ -1029,11 +1041,7 @@ FileHeader *hd=(FileHeader *)bb; uint EncVersion=(uint)Raw->GetV(); if (EncVersion>CRYPT_VERSION) - { - wchar Info[20]; - swprintf(Info,ASIZE(Info),L"x%u",EncVersion); - UnkEncVerMsg(hd->FileName,Info); - } + UnkEncVerMsg(hd->FileName,L"x" + std::to_wstring(EncVersion)); else { uint Flags=(uint)Raw->GetV(); @@ -1041,11 +1049,7 @@ hd->UseHashKey=(Flags & FHEXTRA_CRYPT_HASHMAC)!=0; hd->Lg2Count=Raw->Get1(); if (hd->Lg2Count>CRYPT5_KDF_LG2_COUNT_MAX) - { - wchar Info[20]; - swprintf(Info,ASIZE(Info),L"xc%u",hd->Lg2Count); - UnkEncVerMsg(hd->FileName,Info); - } + UnkEncVerMsg(hd->FileName,L"xc" + std::to_wstring(hd->Lg2Count)); Raw->GetB(hd->Salt,SIZE_SALT50); Raw->GetB(hd->InitV,SIZE_INITV); if (hd->UsePswCheck) @@ -1062,12 +1066,8 @@ byte csum[SIZE_PSWCHECK_CSUM]; Raw->GetB(csum,SIZE_PSWCHECK_CSUM); - sha256_context ctx; - sha256_init(&ctx); - sha256_process(&ctx, hd->PswCheck, SIZE_PSWCHECK); - byte Digest[SHA256_DIGEST_SIZE]; - sha256_done(&ctx, Digest); + sha256_get(hd->PswCheck, SIZE_PSWCHECK, Digest); hd->UsePswCheck=memcmp(csum,Digest,SIZE_PSWCHECK_CSUM)==0; @@ -1133,31 +1133,27 @@ if (Version!=0) { hd->Version=true; - - wchar VerText[20]; - swprintf(VerText,ASIZE(VerText),L";%u",Version); - wcsncatz(hd->FileName,VerText,ASIZE(hd->FileName)); + hd->FileName += L';' + std::to_wstring(Version); } } break; case FHEXTRA_REDIR: { - hd->RedirType=(FILE_SYSTEM_REDIRECT)Raw->GetV(); + FILE_SYSTEM_REDIRECT RedirType=(FILE_SYSTEM_REDIRECT)Raw->GetV(); uint Flags=(uint)Raw->GetV(); - hd->DirTarget=(Flags & FHEXTRA_REDIR_DIR)!=0; size_t NameSize=(size_t)Raw->GetV(); - char UtfName[NM*4]; - *UtfName=0; - if (NameSize<ASIZE(UtfName)-1) + if (NameSize>0 && NameSize<MAXPATHSIZE) { - Raw->GetB(UtfName,NameSize); - UtfName[NameSize]=0; - } + std::string UtfName(NameSize,0); + hd->RedirType=RedirType; + hd->DirTarget=(Flags & FHEXTRA_REDIR_DIR)!=0; + Raw->GetB(&UtfName[0],NameSize); + UtfToWide(&UtfName[0],hd->RedirName); #ifdef _WIN_ALL - UnixSlashToDos(UtfName,UtfName,ASIZE(UtfName)); + UnixSlashToDos(hd->RedirName,hd->RedirName); #endif - UtfToWide(UtfName,hd->RedirName,ASIZE(hd->RedirName)); + } } break; case FHEXTRA_UOWNER: @@ -1214,8 +1210,8 @@ // We cannot allocate too much memory here, because above // we check FieldSize againt Raw size and we control that Raw size // is sensible when reading headers. - hd->SubData.Alloc((size_t)FieldSize); - Raw->GetB(hd->SubData.Addr(0),(size_t)FieldSize); + hd->SubData.resize((size_t)FieldSize); + Raw->GetB(hd->SubData.data(),(size_t)FieldSize); } break; } @@ -1238,7 +1234,7 @@ Raw.GetB(Mark,4); uint HeadSize=Raw.Get2(); if (HeadSize<7) - return false; + return 0; byte Flags=Raw.Get1(); NextBlockPos=CurBlockPos+HeadSize; CurHeaderType=HEAD_MAIN; @@ -1261,7 +1257,7 @@ FileHead.FileHash.CRC32=Raw.Get2(); FileHead.HeadSize=Raw.Get2(); if (FileHead.HeadSize<21) - return false; + return 0; uint FileTime=Raw.Get4(); FileHead.FileAttr=Raw.Get1(); FileHead.Flags=Raw.Get1()|LONG_BLOCK; @@ -1285,12 +1281,13 @@ Raw.Read(NameSize); - char FileName[NM]; - size_t ReadNameSize=Min(NameSize,ASIZE(FileName)-1); - Raw.GetB((byte *)FileName,ReadNameSize); - FileName[ReadNameSize]=0; - IntToExt(FileName,FileName,ASIZE(FileName)); - CharToWide(FileName,FileHead.FileName,ASIZE(FileHead.FileName)); + // RAR 1.4 name size is stored in a single byte field and it can't + // exceed 255, so additional checks are not needed. + std::string FileName(NameSize,0); + Raw.GetB((byte *)&FileName[0],NameSize); + std::string NameA; + IntToExt(FileName,NameA); + CharToWide(NameA,FileHead.FileName); ConvertNameCase(FileHead.FileName); ConvertFileHeader(&FileHead); @@ -1304,7 +1301,7 @@ #ifndef SFX_MODULE -void Archive::ConvertNameCase(wchar *Name) +void Archive::ConvertNameCase(std::wstring &Name) { if (Cmd->ConvertNames==NAMES_UPPERCASE) wcsupper(Name); @@ -1322,7 +1319,7 @@ void Archive::ConvertAttributes() { -#if defined(_WIN_ALL) || defined(_EMX) +#ifdef _WIN_ALL if (FileHead.HSType!=HSYS_WINDOWS) FileHead.FileAttr=FileHead.Dir ? 0x10 : 0x20; #endif @@ -1387,19 +1384,23 @@ void Archive::ConvertFileHeader(FileHeader *hd) { +/* if (hd->HSType==HSYS_UNKNOWN) if (hd->Dir) hd->FileAttr=0x10; else hd->FileAttr=0x20; +*/ #ifdef _WIN_ALL if (hd->HSType==HSYS_UNIX) // Convert Unix, OS X and Android decomposed chracters to Windows precomposed. - ConvertToPrecomposed(hd->FileName,ASIZE(hd->FileName)); + ConvertToPrecomposed(hd->FileName); #endif - for (wchar *s=hd->FileName;*s!=0;s++) + for (uint I=0;I<hd->FileName.size();I++) { + wchar *s=&hd->FileName[I]; + #ifdef _UNIX // Backslash is the invalid character for Windows file headers, // but it can present in Unix file names extracted in Unix. @@ -1407,7 +1408,7 @@ *s='_'; #endif -#if defined(_WIN_ALL) || defined(_EMX) +#ifdef _WIN_ALL // RAR 5.0 archives do not use '\' as path separator, so if we see it, // it means that it is a part of Unix file name, which we cannot // extract in Windows. @@ -1432,6 +1433,9 @@ if (*s=='/' || *s=='\\' && Format!=RARFMT50) *s=CPATHDIVIDER; } + + // Zeroes inside might be possible in broken Unicode names decoded with EncodeFileName::Decode. + TruncateAtZero(hd->FileName); // Ensure there are no zeroes inside of string. } @@ -1446,7 +1450,7 @@ } -bool Archive::ReadSubData(Array<byte> *UnpData,File *DestFile,bool TestMode) +bool Archive::ReadSubData(std::vector<byte> *UnpData,File *DestFile,bool TestMode) { if (BrokenHeader) { @@ -1454,7 +1458,7 @@ ErrHandler.SetErrorCode(RARX_CRC); return false; } - if (SubHead.Method>5 || SubHead.UnpVer>(Format==RARFMT50 ? VER_UNPACK5:VER_UNPACK)) + if (SubHead.Method>5 || SubHead.UnpVer>(Format==RARFMT50 ? VER_UNPACK7:VER_UNPACK)) { uiMsg(UIERROR_SUBHEADERUNKNOWN,FileName); return false; @@ -1481,7 +1485,7 @@ SubDataIO.SetTestMode(true); else { - UnpData->Alloc((size_t)SubHead.UnpSize); + UnpData->resize((size_t)SubHead.UnpSize); SubDataIO.SetUnpackToMemory(&(*UnpData)[0],(uint)SubHead.UnpSize); } } @@ -1510,7 +1514,7 @@ uiMsg(UIERROR_SUBHEADERDATABROKEN,FileName,SubHead.FileName); ErrHandler.SetErrorCode(RARX_CRC); if (UnpData!=NULL) - UnpData->Reset(); + UnpData->clear(); return false; } return true; Modified: trunk/OpenMPT/include/unrar/blake2s.cpp ============================================================================== --- trunk/OpenMPT/include/unrar/blake2s.cpp Sat Mar 2 22:17:07 2024 (r20180) +++ trunk/OpenMPT/include/unrar/blake2s.cpp Sat Mar 2 23:29:05 2024 (r20181) @@ -2,6 +2,20 @@ #include "rar.hpp" +static const byte blake2s_sigma[10][16] = +{ + { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15 } , + { 14, 10, 4, 8, 9, 15, 13, 6, 1, 12, 0, 2, 11, 7, 5, 3 } , + { 11, 8, 12, 0, 5, 2, 15, 13, 10, 14, 3, 6, 7, 1, 9, 4 } , + { 7, 9, 3, 1, 13, 12, 11, 14, 2, 6, 5, 10, 4, 0, 15, 8 } , + { 9, 0, 5, 7, 2, 4, 10, 15, 14, 1, 11, 12, 6, 8, 3, 13 } , + { 2, 12, 6, 10, 0, 11, 8, 3, 4, 13, 7, 5, 15, 14, 1, 9 } , + { 12, 5, 1, 15, 14, 13, 4, 10, 0, 7, 6, 3, 9, 2, 8, 11 } , + { 13, 11, 7, 14, 12, 1, 3, 9, 5, 0, 15, 4, 8, 6, 2, 10 } , + { 6, 15, 14, 9, 11, 3, 0, 8, 12, 2, 13, 7, 1, 4, 10, 5 } , + { 10, 2, 8, 4, 7, 6, 1, 5, 15, 11, 9, 14, 3, 12, 13 , 0 } , +}; + #ifdef USE_SSE #include "blake2s_sse.cpp" #endif @@ -18,20 +32,6 @@ 0x510E527FUL, 0x9B05688CUL, 0x1F83D9ABUL, 0x5BE0CD19UL }; -static const byte blake2s_sigma[10][16] = -{ - { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15 } , - { 14, 10, 4, 8, 9, 15, 13, 6, 1, 12, 0, 2, 11, 7, 5, 3 } , - { 11, 8, 12, 0, 5, 2, 15, 13, 10, 14, 3, 6, 7, 1, 9, 4 } , - { 7, 9, 3, 1, 13, 12, 11, 14, 2, 6, 5, 10, 4, 0, 15, 8 } , - { 9, 0, 5, 7, 2, 4, 10, 15, 14, 1, 11, 12, 6, 8, 3, 13 } , - { 2, 12, 6, 10, 0, 11, 8, 3, 4, 13, 7, 5, 15, 14, 1, 9 } , - { 12, 5, 1, 15, 14, 13, 4, 10, 0, 7, 6, 3, 9, 2, 8, 11 } , - { 13, 11, 7, 14, 12, 1, 3, 9, 5, 0, 15, 4, 8, 6, 2, 10 } , - { 6, 15, 14, 9, 11, 3, 0, 8, 12, 2, 13, 7, 1, 4, 10, 5 } , - { 10, 2, 8, 4, 7, 6, 1, 5, 15, 11, 9, 14, 3, 12, 13 , 0 } , -}; - static inline void blake2s_set_lastnode( blake2s_state *S ) { S->f[1] = ~0U; @@ -134,11 +134,7 @@ blake2s_increment_counter( S, BLAKE2S_BLOCKBYTES ); #ifdef USE_SSE -#ifdef _WIN_32 // We use SSSE3 _mm_shuffle_epi8 only in x64 mode. - if (_SSE_Version>=SSE_SSE2) -#else if (_SSE_Version>=SSE_SSSE3) -#endif blake2s_compress_sse( S, S->buf ); else blake2s_compress( S, S->buf ); // Compress Modified: trunk/OpenMPT/include/unrar/blake2s_sse.cpp ============================================================================== --- trunk/OpenMPT/include/unrar/blake2s_sse.cpp Sat Mar 2 22:17:07 2024 (r20180) +++ trunk/OpenMPT/include/unrar/blake2s_sse.cpp Sat Mar 2 23:29:05 2024 (r20181) @@ -1,15 +1,14 @@ // Based on public domain code written in 2012 by Samuel Neves -extern const byte blake2s_sigma[10][16]; - // Initialization vector. static __m128i blake2s_IV_0_3, blake2s_IV_4_7; -#ifdef _WIN_64 -// Constants for cyclic rotation. Used in 64-bit mode in mm_rotr_epi32 macro. +// Constants for cyclic rotation. static __m128i crotr8, crotr16; -#endif +#ifdef __GNUC__ +__attribute__((target("sse2"))) +#endif static void blake2s_init_sse() { // We cannot initialize these 128 bit variables in place when declaring @@ -24,28 +23,18 @@ blake2s_IV_0_3 = _mm_setr_epi32( 0x6A09E667, 0xBB67AE85, 0x3C6EF372, 0xA54FF53A ); blake2s_IV_4_7 = _mm_setr_epi32( 0x510E527F, 0x9B05688C, 0x1F83D9AB, 0x5BE0CD19 ); -#ifdef _WIN_64 crotr8 = _mm_set_epi8( 12, 15, 14, 13, 8, 11, 10, 9, 4, 7, 6, 5, 0, 3, 2, 1 ); crotr16 = _mm_set_epi8( 13, 12, 15, 14, 9, 8, 11, 10, 5, 4, 7, 6, 1, 0, 3, 2 ); -#endif } #define LOAD(p) _mm_load_si128( (__m128i *)(p) ) #define STORE(p,r) _mm_store_si128((__m128i *)(p), r) -#ifdef _WIN_32 -// 32-bit mode has less SSE2 registers and in MSVC2008 it is more efficient -// to not use _mm_shuffle_epi8 here. -#define mm_rotr_epi32(r, c) ( \ - _mm_xor_si128(_mm_srli_epi32( (r), c ),_mm_slli_epi32( (r), 32-c )) ) -#else #define mm_rotr_epi32(r, c) ( \ c==8 ? _mm_shuffle_epi8(r,crotr8) \ : c==16 ? _mm_shuffle_epi8(r,crotr16) \ : _mm_xor_si128(_mm_srli_epi32( (r), c ),_mm_slli_epi32( (r), 32-c )) ) -#endif - #define G1(row1,row2,row3,row4,buf) \ row1 = _mm_add_epi32( _mm_add_epi32( row1, buf), row2 ); \ @@ -73,14 +62,6 @@ row3 = _mm_shuffle_epi32( row3, _MM_SHUFFLE(1,0,3,2) ); \ row2 = _mm_shuffle_epi32( row2, _MM_SHUFFLE(2,1,0,3) ); -#ifdef _WIN_64 - // MSVC 2008 in x64 mode expands _mm_set_epi32 to store to stack and load - // from stack operations, which are slower than this code. - #define _mm_set_epi32(i3,i2,i1,i0) \ - _mm_unpacklo_epi32(_mm_unpacklo_epi32(_mm_cvtsi32_si128(i0),_mm_cvtsi32_si128(i2)), \ - _mm_unpacklo_epi32(_mm_cvtsi32_si128(i1),_mm_cvtsi32_si128(i3))) -#endif - // Original BLAKE2 SSE4.1 message loading code was a little slower in x86 mode // and about the same in x64 mode in our test. Perhaps depends on compiler. // We also tried _mm_i32gather_epi32 and _mm256_i32gather_epi32 AVX2 gather @@ -101,6 +82,9 @@ } +#ifdef __GNUC__ +__attribute__((target("ssse3"))) +#endif static int blake2s_compress_sse( blake2s_state *S, const byte block[BLAKE2S_BLOCKBYTES] ) { __m128i row[4]; Modified: trunk/OpenMPT/include/unrar/blake2sp.cpp ============================================================================== --- trunk/OpenMPT/include/unrar/blake2sp.cpp Sat Mar 2 22:17:07 2024 (r20180) +++ trunk/OpenMPT/include/unrar/blake2sp.cpp Sat Mar 2 23:29:05 2024 (r20181) @@ -20,7 +20,7 @@ blake2s_init_param( &S->R, 0, 1 ); // Init root. - for( uint i = 0; i < PARALLELISM_DEGREE; ++i ) + for( uint32 i = 0; i < PARALLELISM_DEGREE; ++i ) blake2s_init_param( &S->S[i], i, 0 ); // Init leaf. S->R.last_node = 1; @@ -49,6 +49,8 @@ if (_SSE_Version>=SSE_SSE && inlen__ >= 2 * PARALLELISM_DEGREE * BLAKE2S_BLOCKBYTES) _mm_prefetch((char*)(in__ + PARALLELISM_DEGREE * BLAKE2S_BLOCKBYTES), _MM_HINT_T0); #endif + // We tried to _forceinline blake2s_update and blake2s_compress_sse, + // but it didn't improve performance. blake2s_update( S, in__, BLAKE2S_BLOCKBYTES ); in__ += PARALLELISM_DEGREE * BLAKE2S_BLOCKBYTES; inlen__ -= PARALLELISM_DEGREE * BLAKE2S_BLOCKBYTES; Modified: trunk/OpenMPT/include/unrar/cmddata.cpp ============================================================================== --- trunk/OpenMPT/include/unrar/cmddata.cpp Sat Mar 2 22:17:07 2024 (r20180) +++ trunk/OpenMPT/include/unrar/cmddata.cpp Sat Mar 2 23:29:05 2024 (r20181) @@ -13,8 +13,18 @@ { RAROptions::Init(); - *Command=0; - *ArcName=0; + Command.clear(); + ArcName.clear(); + ExtrPath.clear(); + TempPath.clear(); + SFXModule.clear(); + CommentFile.clear(); + ArcPath.clear(); + ExclArcPath.clear(); + LogName.clear(); + EmailTo.clear(); + UseStdin.clear(); + FileLists=false; NoMoreSwitches=false; @@ -30,57 +40,45 @@ StoreArgs.Reset(); Password.Clean(); NextVolSizes.clear(); -} - - -// Return the pointer to next position in the string and store dynamically -// allocated command line parameter in Par. -static const wchar *AllocCmdParam(const wchar *CmdLine,wchar **Par) -{ - const wchar *NextCmd=GetCmdParam(CmdLine,NULL,0); - if (NextCmd==NULL) - return NULL; - size_t ParSize=NextCmd-CmdLine+2; // Parameter size including the trailing zero. - *Par=(wchar *)malloc(ParSize*sizeof(wchar)); - if (*Par==NULL) - return NULL; - return GetCmdParam(CmdLine,*Par,ParSize); +#ifdef RARDLL + DllDestName.clear(); +#endif } #if !defined(SFX_MODULE) void CommandData::ParseCommandLine(bool Preprocess,int argc, char *argv[]) { - *Command=0; + Command.clear(); NoMoreSwitches=false; #ifdef CUSTOM_CMDLINE_PARSER // In Windows we may prefer to implement our own command line parser // to avoid replacing \" by " in standard parser. Such replacing corrupts // destination paths like "dest path\" in extraction commands. - const wchar *CmdLine=GetCommandLine(); + std::wstring CmdLine=GetCommandLine(); + + std::wstring Param; + std::wstring::size_type Pos=0; - wchar *Par; for (bool FirstParam=true;;FirstParam=false) { - if ((CmdLine=AllocCmdParam(CmdLine,&Par))==NULL) + if (!GetCmdParam(CmdLine,Pos,Param)) break; if (!FirstParam) // First parameter is the executable name. if (Preprocess) - PreprocessArg(Par); + PreprocessArg(Param.data()); else - ParseArg(Par); - free(Par); + ParseArg(Param.data()); } #else - Array<wchar> Arg; for (int I=1;I<argc;I++) { - Arg.Alloc(strlen(argv[I])+1); - CharToWide(argv[I],&Arg[0],Arg.Size()); + std::wstring Arg; + CharToWide(argv[I],Arg); if (Preprocess) - PreprocessArg(&Arg[0]); + PreprocessArg(Arg.data()); else - ParseArg(&Arg[0]); + ParseArg(Arg.data()); } #endif if (!Preprocess) @@ -90,7 +88,7 @@ #if !defined(SFX_MODULE) -void CommandData::ParseArg(wchar *Arg) +void CommandData::ParseArg(const wchar *Arg) { if (IsSwitch(*Arg) && !NoMoreSwitches) if (Arg[1]=='-' && Arg[2]==0) @@ -98,39 +96,52 @@ else ProcessSwitch(Arg+1); else - if (*Command==0) + if (Command.empty()) { - wcsncpyz(Command,Arg,ASIZE(Command)); + Command=Arg; - *Command=toupperw(*Command); + Command[0]=toupperw(Command[0]); // 'I' and 'S' commands can contain case sensitive strings after // the first character, so we must not modify their case. // 'S' can contain SFX name, which case is important in Unix. - if (*Command!='I' && *Command!='S') + if (Command[0]!='I' && Command[0]!='S') wcsupper(Command); - if (*Command=='P') // Enforce -idq for print command. + if (Command[0]=='P') // Enforce -idq for print command. { MsgStream=MSG_ERRONLY; SetConsoleMsgStream(MSG_ERRONLY); } } else - if (*ArcName==0) - wcsncpyz(ArcName,Arg,ASIZE(ArcName)); + if (ArcName.empty()) + ArcName=Arg; else { // Check if last character is the path separator. size_t Length=wcslen(Arg); wchar EndChar=Length==0 ? 0:Arg[Length-1]; - bool EndSeparator=IsDriveDiv(EndChar) || IsPathDiv(EndChar); + // Check if trailing path separator like path\ is present. + bool FolderArg=IsDriveDiv(EndChar) || IsPathDiv(EndChar); + + // 2024.01.05: We were asked to support exotic d:. and d:.. paths. + if (IsDriveLetter(Arg) && Arg[2]=='.' && (Arg[3]==0 || Arg[3]=='.' && Arg[4]==0)) + FolderArg=true; + + // 2024.01.06: FindFile::FastFind check below fails in Windows 10 if + // "." or ".." points at disk root. So we enforce it for "." and ".." + // optionally preceded with some path like "..\..". + size_t L=Length; + if (L>0 && Arg[L-1]=='.' && (L==1 || L>=2 && (IsPathDiv(Arg[L-2]) || + Arg[L-2]=='.' && (L==2 || L>=3 && IsPathDiv(Arg[L-3]))))) + FolderArg=true; - wchar CmdChar=toupperw(*Command); + wchar CmdChar=toupperw(Command[0]); bool Add=wcschr(L"AFUM",CmdChar)!=NULL; bool Extract=CmdChar=='X' || CmdChar=='E'; bool Repair=CmdChar=='R' && Command[1]==0; - if (EndSeparator && !Add) - wcsncpyz(ExtrPath,Arg,ASIZE(ExtrPath)); + if (FolderArg && !Add) + ExtrPath=Arg; else if ((Add || CmdChar=='T') && (*Arg!='@' || ListMode==RCLM_REJECT_LISTS)) FileArgs.AddString(Arg); @@ -147,10 +158,10 @@ } else // We use 'destpath\' when extracting and reparing. - if (Found && FileData.IsDir && (Extract || Repair) && *ExtrPath==0) + if (Found && FileData.IsDir && (Extract || Repair) && ExtrPath.empty()) { - wcsncpyz(ExtrPath,Arg,ASIZE(ExtrPath)); - AddEndSlash(ExtrPath,ASIZE(ExtrPath)); + ExtrPath=Arg; + AddEndSlash(ExtrPath); } else FileArgs.AddString(Arg); @@ -178,12 +189,12 @@ #if !defined(SFX_MODULE) void CommandData::ParseEnvVar() { - char *EnvStr=getenv("RAR"); - if (EnvStr!=NULL) + char *EnvVar=getenv("RAR"); + if (EnvVar!=NULL) { - Array<wchar> EnvStrW(strlen(EnvStr)+1); - CharToWide(EnvStr,&EnvStrW[0],EnvStrW.Size()); - ProcessSwitchesString(&EnvStrW[0]); + std::wstring EnvStr; + CharToWide(EnvVar,EnvStr); + ProcessSwitchesString(EnvStr); } } #endif @@ -192,7 +203,7 @@ #if !defined(SFX_MODULE) // Preprocess those parameters, which must be processed before the rest of -// command line. Return 'false' to stop further processing. +// command line. void CommandData::PreprocessArg(const wchar *Arg) { if (IsSwitch(Arg[0]) && !NoMoreSwitches) @@ -201,7 +212,7 @@ if (Arg[0]=='-' && Arg[1]==0) // Switch "--". NoMoreSwitches=true; if (wcsicomp(Arg,L"cfg-")==0) - ConfigDisabled=true; + ProcessSwitch(Arg); if (wcsnicomp(Arg,L"ilog",4)==0) { // Ensure that correct log file name is already set @@ -213,13 +224,13 @@ { // Process -sc before reading any file lists. ProcessSwitch(Arg); - if (*LogName!=0) + if (!LogName.empty()) InitLogOptions(LogName,ErrlogCharset); } } else - if (*Command==0) - wcsncpy(Command,Arg,ASIZE(Command)); // Need for rar.ini. + if (Command.empty()) + Command=Arg; // Need for rar.ini. } #endif @@ -237,10 +248,10 @@ Str++; if (wcsnicomp(Str,L"switches=",9)==0) ProcessSwitchesString(Str+9); - if (*Command!=0) + if (!Command.empty()) { wchar Cmd[16]; - wcsncpyz(Cmd,Command,ASIZE(Cmd)); + wcsncpyz(Cmd,Command.c_str(),ASIZE(Cmd)); wchar C0=toupperw(Cmd[0]); wchar C1=toupperw(Cmd[1]); if (C0=='I' || C0=='L' || C0=='M' || C0=='S' || C0=='V') @@ -260,14 +271,19 @@ #if !defined(SFX_MODULE) -void CommandData::ProcessSwitchesString(const wchar *Str) +void CommandData::ProcessSwitchesString(const std::wstring &Str) { - wchar *Par; - while ((Str=AllocCmdParam(Str,&Par))!=NULL) + std::wstring Par; + std::wstring::size_type Pos=0; + while (GetCmdParam(Str,Pos,Par)) { - if (IsSwitch(*Par)) - ProcessSwitch(Par+1); - free(Par); + if (IsSwitch(Par[0])) + ProcessSwitch(&Par[1]); + else + { + mprintf(St(MSwSyntaxError),Par.c_str()); + ErrHandler.Exit(RARX_USERERROR); + } } } #endif @@ -330,13 +346,12 @@ break; } break; - case 'N': // Reserved for archive name. - break; case 'O': AddArcOnly=true; break; case 'P': - wcsncpyz(ArcPath,Switch+2,ASIZE(ArcPath)); + // Convert slashes here than before every comparison. + SlashToNative(Switch+2,ArcPath); break; case 'S': SyncFiles=true; @@ -347,7 +362,14 @@ } break; case 'C': - if (Switch[2]==0) + if (Switch[2]!=0) + { + if (wcsicomp(Switch+1,L"FG-")==0) + ConfigDisabled=true; + else + BadSwitch(Switch); + } + else switch(toupperw(Switch[1])) { case '-': @@ -359,10 +381,15 @@ case 'L': ConvertNames=NAMES_LOWERCASE; break; + default: + BadSwitch(Switch); + break; } break; case 'D': - if (Switch[2]==0) + if (Switch[2]!=0) + BadSwitch(Switch); + else switch(toupperw(Switch[1])) { case 'S': @@ -374,6 +401,9 @@ case 'F': DeleteFiles=true; break; + default: + BadSwitch(Switch); + break; } break; case 'E': @@ -395,7 +425,11 @@ ExclPath=EXCL_ABSPATH; break; case '4': - wcsncpyz(ExclArcPath,Switch+3,ASIZE(ExclArcPath)); + // Convert slashes here than before every comparison. + SlashToNative(Switch+3,ArcPath); + break; + default: + BadSwitch(Switch); break; } break; @@ -431,7 +465,7 @@ else if (!Password.IsSet()) { - uiGetPassword(UIPASSWORD_GLOBAL,NULL,&Password,NULL); + uiGetPassword(UIPASSWORD_GLOBAL,L"",&Password,NULL); eprintf(L"\n"); } break; @@ -443,7 +477,7 @@ case 'I': if (wcsnicomp(Switch+1,L"LOG",3)==0) { - wcsncpyz(LogName,Switch[4]!=0 ? Switch+4:DefLogName,ASIZE(LogName)); + LogName=Switch[4]!=0 ? Switch+4:DefLogName; break; } if (wcsnicomp(Switch+1,L"SND",3)==0) @@ -461,7 +495,7 @@ } if (wcsnicomp(Switch+1,L"EML",3)==0) { - wcsncpyz(EmailTo,Switch[4]!=0 ? Switch+4:L"@",ASIZE(EmailTo)); + EmailTo=Switch[4]!=0 ? Switch+4:L"@"; break; } if (wcsicomp(Switch+1,L"M")==0) // For compatibility with pre-WinRAR 6.0 -im syntax. Replaced with -idv. @@ -568,12 +602,14 @@ } switch(toupperw(*(Str++))) { - case 'T': Type=FILTER_PPM; break; +// case 'T': Type=FILTER_TEXT; break; case 'E': Type=FILTER_E8; break; case 'D': Type=FILTER_DELTA; break; - case 'A': Type=FILTER_AUDIO; break; - case 'C': Type=FILTER_RGB; break; - case 'R': Type=FILTER_ARM; break; +// case 'A': Type=FILTER_AUDIO; break; +// case 'C': Type=FILTER_RGB; break; +// case 'R': Type=FILTER_ARM; break; + case 'L': Type=FILTER_LONGRANGE; break; + case 'X': Type=FILTER_EXHAUSTIVE; break; } if (*Str=='+' || *Str=='-') State=*(Str++)=='+' ? FILTER_FORCE:FILTER_DISABLE; @@ -586,6 +622,44 @@ case 'M': break; case 'D': + { + bool SetDictLimit=toupperw(Switch[2])=='X'; + + uint64 Size=atoiw(Switch+(SetDictLimit ? 3 : 2)); + wchar LastChar=toupperw(Switch[wcslen(Switch)-1]); + if (IsDigit(LastChar)) + LastChar=SetDictLimit ? 'G':'M'; // Treat -md128 as -md128m and -mdx32 as -mdx32g. + switch(LastChar) + { + case 'K': + Size*=1024; + break; + case 'M': + Size*=1024*1024; + break; + case 'G': + Size*=1024*1024*1024; + break; + default: + BadSwitch(Switch); + } + + // 2023.07.22: For 4 GB and less we also check that it is power of 2, + // so archives are compatible with RAR 5.0+. + // We allow Size>PACK_MAX_DICT here, so we can use -md[x] to unpack + // archives created by future versions with higher PACK_MAX_DICT + uint Flags; + if ((Size=Archive::GetWinSize(Size,Flags))==0 || + Size<=0x100000000ULL && !IsPow2(Size)) + BadSwitch(Switch); + else + if (SetDictLimit) + WinSizeLimit=Size; + else + { + WinSize=Size; + } + } break; case 'E': if (toupperw(Switch[2])=='S' && Switch[3]==0) @@ -593,25 +667,20 @@ break; case 'S': { - wchar StoreNames[1024]; - wcsncpyz(StoreNames,(Switch[2]==0 ? DefaultStoreList:Switch+2),ASIZE(StoreNames)); - wchar *Names=StoreNames; - while (*Names!=0) + std::wstring StoreNames=(Switch[2]==0 ? DefaultStoreList:Switch+2); + size_t Pos=0; + while (Pos<StoreNames.size()) { - wchar *End=wcschr(Names,';'); - if (End!=NULL) - *End=0; - if (*Names=='.') - Names++; - wchar Mask[NM]; - if (wcspbrk(Names,L"*?.")==NULL) - swprintf(Mask,ASIZE(Mask),L"*.%ls",Names); - else - wcsncpyz(Mask,Names,ASIZE(Mask)); + if (StoreNames[Pos]=='.') + Pos++; + size_t EndPos=StoreNames.find(';',Pos); + std::wstring Mask=StoreNames.substr(Pos,EndPos==std::wstring::npos ? EndPos:EndPos-Pos); + if (Mask.find_first_of(L"*?.")==std::wstring::npos) + Mask.insert(0,L"*."); StoreArgs.AddString(Mask); - if (End==NULL) + if (EndPos==std::wstring::npos) break; - Names=End+1; + Pos=EndPos+1; } } break; @@ -668,8 +737,19 @@ #ifdef SAVE_LINKS case 'L': SaveSymLinks=true; - if (toupperw(Switch[2])=='A') - AbsoluteLinks=true; + for (uint I=2;Switch[I]!=0;I++) + switch(toupperw(Switch[I])) + { + case 'A': + AbsoluteLinks=true; + break; + case '-': + SkipSymLinks=true; + break; + default: + BadSwitch(Switch); + break; + } break; #endif #ifdef _WIN_ALL @@ -679,8 +759,8 @@ break; #endif case 'P': - wcsncpyz(ExtrPath,Switch+2,ASIZE(ExtrPath)); - AddEndSlash(ExtrPath,ASIZE(ExtrPath)); + ExtrPath=Switch+2; + AddEndSlash(ExtrPath); break; case 'R': Overwrite=OVERWRITE_AUTORENAME; @@ -701,7 +781,7 @@ case 'P': if (Switch[1]==0) { - uiGetPassword(UIPASSWORD_GLOBAL,NULL,&Password,NULL); + uiGetPassword(UIPASSWORD_GLOBAL,L"",&Password,NULL); eprintf(L"\n"); } else @@ -790,15 +870,15 @@ break; case 'I': ProhibitConsoleInput(); - wcsncpyz(UseStdin,Switch[2] ? Switch+2:L"stdin",ASIZE(UseStdin)); + UseStdin=Switch[2] ? Switch+2:L"stdin"; break; case 'L': if (IsDigit(Switch[2])) - FileSizeLess=atoilw(Switch+2); + FileSizeLess=GetVolSize(Switch+2,1); break; case 'M': if (IsDigit(Switch[2])) - FileSizeMore=atoilw(Switch+2); + FileSizeMore=GetVolSize(Switch+2,1); break; case 'C': { @@ -913,8 +993,8 @@ } break; case 'W': - wcsncpyz(TempPath,Switch+1,ASIZE(TempPath)); - AddEndSlash(TempPath,ASIZE(TempPath)); + TempPath=Switch+1; + AddEndSlash(TempPath); break; case 'Y': AllYes=true; @@ -923,10 +1003,10 @@ if (Switch[1]==0) { // If comment file is not specified, we read data from stdin. - wcsncpyz(CommentFile,L"stdin",ASIZE(CommentFile)); + CommentFile=L"stdin"; } else - wcsncpyz(CommentFile,Switch+1,ASIZE(CommentFile)); + CommentFile=Switch+1; break; case '?' : OutHelp(RARX_SUCCESS); @@ -943,7 +1023,6 @@ void CommandData::BadSwitch(const wchar *Switch) { mprintf(St(MUnknownOption),Switch); - mprintf(L"\n"); ErrHandler.Exit(RARX_USERERROR); } #endif @@ -954,34 +1033,36 @@ #ifndef SFX_MODULE const wchar *SingleCharCommands=L"FUADPXETK"; - if (Command[0]!=0 && Command[1]!=0 && wcschr(SingleCharCommands,Command[0])!=NULL || *ArcName==0) - Out... [truncated message content] |