From c9c03dd1919319ca9a54161d9d6fdb30aff55494 Mon Sep 17 00:00:00 2001 From: philsmd Date: Tue, 8 Sep 2020 10:46:44 +0200 Subject: [PATCH] UnRAR: Use our own buffers and memory allocations --- deps/unrar/getbits.hpp | 2 +- deps/unrar/model.cpp | 6 +++++- deps/unrar/model.hpp | 2 +- deps/unrar/rdwrfn.cpp | 2 +- deps/unrar/suballoc.cpp | 5 +++-- deps/unrar/suballoc.hpp | 3 +++ deps/unrar/unpack.cpp | 31 +++++++++++++++++++++++-------- deps/unrar/unpack.hpp | 6 ++++++ deps/unrar/unpack30.cpp | 2 +- 9 files changed, 44 insertions(+), 15 deletions(-) diff --git a/deps/unrar/getbits.hpp b/deps/unrar/getbits.hpp index 2e151da9a..7fbdfdf30 100644 --- a/deps/unrar/getbits.hpp +++ b/deps/unrar/getbits.hpp @@ -4,7 +4,7 @@ class BitInput { public: - enum BufferSize {MAX_SIZE=0x8000}; // Size of input buffer. + enum BufferSize {MAX_SIZE=0x50000}; // Size of input buffer. int InAddr; // Curent byte position in the buffer. int InBit; // Current bit position in the current byte. diff --git a/deps/unrar/model.cpp b/deps/unrar/model.cpp index 83391c5a4..3aa29b245 100644 --- a/deps/unrar/model.cpp +++ b/deps/unrar/model.cpp @@ -566,14 +566,17 @@ void ModelPPM::CleanUp() } -bool ModelPPM::DecodeInit(Unpack *UnpackRead,int &EscChar) +bool ModelPPM::DecodeInit(Unpack *UnpackRead,int &EscChar,byte *hcppm) { int MaxOrder=UnpackRead->GetChar(); bool Reset=(MaxOrder & 0x20)!=0; int MaxMB; if (Reset) + { MaxMB=UnpackRead->GetChar(); + if (MaxMB>128) return(false); + } else if (SubAlloc.GetAllocatedMemory()==0) return(false); @@ -590,6 +593,7 @@ bool ModelPPM::DecodeInit(Unpack *UnpackRead,int &EscChar) SubAlloc.StopSubAllocator(); return(false); } + SubAlloc.SetHeapStartFixed(hcppm); SubAlloc.StartSubAllocator(MaxMB+1); StartModelRare(MaxOrder); } diff --git a/deps/unrar/model.hpp b/deps/unrar/model.hpp index 52abc89b3..c7444de33 100644 --- a/deps/unrar/model.hpp +++ b/deps/unrar/model.hpp @@ -115,7 +115,7 @@ class ModelPPM : RARPPM_DEF public: ModelPPM(); void CleanUp(); // reset PPM variables after data error - bool DecodeInit(Unpack *UnpackRead,int &EscChar); + bool DecodeInit(Unpack *UnpackRead,int &EscChar,byte *hcppm); int DecodeChar(); }; diff --git a/deps/unrar/rdwrfn.cpp b/deps/unrar/rdwrfn.cpp index 09cd9e6a7..5c85753da 100644 --- a/deps/unrar/rdwrfn.cpp +++ b/deps/unrar/rdwrfn.cpp @@ -201,7 +201,7 @@ void ComprDataIO::UnpWrite(byte *Addr,size_t Count) { if (Count <= UnpackToMemorySize) { - memcpy(UnpackToMemoryAddr,Addr,Count); + //memcpy(UnpackToMemoryAddr,Addr,Count); UnpackToMemoryAddr+=Count; UnpackToMemorySize-=Count; } diff --git a/deps/unrar/suballoc.cpp b/deps/unrar/suballoc.cpp index 07d32859f..bdf2b06f0 100644 --- a/deps/unrar/suballoc.cpp +++ b/deps/unrar/suballoc.cpp @@ -71,7 +71,7 @@ void SubAllocator::StopSubAllocator() if ( SubAllocatorSize ) { SubAllocatorSize=0; - free(HeapStart); + //free(HeapStart); } } @@ -88,7 +88,8 @@ bool SubAllocator::StartSubAllocator(int SASize) // units: one as reserve for HeapEnd overflow checks and another // to provide the space to correctly align UnitsStart. uint AllocSize=t/FIXED_UNIT_SIZE*UNIT_SIZE+2*UNIT_SIZE; - if ((HeapStart=(byte *)malloc(AllocSize)) == NULL) + //if ((HeapStart=(byte *)malloc(AllocSize)) == NULL) + if ((HeapStart=(byte *)HeapStartFixed) == NULL) { ErrHandler.MemoryError(); return false; diff --git a/deps/unrar/suballoc.hpp b/deps/unrar/suballoc.hpp index 2a1d1320e..fec0aac2a 100644 --- a/deps/unrar/suballoc.hpp +++ b/deps/unrar/suballoc.hpp @@ -80,6 +80,9 @@ class SubAllocator long GetAllocatedMemory() {return(SubAllocatorSize);} byte *pText, *UnitsStart,*HeapEnd,*FakeUnitsStart; + + byte *HeapStartFixed; + void SetHeapStartFixed(byte *p) {HeapStartFixed=p;} }; diff --git a/deps/unrar/unpack.cpp b/deps/unrar/unpack.cpp index 037c35546..5f577d85d 100644 --- a/deps/unrar/unpack.cpp +++ b/deps/unrar/unpack.cpp @@ -16,7 +16,7 @@ #include "unpack50frag.cpp" Unpack::Unpack(ComprDataIO *DataIO) -:Inp(true),VMCodeInp(true) +:Inp(false),VMCodeInp(false) { UnpIO=DataIO; Window=NULL; @@ -49,8 +49,8 @@ Unpack::~Unpack() { InitFilters30(false); - if (Window!=NULL) - free(Window); + //if (Window!=NULL) + // free(Window); #ifdef RAR_SMP delete UnpThreadPool; delete[] ReadBufMT; @@ -69,6 +69,21 @@ void Unpack::SetThreads(uint Threads) } #endif +void Unpack::SetWin(void *win) +{ + hcwin=(byte *)win; +} + +void Unpack::SetPPM(void *ppm) +{ + hcppm=(byte *)ppm; +} + +void Unpack::SetExternalBuffer(byte *InpBuf,byte *VMCodeBuf) +{ + Inp.SetExternalBuffer(InpBuf); + VMCodeInp.SetExternalBuffer(VMCodeBuf); +} void Unpack::Init(size_t WinSize,bool Solid) { @@ -102,7 +117,7 @@ void Unpack::Init(size_t WinSize,bool Solid) if (Grow && Fragmented) throw std::bad_alloc(); - byte *NewWindow=Fragmented ? NULL : (byte *)malloc(WinSize); + byte *NewWindow=Fragmented ? NULL : (byte *)hcwin; if (NewWindow==NULL) if (Grow || WinSize<0x1000000) @@ -115,7 +130,7 @@ void Unpack::Init(size_t WinSize,bool Solid) { if (Window!=NULL) // If allocated by preceding files. { - free(Window); + //free(Window); Window=NULL; } FragWindow.Init(WinSize); @@ -126,7 +141,7 @@ void Unpack::Init(size_t WinSize,bool Solid) { // Clean the window to generate the same output when unpacking corrupt // RAR files, which may access unused areas of sliding dictionary. - memset(NewWindow,0,WinSize); + //memset(NewWindow,0,WinSize); // If Window is not NULL, it means that window size has grown. // In solid streams we need to copy data to a new window in such case. @@ -136,8 +151,8 @@ void Unpack::Init(size_t WinSize,bool Solid) for (size_t I=1;I<=MaxWinSize;I++) NewWindow[(UnpPtr-I)&(WinSize-1)]=Window[(UnpPtr-I)&(MaxWinSize-1)]; - if (Window!=NULL) - free(Window); + //if (Window!=NULL) + // free(Window); Window=NewWindow; } diff --git a/deps/unrar/unpack.hpp b/deps/unrar/unpack.hpp index 75dadb0e0..f76ddcc86 100644 --- a/deps/unrar/unpack.hpp +++ b/deps/unrar/unpack.hpp @@ -375,6 +375,9 @@ class Unpack:PackDef public: Unpack(ComprDataIO *DataIO); ~Unpack(); + void SetWin(void *win); + void SetPPM(void *PPM); + void SetExternalBuffer(byte *InpBuf,byte *VMCodeBuf); void Init(size_t WinSize,bool Solid); void DoUnpack(uint Method,bool Solid); bool IsFileExtracted() {return(FileExtracted);} @@ -386,6 +389,9 @@ class Unpack:PackDef void UnpackDecode(UnpackThreadData &D); #endif + byte *hcwin; + byte *hcppm; + size_t MaxWinSize; size_t MaxWinMask; diff --git a/deps/unrar/unpack30.cpp b/deps/unrar/unpack30.cpp index 6a8efa23b..346bcf970 100644 --- a/deps/unrar/unpack30.cpp +++ b/deps/unrar/unpack30.cpp @@ -637,7 +637,7 @@ bool Unpack::ReadTables30() if (BitField & 0x8000) { UnpBlockType=BLOCK_PPM; - return(PPM.DecodeInit(this,PPMEscChar)); + return(PPM.DecodeInit(this,PPMEscChar,hcppm)); } UnpBlockType=BLOCK_LZ;