Coverage Report

Created: 2024-04-23 06:19

/src/unrar/unpack15.cpp
Line
Count
Source
1
624k
#define STARTL1  2
2
static unsigned int DecL1[]={0x8000,0xa000,0xc000,0xd000,0xe000,0xea00,
3
                             0xee00,0xf000,0xf200,0xf200,0xffff};
4
static unsigned int PosL1[]={0,0,0,2,3,5,7,11,16,20,24,32,32};
5
6
1.54M
#define STARTL2  3
7
static unsigned int DecL2[]={0xa000,0xc000,0xd000,0xe000,0xea00,0xee00,
8
                             0xf000,0xf200,0xf240,0xffff};
9
static unsigned int PosL2[]={0,0,0,0,5,7,9,13,18,22,26,34,36};
10
11
2.07M
#define STARTHF0  4
12
static unsigned int DecHf0[]={0x8000,0xc000,0xe000,0xf200,0xf200,0xf200,
13
                              0xf200,0xf200,0xffff};
14
static unsigned int PosHf0[]={0,0,0,0,0,8,16,24,33,33,33,33,33};
15
16
17
1.50M
#define STARTHF1  5
18
static unsigned int DecHf1[]={0x2000,0xc000,0xe000,0xf000,0xf200,0xf200,
19
                              0xf7e0,0xffff};
20
static unsigned int PosHf1[]={0,0,0,0,0,0,4,44,60,76,80,80,127};
21
22
23
4.52M
#define STARTHF2  5
24
static unsigned int DecHf2[]={0x1000,0x2400,0x8000,0xc000,0xfa00,0xffff,
25
                              0xffff,0xffff};
26
static unsigned int PosHf2[]={0,0,0,0,0,0,2,7,53,117,233,0,0};
27
28
29
32.6k
#define STARTHF3  6
30
static unsigned int DecHf3[]={0x800,0x2400,0xee00,0xfe80,0xffff,0xffff,
31
                              0xffff};
32
static unsigned int PosHf3[]={0,0,0,0,0,0,0,2,16,218,251,0,0};
33
34
35
992k
#define STARTHF4  8
36
static unsigned int DecHf4[]={0xff00,0xffff,0xffff,0xffff,0xffff,0xffff};
37
static unsigned int PosHf4[]={0,0,0,0,0,0,0,0,0,255,0,0,0};
38
39
40
void Unpack::Unpack15(bool Solid)
41
543
{
42
543
  UnpInitData(Solid);
43
543
  UnpInitData15(Solid);
44
543
  UnpReadBuf();
45
543
  if (!Solid)
46
539
  {
47
539
    InitHuff();
48
539
    UnpPtr=0;
49
539
  }
50
4
  else
51
4
    UnpPtr=WrPtr;
52
543
  --DestUnpSize;
53
543
  if (DestUnpSize>=0)
54
537
  {
55
537
    GetFlagsBuf();
56
537
    FlagsCnt=8;
57
537
  }
58
59
7.88M
  while (DestUnpSize>=0)
60
7.88M
  {
61
7.88M
    UnpPtr&=MaxWinMask;
62
63
7.88M
    if (Inp.InAddr>ReadTop-30 && !UnpReadBuf())
64
477
      break;
65
7.88M
    if (((WrPtr-UnpPtr) & MaxWinMask)<270 && WrPtr!=UnpPtr)
66
346
      UnpWriteBuf20();
67
7.88M
    if (StMode)
68
67.8k
    {
69
67.8k
      HuffDecode();
70
67.8k
      continue;
71
67.8k
    }
72
73
7.82M
    if (--FlagsCnt < 0)
74
972k
    {
75
972k
      GetFlagsBuf();
76
972k
      FlagsCnt=7;
77
972k
    }
78
79
7.82M
    if (FlagBuf & 0x80)
80
4.03M
    {
81
4.03M
      FlagBuf<<=1;
82
4.03M
      if (Nlzb > Nhfb)
83
1.78M
        LongLZ();
84
2.24M
      else
85
2.24M
        HuffDecode();
86
4.03M
    }
87
3.78M
    else
88
3.78M
    {
89
3.78M
      FlagBuf<<=1;
90
3.78M
      if (--FlagsCnt < 0)
91
477k
      {
92
477k
        GetFlagsBuf();
93
477k
        FlagsCnt=7;
94
477k
      }
95
3.78M
      if (FlagBuf & 0x80)
96
1.72M
      {
97
1.72M
        FlagBuf<<=1;
98
1.72M
        if (Nlzb > Nhfb)
99
775k
          HuffDecode();
100
951k
        else
101
951k
          LongLZ();
102
1.72M
      }
103
2.05M
      else
104
2.05M
      {
105
2.05M
        FlagBuf<<=1;
106
2.05M
        ShortLZ();
107
2.05M
      }
108
3.78M
    }
109
7.82M
  }
110
543
  UnpWriteBuf20();
111
543
}
112
113
114
3.92M
#define GetShortLen1(pos) ((pos)==1 ? Buf60+3:ShortLen1[pos])
115
7.58M
#define GetShortLen2(pos) ((pos)==3 ? Buf60+3:ShortLen2[pos])
116
117
void Unpack::ShortLZ()
118
2.05M
{
119
2.05M
  static unsigned int ShortLen1[]={1,3,4,4,5,6,7,8,8,4,4,5,6,6,4,0};
120
2.05M
  static unsigned int ShortXor1[]={0,0xa0,0xd0,0xe0,0xf0,0xf8,0xfc,0xfe,
121
2.05M
                                   0xff,0xc0,0x80,0x90,0x98,0x9c,0xb0};
122
2.05M
  static unsigned int ShortLen2[]={2,3,3,3,4,4,5,6,6,4,4,5,6,6,4,0};
123
2.05M
  static unsigned int ShortXor2[]={0,0x40,0x60,0xa0,0xd0,0xe0,0xf0,0xf8,
124
2.05M
                                   0xfc,0xc0,0x80,0x90,0x98,0x9c,0xb0};
125
126
127
2.05M
  unsigned int Length,SaveLength;
128
2.05M
  unsigned int LastDistance;
129
2.05M
  unsigned int Distance;
130
2.05M
  int DistancePlace;
131
2.05M
  NumHuf=0;
132
133
2.05M
  unsigned int BitField=Inp.fgetbits();
134
2.05M
  if (LCount==2)
135
39.6k
  {
136
39.6k
    Inp.faddbits(1);
137
39.6k
    if (BitField >= 0x8000)
138
37.3k
    {
139
37.3k
      CopyString15((unsigned int)LastDist,LastLength);
140
37.3k
      return;
141
37.3k
    }
142
2.29k
    BitField <<= 1;
143
2.29k
    LCount=0;
144
2.29k
  }
145
146
2.01M
  BitField>>=8;
147
148
//  not thread safe, replaced by GetShortLen1 and GetShortLen2 macro
149
//  ShortLen1[1]=ShortLen2[3]=Buf60+3;
150
151
2.01M
  if (AvrLn1<37)
152
1.04M
  {
153
1.83M
    for (Length=0;;Length++)
154
2.88M
      if (((BitField^ShortXor1[Length]) & (~(0xff>>GetShortLen1(Length))))==0)
155
1.04M
        break;
156
1.04M
    Inp.faddbits(GetShortLen1(Length));
157
1.04M
  }
158
968k
  else
159
968k
  {
160
5.64M
    for (Length=0;;Length++)
161
6.61M
      if (((BitField^ShortXor2[Length]) & (~(0xff>>GetShortLen2(Length))))==0)
162
968k
        break;
163
968k
    Inp.faddbits(GetShortLen2(Length));
164
968k
  }
165
166
2.01M
  if (Length >= 9)
167
195k
  {
168
195k
    if (Length == 9)
169
30.9k
    {
170
30.9k
      LCount++;
171
30.9k
      CopyString15((unsigned int)LastDist,LastLength);
172
30.9k
      return;
173
30.9k
    }
174
164k
    if (Length == 14)
175
7.50k
    {
176
7.50k
      LCount=0;
177
7.50k
      Length=DecodeNum(Inp.fgetbits(),STARTL2,DecL2,PosL2)+5;
178
7.50k
      Distance=(Inp.fgetbits()>>1) | 0x8000;
179
7.50k
      Inp.faddbits(15);
180
7.50k
      LastLength=Length;
181
7.50k
      LastDist=Distance;
182
7.50k
      CopyString15(Distance,Length);
183
7.50k
      return;
184
7.50k
    }
185
186
156k
    LCount=0;
187
156k
    SaveLength=Length;
188
156k
    Distance=OldDist[(OldDistPtr-(Length-9)) & 3];
189
156k
    Length=DecodeNum(Inp.fgetbits(),STARTL1,DecL1,PosL1)+2;
190
156k
    if (Length==0x101 && SaveLength==10)
191
359
    {
192
359
      Buf60 ^= 1;
193
359
      return;
194
359
    }
195
156k
    if (Distance > 256)
196
56.8k
      Length++;
197
156k
    if (Distance >= MaxDist3)
198
18.7k
      Length++;
199
200
156k
    OldDist[OldDistPtr++]=Distance;
201
156k
    OldDistPtr = OldDistPtr & 3;
202
156k
    LastLength=Length;
203
156k
    LastDist=Distance;
204
156k
    CopyString15(Distance,Length);
205
156k
    return;
206
156k
  }
207
208
1.82M
  LCount=0;
209
1.82M
  AvrLn1 += Length;
210
1.82M
  AvrLn1 -= AvrLn1 >> 4;
211
212
1.82M
  DistancePlace=DecodeNum(Inp.fgetbits(),STARTHF2,DecHf2,PosHf2) & 0xff;
213
1.82M
  Distance=ChSetA[DistancePlace];
214
1.82M
  if (--DistancePlace != -1)
215
1.28M
  {
216
1.28M
    LastDistance=ChSetA[DistancePlace];
217
1.28M
    ChSetA[DistancePlace+1]=LastDistance;
218
1.28M
    ChSetA[DistancePlace]=Distance;
219
1.28M
  }
220
1.82M
  Length+=2;
221
1.82M
  OldDist[OldDistPtr++] = ++Distance;
222
1.82M
  OldDistPtr = OldDistPtr & 3;
223
1.82M
  LastLength=Length;
224
1.82M
  LastDist=Distance;
225
1.82M
  CopyString15(Distance,Length);
226
1.82M
}
227
228
229
void Unpack::LongLZ()
230
2.73M
{
231
2.73M
  unsigned int Length;
232
2.73M
  unsigned int Distance;
233
2.73M
  unsigned int DistancePlace,NewDistancePlace;
234
2.73M
  unsigned int OldAvr2,OldAvr3;
235
236
2.73M
  NumHuf=0;
237
2.73M
  Nlzb+=16;
238
2.73M
  if (Nlzb > 0xff)
239
256k
  {
240
256k
    Nlzb=0x90;
241
256k
    Nhfb >>= 1;
242
256k
  }
243
2.73M
  OldAvr2=AvrLn2;
244
245
2.73M
  unsigned int BitField=Inp.fgetbits();
246
2.73M
  if (AvrLn2 >= 122)
247
1.53M
    Length=DecodeNum(BitField,STARTL2,DecL2,PosL2);
248
1.20M
  else
249
1.20M
    if (AvrLn2 >= 64)
250
467k
      Length=DecodeNum(BitField,STARTL1,DecL1,PosL1);
251
735k
    else
252
735k
      if (BitField < 0x100)
253
44.1k
      {
254
44.1k
        Length=BitField;
255
44.1k
        Inp.faddbits(16);
256
44.1k
      }
257
691k
      else
258
691k
      {
259
2.26M
        for (Length=0;((BitField<<Length)&0x8000)==0;Length++)
260
1.57M
          ;
261
691k
        Inp.faddbits(Length+1);
262
691k
      }
263
264
2.73M
  AvrLn2 += Length;
265
2.73M
  AvrLn2 -= AvrLn2 >> 5;
266
267
2.73M
  BitField=Inp.fgetbits();
268
2.73M
  if (AvrPlcB > 0x28ff)
269
1.13M
    DistancePlace=DecodeNum(BitField,STARTHF2,DecHf2,PosHf2);
270
1.60M
  else
271
1.60M
    if (AvrPlcB > 0x6ff)
272
782k
      DistancePlace=DecodeNum(BitField,STARTHF1,DecHf1,PosHf1);
273
820k
    else
274
820k
      DistancePlace=DecodeNum(BitField,STARTHF0,DecHf0,PosHf0);
275
276
2.73M
  AvrPlcB += DistancePlace;
277
2.73M
  AvrPlcB -= AvrPlcB >> 8;
278
2.74M
  while (1)
279
2.74M
  {
280
2.74M
    Distance = ChSetB[DistancePlace & 0xff];
281
2.74M
    NewDistancePlace = NToPlB[Distance++ & 0xff]++;
282
2.74M
    if (!(Distance & 0xff))
283
3.33k
      CorrHuff(ChSetB,NToPlB);
284
2.73M
    else
285
2.73M
      break;
286
2.74M
  }
287
288
2.73M
  ChSetB[DistancePlace & 0xff]=ChSetB[NewDistancePlace];
289
2.73M
  ChSetB[NewDistancePlace]=Distance;
290
291
2.73M
  Distance=((Distance & 0xff00) | (Inp.fgetbits() >> 8)) >> 1;
292
2.73M
  Inp.faddbits(7);
293
294
2.73M
  OldAvr3=AvrLn3;
295
2.73M
  if (Length!=1 && Length!=4)
296
2.31M
    if (Length==0 && Distance <= MaxDist3)
297
664k
    {
298
664k
      AvrLn3++;
299
664k
      AvrLn3 -= AvrLn3 >> 8;
300
664k
    }
301
1.64M
    else
302
1.64M
      if (AvrLn3 > 0)
303
457k
        AvrLn3--;
304
2.73M
  Length+=3;
305
2.73M
  if (Distance >= MaxDist3)
306
920k
    Length++;
307
2.73M
  if (Distance <= 256)
308
245k
    Length+=8;
309
2.73M
  if (OldAvr3 > 0xb0 || AvrPlc >= 0x2a00 && OldAvr2 < 0x40)
310
812k
    MaxDist3=0x7f00;
311
1.92M
  else
312
1.92M
    MaxDist3=0x2001;
313
2.73M
  OldDist[OldDistPtr++]=Distance;
314
2.73M
  OldDistPtr = OldDistPtr & 3;
315
2.73M
  LastLength=Length;
316
2.73M
  LastDist=Distance;
317
2.73M
  CopyString15(Distance,Length);
318
2.73M
}
319
320
321
void Unpack::HuffDecode()
322
3.09M
{
323
3.09M
  unsigned int CurByte,NewBytePlace;
324
3.09M
  unsigned int Length;
325
3.09M
  unsigned int Distance;
326
3.09M
  int BytePlace;
327
328
3.09M
  unsigned int BitField=Inp.fgetbits();
329
330
3.09M
  if (AvrPlc > 0x75ff)
331
992k
    BytePlace=DecodeNum(BitField,STARTHF4,DecHf4,PosHf4);
332
2.10M
  else
333
2.10M
    if (AvrPlc > 0x5dff)
334
32.6k
      BytePlace=DecodeNum(BitField,STARTHF3,DecHf3,PosHf3);
335
2.06M
    else
336
2.06M
      if (AvrPlc > 0x35ff)
337
84.9k
        BytePlace=DecodeNum(BitField,STARTHF2,DecHf2,PosHf2);
338
1.98M
      else
339
1.98M
        if (AvrPlc > 0x0dff)
340
726k
          BytePlace=DecodeNum(BitField,STARTHF1,DecHf1,PosHf1);
341
1.25M
        else
342
1.25M
          BytePlace=DecodeNum(BitField,STARTHF0,DecHf0,PosHf0);
343
3.09M
  BytePlace&=0xff;
344
3.09M
  if (StMode)
345
67.8k
  {
346
67.8k
    if (BytePlace==0 && BitField > 0xfff)
347
2.64k
      BytePlace=0x100;
348
67.8k
    if (--BytePlace==-1)
349
28.2k
    {
350
28.2k
      BitField=Inp.fgetbits();
351
28.2k
      Inp.faddbits(1);
352
28.2k
      if (BitField & 0x8000)
353
967
      {
354
967
        NumHuf=StMode=0;
355
967
        return;
356
967
      }
357
27.2k
      else
358
27.2k
      {
359
27.2k
        Length = (BitField & 0x4000) ? 4 : 3;
360
27.2k
        Inp.faddbits(1);
361
27.2k
        Distance=DecodeNum(Inp.fgetbits(),STARTHF2,DecHf2,PosHf2);
362
27.2k
        Distance = (Distance << 5) | (Inp.fgetbits() >> 11);
363
27.2k
        Inp.faddbits(5);
364
27.2k
        CopyString15(Distance,Length);
365
27.2k
        return;
366
27.2k
      }
367
28.2k
    }
368
67.8k
  }
369
3.02M
  else
370
3.02M
    if (NumHuf++ >= 16 && FlagsCnt==0)
371
985
      StMode=1;
372
3.06M
  AvrPlc += BytePlace;
373
3.06M
  AvrPlc -= AvrPlc >> 8;
374
3.06M
  Nhfb+=16;
375
3.06M
  if (Nhfb > 0xff)
376
327k
  {
377
327k
    Nhfb=0x90;
378
327k
    Nlzb >>= 1;
379
327k
  }
380
381
3.06M
  Window[UnpPtr++]=(byte)(ChSet[BytePlace]>>8);
382
3.06M
  --DestUnpSize;
383
384
3.06M
  while (1)
385
3.06M
  {
386
3.06M
    CurByte=ChSet[BytePlace];
387
3.06M
    NewBytePlace=NToPl[CurByte++ & 0xff]++;
388
3.06M
    if ((CurByte & 0xff) > 0xa1)
389
4.94k
      CorrHuff(ChSet,NToPl);
390
3.06M
    else
391
3.06M
      break;
392
3.06M
  }
393
394
3.06M
  ChSet[BytePlace]=ChSet[NewBytePlace];
395
3.06M
  ChSet[NewBytePlace]=CurByte;
396
3.06M
}
397
398
399
void Unpack::GetFlagsBuf()
400
1.45M
{
401
1.45M
  unsigned int Flags,NewFlagsPlace;
402
1.45M
  unsigned int FlagsPlace=DecodeNum(Inp.fgetbits(),STARTHF2,DecHf2,PosHf2);
403
404
  // Our Huffman table stores 257 items and needs all them in other parts
405
  // of code such as when StMode is on, so the first item is control item.
406
  // While normally we do not use the last item to code the flags byte here,
407
  // we need to check for value 256 when unpacking in case we unpack
408
  // a corrupt archive.
409
1.45M
  if (FlagsPlace>=sizeof(ChSetC)/sizeof(ChSetC[0]))
410
78.1k
    return;
411
412
1.37M
  while (1)
413
1.37M
  {
414
1.37M
    Flags=ChSetC[FlagsPlace];
415
1.37M
    FlagBuf=Flags>>8;
416
1.37M
    NewFlagsPlace=NToPlC[Flags++ & 0xff]++;
417
1.37M
    if ((Flags & 0xff) != 0)
418
1.37M
      break;
419
1.27k
    CorrHuff(ChSetC,NToPlC);
420
1.27k
  }
421
422
1.37M
  ChSetC[FlagsPlace]=ChSetC[NewFlagsPlace];
423
1.37M
  ChSetC[NewFlagsPlace]=Flags;
424
1.37M
}
425
426
427
void Unpack::UnpInitData15(int Solid)
428
4.83k
{
429
4.83k
  if (!Solid)
430
4.83k
  {
431
4.83k
    AvrPlcB=AvrLn1=AvrLn2=AvrLn3=NumHuf=Buf60=0;
432
4.83k
    AvrPlc=0x3500;
433
4.83k
    MaxDist3=0x2001;
434
4.83k
    Nhfb=Nlzb=0x80;
435
4.83k
  }
436
4.83k
  FlagsCnt=0;
437
4.83k
  FlagBuf=0;
438
4.83k
  StMode=0;
439
4.83k
  LCount=0;
440
4.83k
  ReadTop=0;
441
4.83k
}
442
443
444
void Unpack::InitHuff()
445
4.83k
{
446
1.24M
  for (unsigned int I=0;I<256;I++)
447
1.23M
  {
448
1.23M
    ChSet[I]=ChSetB[I]=I<<8;
449
1.23M
    ChSetA[I]=I;
450
1.23M
    ChSetC[I]=((~I+1) & 0xff)<<8;
451
1.23M
  }
452
4.83k
  memset(NToPl,0,sizeof(NToPl));
453
4.83k
  memset(NToPlB,0,sizeof(NToPlB));
454
4.83k
  memset(NToPlC,0,sizeof(NToPlC));
455
4.83k
  CorrHuff(ChSetB,NToPlB);
456
4.83k
}
457
458
459
void Unpack::CorrHuff(ushort *CharSet,byte *NumToPlace)
460
14.3k
{
461
14.3k
  int I,J;
462
129k
  for (I=7;I>=0;I--)
463
3.79M
    for (J=0;J<32;J++,CharSet++)
464
3.68M
      *CharSet=(*CharSet & ~0xff) | I;
465
14.3k
  memset(NumToPlace,0,sizeof(NToPl));
466
115k
  for (I=6;I>=0;I--)
467
100k
    NumToPlace[I]=(7-I)*32;
468
14.3k
}
469
470
471
void Unpack::CopyString15(uint Distance,uint Length)
472
4.82M
{
473
4.82M
  DestUnpSize-=Length;
474
109M
  while (Length--)
475
104M
  {
476
104M
    Window[UnpPtr]=Window[(UnpPtr-Distance) & MaxWinMask];
477
104M
    UnpPtr=(UnpPtr+1) & MaxWinMask;
478
104M
  }
479
4.82M
}
480
481
482
uint Unpack::DecodeNum(uint Num,uint StartPos,uint *DecTab,uint *PosTab)
483
11.3M
{
484
11.3M
  int I;
485
32.3M
  for (Num&=0xfff0,I=0;DecTab[I]<=Num;I++)
486
21.0M
    StartPos++;
487
11.3M
  Inp.faddbits(StartPos);
488
11.3M
  return(((Num-(I ? DecTab[I-1]:0))>>(16-StartPos))+PosTab[StartPos]);
489
11.3M
}