unrarsrc  6.1.7
About: unrar extracts, views and tests the contents of archives created with the RAR archiver.
  Fossies Dox: unrarsrc-6.1.7.tar.gz  ("unofficial" and yet experimental doxygen-generated source code documentation)  

unpack.cpp
Go to the documentation of this file.
1#include "rar.hpp"
2
3#include "coder.cpp"
4#include "suballoc.cpp"
5#include "model.cpp"
6#include "unpackinline.cpp"
7#ifdef RAR_SMP
8#include "unpack50mt.cpp"
9#endif
10#ifndef SFX_MODULE
11#include "unpack15.cpp"
12#include "unpack20.cpp"
13#endif
14#include "unpack30.cpp"
15#include "unpack50.cpp"
16#include "unpack50frag.cpp"
17
19:Inp(true),VMCodeInp(true)
20{
21 UnpIO=DataIO;
22 Window=NULL;
23 Fragmented=false;
24 Suspended=false;
25 UnpAllBuf=false;
26 UnpSomeRead=false;
27#ifdef RAR_SMP
28 MaxUserThreads=1;
29 UnpThreadPool=NULL;
30 ReadBufMT=NULL;
31 UnpThreadData=NULL;
32#endif
33 MaxWinSize=0;
34 MaxWinMask=0;
35
36 // Perform initialization, which should be done only once for all files.
37 // It prevents crash if first DoUnpack call is later made with wrong
38 // (true) 'Solid' value.
39 UnpInitData(false);
40#ifndef SFX_MODULE
41 // RAR 1.5 decompression initialization
42 UnpInitData15(false);
43 InitHuff();
44#endif
45}
46
47
49{
50 InitFilters30(false);
51
52 if (Window!=NULL)
53 free(Window);
54#ifdef RAR_SMP
55 delete UnpThreadPool;
56 delete[] ReadBufMT;
57 delete[] UnpThreadData;
58#endif
59}
60
61
62#ifdef RAR_SMP
63void Unpack::SetThreads(uint Threads)
64{
65 // More than 8 threads are unlikely to provide noticeable gain
66 // for unpacking, but would use the additional memory.
67 MaxUserThreads=Min(Threads,8);
68 UnpThreadPool=new ThreadPool(MaxUserThreads);
69}
70#endif
71
72
73void Unpack::Init(size_t WinSize,bool Solid)
74{
75 // If 32-bit RAR unpacks an archive with 4 GB dictionary, the window size
76 // will be 0 because of size_t overflow. Let's issue the memory error.
77 if (WinSize==0)
79
80 // Minimum window size must be at least twice more than maximum possible
81 // size of filter block, which is 0x10000 in RAR now. If window size is
82 // smaller, we can have a block with never cleared flt->NextWindow flag
83 // in UnpWriteBuf(). Minimum window size 0x20000 would be enough, but let's
84 // use 0x40000 for extra safety and possible filter area size expansion.
85 const size_t MinAllocSize=0x40000;
86 if (WinSize<MinAllocSize)
87 WinSize=MinAllocSize;
88
89 if (WinSize<=MaxWinSize) // Use the already allocated window.
90 return;
91 if ((WinSize>>16)>0x10000) // Window size must not exceed 4 GB.
92 return;
93
94 // Archiving code guarantees that window size does not grow in the same
95 // solid stream. So if we are here, we are either creating a new window
96 // or increasing the size of non-solid window. So we could safely reject
97 // current window data without copying them to a new window, though being
98 // extra cautious, we still handle the solid window grow case below.
99 bool Grow=Solid && (Window!=NULL || Fragmented);
100
101 // We do not handle growth for existing fragmented window.
102 if (Grow && Fragmented)
103 throw std::bad_alloc();
104
105 byte *NewWindow=Fragmented ? NULL : (byte *)malloc(WinSize);
106
107 if (NewWindow==NULL)
108 if (Grow || WinSize<0x1000000)
109 {
110 // We do not support growth for new fragmented window.
111 // Also exclude RAR4 and small dictionaries.
112 throw std::bad_alloc();
113 }
114 else
115 {
116 if (Window!=NULL) // If allocated by preceding files.
117 {
118 free(Window);
119 Window=NULL;
120 }
121 FragWindow.Init(WinSize);
122 Fragmented=true;
123 }
124
125 if (!Fragmented)
126 {
127 // Clean the window to generate the same output when unpacking corrupt
128 // RAR files, which may access unused areas of sliding dictionary.
129 memset(NewWindow,0,WinSize);
130
131 // If Window is not NULL, it means that window size has grown.
132 // In solid streams we need to copy data to a new window in such case.
133 // RAR archiving code does not allow it in solid streams now,
134 // but let's implement it anyway just in case we'll change it sometimes.
135 if (Grow)
136 for (size_t I=1;I<=MaxWinSize;I++)
137 NewWindow[(UnpPtr-I)&(WinSize-1)]=Window[(UnpPtr-I)&(MaxWinSize-1)];
138
139 if (Window!=NULL)
140 free(Window);
141 Window=NewWindow;
142 }
143
144 MaxWinSize=WinSize;
146}
147
148
149void Unpack::DoUnpack(uint Method,bool Solid)
150{
151 // Methods <50 will crash in Fragmented mode when accessing NULL Window.
152 // They cannot be called in such mode now, but we check it below anyway
153 // just for extra safety.
154 switch(Method)
155 {
156#ifndef SFX_MODULE
157 case 15: // rar 1.5 compression
158 if (!Fragmented)
159 Unpack15(Solid);
160 break;
161 case 20: // rar 2.x compression
162 case 26: // files larger than 2GB
163 if (!Fragmented)
164 Unpack20(Solid);
165 break;
166#endif
167 case 29: // rar 3.x compression
168 if (!Fragmented)
169 Unpack29(Solid);
170 break;
171 case 50: // RAR 5.0 compression algorithm.
172#ifdef RAR_SMP
173 if (MaxUserThreads>1)
174 {
175// We do not use the multithreaded unpack routine to repack RAR archives
176// in 'suspended' mode, because unlike the single threaded code it can
177// write more than one dictionary for same loop pass. So we would need
178// larger buffers of unknown size. Also we do not support multithreading
179// in fragmented window mode.
180 if (!Fragmented)
181 {
182 Unpack5MT(Solid);
183 break;
184 }
185 }
186#endif
187 Unpack5(Solid);
188 break;
189 }
190}
191
192
193void Unpack::UnpInitData(bool Solid)
194{
195 if (!Solid)
196 {
197 memset(OldDist,0,sizeof(OldDist));
198 OldDistPtr=0;
200// memset(Window,0,MaxWinSize);
201 memset(&BlockTables,0,sizeof(BlockTables));
202 UnpPtr=WrPtr=0;
204 }
205 // Filters never share several solid files, so we can safely reset them
206 // even in solid archive.
207 InitFilters();
208
211 ReadTop=0;
212 ReadBorder=0;
213
214 memset(&BlockHeader,0,sizeof(BlockHeader));
215 BlockHeader.BlockSize=-1; // '-1' means not defined yet.
216#ifndef SFX_MODULE
217 UnpInitData20(Solid);
218#endif
219 UnpInitData30(Solid);
220 UnpInitData50(Solid);
221}
222
223
224// LengthTable contains the length in bits for every element of alphabet.
225// Dec is the structure to decode Huffman code/
226// Size is size of length table and DecodeNum field in Dec structure,
227void Unpack::MakeDecodeTables(byte *LengthTable,DecodeTable *Dec,uint Size)
228{
229 // Size of alphabet and DecodePos array.
230 Dec->MaxNum=Size;
231
232 // Calculate how many entries for every bit length in LengthTable we have.
233 uint LengthCount[16];
234 memset(LengthCount,0,sizeof(LengthCount));
235 for (size_t I=0;I<Size;I++)
236 LengthCount[LengthTable[I] & 0xf]++;
237
238 // We must not calculate the number of zero length codes.
239 LengthCount[0]=0;
240
241 // Set the entire DecodeNum to zero.
242 memset(Dec->DecodeNum,0,Size*sizeof(*Dec->DecodeNum));
243
244 // Initialize not really used entry for zero length code.
245 Dec->DecodePos[0]=0;
246
247 // Start code for bit length 1 is 0.
248 Dec->DecodeLen[0]=0;
249
250 // Right aligned upper limit code for current bit length.
251 uint UpperLimit=0;
252
253 for (size_t I=1;I<16;I++)
254 {
255 // Adjust the upper limit code.
256 UpperLimit+=LengthCount[I];
257
258 // Left aligned upper limit code.
259 uint LeftAligned=UpperLimit<<(16-I);
260
261 // Prepare the upper limit code for next bit length.
262 UpperLimit*=2;
263
264 // Store the left aligned upper limit code.
265 Dec->DecodeLen[I]=(uint)LeftAligned;
266
267 // Every item of this array contains the sum of all preceding items.
268 // So it contains the start position in code list for every bit length.
269 Dec->DecodePos[I]=Dec->DecodePos[I-1]+LengthCount[I-1];
270 }
271
272 // Prepare the copy of DecodePos. We'll modify this copy below,
273 // so we cannot use the original DecodePos.
274 uint CopyDecodePos[ASIZE(Dec->DecodePos)];
275 memcpy(CopyDecodePos,Dec->DecodePos,sizeof(CopyDecodePos));
276
277 // For every bit length in the bit length table and so for every item
278 // of alphabet.
279 for (uint I=0;I<Size;I++)
280 {
281 // Get the current bit length.
282 byte CurBitLength=LengthTable[I] & 0xf;
283
284 if (CurBitLength!=0)
285 {
286 // Last position in code list for current bit length.
287 uint LastPos=CopyDecodePos[CurBitLength];
288
289 // Prepare the decode table, so this position in code list will be
290 // decoded to current alphabet item number.
291 Dec->DecodeNum[LastPos]=(ushort)I;
292
293 // We'll use next position number for this bit length next time.
294 // So we pass through the entire range of positions available
295 // for every bit length.
296 CopyDecodePos[CurBitLength]++;
297 }
298 }
299
300 // Define the number of bits to process in quick mode. We use more bits
301 // for larger alphabets. More bits means that more codes will be processed
302 // in quick mode, but also that more time will be spent to preparation
303 // of tables for quick decode.
304 switch (Size)
305 {
306 case NC:
307 case NC20:
308 case NC30:
310 break;
311 default:
313 break;
314 }
315
316 // Size of tables for quick mode.
317 uint QuickDataSize=1<<Dec->QuickBits;
318
319 // Bit length for current code, start from 1 bit codes. It is important
320 // to use 1 bit instead of 0 for minimum code length, so we are moving
321 // forward even when processing a corrupt archive.
322 uint CurBitLength=1;
323
324 // For every right aligned bit string which supports the quick decoding.
325 for (uint Code=0;Code<QuickDataSize;Code++)
326 {
327 // Left align the current code, so it will be in usual bit field format.
328 uint BitField=Code<<(16-Dec->QuickBits);
329
330 // Prepare the table for quick decoding of bit lengths.
331
332 // Find the upper limit for current bit field and adjust the bit length
333 // accordingly if necessary.
334 while (CurBitLength<ASIZE(Dec->DecodeLen) && BitField>=Dec->DecodeLen[CurBitLength])
335 CurBitLength++;
336
337 // Translation of right aligned bit string to bit length.
338 Dec->QuickLen[Code]=CurBitLength;
339
340 // Prepare the table for quick translation of position in code list
341 // to position in alphabet.
342
343 // Calculate the distance from the start code for current bit length.
344 uint Dist=BitField-Dec->DecodeLen[CurBitLength-1];
345
346 // Right align the distance.
347 Dist>>=(16-CurBitLength);
348
349 // Now we can calculate the position in the code list. It is the sum
350 // of first position for current bit length and right aligned distance
351 // between our bit field and start code for current bit length.
352 uint Pos;
353 if (CurBitLength<ASIZE(Dec->DecodePos) &&
354 (Pos=Dec->DecodePos[CurBitLength]+Dist)<Size)
355 {
356 // Define the code to alphabet number translation.
357 Dec->QuickNum[Code]=Dec->DecodeNum[Pos];
358 }
359 else
360 {
361 // Can be here for length table filled with zeroes only (empty).
362 Dec->QuickNum[Code]=0;
363 }
364 }
365}
ErrorHandler ErrHandler
void InitBitInput()
Definition: getbits.hpp:19
void MemoryError()
Definition: errhnd.cpp:22
void Init(size_t WinSize)
static const uint NC
Definition: compress.hpp:22
static const uint NC20
Definition: compress.hpp:36
static const uint NC30
Definition: compress.hpp:29
~Unpack()
Definition: unpack.cpp:48
void UnpInitData30(bool Solid)
Definition: unpack30.cpp:738
UnpackBlockTables BlockTables
Definition: unpack.hpp:267
void UnpInitData(bool Solid)
Definition: unpack.cpp:193
void Unpack5MT(bool Solid)
Definition: unpack50mt.cpp:56
void Unpack20(bool Solid)
Definition: unpack20.cpp:13
bool UnpAllBuf
Definition: unpack.hpp:280
size_t WrPtr
Definition: unpack.hpp:256
int64 WrittenFileSize
Definition: unpack.hpp:282
void Init(size_t WinSize, bool Solid)
Definition: unpack.cpp:73
void UnpInitData50(bool Solid)
Definition: unpack50.cpp:528
void DoUnpack(uint Method, bool Solid)
Definition: unpack.cpp:149
uint OldDist[4]
Definition: unpack.hpp:249
bool Suspended
Definition: unpack.hpp:279
size_t UnpPtr
Definition: unpack.hpp:256
uint LastDist
Definition: unpack.hpp:254
size_t WriteBorder
Definition: unpack.hpp:269
BitInput Inp
Definition: unpack.hpp:230
bool Fragmented
Definition: unpack.hpp:274
byte * Window
Definition: unpack.hpp:271
void UnpInitData20(int Solid)
Definition: unpack20.cpp:271
int ReadBorder
Definition: unpack.hpp:264
void Unpack15(bool Solid)
Definition: unpack15.cpp:40
ComprDataIO * UnpIO
Definition: unpack.hpp:229
bool UnpSomeRead
Definition: unpack.hpp:281
uint LastLength
Definition: unpack.hpp:250
size_t MaxWinSize
Definition: unpack.hpp:389
void InitFilters30(bool Solid)
Definition: unpack30.cpp:751
void InitHuff()
Definition: unpack15.cpp:444
FragmentedWindow FragWindow
Definition: unpack.hpp:273
uint OldDistPtr
Definition: unpack.hpp:249
void Unpack29(bool Solid)
Definition: unpack30.cpp:16
void UnpInitData15(int Solid)
Definition: unpack15.cpp:427
int ReadTop
Definition: unpack.hpp:259
size_t MaxWinMask
Definition: unpack.hpp:390
Unpack(ComprDataIO *DataIO)
Definition: unpack.cpp:18
void MakeDecodeTables(byte *LengthTable, DecodeTable *Dec, uint Size)
Definition: unpack.cpp:227
void InitFilters()
Definition: unpack50.cpp:684
void Unpack5(bool Solid)
Definition: unpack50.cpp:1
#define Min(x, y)
Definition: rardefs.hpp:4
#define ASIZE(x)
Definition: rardefs.hpp:10
unsigned int uint
Definition: rartypes.hpp:8
uint16_t ushort
Definition: rartypes.hpp:7
uint MaxNum
Definition: unpack.hpp:34
uint QuickBits
Definition: unpack.hpp:49
ushort DecodeNum[LARGEST_TABLE_SIZE]
Definition: unpack.hpp:69
uint DecodePos[16]
Definition: unpack.hpp:45
ushort QuickNum[1<< 10]
Definition: unpack.hpp:59
byte QuickLen[1<< 10]
Definition: unpack.hpp:53
uint DecodeLen[16]
Definition: unpack.hpp:41
#define UNPACK_MAX_WRITE
Definition: unpack.hpp:28
#define MAX_QUICK_DECODE_BITS
Definition: unpack.hpp:5