UnRAR: Use our own buffers and memory allocations

pull/2542/head
philsmd 4 years ago
parent 9f380afa13
commit c9c03dd191
No known key found for this signature in database
GPG Key ID: 4F25D016D9D6A8AF

@ -4,7 +4,7 @@
class BitInput class BitInput
{ {
public: 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 InAddr; // Curent byte position in the buffer.
int InBit; // Current bit position in the current byte. int InBit; // Current bit position in the current byte.

@ -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(); int MaxOrder=UnpackRead->GetChar();
bool Reset=(MaxOrder & 0x20)!=0; bool Reset=(MaxOrder & 0x20)!=0;
int MaxMB; int MaxMB;
if (Reset) if (Reset)
{
MaxMB=UnpackRead->GetChar(); MaxMB=UnpackRead->GetChar();
if (MaxMB>128) return(false);
}
else else
if (SubAlloc.GetAllocatedMemory()==0) if (SubAlloc.GetAllocatedMemory()==0)
return(false); return(false);
@ -590,6 +593,7 @@ bool ModelPPM::DecodeInit(Unpack *UnpackRead,int &EscChar)
SubAlloc.StopSubAllocator(); SubAlloc.StopSubAllocator();
return(false); return(false);
} }
SubAlloc.SetHeapStartFixed(hcppm);
SubAlloc.StartSubAllocator(MaxMB+1); SubAlloc.StartSubAllocator(MaxMB+1);
StartModelRare(MaxOrder); StartModelRare(MaxOrder);
} }

@ -115,7 +115,7 @@ class ModelPPM : RARPPM_DEF
public: public:
ModelPPM(); ModelPPM();
void CleanUp(); // reset PPM variables after data error void CleanUp(); // reset PPM variables after data error
bool DecodeInit(Unpack *UnpackRead,int &EscChar); bool DecodeInit(Unpack *UnpackRead,int &EscChar,byte *hcppm);
int DecodeChar(); int DecodeChar();
}; };

@ -201,7 +201,7 @@ void ComprDataIO::UnpWrite(byte *Addr,size_t Count)
{ {
if (Count <= UnpackToMemorySize) if (Count <= UnpackToMemorySize)
{ {
memcpy(UnpackToMemoryAddr,Addr,Count); //memcpy(UnpackToMemoryAddr,Addr,Count);
UnpackToMemoryAddr+=Count; UnpackToMemoryAddr+=Count;
UnpackToMemorySize-=Count; UnpackToMemorySize-=Count;
} }

@ -71,7 +71,7 @@ void SubAllocator::StopSubAllocator()
if ( SubAllocatorSize ) if ( SubAllocatorSize )
{ {
SubAllocatorSize=0; 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 // units: one as reserve for HeapEnd overflow checks and another
// to provide the space to correctly align UnitsStart. // to provide the space to correctly align UnitsStart.
uint AllocSize=t/FIXED_UNIT_SIZE*UNIT_SIZE+2*UNIT_SIZE; 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(); ErrHandler.MemoryError();
return false; return false;

@ -80,6 +80,9 @@ class SubAllocator
long GetAllocatedMemory() {return(SubAllocatorSize);} long GetAllocatedMemory() {return(SubAllocatorSize);}
byte *pText, *UnitsStart,*HeapEnd,*FakeUnitsStart; byte *pText, *UnitsStart,*HeapEnd,*FakeUnitsStart;
byte *HeapStartFixed;
void SetHeapStartFixed(byte *p) {HeapStartFixed=p;}
}; };

@ -16,7 +16,7 @@
#include "unpack50frag.cpp" #include "unpack50frag.cpp"
Unpack::Unpack(ComprDataIO *DataIO) Unpack::Unpack(ComprDataIO *DataIO)
:Inp(true),VMCodeInp(true) :Inp(false),VMCodeInp(false)
{ {
UnpIO=DataIO; UnpIO=DataIO;
Window=NULL; Window=NULL;
@ -49,8 +49,8 @@ Unpack::~Unpack()
{ {
InitFilters30(false); InitFilters30(false);
if (Window!=NULL) //if (Window!=NULL)
free(Window); // free(Window);
#ifdef RAR_SMP #ifdef RAR_SMP
delete UnpThreadPool; delete UnpThreadPool;
delete[] ReadBufMT; delete[] ReadBufMT;
@ -69,6 +69,21 @@ void Unpack::SetThreads(uint Threads)
} }
#endif #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) void Unpack::Init(size_t WinSize,bool Solid)
{ {
@ -102,7 +117,7 @@ void Unpack::Init(size_t WinSize,bool Solid)
if (Grow && Fragmented) if (Grow && Fragmented)
throw std::bad_alloc(); throw std::bad_alloc();
byte *NewWindow=Fragmented ? NULL : (byte *)malloc(WinSize); byte *NewWindow=Fragmented ? NULL : (byte *)hcwin;
if (NewWindow==NULL) if (NewWindow==NULL)
if (Grow || WinSize<0x1000000) if (Grow || WinSize<0x1000000)
@ -115,7 +130,7 @@ void Unpack::Init(size_t WinSize,bool Solid)
{ {
if (Window!=NULL) // If allocated by preceding files. if (Window!=NULL) // If allocated by preceding files.
{ {
free(Window); //free(Window);
Window=NULL; Window=NULL;
} }
FragWindow.Init(WinSize); 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 // Clean the window to generate the same output when unpacking corrupt
// RAR files, which may access unused areas of sliding dictionary. // 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. // 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. // 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++) for (size_t I=1;I<=MaxWinSize;I++)
NewWindow[(UnpPtr-I)&(WinSize-1)]=Window[(UnpPtr-I)&(MaxWinSize-1)]; NewWindow[(UnpPtr-I)&(WinSize-1)]=Window[(UnpPtr-I)&(MaxWinSize-1)];
if (Window!=NULL) //if (Window!=NULL)
free(Window); // free(Window);
Window=NewWindow; Window=NewWindow;
} }

@ -375,6 +375,9 @@ class Unpack:PackDef
public: public:
Unpack(ComprDataIO *DataIO); Unpack(ComprDataIO *DataIO);
~Unpack(); ~Unpack();
void SetWin(void *win);
void SetPPM(void *PPM);
void SetExternalBuffer(byte *InpBuf,byte *VMCodeBuf);
void Init(size_t WinSize,bool Solid); void Init(size_t WinSize,bool Solid);
void DoUnpack(uint Method,bool Solid); void DoUnpack(uint Method,bool Solid);
bool IsFileExtracted() {return(FileExtracted);} bool IsFileExtracted() {return(FileExtracted);}
@ -386,6 +389,9 @@ class Unpack:PackDef
void UnpackDecode(UnpackThreadData &D); void UnpackDecode(UnpackThreadData &D);
#endif #endif
byte *hcwin;
byte *hcppm;
size_t MaxWinSize; size_t MaxWinSize;
size_t MaxWinMask; size_t MaxWinMask;

@ -637,7 +637,7 @@ bool Unpack::ReadTables30()
if (BitField & 0x8000) if (BitField & 0x8000)
{ {
UnpBlockType=BLOCK_PPM; UnpBlockType=BLOCK_PPM;
return(PPM.DecodeInit(this,PPMEscChar)); return(PPM.DecodeInit(this,PPMEscChar,hcppm));
} }
UnpBlockType=BLOCK_LZ; UnpBlockType=BLOCK_LZ;

Loading…
Cancel
Save