Coverage Report

Created: 2024-04-23 06:19

/src/unrar/unpack.cpp
Line
Count
Source (jump to first uncovered line)
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
18
Unpack::Unpack(ComprDataIO *DataIO)
19
:Inp(true),VMCodeInp(true)
20
4.29k
{
21
4.29k
  UnpIO=DataIO;
22
4.29k
  Window=NULL;
23
4.29k
  Fragmented=false;
24
4.29k
  Suspended=false;
25
4.29k
  UnpAllBuf=false;
26
4.29k
  UnpSomeRead=false;
27
4.29k
#ifdef RAR_SMP
28
4.29k
  MaxUserThreads=1;
29
4.29k
  UnpThreadPool=NULL;
30
4.29k
  ReadBufMT=NULL;
31
4.29k
  UnpThreadData=NULL;
32
4.29k
#endif
33
4.29k
  MaxWinSize=0;
34
4.29k
  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
4.29k
  UnpInitData(false);
40
4.29k
#ifndef SFX_MODULE
41
  // RAR 1.5 decompression initialization
42
4.29k
  UnpInitData15(false);
43
4.29k
  InitHuff();
44
4.29k
#endif
45
4.29k
}
46
47
48
Unpack::~Unpack()
49
4.29k
{
50
4.29k
  InitFilters30(false);
51
52
4.29k
  if (Window!=NULL)
53
3.21k
    free(Window);
54
4.29k
#ifdef RAR_SMP
55
4.29k
  delete UnpThreadPool;
56
4.29k
  delete[] ReadBufMT;
57
4.29k
  delete[] UnpThreadData;
58
4.29k
#endif
59
4.29k
}
60
61
62
#ifdef RAR_SMP
63
void Unpack::SetThreads(uint Threads)
64
4.09k
{
65
  // More than 8 threads are unlikely to provide noticeable gain
66
  // for unpacking, but would use the additional memory.
67
4.09k
  MaxUserThreads=Min(Threads,8);
68
4.09k
  UnpThreadPool=new ThreadPool(MaxUserThreads);
69
4.09k
}
70
#endif
71
72
73
void Unpack::Init(size_t WinSize,bool Solid)
74
3.24k
{
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
3.24k
  if (WinSize==0)
78
0
    ErrHandler.MemoryError();
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
3.24k
  const size_t MinAllocSize=0x40000;
86
3.24k
  if (WinSize<MinAllocSize)
87
2.43k
    WinSize=MinAllocSize;
88
89
3.24k
  if (WinSize<=MaxWinSize) // Use the already allocated window.
90
28
    return;
91
3.21k
  if ((WinSize>>16)>0x10000) // Window size must not exceed 4 GB.
92
0
    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
3.21k
  bool Grow=Solid && (Window!=NULL || Fragmented);
100
101
  // We do not handle growth for existing fragmented window.
102
3.21k
  if (Grow && Fragmented)
103
0
    throw std::bad_alloc();
104
105
3.21k
  byte *NewWindow=Fragmented ? NULL : (byte *)malloc(WinSize);
106
107
3.21k
  if (NewWindow==NULL)
108
0
    if (Grow || WinSize<0x1000000)
109
0
    {
110
      // We do not support growth for new fragmented window.
111
      // Also exclude RAR4 and small dictionaries.
112
0
      throw std::bad_alloc();
113
0
    }
114
0
    else
115
0
    {
116
0
      if (Window!=NULL) // If allocated by preceding files.
117
0
      {
118
0
        free(Window);
119
0
        Window=NULL;
120
0
      }
121
0
      FragWindow.Init(WinSize);
122
0
      Fragmented=true;
123
0
    }
124
125
3.21k
  if (!Fragmented)
126
3.21k
  {
127
    // Clean the window to generate the same output when unpacking corrupt
128
    // RAR files, which may access unused areas of sliding dictionary.
129
3.21k
    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
3.21k
    if (Grow)
136
786k
      for (size_t I=1;I<=MaxWinSize;I++)
137
786k
        NewWindow[(UnpPtr-I)&(WinSize-1)]=Window[(UnpPtr-I)&(MaxWinSize-1)];
138
139
3.21k
    if (Window!=NULL)
140
3
      free(Window);
141
3.21k
    Window=NewWindow;
142
3.21k
  }
143
144
3.21k
  MaxWinSize=WinSize;
145
3.21k
  MaxWinMask=MaxWinSize-1;
146
3.21k
}
147
148
149
void Unpack::DoUnpack(uint Method,bool Solid)
150
3.24k
{
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
3.24k
  switch(Method)
155
3.24k
  {
156
0
#ifndef SFX_MODULE
157
543
    case 15: // rar 1.5 compression
158
543
      if (!Fragmented)
159
543
        Unpack15(Solid);
160
543
      break;
161
2
    case 20: // rar 2.x compression
162
561
    case 26: // files larger than 2GB
163
561
      if (!Fragmented)
164
561
        Unpack20(Solid);
165
561
      break;
166
0
#endif
167
1.24k
    case 29: // rar 3.x compression
168
1.24k
      if (!Fragmented)
169
1.24k
        Unpack29(Solid);
170
1.24k
      break;
171
892
    case 50: // RAR 5.0 compression algorithm.
172
892
#ifdef RAR_SMP
173
892
      if (MaxUserThreads>1)
174
892
      {
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
892
          if (!Fragmented)
181
892
          {
182
892
            Unpack5MT(Solid);
183
892
            break;
184
892
          }
185
892
      }
186
0
#endif
187
0
      Unpack5(Solid);
188
0
      break;
189
3.24k
  }
190
3.24k
}
191
192
193
void Unpack::UnpInitData(bool Solid)
194
7.53k
{
195
7.53k
  if (!Solid)
196
7.49k
  {
197
7.49k
    memset(OldDist,0,sizeof(OldDist));
198
7.49k
    OldDistPtr=0;
199
7.49k
    LastDist=LastLength=0;
200
//    memset(Window,0,MaxWinSize);
201
7.49k
    memset(&BlockTables,0,sizeof(BlockTables));
202
7.49k
    UnpPtr=WrPtr=0;
203
7.49k
    WriteBorder=Min(MaxWinSize,UNPACK_MAX_WRITE)&MaxWinMask;
204
7.49k
  }
205
  // Filters never share several solid files, so we can safely reset them
206
  // even in solid archive.
207
7.53k
  InitFilters();
208
209
7.53k
  Inp.InitBitInput();
210
7.53k
  WrittenFileSize=0;
211
7.53k
  ReadTop=0;
212
7.53k
  ReadBorder=0;
213
214
7.53k
  memset(&BlockHeader,0,sizeof(BlockHeader));
215
7.53k
  BlockHeader.BlockSize=-1;  // '-1' means not defined yet.
216
7.53k
#ifndef SFX_MODULE
217
7.53k
  UnpInitData20(Solid);
218
7.53k
#endif
219
7.53k
  UnpInitData30(Solid);
220
7.53k
  UnpInitData50(Solid);
221
7.53k
}
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,
227
void Unpack::MakeDecodeTables(byte *LengthTable,DecodeTable *Dec,uint Size)
228
25.2k
{
229
  // Size of alphabet and DecodePos array.
230
25.2k
  Dec->MaxNum=Size;
231
232
  // Calculate how many entries for every bit length in LengthTable we have.
233
25.2k
  uint LengthCount[16];
234
25.2k
  memset(LengthCount,0,sizeof(LengthCount));
235
2.34M
  for (size_t I=0;I<Size;I++)
236
2.32M
    LengthCount[LengthTable[I] & 0xf]++;
237
238
  // We must not calculate the number of zero length codes.
239
25.2k
  LengthCount[0]=0;
240
241
  // Set the entire DecodeNum to zero.
242
25.2k
  memset(Dec->DecodeNum,0,Size*sizeof(*Dec->DecodeNum));
243
244
  // Initialize not really used entry for zero length code.
245
25.2k
  Dec->DecodePos[0]=0;
246
247
  // Start code for bit length 1 is 0.
248
25.2k
  Dec->DecodeLen[0]=0;
249
250
  // Right aligned upper limit code for current bit length.
251
25.2k
  uint UpperLimit=0;
252
253
403k
  for (size_t I=1;I<16;I++)
254
378k
  {
255
    // Adjust the upper limit code.
256
378k
    UpperLimit+=LengthCount[I];
257
258
    // Left aligned upper limit code.
259
378k
    uint LeftAligned=UpperLimit<<(16-I);
260
261
    // Prepare the upper limit code for next bit length.
262
378k
    UpperLimit*=2;
263
264
    // Store the left aligned upper limit code.
265
378k
    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
378k
    Dec->DecodePos[I]=Dec->DecodePos[I-1]+LengthCount[I-1];
270
378k
  }
271
272
  // Prepare the copy of DecodePos. We'll modify this copy below,
273
  // so we cannot use the original DecodePos.
274
25.2k
  uint CopyDecodePos[ASIZE(Dec->DecodePos)];
275
25.2k
  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
2.34M
  for (uint I=0;I<Size;I++)
280
2.32M
  {
281
    // Get the current bit length.
282
2.32M
    byte CurBitLength=LengthTable[I] & 0xf;
283
284
2.32M
    if (CurBitLength!=0)
285
1.98M
    {
286
      // Last position in code list for current bit length.
287
1.98M
      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
1.98M
      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
1.98M
      CopyDecodePos[CurBitLength]++;
297
1.98M
    }
298
2.32M
  }
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
25.2k
  switch (Size)
305
25.2k
  {
306
1.01k
    case NC:
307
1.40k
    case NC20:
308
4.82k
    case NC30:
309
4.82k
      Dec->QuickBits=MAX_QUICK_DECODE_BITS;
310
4.82k
      break;
311
20.4k
    default:
312
20.4k
      Dec->QuickBits=MAX_QUICK_DECODE_BITS-3;
313
20.4k
      break;
314
25.2k
  }
315
316
  // Size of tables for quick mode.
317
25.2k
  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
25.2k
  uint CurBitLength=1;
323
324
  // For every right aligned bit string which supports the quick decoding.
325
7.57M
  for (uint Code=0;Code<QuickDataSize;Code++)
326
7.55M
  {
327
    // Left align the current code, so it will be in usual bit field format.
328
7.55M
    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
7.86M
    while (CurBitLength<ASIZE(Dec->DecodeLen) && BitField>=Dec->DecodeLen[CurBitLength])
335
314k
      CurBitLength++;
336
337
    // Translation of right aligned bit string to bit length.
338
7.55M
    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
7.55M
    uint Dist=BitField-Dec->DecodeLen[CurBitLength-1];
345
346
    // Right align the distance.
347
7.55M
    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
7.55M
    uint Pos;
353
7.55M
    if (CurBitLength<ASIZE(Dec->DecodePos) &&
354
7.55M
        (Pos=Dec->DecodePos[CurBitLength]+Dist)<Size)
355
5.11M
    {
356
      // Define the code to alphabet number translation.
357
5.11M
      Dec->QuickNum[Code]=Dec->DecodeNum[Pos];
358
5.11M
    }
359
2.43M
    else
360
2.43M
    {
361
      // Can be here for length table filled with zeroes only (empty).
362
2.43M
      Dec->QuickNum[Code]=0;
363
2.43M
    }
364
7.55M
  }
365
25.2k
}