Coverage Report

Created: 2024-04-23 06:19

/src/unrar/unpack20.cpp
Line
Count
Source (jump to first uncovered line)
1
#include "rar.hpp"
2
3
void Unpack::CopyString20(uint Length,uint Distance)
4
1.77M
{
5
1.77M
  LastDist=OldDist[OldDistPtr++]=Distance;
6
1.77M
  OldDistPtr = OldDistPtr & 3; // Needed if RAR 1.5 file is called after RAR 2.0.
7
1.77M
  LastLength=Length;
8
1.77M
  DestUnpSize-=Length;
9
1.77M
  CopyString(Length,Distance);
10
1.77M
}
11
12
13
void Unpack::Unpack20(bool Solid)
14
561
{
15
561
  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};
16
561
  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};
17
561
  static uint DDecode[]={0,1,2,3,4,6,8,12,16,24,32,48,64,96,128,192,256,384,512,768,1024,1536,2048,3072,4096,6144,8192,12288,16384,24576,32768U,49152U,65536,98304,131072,196608,262144,327680,393216,458752,524288,589824,655360,720896,786432,851968,917504,983040};
18
561
  static unsigned char DBits[]=  {0,0,0,0,1,1,2, 2, 3, 3, 4, 4, 5, 5,  6,  6,  7,  7,  8,  8,   9,   9,  10,  10,  11,  11,  12,   12,   13,   13,    14,    14,   15,   15,    16,    16,    16,    16,    16,    16,    16,    16,    16,    16,    16,    16,    16,    16};
19
561
  static unsigned char SDDecode[]={0,4,8,16,32,64,128,192};
20
561
  static unsigned char SDBits[]=  {2,2,3, 4, 5, 6,  6,  6};
21
561
  uint Bits;
22
23
561
  if (Suspended)
24
0
    UnpPtr=WrPtr;
25
561
  else
26
561
  {
27
561
    UnpInitData(Solid);
28
561
    if (!UnpReadBuf())
29
1
      return;
30
560
    if ((!Solid || !TablesRead2) && !ReadTables20())
31
38
      return;
32
522
    --DestUnpSize;
33
522
  }
34
35
17.1M
  while (DestUnpSize>=0)
36
17.1M
  {
37
17.1M
    UnpPtr&=MaxWinMask;
38
39
17.1M
    if (Inp.InAddr>ReadTop-30)
40
40.5k
      if (!UnpReadBuf())
41
440
        break;
42
17.1M
    if (((WrPtr-UnpPtr) & MaxWinMask)<270 && WrPtr!=UnpPtr)
43
376
    {
44
376
      UnpWriteBuf20();
45
376
      if (Suspended)
46
0
        return;
47
376
    }
48
17.1M
    if (UnpAudioBlock)
49
11.1M
    {
50
11.1M
      uint AudioNumber=DecodeNumber(Inp,&MD[UnpCurChannel]);
51
52
11.1M
      if (AudioNumber==256)
53
134
      {
54
134
        if (!ReadTables20())
55
22
          break;
56
112
        continue;
57
134
      }
58
11.1M
      Window[UnpPtr++]=DecodeAudio((int)AudioNumber);
59
11.1M
      if (++UnpCurChannel==UnpChannels)
60
5.45M
        UnpCurChannel=0;
61
11.1M
      --DestUnpSize;
62
11.1M
      continue;
63
11.1M
    }
64
65
5.97M
    uint Number=DecodeNumber(Inp,&BlockTables.LD);
66
5.97M
    if (Number<256)
67
4.20M
    {
68
4.20M
      Window[UnpPtr++]=(byte)Number;
69
4.20M
      --DestUnpSize;
70
4.20M
      continue;
71
4.20M
    }
72
1.77M
    if (Number>269)
73
712k
    {
74
712k
      uint Length=LDecode[Number-=270]+3;
75
712k
      if ((Bits=LBits[Number])>0)
76
504k
      {
77
504k
        Length+=Inp.getbits()>>(16-Bits);
78
504k
        Inp.addbits(Bits);
79
504k
      }
80
81
712k
      uint DistNumber=DecodeNumber(Inp,&BlockTables.DD);
82
712k
      uint Distance=DDecode[DistNumber]+1;
83
712k
      if ((Bits=DBits[DistNumber])>0)
84
455k
      {
85
455k
        Distance+=Inp.getbits()>>(16-Bits);
86
455k
        Inp.addbits(Bits);
87
455k
      }
88
89
712k
      if (Distance>=0x2000)
90
16.7k
      {
91
16.7k
        Length++;
92
16.7k
        if (Distance>=0x40000L)
93
7.70k
          Length++;
94
16.7k
      }
95
96
712k
      CopyString20(Length,Distance);
97
712k
      continue;
98
712k
    }
99
1.06M
    if (Number==269)
100
127
    {
101
127
      if (!ReadTables20())
102
21
        break;
103
106
      continue;
104
127
    }
105
1.05M
    if (Number==256)
106
317k
    {
107
317k
      CopyString20(LastLength,LastDist);
108
317k
      continue;
109
317k
    }
110
741k
    if (Number<261)
111
55.2k
    {
112
55.2k
      uint Distance=OldDist[(OldDistPtr-(Number-256)) & 3];
113
55.2k
      uint LengthNumber=DecodeNumber(Inp,&BlockTables.RD);
114
55.2k
      uint Length=LDecode[LengthNumber]+2;
115
55.2k
      if ((Bits=LBits[LengthNumber])>0)
116
24.7k
      {
117
24.7k
        Length+=Inp.getbits()>>(16-Bits);
118
24.7k
        Inp.addbits(Bits);
119
24.7k
      }
120
55.2k
      if (Distance>=0x101)
121
8.78k
      {
122
8.78k
        Length++;
123
8.78k
        if (Distance>=0x2000)
124
6.97k
        {
125
6.97k
          Length++;
126
6.97k
          if (Distance>=0x40000)
127
2.36k
            Length++;
128
6.97k
        }
129
8.78k
      }
130
55.2k
      CopyString20(Length,Distance);
131
55.2k
      continue;
132
55.2k
    }
133
686k
    if (Number<270)
134
686k
    {
135
686k
      uint Distance=SDDecode[Number-=261]+1;
136
686k
      if ((Bits=SDBits[Number])>0)
137
686k
      {
138
686k
        Distance+=Inp.getbits()>>(16-Bits);
139
686k
        Inp.addbits(Bits);
140
686k
      }
141
686k
      CopyString20(2,Distance);
142
686k
      continue;
143
686k
   }
144
686k
  }
145
522
  ReadLastTables();
146
522
  UnpWriteBuf20();
147
522
}
148
149
150
void Unpack::UnpWriteBuf20()
151
1.78k
{
152
1.78k
  if (UnpPtr!=WrPtr)
153
1.76k
    UnpSomeRead=true;
154
1.78k
  if (UnpPtr<WrPtr)
155
721
  {
156
721
    UnpIO->UnpWrite(&Window[WrPtr],-(int)WrPtr & MaxWinMask);
157
721
    UnpIO->UnpWrite(Window,UnpPtr);
158
721
    UnpAllBuf=true;
159
721
  }
160
1.06k
  else
161
1.06k
    UnpIO->UnpWrite(&Window[WrPtr],UnpPtr-WrPtr);
162
1.78k
  WrPtr=UnpPtr;
163
1.78k
}
164
165
166
bool Unpack::ReadTables20()
167
823
{
168
823
  byte BitLength[BC20];
169
823
  byte Table[MC20*4];
170
823
  if (Inp.InAddr>ReadTop-25)
171
11
    if (!UnpReadBuf())
172
1
      return false;
173
822
  uint BitField=Inp.getbits();
174
822
  UnpAudioBlock=(BitField & 0x8000)!=0;
175
176
822
  if (!(BitField & 0x4000))
177
388
    memset(UnpOldTable20,0,sizeof(UnpOldTable20));
178
822
  Inp.addbits(2);
179
180
822
  uint TableSize;
181
822
  if (UnpAudioBlock)
182
387
  {
183
387
    UnpChannels=((BitField>>12) & 3)+1;
184
387
    if (UnpCurChannel>=UnpChannels)
185
9
      UnpCurChannel=0;
186
387
    Inp.addbits(2);
187
387
    TableSize=MC20*UnpChannels;
188
387
  }
189
435
  else
190
435
    TableSize=NC20+DC20+RC20;
191
192
16.4k
  for (uint I=0;I<BC20;I++)
193
15.6k
  {
194
15.6k
    BitLength[I]=(byte)(Inp.getbits() >> 12);
195
15.6k
    Inp.addbits(4);
196
15.6k
  }
197
822
  MakeDecodeTables(BitLength,&BlockTables.BD,BC20);
198
354k
  for (uint I=0;I<TableSize;)
199
353k
  {
200
353k
    if (Inp.InAddr>ReadTop-5)
201
466
      if (!UnpReadBuf())
202
50
        return false;
203
353k
    uint Number=DecodeNumber(Inp,&BlockTables.BD);
204
353k
    if (Number<16)
205
344k
    {
206
344k
      Table[I]=(Number+UnpOldTable20[I]) & 0xf;
207
344k
      I++;
208
344k
    }
209
9.01k
    else
210
9.01k
      if (Number==16)
211
5.34k
      {
212
5.34k
        uint N=(Inp.getbits() >> 14)+3;
213
5.34k
        Inp.addbits(2);
214
5.34k
        if (I==0)
215
32
          return false; // We cannot have "repeat previous" code at the first position.
216
5.31k
        else
217
27.4k
          while (N-- > 0 && I<TableSize)
218
22.1k
          {
219
22.1k
            Table[I]=Table[I-1];
220
22.1k
            I++;
221
22.1k
          }
222
5.34k
      }
223
3.66k
      else
224
3.66k
      {
225
3.66k
        uint N;
226
3.66k
        if (Number==17)
227
2.96k
        {
228
2.96k
          N=(Inp.getbits() >> 13)+3;
229
2.96k
          Inp.addbits(3);
230
2.96k
        }
231
696
        else
232
696
        {
233
696
          N=(Inp.getbits() >> 9)+11;
234
696
          Inp.addbits(7);
235
696
        }
236
51.8k
        while (N-- > 0 && I<TableSize)
237
48.1k
          Table[I++]=0;
238
3.66k
      }
239
353k
  }
240
740
  TablesRead2=true;
241
740
  if (Inp.InAddr>ReadTop)
242
2
    return true;
243
738
  if (UnpAudioBlock)
244
1.34k
    for (uint I=0;I<UnpChannels;I++)
245
995
      MakeDecodeTables(&Table[I*MC20],&MD[I],MC20);
246
390
  else
247
390
  {
248
390
    MakeDecodeTables(&Table[0],&BlockTables.LD,NC20);
249
390
    MakeDecodeTables(&Table[NC20],&BlockTables.DD,DC20);
250
390
    MakeDecodeTables(&Table[NC20+DC20],&BlockTables.RD,RC20);
251
390
  }
252
738
  memcpy(UnpOldTable20,Table,TableSize);
253
738
  return true;
254
740
}
255
256
257
void Unpack::ReadLastTables()
258
522
{
259
522
  if (ReadTop>=Inp.InAddr+5)
260
70
    if (UnpAudioBlock)
261
30
    {
262
30
      if (DecodeNumber(Inp,&MD[UnpCurChannel])==256)
263
1
        ReadTables20();
264
30
    }
265
40
    else
266
40
      if (DecodeNumber(Inp,&BlockTables.LD)==269)
267
1
        ReadTables20();
268
522
}
269
270
271
void Unpack::UnpInitData20(int Solid)
272
7.53k
{
273
7.53k
  if (!Solid)
274
7.49k
  {
275
7.49k
    TablesRead2=false;
276
7.49k
    UnpAudioBlock=false;
277
7.49k
    UnpChannelDelta=0;
278
7.49k
    UnpCurChannel=0;
279
7.49k
    UnpChannels=1;
280
281
7.49k
    memset(AudV,0,sizeof(AudV));
282
7.49k
    memset(UnpOldTable20,0,sizeof(UnpOldTable20));
283
7.49k
    memset(MD,0,sizeof(MD));
284
7.49k
  }
285
7.53k
}
286
287
288
byte Unpack::DecodeAudio(int Delta)
289
11.1M
{
290
11.1M
  struct AudioVariables *V=&AudV[UnpCurChannel];
291
11.1M
  V->ByteCount++;
292
11.1M
  V->D4=V->D3;
293
11.1M
  V->D3=V->D2;
294
11.1M
  V->D2=V->LastDelta-V->D1;
295
11.1M
  V->D1=V->LastDelta;
296
11.1M
  int PCh=8*V->LastChar+V->K1*V->D1+V->K2*V->D2+V->K3*V->D3+V->K4*V->D4+V->K5*UnpChannelDelta;
297
11.1M
  PCh=(PCh>>3) & 0xFF;
298
299
11.1M
  uint Ch=PCh-Delta;
300
301
11.1M
  int D=(signed char)Delta;
302
  // Left shift of negative value is undefined behavior in C++,
303
  // so we cast it to unsigned to follow the standard.
304
11.1M
  D=(uint)D<<3;
305
306
11.1M
  V->Dif[0]+=abs(D);
307
11.1M
  V->Dif[1]+=abs(D-V->D1);
308
11.1M
  V->Dif[2]+=abs(D+V->D1);
309
11.1M
  V->Dif[3]+=abs(D-V->D2);
310
11.1M
  V->Dif[4]+=abs(D+V->D2);
311
11.1M
  V->Dif[5]+=abs(D-V->D3);
312
11.1M
  V->Dif[6]+=abs(D+V->D3);
313
11.1M
  V->Dif[7]+=abs(D-V->D4);
314
11.1M
  V->Dif[8]+=abs(D+V->D4);
315
11.1M
  V->Dif[9]+=abs(D-UnpChannelDelta);
316
11.1M
  V->Dif[10]+=abs(D+UnpChannelDelta);
317
318
11.1M
  UnpChannelDelta=V->LastDelta=(signed char)(Ch-V->LastChar);
319
11.1M
  V->LastChar=Ch;
320
321
11.1M
  if ((V->ByteCount & 0x1F)==0)
322
348k
  {
323
348k
    uint MinDif=V->Dif[0],NumMinDif=0;
324
348k
    V->Dif[0]=0;
325
3.83M
    for (uint I=1;I<ASIZE(V->Dif);I++)
326
3.48M
    {
327
3.48M
      if (V->Dif[I]<MinDif)
328
702k
      {
329
702k
        MinDif=V->Dif[I];
330
702k
        NumMinDif=I;
331
702k
      }
332
3.48M
      V->Dif[I]=0;
333
3.48M
    }
334
348k
    switch(NumMinDif)
335
348k
    {
336
50.5k
      case 1:
337
50.5k
        if (V->K1>=-16)
338
49.0k
          V->K1--;
339
50.5k
        break;
340
54.7k
      case 2:
341
54.7k
        if (V->K1<16)
342
51.0k
          V->K1++;
343
54.7k
        break;
344
19.8k
      case 3:
345
19.8k
        if (V->K2>=-16)
346
19.1k
          V->K2--;
347
19.8k
        break;
348
20.0k
      case 4:
349
20.0k
        if (V->K2<16)
350
19.3k
          V->K2++;
351
20.0k
        break;
352
19.5k
      case 5:
353
19.5k
        if (V->K3>=-16)
354
19.0k
          V->K3--;
355
19.5k
        break;
356
19.7k
      case 6:
357
19.7k
        if (V->K3<16)
358
19.2k
          V->K3++;
359
19.7k
        break;
360
21.4k
      case 7:
361
21.4k
        if (V->K4>=-16)
362
20.9k
          V->K4--;
363
21.4k
        break;
364
21.4k
      case 8:
365
21.4k
        if (V->K4<16)
366
20.7k
          V->K4++;
367
21.4k
        break;
368
53.4k
      case 9:
369
53.4k
        if (V->K5>=-16)
370
51.8k
          V->K5--;
371
53.4k
        break;
372
56.1k
      case 10:
373
56.1k
        if (V->K5<16)
374
51.9k
          V->K5++;
375
56.1k
        break;
376
348k
    }
377
348k
  }
378
11.1M
  return (byte)Ch;
379
11.1M
}