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