1 #include "rar.hpp"
2 
3 #include "coder.cpp"
4 #include "suballoc.cpp"
5 #include "model.cpp"
6 #ifndef SFX_MODULE
7 #include "unpack15.cpp"
8 #include "unpack20.cpp"
9 #endif
10 
Unpack(ComprDataIO * DataIO)11 Unpack::Unpack(ComprDataIO *DataIO)
12 {
13   UnpIO=DataIO;
14   Window=NULL;
15   ExternalWindow=false;
16   Suspended=false;
17   UnpAllBuf=false;
18   UnpSomeRead=false;
19 }
20 
21 
~Unpack()22 Unpack::~Unpack()
23 {
24   if (Window!=NULL && !ExternalWindow)
25     delete[] Window;
26   InitFilters();
27 }
28 
29 
Init(byte * Window)30 void Unpack::Init(byte *Window)
31 {
32   if (Window==NULL)
33   {
34     Unpack::Window=new byte[MAXWINSIZE];
35 
36     // Clean the window to generate the same output when unpacking corrupt
37     // RAR files, which may access to unused areas of sliding dictionary.
38     memset(Unpack::Window,0,MAXWINSIZE);
39 #ifndef ALLOW_EXCEPTIONS
40     if (Unpack::Window==NULL)
41       ErrHandler.MemoryError();
42 #endif
43   }
44   else
45   {
46     Unpack::Window=Window;
47     ExternalWindow=true;
48   }
49   UnpInitData(false);
50 
51 #ifndef SFX_MODULE
52   // RAR 1.5 decompression initialization
53   OldUnpInitData(false);
54   InitHuff();
55 #endif
56 }
57 
58 
DoUnpack(int Method,bool Solid)59 void Unpack::DoUnpack(int Method,bool Solid)
60 {
61   switch(Method)
62   {
63 #ifndef SFX_MODULE
64     case 15: // rar 1.5 compression
65       Unpack15(Solid);
66       break;
67     case 20: // rar 2.x compression
68     case 26: // files larger than 2GB
69       Unpack20(Solid);
70       break;
71 #endif
72     case 29: // rar 3.x compression
73     case 36: // alternative hash
74       Unpack29(Solid);
75       break;
76   }
77 }
78 
79 
InsertOldDist(unsigned int Distance)80 inline void Unpack::InsertOldDist(unsigned int Distance)
81 {
82   OldDist[3]=OldDist[2];
83   OldDist[2]=OldDist[1];
84   OldDist[1]=OldDist[0];
85   OldDist[0]=Distance;
86 }
87 
88 
InsertLastMatch(unsigned int Length,unsigned int Distance)89 inline void Unpack::InsertLastMatch(unsigned int Length,unsigned int Distance)
90 {
91   LastDist=Distance;
92   LastLength=Length;
93 }
94 
95 
CopyString(uint Length,uint Distance)96 _forceinline void Unpack::CopyString(uint Length,uint Distance)
97 {
98   uint SrcPtr=UnpPtr-Distance;
99   if (SrcPtr<MAXWINSIZE-MAX_LZ_MATCH && UnpPtr<MAXWINSIZE-MAX_LZ_MATCH)
100   {
101     // If we are not close to end of window, we do not need to waste time
102     // to "& MAXWINMASK" pointer protection.
103 
104     byte *Src=Window+SrcPtr;
105     byte *Dest=Window+UnpPtr;
106     UnpPtr+=Length;
107 
108     while (Length>=8)
109     {
110       // Unroll the loop for 8 byte and longer strings.
111       Dest[0]=Src[0];
112       Dest[1]=Src[1];
113       Dest[2]=Src[2];
114       Dest[3]=Src[3];
115       Dest[4]=Src[4];
116       Dest[5]=Src[5];
117       Dest[6]=Src[6];
118       Dest[7]=Src[7];
119       Src+=8;
120       Dest+=8;
121       Length-=8;
122     }
123 
124     // Unroll the loop for 0 - 7 bytes left. Note that we use nested "if"s.
125     if (Length>0) { Dest[0]=Src[0];
126     if (Length>1) { Dest[1]=Src[1];
127     if (Length>2) { Dest[2]=Src[2];
128     if (Length>3) { Dest[3]=Src[3];
129     if (Length>4) { Dest[4]=Src[4];
130     if (Length>5) { Dest[5]=Src[5];
131     if (Length>6) { Dest[6]=Src[6]; } } } } } } } // Close all nested "if"s.
132   }
133   else
134     while (Length--) // Slow copying with all possible precautions.
135     {
136       Window[UnpPtr]=Window[SrcPtr++ & MAXWINMASK];
137       UnpPtr=(UnpPtr+1) & MAXWINMASK;
138     }
139 }
140 
141 
DecodeNumber(DecodeTable * Dec)142 _forceinline uint Unpack::DecodeNumber(DecodeTable *Dec)
143 {
144   // Left aligned 15 bit length raw bit field.
145   uint BitField=getbits() & 0xfffe;
146 
147   if (BitField<Dec->DecodeLen[Dec->QuickBits])
148   {
149     uint Code=BitField>>(16-Dec->QuickBits);
150     addbits(Dec->QuickLen[Code]);
151     return Dec->QuickNum[Code];
152   }
153 
154   // Detect the real bit length for current code.
155   uint Bits=15;
156   for (uint I=Dec->QuickBits+1;I<15;I++)
157     if (BitField<Dec->DecodeLen[I])
158     {
159       Bits=I;
160       break;
161     }
162 
163   addbits(Bits);
164 
165   // Calculate the distance from the start code for current bit length.
166   uint Dist=BitField-Dec->DecodeLen[Bits-1];
167 
168   // Start codes are left aligned, but we need the normal right aligned
169   // number. So we shift the distance to the right.
170   Dist>>=(16-Bits);
171 
172   // Now we can calculate the position in the code list. It is the sum
173   // of first position for current bit length and right aligned distance
174   // between our bit field and start code for current bit length.
175   uint Pos=Dec->DecodePos[Bits]+Dist;
176 
177   // Out of bounds safety check required for damaged archives.
178   if (Pos>=Dec->MaxNum)
179     Pos=0;
180 
181   // Convert the position in the code list to position in alphabet
182   // and return it.
183   return(Dec->DecodeNum[Pos]);
184 }
185 
186 
187 // We use it instead of direct PPM.DecodeChar call to be sure that
188 // we reset PPM structures in case of corrupt data. It is important,
189 // because these structures can be invalid after PPM.DecodeChar returned -1.
SafePPMDecodeChar()190 inline int Unpack::SafePPMDecodeChar()
191 {
192   int Ch=PPM.DecodeChar();
193   if (Ch==-1)              // Corrupt PPM data found.
194   {
195     PPM.CleanUp();         // Reset possibly corrupt PPM data structures.
196     UnpBlockType=BLOCK_LZ; // Set faster and more fail proof LZ mode.
197   }
198   return(Ch);
199 }
200 
201 
Unpack29(bool Solid)202 void Unpack::Unpack29(bool Solid)
203 {
204   static unsigned char LDecode[]={0,1,2,3,4,5,6,7,8,10,12,14,16,20,24,28,32,40,48,56,64,80,96,112,128,160,192,224};
205   static unsigned char LBits[]=  {0,0,0,0,0,0,0,0,1, 1, 1, 1, 2, 2, 2, 2, 3, 3, 3, 3, 4, 4, 4,  4,  5,  5,  5,  5};
206   static int DDecode[DC];
207   static byte DBits[DC];
208   static int DBitLengthCounts[]= {4,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,14,0,12};
209   static unsigned char SDDecode[]={0,4,8,16,32,64,128,192};
210   static unsigned char SDBits[]=  {2,2,3, 4, 5, 6,  6,  6};
211   unsigned int Bits;
212 
213   if (DDecode[1]==0)
214   {
215     int Dist=0,BitLength=0,Slot=0;
216     for (int I=0;I<sizeof(DBitLengthCounts)/sizeof(DBitLengthCounts[0]);I++,BitLength++)
217       for (int J=0;J<DBitLengthCounts[I];J++,Slot++,Dist+=(1<<BitLength))
218       {
219         DDecode[Slot]=Dist;
220         DBits[Slot]=BitLength;
221       }
222   }
223 
224   FileExtracted=true;
225 
226   if (!Suspended)
227   {
228     UnpInitData(Solid);
229     if (!UnpReadBuf())
230       return;
231     if ((!Solid || !TablesRead) && !ReadTables())
232       return;
233   }
234 
235   while (true)
236   {
237     UnpPtr&=MAXWINMASK;
238 
239     if (InAddr>ReadBorder)
240     {
241       if (!UnpReadBuf())
242         break;
243     }
244     if (((WrPtr-UnpPtr) & MAXWINMASK)<260 && WrPtr!=UnpPtr)
245     {
246       UnpWriteBuf();
247       if (WrittenFileSize>DestUnpSize)
248         return;
249       if (Suspended)
250       {
251         FileExtracted=false;
252         return;
253       }
254     }
255     if (UnpBlockType==BLOCK_PPM)
256     {
257       // Here speed is critical, so we do not use SafePPMDecodeChar,
258       // because sometimes even the inline function can introduce
259       // some additional penalty.
260       int Ch=PPM.DecodeChar();
261       if (Ch==-1)              // Corrupt PPM data found.
262       {
263         PPM.CleanUp();         // Reset possibly corrupt PPM data structures.
264         UnpBlockType=BLOCK_LZ; // Set faster and more fail proof LZ mode.
265         break;
266       }
267       if (Ch==PPMEscChar)
268       {
269         int NextCh=SafePPMDecodeChar();
270         if (NextCh==0)  // End of PPM encoding.
271         {
272           if (!ReadTables())
273             break;
274           continue;
275         }
276         if (NextCh==-1) // Corrupt PPM data found.
277           break;
278         if (NextCh==2)  // End of file in PPM mode..
279           break;
280         if (NextCh==3)  // Read VM code.
281         {
282           if (!ReadVMCodePPM())
283             break;
284           continue;
285         }
286         if (NextCh==4) // LZ inside of PPM.
287         {
288           unsigned int Distance=0,Length;
289           bool Failed=false;
290           for (int I=0;I<4 && !Failed;I++)
291           {
292             int Ch=SafePPMDecodeChar();
293             if (Ch==-1)
294               Failed=true;
295             else
296               if (I==3)
297                 Length=(byte)Ch;
298               else
299                 Distance=(Distance<<8)+(byte)Ch;
300           }
301           if (Failed)
302             break;
303 
304           CopyString(Length+32,Distance+2);
305           continue;
306         }
307         if (NextCh==5) // One byte distance match (RLE) inside of PPM.
308         {
309           int Length=SafePPMDecodeChar();
310           if (Length==-1)
311             break;
312           CopyString(Length+4,1);
313           continue;
314         }
315         // If we are here, NextCh must be 1, what means that current byte
316         // is equal to our 'escape' byte, so we just store it to Window.
317       }
318       Window[UnpPtr++]=Ch;
319       continue;
320     }
321 
322     int Number=DecodeNumber(&LD);
323     if (Number<256)
324     {
325       Window[UnpPtr++]=(byte)Number;
326       continue;
327     }
328     if (Number>=271)
329     {
330       int Length=LDecode[Number-=271]+3;
331       if ((Bits=LBits[Number])>0)
332       {
333         Length+=getbits()>>(16-Bits);
334         addbits(Bits);
335       }
336 
337       int DistNumber=DecodeNumber(&DD);
338       unsigned int Distance=DDecode[DistNumber]+1;
339       if ((Bits=DBits[DistNumber])>0)
340       {
341         if (DistNumber>9)
342         {
343           if (Bits>4)
344           {
345             Distance+=((getbits()>>(20-Bits))<<4);
346             addbits(Bits-4);
347           }
348           if (LowDistRepCount>0)
349           {
350             LowDistRepCount--;
351             Distance+=PrevLowDist;
352           }
353           else
354           {
355             int LowDist=DecodeNumber(&LDD);
356             if (LowDist==16)
357             {
358               LowDistRepCount=LOW_DIST_REP_COUNT-1;
359               Distance+=PrevLowDist;
360             }
361             else
362             {
363               Distance+=LowDist;
364               PrevLowDist=LowDist;
365             }
366           }
367         }
368         else
369         {
370           Distance+=getbits()>>(16-Bits);
371           addbits(Bits);
372         }
373       }
374 
375       if (Distance>=0x2000)
376       {
377         Length++;
378         if (Distance>=0x40000L)
379           Length++;
380       }
381 
382       InsertOldDist(Distance);
383       InsertLastMatch(Length,Distance);
384       CopyString(Length,Distance);
385       continue;
386     }
387     if (Number==256)
388     {
389       if (!ReadEndOfBlock())
390         break;
391       continue;
392     }
393     if (Number==257)
394     {
395       if (!ReadVMCode())
396         break;
397       continue;
398     }
399     if (Number==258)
400     {
401       if (LastLength!=0)
402         CopyString(LastLength,LastDist);
403       continue;
404     }
405     if (Number<263)
406     {
407       int DistNum=Number-259;
408       unsigned int Distance=OldDist[DistNum];
409       for (int I=DistNum;I>0;I--)
410         OldDist[I]=OldDist[I-1];
411       OldDist[0]=Distance;
412 
413       int LengthNumber=DecodeNumber(&RD);
414       int Length=LDecode[LengthNumber]+2;
415       if ((Bits=LBits[LengthNumber])>0)
416       {
417         Length+=getbits()>>(16-Bits);
418         addbits(Bits);
419       }
420       InsertLastMatch(Length,Distance);
421       CopyString(Length,Distance);
422       continue;
423     }
424     if (Number<272)
425     {
426       unsigned int Distance=SDDecode[Number-=263]+1;
427       if ((Bits=SDBits[Number])>0)
428       {
429         Distance+=getbits()>>(16-Bits);
430         addbits(Bits);
431       }
432       InsertOldDist(Distance);
433       InsertLastMatch(2,Distance);
434       CopyString(2,Distance);
435       continue;
436     }
437   }
438   UnpWriteBuf();
439 }
440 
441 
ReadEndOfBlock()442 bool Unpack::ReadEndOfBlock()
443 {
444   unsigned int BitField=getbits();
445   bool NewTable,NewFile=false;
446   if (BitField & 0x8000)
447   {
448     NewTable=true;
449     addbits(1);
450   }
451   else
452   {
453     NewFile=true;
454     NewTable=(BitField & 0x4000)!=0;
455     addbits(2);
456   }
457   TablesRead=!NewTable;
458   return !(NewFile || NewTable && !ReadTables());
459 }
460 
461 
ReadVMCode()462 bool Unpack::ReadVMCode()
463 {
464   unsigned int FirstByte=getbits()>>8;
465   addbits(8);
466   int Length=(FirstByte & 7)+1;
467   if (Length==7)
468   {
469     Length=(getbits()>>8)+7;
470     addbits(8);
471   }
472   else
473     if (Length==8)
474     {
475       Length=getbits();
476       addbits(16);
477     }
478   Array<byte> VMCode(Length);
479   for (int I=0;I<Length;I++)
480   {
481     // Try to read the new buffer if only one byte is left.
482     // But if we read all bytes except the last, one byte is enough.
483     if (InAddr>=ReadTop-1 && !UnpReadBuf() && I<Length-1)
484       return(false);
485     VMCode[I]=getbits()>>8;
486     addbits(8);
487   }
488   return(AddVMCode(FirstByte,&VMCode[0],Length));
489 }
490 
491 
ReadVMCodePPM()492 bool Unpack::ReadVMCodePPM()
493 {
494   unsigned int FirstByte=SafePPMDecodeChar();
495   if ((int)FirstByte==-1)
496     return(false);
497   int Length=(FirstByte & 7)+1;
498   if (Length==7)
499   {
500     int B1=SafePPMDecodeChar();
501     if (B1==-1)
502       return(false);
503     Length=B1+7;
504   }
505   else
506     if (Length==8)
507     {
508       int B1=SafePPMDecodeChar();
509       if (B1==-1)
510         return(false);
511       int B2=SafePPMDecodeChar();
512       if (B2==-1)
513         return(false);
514       Length=B1*256+B2;
515     }
516   Array<byte> VMCode(Length);
517   for (int I=0;I<Length;I++)
518   {
519     int Ch=SafePPMDecodeChar();
520     if (Ch==-1)
521       return(false);
522     VMCode[I]=Ch;
523   }
524   return(AddVMCode(FirstByte,&VMCode[0],Length));
525 }
526 
527 
AddVMCode(unsigned int FirstByte,byte * Code,int CodeSize)528 bool Unpack::AddVMCode(unsigned int FirstByte,byte *Code,int CodeSize)
529 {
530   VMCodeInp.InitBitInput();
531   memcpy(VMCodeInp.InBuf,Code,Min(BitInput::MAX_SIZE,CodeSize));
532   VM.Init();
533 
534   uint FiltPos;
535   if (FirstByte & 0x80)
536   {
537     FiltPos=RarVM::ReadData(VMCodeInp);
538     if (FiltPos==0)
539       InitFilters();
540     else
541       FiltPos--;
542   }
543   else
544     FiltPos=LastFilter; // Use the same filter as last time.
545 
546   if (FiltPos>Filters.Size() || FiltPos>OldFilterLengths.Size())
547     return(false);
548   LastFilter=FiltPos;
549   bool NewFilter=(FiltPos==Filters.Size());
550 
551   UnpackFilter *StackFilter=new UnpackFilter; // New filter for PrgStack.
552 
553   UnpackFilter *Filter;
554   if (NewFilter) // New filter code, never used before since VM reset.
555   {
556     // Too many different filters, corrupt archive.
557     if (FiltPos>1024)
558     {
559       delete StackFilter;
560       return false;
561     }
562 
563     Filters.Add(1);
564     Filters[Filters.Size()-1]=Filter=new UnpackFilter;
565     StackFilter->ParentFilter=(uint)(Filters.Size()-1);
566 
567     // Reserve one item, where we store the data block length of our new
568     // filter entry. We'll set it to real block length below, after reading
569     // it. But we need to initialize it now, because when processing corrupt
570     // data, we can access this item even before we set it to real value.
571     OldFilterLengths.Push(0);
572     Filter->ExecCount=0;
573   }
574   else  // Filter was used in the past.
575   {
576     Filter=Filters[FiltPos];
577     StackFilter->ParentFilter=FiltPos;
578     Filter->ExecCount++;
579   }
580 
581   int EmptyCount=0;
582   for (uint I=0;I<PrgStack.Size();I++)
583   {
584     PrgStack[I-EmptyCount]=PrgStack[I];
585     if (PrgStack[I]==NULL)
586       EmptyCount++;
587     if (EmptyCount>0)
588       PrgStack[I]=NULL;
589   }
590   if (EmptyCount==0)
591   {
592     PrgStack.Add(1);
593     EmptyCount=1;
594   }
595   int StackPos=(int)(PrgStack.Size()-EmptyCount);
596   PrgStack[StackPos]=StackFilter;
597   StackFilter->ExecCount=Filter->ExecCount;
598 
599   uint BlockStart=RarVM::ReadData(VMCodeInp);
600   if (FirstByte & 0x40)
601     BlockStart+=258;
602   StackFilter->BlockStart=(BlockStart+UnpPtr)&MAXWINMASK;
603   if (FirstByte & 0x20)
604   {
605     StackFilter->BlockLength=RarVM::ReadData(VMCodeInp);
606 
607     // Store the last data block length for current filter.
608     OldFilterLengths[FiltPos]=StackFilter->BlockLength;
609   }
610   else
611   {
612     // Set the data block size to same value as the previous block size
613     // for same filter. It is possible on corrupt data to access here a new
614     // and not filled yet item of OldFilterLengths array. This is why above
615     // we set new OldFilterLengths items to zero.
616     StackFilter->BlockLength=FiltPos<OldFilterLengths.Size() ? OldFilterLengths[FiltPos]:0;
617   }
618 
619   StackFilter->NextWindow=WrPtr!=UnpPtr && ((WrPtr-UnpPtr)&MAXWINMASK)<=BlockStart;
620 
621 //  DebugLog("\nNextWindow: UnpPtr=%08x WrPtr=%08x BlockStart=%08x",UnpPtr,WrPtr,BlockStart);
622 
623   memset(StackFilter->Prg.InitR,0,sizeof(StackFilter->Prg.InitR));
624   StackFilter->Prg.InitR[3]=VM_GLOBALMEMADDR;
625   StackFilter->Prg.InitR[4]=StackFilter->BlockLength;
626   StackFilter->Prg.InitR[5]=StackFilter->ExecCount;
627 
628   if (FirstByte & 0x10)   // set registers to optional parameters if any
629   {
630     unsigned int InitMask=VMCodeInp.fgetbits()>>9;
631     VMCodeInp.faddbits(7);
632     for (int I=0;I<7;I++)
633       if (InitMask & (1<<I))
634         StackFilter->Prg.InitR[I]=RarVM::ReadData(VMCodeInp);
635   }
636 
637   if (NewFilter)
638   {
639     uint VMCodeSize=RarVM::ReadData(VMCodeInp);
640     if (VMCodeSize>=0x10000 || VMCodeSize==0)
641       return(false);
642     Array<byte> VMCode(VMCodeSize);
643     for (uint I=0;I<VMCodeSize;I++)
644     {
645       if (VMCodeInp.Overflow(3))
646         return(false);
647       VMCode[I]=VMCodeInp.fgetbits()>>8;
648       VMCodeInp.faddbits(8);
649     }
650     VM.Prepare(&VMCode[0],VMCodeSize,&Filter->Prg);
651   }
652   StackFilter->Prg.AltCmd=&Filter->Prg.Cmd[0];
653   StackFilter->Prg.CmdCount=Filter->Prg.CmdCount;
654 
655   size_t StaticDataSize=Filter->Prg.StaticData.Size();
656   if (StaticDataSize>0 && StaticDataSize<VM_GLOBALMEMSIZE)
657   {
658     // read statically defined data contained in DB commands
659     StackFilter->Prg.StaticData.Add(StaticDataSize);
660     memcpy(&StackFilter->Prg.StaticData[0],&Filter->Prg.StaticData[0],StaticDataSize);
661   }
662 
663   if (StackFilter->Prg.GlobalData.Size()<VM_FIXEDGLOBALSIZE)
664   {
665     StackFilter->Prg.GlobalData.Reset();
666     StackFilter->Prg.GlobalData.Add(VM_FIXEDGLOBALSIZE);
667   }
668   byte *GlobalData=&StackFilter->Prg.GlobalData[0];
669   for (int I=0;I<7;I++)
670     VM.SetLowEndianValue((uint *)&GlobalData[I*4],StackFilter->Prg.InitR[I]);
671   VM.SetLowEndianValue((uint *)&GlobalData[0x1c],StackFilter->BlockLength);
672   VM.SetLowEndianValue((uint *)&GlobalData[0x20],0);
673   VM.SetLowEndianValue((uint *)&GlobalData[0x2c],StackFilter->ExecCount);
674   memset(&GlobalData[0x30],0,16);
675 
676   if (FirstByte & 8) // Put the data block passed as parameter if any.
677   {
678     if (VMCodeInp.Overflow(3))
679       return(false);
680     uint DataSize=RarVM::ReadData(VMCodeInp);
681     if (DataSize>VM_GLOBALMEMSIZE-VM_FIXEDGLOBALSIZE)
682       return(false);
683     size_t CurSize=StackFilter->Prg.GlobalData.Size();
684     if (CurSize<DataSize+VM_FIXEDGLOBALSIZE)
685       StackFilter->Prg.GlobalData.Add(DataSize+VM_FIXEDGLOBALSIZE-CurSize);
686     byte *GlobalData=&StackFilter->Prg.GlobalData[VM_FIXEDGLOBALSIZE];
687     for (uint I=0;I<DataSize;I++)
688     {
689       if (VMCodeInp.Overflow(3))
690         return(false);
691       GlobalData[I]=VMCodeInp.fgetbits()>>8;
692       VMCodeInp.faddbits(8);
693     }
694   }
695   return(true);
696 }
697 
698 
UnpReadBuf()699 bool Unpack::UnpReadBuf()
700 {
701   int DataSize=ReadTop-InAddr; // Data left to process.
702   if (DataSize<0)
703     return(false);
704   if (InAddr>BitInput::MAX_SIZE/2)
705   {
706     // If we already processed more than half of buffer, let's move
707     // remaining data into beginning to free more space for new data.
708     if (DataSize>0)
709       memmove(InBuf,InBuf+InAddr,DataSize);
710     InAddr=0;
711     ReadTop=DataSize;
712   }
713   else
714     DataSize=ReadTop;
715   int ReadCode=UnpIO->UnpRead(InBuf+DataSize,(BitInput::MAX_SIZE-DataSize)&~0xf);
716   if (ReadCode>0)
717     ReadTop+=ReadCode;
718   ReadBorder=ReadTop-30;
719   return(ReadCode!=-1);
720 }
721 
722 
UnpWriteBuf()723 void Unpack::UnpWriteBuf()
724 {
725   unsigned int WrittenBorder=WrPtr;
726   unsigned int WriteSize=(UnpPtr-WrittenBorder)&MAXWINMASK;
727   for (size_t I=0;I<PrgStack.Size();I++)
728   {
729     // Here we apply filters to data which we need to write.
730     // We always copy data to virtual machine memory before processing.
731     // We cannot process them just in place in Window buffer, because
732     // these data can be used for future string matches, so we must
733     // preserve them in original form.
734 
735     UnpackFilter *flt=PrgStack[I];
736     if (flt==NULL)
737       continue;
738     if (flt->NextWindow)
739     {
740       flt->NextWindow=false;
741       continue;
742     }
743     unsigned int BlockStart=flt->BlockStart;
744     unsigned int BlockLength=flt->BlockLength;
745     if (((BlockStart-WrittenBorder)&MAXWINMASK)<WriteSize)
746     {
747       if (WrittenBorder!=BlockStart)
748       {
749         UnpWriteArea(WrittenBorder,BlockStart);
750         WrittenBorder=BlockStart;
751         WriteSize=(UnpPtr-WrittenBorder)&MAXWINMASK;
752       }
753       if (BlockLength<=WriteSize)
754       {
755         unsigned int BlockEnd=(BlockStart+BlockLength)&MAXWINMASK;
756         if (BlockStart<BlockEnd || BlockEnd==0)
757           VM.SetMemory(0,Window+BlockStart,BlockLength);
758         else
759         {
760           unsigned int FirstPartLength=MAXWINSIZE-BlockStart;
761           VM.SetMemory(0,Window+BlockStart,FirstPartLength);
762           VM.SetMemory(FirstPartLength,Window,BlockEnd);
763         }
764 
765         VM_PreparedProgram *ParentPrg=&Filters[flt->ParentFilter]->Prg;
766         VM_PreparedProgram *Prg=&flt->Prg;
767 
768         if (ParentPrg->GlobalData.Size()>VM_FIXEDGLOBALSIZE)
769         {
770           // Copy global data from previous script execution if any.
771           Prg->GlobalData.Alloc(ParentPrg->GlobalData.Size());
772           memcpy(&Prg->GlobalData[VM_FIXEDGLOBALSIZE],&ParentPrg->GlobalData[VM_FIXEDGLOBALSIZE],ParentPrg->GlobalData.Size()-VM_FIXEDGLOBALSIZE);
773         }
774 
775         ExecuteCode(Prg);
776 
777         if (Prg->GlobalData.Size()>VM_FIXEDGLOBALSIZE)
778         {
779           // Save global data for next script execution.
780           if (ParentPrg->GlobalData.Size()<Prg->GlobalData.Size())
781             ParentPrg->GlobalData.Alloc(Prg->GlobalData.Size());
782           memcpy(&ParentPrg->GlobalData[VM_FIXEDGLOBALSIZE],&Prg->GlobalData[VM_FIXEDGLOBALSIZE],Prg->GlobalData.Size()-VM_FIXEDGLOBALSIZE);
783         }
784         else
785           ParentPrg->GlobalData.Reset();
786 
787         byte *FilteredData=Prg->FilteredData;
788         unsigned int FilteredDataSize=Prg->FilteredDataSize;
789 
790         delete PrgStack[I];
791         PrgStack[I]=NULL;
792         while (I+1<PrgStack.Size())
793         {
794           UnpackFilter *NextFilter=PrgStack[I+1];
795           if (NextFilter==NULL || NextFilter->BlockStart!=BlockStart ||
796               NextFilter->BlockLength!=FilteredDataSize || NextFilter->NextWindow)
797             break;
798 
799           // Apply several filters to same data block.
800 
801           VM.SetMemory(0,FilteredData,FilteredDataSize);
802 
803           VM_PreparedProgram *ParentPrg=&Filters[NextFilter->ParentFilter]->Prg;
804           VM_PreparedProgram *NextPrg=&NextFilter->Prg;
805 
806           if (ParentPrg->GlobalData.Size()>VM_FIXEDGLOBALSIZE)
807           {
808             // Copy global data from previous script execution if any.
809             NextPrg->GlobalData.Alloc(ParentPrg->GlobalData.Size());
810             memcpy(&NextPrg->GlobalData[VM_FIXEDGLOBALSIZE],&ParentPrg->GlobalData[VM_FIXEDGLOBALSIZE],ParentPrg->GlobalData.Size()-VM_FIXEDGLOBALSIZE);
811           }
812 
813           ExecuteCode(NextPrg);
814 
815           if (NextPrg->GlobalData.Size()>VM_FIXEDGLOBALSIZE)
816           {
817             // Save global data for next script execution.
818             if (ParentPrg->GlobalData.Size()<NextPrg->GlobalData.Size())
819               ParentPrg->GlobalData.Alloc(NextPrg->GlobalData.Size());
820             memcpy(&ParentPrg->GlobalData[VM_FIXEDGLOBALSIZE],&NextPrg->GlobalData[VM_FIXEDGLOBALSIZE],NextPrg->GlobalData.Size()-VM_FIXEDGLOBALSIZE);
821           }
822           else
823             ParentPrg->GlobalData.Reset();
824 
825           FilteredData=NextPrg->FilteredData;
826           FilteredDataSize=NextPrg->FilteredDataSize;
827           I++;
828           delete PrgStack[I];
829           PrgStack[I]=NULL;
830         }
831         UnpIO->UnpWrite(FilteredData,FilteredDataSize);
832         UnpSomeRead=true;
833         WrittenFileSize+=FilteredDataSize;
834         WrittenBorder=BlockEnd;
835         WriteSize=(UnpPtr-WrittenBorder)&MAXWINMASK;
836       }
837       else
838       {
839         for (size_t J=I;J<PrgStack.Size();J++)
840         {
841           UnpackFilter *flt=PrgStack[J];
842           if (flt!=NULL && flt->NextWindow)
843             flt->NextWindow=false;
844         }
845         WrPtr=WrittenBorder;
846         return;
847       }
848     }
849   }
850 
851   UnpWriteArea(WrittenBorder,UnpPtr);
852   WrPtr=UnpPtr;
853 }
854 
855 
ExecuteCode(VM_PreparedProgram * Prg)856 void Unpack::ExecuteCode(VM_PreparedProgram *Prg)
857 {
858   if (Prg->GlobalData.Size()>0)
859   {
860     Prg->InitR[6]=(uint)WrittenFileSize;
861     VM.SetLowEndianValue((uint *)&Prg->GlobalData[0x24],(uint)WrittenFileSize);
862     VM.SetLowEndianValue((uint *)&Prg->GlobalData[0x28],(uint)(WrittenFileSize>>32));
863     VM.Execute(Prg);
864   }
865 }
866 
867 
UnpWriteArea(unsigned int StartPtr,unsigned int EndPtr)868 void Unpack::UnpWriteArea(unsigned int StartPtr,unsigned int EndPtr)
869 {
870   if (EndPtr!=StartPtr)
871     UnpSomeRead=true;
872   if (EndPtr<StartPtr)
873   {
874     UnpWriteData(&Window[StartPtr],-(int)StartPtr & MAXWINMASK);
875     UnpWriteData(Window,EndPtr);
876     UnpAllBuf=true;
877   }
878   else
879     UnpWriteData(&Window[StartPtr],EndPtr-StartPtr);
880 }
881 
882 
UnpWriteData(byte * Data,size_t Size)883 void Unpack::UnpWriteData(byte *Data,size_t Size)
884 {
885   if (WrittenFileSize>=DestUnpSize)
886     return;
887   size_t WriteSize=Size;
888   int64 LeftToWrite=DestUnpSize-WrittenFileSize;
889   if ((int64)WriteSize>LeftToWrite)
890     WriteSize=(size_t)LeftToWrite;
891   UnpIO->UnpWrite(Data,WriteSize);
892   WrittenFileSize+=Size;
893 }
894 
895 
ReadTables()896 bool Unpack::ReadTables()
897 {
898   byte BitLength[BC];
899   byte Table[HUFF_TABLE_SIZE];
900   if (InAddr>ReadTop-25)
901     if (!UnpReadBuf())
902       return(false);
903   faddbits((8-InBit)&7);
904   uint BitField=fgetbits();
905   if (BitField & 0x8000)
906   {
907     UnpBlockType=BLOCK_PPM;
908     return(PPM.DecodeInit(this,PPMEscChar));
909   }
910   UnpBlockType=BLOCK_LZ;
911 
912   PrevLowDist=0;
913   LowDistRepCount=0;
914 
915   if (!(BitField & 0x4000))
916     memset(UnpOldTable,0,sizeof(UnpOldTable));
917   faddbits(2);
918 
919   for (int I=0;I<BC;I++)
920   {
921     int Length=(byte)(fgetbits() >> 12);
922     faddbits(4);
923     if (Length==15)
924     {
925       int ZeroCount=(byte)(fgetbits() >> 12);
926       faddbits(4);
927       if (ZeroCount==0)
928         BitLength[I]=15;
929       else
930       {
931         ZeroCount+=2;
932         while (ZeroCount-- > 0 && I<sizeof(BitLength)/sizeof(BitLength[0]))
933           BitLength[I++]=0;
934         I--;
935       }
936     }
937     else
938       BitLength[I]=Length;
939   }
940   MakeDecodeTables(BitLength,&BD,BC);
941 
942   const int TableSize=HUFF_TABLE_SIZE;
943   for (int I=0;I<TableSize;)
944   {
945     if (InAddr>ReadTop-5)
946       if (!UnpReadBuf())
947         return(false);
948     int Number=DecodeNumber(&BD);
949     if (Number<16)
950     {
951       Table[I]=(Number+UnpOldTable[I]) & 0xf;
952       I++;
953     }
954     else
955       if (Number<18)
956       {
957         int N;
958         if (Number==16)
959         {
960           N=(fgetbits() >> 13)+3;
961           faddbits(3);
962         }
963         else
964         {
965           N=(fgetbits() >> 9)+11;
966           faddbits(7);
967         }
968         while (N-- > 0 && I<TableSize)
969         {
970           Table[I]=Table[I-1];
971           I++;
972         }
973       }
974       else
975       {
976         int N;
977         if (Number==18)
978         {
979           N=(fgetbits() >> 13)+3;
980           faddbits(3);
981         }
982         else
983         {
984           N=(fgetbits() >> 9)+11;
985           faddbits(7);
986         }
987         while (N-- > 0 && I<TableSize)
988           Table[I++]=0;
989       }
990   }
991   TablesRead=true;
992   if (InAddr>ReadTop)
993     return(false);
994   MakeDecodeTables(&Table[0],&LD,NC);
995   MakeDecodeTables(&Table[NC],&DD,DC);
996   MakeDecodeTables(&Table[NC+DC],&LDD,LDC);
997   MakeDecodeTables(&Table[NC+DC+LDC],&RD,RC);
998   memcpy(UnpOldTable,Table,sizeof(UnpOldTable));
999   return(true);
1000 }
1001 
1002 
UnpInitData(int Solid)1003 void Unpack::UnpInitData(int Solid)
1004 {
1005   if (!Solid)
1006   {
1007     TablesRead=false;
1008     memset(OldDist,0,sizeof(OldDist));
1009     OldDistPtr=0;
1010     LastDist=LastLength=0;
1011 //    memset(Window,0,MAXWINSIZE);
1012     memset(UnpOldTable,0,sizeof(UnpOldTable));
1013     memset(&LD,0,sizeof(LD));
1014     memset(&DD,0,sizeof(DD));
1015     memset(&LDD,0,sizeof(LDD));
1016     memset(&RD,0,sizeof(RD));
1017     memset(&BD,0,sizeof(BD));
1018     UnpPtr=WrPtr=0;
1019     PPMEscChar=2;
1020     UnpBlockType=BLOCK_LZ;
1021 
1022     InitFilters();
1023   }
1024   InitBitInput();
1025   WrittenFileSize=0;
1026   ReadTop=0;
1027   ReadBorder=0;
1028 #ifndef SFX_MODULE
1029   UnpInitData20(Solid);
1030 #endif
1031 }
1032 
1033 
InitFilters()1034 void Unpack::InitFilters()
1035 {
1036   OldFilterLengths.Reset();
1037   LastFilter=0;
1038 
1039   for (size_t I=0;I<Filters.Size();I++)
1040     delete Filters[I];
1041   Filters.Reset();
1042   for (size_t I=0;I<PrgStack.Size();I++)
1043     delete PrgStack[I];
1044   PrgStack.Reset();
1045 }
1046 
1047 
1048 // LengthTable contains the length in bits for every element of alphabet.
1049 // Dec is the structure to decode Huffman code/
1050 // Size is size of length table and DecodeNum field in Dec structure,
MakeDecodeTables(byte * LengthTable,DecodeTable * Dec,uint Size)1051 void Unpack::MakeDecodeTables(byte *LengthTable,DecodeTable *Dec,uint Size)
1052 {
1053   // Size of alphabet and DecodePos array.
1054   Dec->MaxNum=Size;
1055 
1056   // Calculate how many entries for every bit length in LengthTable we have.
1057   uint LengthCount[16];
1058   memset(LengthCount,0,sizeof(LengthCount));
1059   for (size_t I=0;I<Size;I++)
1060     LengthCount[LengthTable[I] & 0xf]++;
1061 
1062   // We must not calculate the number of zero length codes.
1063   LengthCount[0]=0;
1064 
1065   // Set the entire DecodeNum to zero.
1066   memset(Dec->DecodeNum,0,Size*sizeof(*Dec->DecodeNum));
1067 
1068   // Initialize not really used entry for zero length code.
1069   Dec->DecodePos[0]=0;
1070 
1071   // Start code for bit length 1 is 0.
1072   Dec->DecodeLen[0]=0;
1073 
1074   // Right aligned upper limit code for current bit length.
1075   uint UpperLimit=0;
1076 
1077   for (size_t I=1;I<16;I++)
1078   {
1079     // Adjust the upper limit code.
1080     UpperLimit+=LengthCount[I];
1081 
1082     // Left aligned upper limit code.
1083     uint LeftAligned=UpperLimit<<(16-I);
1084 
1085     // Prepare the upper limit code for next bit length.
1086     UpperLimit*=2;
1087 
1088     // Store the left aligned upper limit code.
1089     Dec->DecodeLen[I]=(uint)LeftAligned;
1090 
1091     // Every item of this array contains the sum of all preceding items.
1092     // So it contains the start position in code list for every bit length.
1093     Dec->DecodePos[I]=Dec->DecodePos[I-1]+LengthCount[I-1];
1094   }
1095 
1096   // Prepare the copy of DecodePos. We'll modify this copy below,
1097   // so we cannot use the original DecodePos.
1098   uint CopyDecodePos[16];
1099   memcpy(CopyDecodePos,Dec->DecodePos,sizeof(CopyDecodePos));
1100 
1101   // For every bit length in the bit length table and so for every item
1102   // of alphabet.
1103   for (uint I=0;I<Size;I++)
1104   {
1105     // Get the current bit length.
1106     byte CurBitLength=LengthTable[I] & 0xf;
1107 
1108     if (CurBitLength!=0)
1109     {
1110       // Last position in code list for current bit length.
1111       uint LastPos=CopyDecodePos[CurBitLength];
1112 
1113       // Prepare the decode table, so this position in code list will be
1114       // decoded to current alphabet item number.
1115       Dec->DecodeNum[LastPos]=I;
1116 
1117       // We'll use next position number for this bit length next time.
1118       // So we pass through the entire range of positions available
1119       // for every bit length.
1120       CopyDecodePos[CurBitLength]++;
1121     }
1122   }
1123 
1124   // Define the number of bits to process in quick mode. We use more bits
1125   // for larger alphabets. More bits means that more codes will be processed
1126   // in quick mode, but also that more time will be spent to preparation
1127   // of tables for quick decode.
1128   switch (Size)
1129   {
1130     case NC:
1131     case NC20:
1132       Dec->QuickBits=MAX_QUICK_DECODE_BITS;
1133       break;
1134     default:
1135       Dec->QuickBits=MAX_QUICK_DECODE_BITS-3;
1136       break;
1137   }
1138 
1139   // Size of tables for quick mode.
1140   uint QuickDataSize=1<<Dec->QuickBits;
1141 
1142   // Bit length for current code, start from 1 bit codes. It is important
1143   // to use 1 bit instead of 0 for minimum code length, so we are moving
1144   // forward even when processing a corrupt archive.
1145   uint CurBitLength=1;
1146 
1147   // For every right aligned bit string which supports the quick decoding.
1148   for (uint Code=0;Code<QuickDataSize;Code++)
1149   {
1150     // Left align the current code, so it will be in usual bit field format.
1151     uint BitField=Code<<(16-Dec->QuickBits);
1152 
1153     // Prepare the table for quick decoding of bit lengths.
1154 
1155     // Find the upper limit for current bit field and adjust the bit length
1156     // accordingly if necessary.
1157     while (BitField>=Dec->DecodeLen[CurBitLength] && CurBitLength<ASIZE(Dec->DecodeLen))
1158       CurBitLength++;
1159 
1160     // Translation of right aligned bit string to bit length.
1161     Dec->QuickLen[Code]=CurBitLength;
1162 
1163     // Prepare the table for quick translation of position in code list
1164     // to position in alphabet.
1165 
1166     // Calculate the distance from the start code for current bit length.
1167     uint Dist=BitField-Dec->DecodeLen[CurBitLength-1];
1168 
1169     // Right align the distance.
1170     Dist>>=(16-CurBitLength);
1171 
1172     // Now we can calculate the position in the code list. It is the sum
1173     // of first position for current bit length and right aligned distance
1174     // between our bit field and start code for current bit length.
1175     uint Pos=Dec->DecodePos[CurBitLength]+Dist;
1176 
1177     if (Pos<Size) // Safety check for damaged archives.
1178     {
1179       // Define the code to alphabet number translation.
1180       Dec->QuickNum[Code]=Dec->DecodeNum[Pos];
1181     }
1182     else
1183       Dec->QuickNum[Code]=0;
1184   }
1185 }
1186