Coverage Report

Created: 2023-06-07 06:02

/src/unrar/unpackinline.cpp
Line
Count
Source (jump to first uncovered line)
1
_forceinline void Unpack::InsertOldDist(uint Distance)
2
0
{
3
0
  OldDist[3]=OldDist[2];
4
0
  OldDist[2]=OldDist[1];
5
0
  OldDist[1]=OldDist[0];
6
0
  OldDist[0]=Distance;
7
0
}
8
9
#ifdef _MSC_VER
10
#define FAST_MEMCPY
11
#endif
12
13
_forceinline void Unpack::CopyString(uint Length,uint Distance)
14
0
{
15
0
  size_t SrcPtr=UnpPtr-Distance;
16
0
  if (SrcPtr<MaxWinSize-MAX_INC_LZ_MATCH && UnpPtr<MaxWinSize-MAX_INC_LZ_MATCH)
17
0
  {
18
    // If we are not close to end of window, we do not need to waste time
19
    // to "& MaxWinMask" pointer protection.
20
21
0
    byte *Src=Window+SrcPtr;
22
0
    byte *Dest=Window+UnpPtr;
23
0
    UnpPtr+=Length;
24
25
#ifdef FAST_MEMCPY
26
    if (Distance<Length) // Overlapping strings
27
#endif
28
0
      while (Length>=8)
29
0
      {
30
0
        Dest[0]=Src[0];
31
0
        Dest[1]=Src[1];
32
0
        Dest[2]=Src[2];
33
0
        Dest[3]=Src[3];
34
0
        Dest[4]=Src[4];
35
0
        Dest[5]=Src[5];
36
0
        Dest[6]=Src[6];
37
0
        Dest[7]=Src[7];
38
39
0
        Src+=8;
40
0
        Dest+=8;
41
0
        Length-=8;
42
0
      }
43
#ifdef FAST_MEMCPY
44
    else
45
      while (Length>=8)
46
      {
47
        // In theory we still could overlap here.
48
        // Supposing Distance == MaxWinSize - 1 we have memcpy(Src, Src + 1, 8).
49
        // But for real RAR archives Distance <= MaxWinSize - MAX_INC_LZ_MATCH
50
        // always, so overlap here is impossible.
51
52
        // This memcpy expanded inline by MSVC. We could also use uint64
53
        // assignment, which seems to provide about the same speed.
54
        memcpy(Dest,Src,8); 
55
56
        Src+=8;
57
        Dest+=8;
58
        Length-=8;
59
      }
60
#endif
61
62
    // Unroll the loop for 0 - 7 bytes left. Note that we use nested "if"s.
63
0
    if (Length>0) { Dest[0]=Src[0];
64
0
    if (Length>1) { Dest[1]=Src[1];
65
0
    if (Length>2) { Dest[2]=Src[2];
66
0
    if (Length>3) { Dest[3]=Src[3];
67
0
    if (Length>4) { Dest[4]=Src[4];
68
0
    if (Length>5) { Dest[5]=Src[5];
69
0
    if (Length>6) { Dest[6]=Src[6]; } } } } } } } // Close all nested "if"s.
70
0
  }
71
0
  else
72
0
    while (Length-- > 0) // Slow copying with all possible precautions.
73
0
    {
74
0
      Window[UnpPtr]=Window[SrcPtr++ & MaxWinMask];
75
      // We need to have masked UnpPtr after quit from loop, so it must not
76
      // be replaced with 'Window[UnpPtr++ & MaxWinMask]'
77
0
      UnpPtr=(UnpPtr+1) & MaxWinMask;
78
0
    }
79
0
}
80
81
82
_forceinline uint Unpack::DecodeNumber(BitInput &Inp,DecodeTable *Dec)
83
0
{
84
  // Left aligned 15 bit length raw bit field.
85
0
  uint BitField=Inp.getbits() & 0xfffe;
86
87
0
  if (BitField<Dec->DecodeLen[Dec->QuickBits])
88
0
  {
89
0
    uint Code=BitField>>(16-Dec->QuickBits);
90
0
    Inp.addbits(Dec->QuickLen[Code]);
91
0
    return Dec->QuickNum[Code];
92
0
  }
93
94
  // Detect the real bit length for current code.
95
0
  uint Bits=15;
96
0
  for (uint I=Dec->QuickBits+1;I<15;I++)
97
0
    if (BitField<Dec->DecodeLen[I])
98
0
    {
99
0
      Bits=I;
100
0
      break;
101
0
    }
102
103
0
  Inp.addbits(Bits);
104
  
105
  // Calculate the distance from the start code for current bit length.
106
0
  uint Dist=BitField-Dec->DecodeLen[Bits-1];
107
108
  // Start codes are left aligned, but we need the normal right aligned
109
  // number. So we shift the distance to the right.
110
0
  Dist>>=(16-Bits);
111
112
  // Now we can calculate the position in the code list. It is the sum
113
  // of first position for current bit length and right aligned distance
114
  // between our bit field and start code for current bit length.
115
0
  uint Pos=Dec->DecodePos[Bits]+Dist;
116
117
  // Out of bounds safety check required for damaged archives.
118
0
  if (Pos>=Dec->MaxNum)
119
0
    Pos=0;
120
121
  // Convert the position in the code list to position in alphabet
122
  // and return it.
123
0
  return Dec->DecodeNum[Pos];
124
0
}
125
126
127
_forceinline uint Unpack::SlotToLength(BitInput &Inp,uint Slot)
128
0
{
129
0
  uint LBits,Length=2;
130
0
  if (Slot<8)
131
0
  {
132
0
    LBits=0;
133
0
    Length+=Slot;
134
0
  }
135
0
  else
136
0
  {
137
0
    LBits=Slot/4-1;
138
0
    Length+=(4 | (Slot & 3)) << LBits;
139
0
  }
140
141
0
  if (LBits>0)
142
0
  {
143
0
    Length+=Inp.getbits()>>(16-LBits);
144
0
    Inp.addbits(LBits);
145
0
  }
146
0
  return Length;
147
0
}