Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion unrar/unrar/arccmt.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -111,7 +111,7 @@ bool Archive::GetComment(Array<wchar> *CmtData)
// 4x memory for OEM to UTF-8 output here.
OemToCharA((char *)&CmtRaw[0],(char *)&CmtRaw[0]);
#endif
CharToWide((char *)&CmtRaw[0],CmtData->Addr(0),CmtLength);
CharToWide((char *)&CmtRaw[0],CmtData->Addr(0),CmtData->Size());
CmtData->Alloc(wcslen(CmtData->Addr(0)));
}
#endif
Expand Down
75 changes: 68 additions & 7 deletions unrar/unrar/archive.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,10 @@
#include "arccmt.cpp"


#ifdef USE_ARCMEM
#include "arcmem.cpp"
#endif

Archive::Archive(RAROptions *InitCmd)
{
Cmd=NULL; // Just in case we'll have an exception in 'new' below.
Expand Down Expand Up @@ -48,6 +52,10 @@ Archive::Archive(RAROptions *InitCmd)

SilentOpen=false;

#ifdef USE_QOPEN
ProhibitQOpen=false;
#endif

}


Expand Down Expand Up @@ -294,39 +302,92 @@ uint Archive::FullHeaderSize(size_t Size)



#ifdef USE_QOPEN
bool Archive::Open(const wchar *Name,uint Mode)
{
#ifdef USE_QOPEN
// Important if we reuse Archive object and it has virtual QOpen
// file position not matching real. For example, for 'l -v volname'.
QOpen.Unload();
#endif

#ifdef USE_ARCMEM
if (Cmd->ArcInMem)
{
wcsncpyz(FileName,Name,ASIZE(FileName));
ArcMem.Load(Cmd->ArcMemData,Cmd->ArcMemSize);
Cmd->SetArcInMem(NULL,0); // Return in memory data for first volume only, not for next volumes.
return true;
}
#endif

return File::Open(Name,Mode);
}



bool Archive::Close()
{
#ifdef USE_ARCMEM
if (ArcMem.Unload())
return true;
#endif
return File::Close();
}



int Archive::Read(void *Data,size_t Size)
{
size_t Result;
if (QOpen.Read(Data,Size,Result))
return (int)Result;
#ifdef USE_QOPEN
size_t QResult;
if (QOpen.Read(Data,Size,QResult))
return (int)QResult;
#endif
#ifdef USE_ARCMEM
size_t AResult;
if (ArcMem.Read(Data,Size,AResult))
return (int)AResult;
#endif
return File::Read(Data,Size);
}


void Archive::Seek(int64 Offset,int Method)
{
if (!QOpen.Seek(Offset,Method))
File::Seek(Offset,Method);
#ifdef USE_QOPEN
if (QOpen.Seek(Offset,Method))
return;
#endif
#ifdef USE_ARCMEM
if (ArcMem.Seek(Offset,Method))
return;
#endif
File::Seek(Offset,Method);
}


int64 Archive::Tell()
{
#ifdef USE_QOPEN
int64 QPos;
if (QOpen.Tell(&QPos))
return QPos;
#endif
#ifdef USE_ARCMEM
int64 APos;
if (ArcMem.Tell(&APos))
return APos;
#endif
return File::Tell();
}
#endif



bool Archive::IsOpened()
{
#ifdef USE_ARCMEM
if (ArcMem.IsLoaded())
return true;
#endif
return File::IsOpened();
};
9 changes: 8 additions & 1 deletion unrar/unrar/archive.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -55,6 +55,10 @@ class Archive:public File
bool SilentOpen;
#ifdef USE_QOPEN
QuickOpen QOpen;
bool ProhibitQOpen;
#endif
#ifdef USE_ARCMEM
ArcMemory ArcMem;
#endif
public:
Archive(RAROptions *InitCmd=NULL);
Expand Down Expand Up @@ -89,12 +93,15 @@ class Archive:public File
#if 0
void GetRecoveryInfo(bool Required,int64 *Size,int *Percent);
#endif
#ifdef USE_QOPEN
bool Open(const wchar *Name,uint Mode=FMF_READ);
bool Close();
int Read(void *Data,size_t Size);
void Seek(int64 Offset,int Method);
int64 Tell();
bool IsOpened();
#ifdef USE_QOPEN
void QOpenUnload() {QOpen.Unload();}
void SetProhibitQOpen(bool Mode) {ProhibitQOpen=Mode;}
#endif

BaseBlock ShortBlock;
Expand Down
62 changes: 62 additions & 0 deletions unrar/unrar/arcmem.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,62 @@
ArcMemory::ArcMemory()
{
Loaded=false;
SeekPos=0;
}


void ArcMemory::Load(const byte *Data,size_t Size)
{
ArcData.Alloc(Size);
memcpy(&ArcData[0],Data,Size);
Loaded=true;
SeekPos=0;
}


bool ArcMemory::Unload()
{
if (!Loaded)
return false;
Loaded=false;
return true;
}


bool ArcMemory::Read(void *Data,size_t Size,size_t &Result)
{
if (!Loaded)
return false;
Result=(size_t)Min(Size,ArcData.Size()-SeekPos);
memcpy(Data,&ArcData[(size_t)SeekPos],Result);
SeekPos+=Result;
return true;
}


bool ArcMemory::Seek(int64 Offset,int Method)
{
if (!Loaded)
return false;
if (Method==SEEK_SET)
SeekPos=Min(Offset,ArcData.Size());
else
if (Method==SEEK_CUR || Method==SEEK_END)
{
if (Method==SEEK_END)
SeekPos=ArcData.Size();
SeekPos+=(uint64)Offset;
if (SeekPos>ArcData.Size())
SeekPos=Offset<0 ? 0 : ArcData.Size();
}
return true;
}


bool ArcMemory::Tell(int64 *Pos)
{
if (!Loaded)
return false;
*Pos=SeekPos;
return true;
}
22 changes: 22 additions & 0 deletions unrar/unrar/arcmem.hpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
#ifndef _RAR_ARCMEM_
#define _RAR_ARCMEM_

// Memory interface for software fuzzers.

class ArcMemory
{
private:
bool Loaded;
Array<byte> ArcData;
uint64 SeekPos;
public:
ArcMemory();
void Load(const byte *Data,size_t Size);
bool Unload();
bool IsLoaded() {return Loaded;}
bool Read(void *Data,size_t Size,size_t &Result);
bool Seek(int64 Offset,int Method);
bool Tell(int64 *Pos);
};

#endif
4 changes: 2 additions & 2 deletions unrar/unrar/arcread.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -734,7 +734,7 @@ size_t Archive::ReadHeader50()
ProcessExtra50(&Raw,(size_t)ExtraSize,&MainHead);

#ifdef USE_QOPEN
if (MainHead.Locator && MainHead.QOpenOffset>0 && Cmd->QOpenMode!=QOPEN_NONE)
if (!ProhibitQOpen && MainHead.Locator && MainHead.QOpenOffset>0 && Cmd->QOpenMode!=QOPEN_NONE)
{
// We seek to QO block in the end of archive when processing
// QOpen.Load, so we need to preserve current block positions
Expand Down Expand Up @@ -1070,7 +1070,7 @@ void Archive::ProcessExtra50(RawRead *Raw,size_t ExtraSize,BaseBlock *bb)

wchar VerText[20];
swprintf(VerText,ASIZE(VerText),L";%u",Version);
wcsncatz(FileHead.FileName,VerText,ASIZE(FileHead.FileName));
wcsncatz(hd->FileName,VerText,ASIZE(hd->FileName));
}
}
break;
Expand Down
8 changes: 4 additions & 4 deletions unrar/unrar/cmddata.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -96,7 +96,7 @@ void CommandData::ParseArg(wchar *Arg)
else
if (*Command==0)
{
wcsncpy(Command,Arg,ASIZE(Command));
wcsncpyz(Command,Arg,ASIZE(Command));


*Command=toupperw(*Command);
Expand Down Expand Up @@ -1208,8 +1208,8 @@ int CommandData::IsProcessFile(FileHeader &FileHead,bool *ExactMatch,int MatchTy
{
if (MatchedArg!=NULL && MatchedArgSize>0)
*MatchedArg=0;
if (wcslen(FileHead.FileName)>=NM)
return 0;
// if (wcslen(FileHead.FileName)>=NM)
// return 0;
bool Dir=FileHead.Dir;
if (ExclCheck(FileHead.FileName,Dir,false,true))
return 0;
Expand Down Expand Up @@ -1267,7 +1267,7 @@ void CommandData::ProcessCommand()
wcsncpyz(ArcName,Name,ASIZE(ArcName));
}

if (wcschr(L"AFUMD",*Command)==NULL)
if (wcschr(L"AFUMD",*Command)==NULL && !ArcInMem)
{
if (GenerateArcName)
GenerateArchiveName(ArcName,ASIZE(ArcName),GenerateMask,false);
Expand Down
9 changes: 9 additions & 0 deletions unrar/unrar/compress.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,16 @@
class PackDef
{
public:
// Maximum LZ match length we can encode even for short distances.
static const uint MAX_LZ_MATCH = 0x1001;

// We increment LZ match length for longer distances, because shortest
// matches are not allowed for them. Maximum length increment is 3
// for distances larger than 256KB (0x40000). Here we define the maximum
// incremented LZ match. Normally packer does not use it, but we must be
// ready to process it in corrupt archives.
static const uint MAX_INC_LZ_MATCH = MAX_LZ_MATCH + 3;

static const uint MAX3_LZ_MATCH = 0x101; // Maximum match length for RAR v3.
static const uint LOW_DIST_REP_COUNT = 16;

Expand Down
4 changes: 2 additions & 2 deletions unrar/unrar/file.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -75,7 +75,7 @@ class File
bool Create(const wchar *Name,uint Mode=FMF_UPDATE|FMF_SHAREREAD);
void TCreate(const wchar *Name,uint Mode=FMF_UPDATE|FMF_SHAREREAD);
bool WCreate(const wchar *Name,uint Mode=FMF_UPDATE|FMF_SHAREREAD);
bool Close();
virtual bool Close();
bool Delete();
bool Rename(const wchar *NewName);
bool Write(const void *Data,size_t Size);
Expand All @@ -93,7 +93,7 @@ class File
void SetCloseFileTime(RarTime *ftm,RarTime *fta=NULL);
static void SetCloseFileTimeByName(const wchar *Name,RarTime *ftm,RarTime *fta);
void GetOpenFileTime(RarTime *ft);
bool IsOpened() {return hFile!=FILE_BAD_HANDLE;};
virtual bool IsOpened() {return hFile!=FILE_BAD_HANDLE;};
int64 FileLength();
void SetHandleType(FILE_HANDLETYPE Type) {HandleType=Type;}
FILE_HANDLETYPE GetHandleType() {return HandleType;}
Expand Down
2 changes: 1 addition & 1 deletion unrar/unrar/makefile
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@

# Linux using GCC
CXX=c++
CXXFLAGS=-O2
CXXFLAGS=-O2 -Wno-logical-op-parentheses -Wno-switch -Wno-dangling-else
LIBFLAGS=-fPIC
DEFINES=-D_FILE_OFFSET_BITS=64 -D_LARGEFILE_SOURCE -DRAR_SMP
STRIP=strip
Expand Down
16 changes: 15 additions & 1 deletion unrar/unrar/options.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -85,10 +85,24 @@ class RAROptions
bool InclAttrSet;
size_t WinSize;
wchar TempPath[NM];
#ifdef USE_QOPEN
wchar SFXModule[NM];

#ifdef USE_QOPEN
QOPEN_MODE QOpenMode;
#endif

bool ArcInMem;
#ifdef USE_ARCMEM
void SetArcInMem(byte *Data,size_t Size)
{
ArcMemData=Data;
ArcMemSize=Size;
ArcInMem=Data!=NULL && Size>0;
}
byte *ArcMemData;
size_t ArcMemSize;
#endif

bool ConfigDisabled; // Switch -cfg-.
wchar ExtrPath[NM];
wchar CommentFile[NM];
Expand Down
17 changes: 15 additions & 2 deletions unrar/unrar/qopen.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -61,14 +61,27 @@ void QuickOpen::Close()

void QuickOpen::Load(uint64 BlockPos)
{
if (!Loaded) // If loading the first time, perform additional intialization.
if (!Loaded)
{
// If loading for the first time, perform additional intialization.
SeekPos=Arc->Tell();
UnsyncSeekPos=false;

SaveFilePos SavePos(*Arc);
Arc->Seek(BlockPos,SEEK_SET);
if (Arc->ReadHeader()==0 || Arc->GetHeaderType()!=HEAD_SERVICE ||

// If BlockPos points to original main header, we'll have the infinite
// recursion, because ReadHeader() for main header will attempt to load
// QOpen and call QuickOpen::Load again. If BlockPos points to long chain
// of other main headers, we'll have multiple recursive calls of this
// function wasting resources. So we prohibit QOpen temporarily to
// prevent this. ReadHeader() calls QOpen.Init and sets MainHead Locator
// and QOpenOffset fields, so we cannot use them to prohibit QOpen.
Arc->SetProhibitQOpen(true);
size_t ReadSize=Arc->ReadHeader();
Arc->SetProhibitQOpen(false);

if (ReadSize==0 || Arc->GetHeaderType()!=HEAD_SERVICE ||
!Arc->SubHead.CmpName(SUBHEAD_TYPE_QOPEN))
return;
QLHeaderPos=Arc->CurBlockPos;
Expand Down
Loading