Coverage Report

Created: 2025-11-16 06:23

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/src/lzma-fuzz/sdk/C/Bcj2.c
Line
Count
Source
1
/* Bcj2.c -- BCJ2 Decoder (Converter for x86 code)
2
2018-04-28 : Igor Pavlov : Public domain */
3
4
#include "Precomp.h"
5
6
#include "Bcj2.h"
7
#include "CpuArch.h"
8
9
168
#define CProb UInt16
10
11
269
#define kTopValue ((UInt32)1 << 24)
12
20.9k
#define kNumModelBits 11
13
20.7k
#define kBitModelTotal (1 << kNumModelBits)
14
168
#define kNumMoveBits 5
15
16
168
#define _IF_BIT_0 ttt = *prob; bound = (p->range >> kNumModelBits) * ttt; if (p->code < bound)
17
145
#define _UPDATE_0 p->range = bound; *prob = (CProb)(ttt + ((kBitModelTotal - ttt) >> kNumMoveBits));
18
23
#define _UPDATE_1 p->range -= bound; p->code -= bound; *prob = (CProb)(ttt - (ttt >> kNumMoveBits));
19
20
void Bcj2Dec_Init(CBcj2Dec *p)
21
80
{
22
80
  unsigned i;
23
24
80
  p->state = BCJ2_DEC_STATE_OK;
25
80
  p->ip = 0;
26
80
  p->temp[3] = 0;
27
80
  p->range = 0;
28
80
  p->code = 0;
29
20.7k
  for (i = 0; i < sizeof(p->probs) / sizeof(p->probs[0]); i++)
30
20.6k
    p->probs[i] = kBitModelTotal >> 1;
31
80
}
32
33
SRes Bcj2Dec_Decode(CBcj2Dec *p)
34
80
{
35
80
  if (p->range <= 5)
36
80
  {
37
80
    p->state = BCJ2_DEC_STATE_OK;
38
476
    for (; p->range != 5; p->range++)
39
397
    {
40
397
      if (p->range == 1 && p->code != 0)
41
1
        return SZ_ERROR_DATA;
42
      
43
396
      if (p->bufs[BCJ2_STREAM_RC] == p->lims[BCJ2_STREAM_RC])
44
0
      {
45
0
        p->state = BCJ2_STREAM_RC;
46
0
        return SZ_OK;
47
0
      }
48
49
396
      p->code = (p->code << 8) | *(p->bufs[BCJ2_STREAM_RC])++;
50
396
    }
51
    
52
79
    if (p->code == 0xFFFFFFFF)
53
1
      return SZ_ERROR_DATA;
54
    
55
78
    p->range = 0xFFFFFFFF;
56
78
  }
57
0
  else if (p->state >= BCJ2_DEC_STATE_ORIG_0)
58
0
  {
59
0
    while (p->state <= BCJ2_DEC_STATE_ORIG_3)
60
0
    {
61
0
      Byte *dest = p->dest;
62
0
      if (dest == p->destLim)
63
0
        return SZ_OK;
64
0
      *dest = p->temp[(size_t)p->state - BCJ2_DEC_STATE_ORIG_0];
65
0
      p->state++;
66
0
      p->dest = dest + 1;
67
0
    }
68
0
  }
69
70
  /*
71
  if (BCJ2_IS_32BIT_STREAM(p->state))
72
  {
73
    const Byte *cur = p->bufs[p->state];
74
    if (cur == p->lims[p->state])
75
      return SZ_OK;
76
    p->bufs[p->state] = cur + 4;
77
    
78
    {
79
      UInt32 val;
80
      Byte *dest;
81
      SizeT rem;
82
      
83
      p->ip += 4;
84
      val = GetBe32(cur) - p->ip;
85
      dest = p->dest;
86
      rem = p->destLim - dest;
87
      if (rem < 4)
88
      {
89
        SizeT i;
90
        SetUi32(p->temp, val);
91
        for (i = 0; i < rem; i++)
92
          dest[i] = p->temp[i];
93
        p->dest = dest + rem;
94
        p->state = BCJ2_DEC_STATE_ORIG_0 + (unsigned)rem;
95
        return SZ_OK;
96
      }
97
      SetUi32(dest, val);
98
      p->temp[3] = (Byte)(val >> 24);
99
      p->dest = dest + 4;
100
      p->state = BCJ2_DEC_STATE_OK;
101
    }
102
  }
103
  */
104
105
78
  for (;;)
106
223
  {
107
223
    if (BCJ2_IS_32BIT_STREAM(p->state))
108
0
      p->state = BCJ2_DEC_STATE_OK;
109
223
    else
110
223
    {
111
223
      if (p->range < kTopValue)
112
3
      {
113
3
        if (p->bufs[BCJ2_STREAM_RC] == p->lims[BCJ2_STREAM_RC])
114
3
        {
115
3
          p->state = BCJ2_STREAM_RC;
116
3
          return SZ_OK;
117
3
        }
118
0
        p->range <<= 8;
119
0
        p->code = (p->code << 8) | *(p->bufs[BCJ2_STREAM_RC])++;
120
0
      }
121
122
220
      {
123
220
        const Byte *src = p->bufs[BCJ2_STREAM_MAIN];
124
220
        const Byte *srcLim;
125
220
        Byte *dest;
126
220
        SizeT num = p->lims[BCJ2_STREAM_MAIN] - src;
127
        
128
220
        if (num == 0)
129
1
        {
130
1
          p->state = BCJ2_STREAM_MAIN;
131
1
          return SZ_OK;
132
1
        }
133
        
134
219
        dest = p->dest;
135
219
        if (num > (SizeT)(p->destLim - dest))
136
0
        {
137
0
          num = p->destLim - dest;
138
0
          if (num == 0)
139
0
          {
140
0
            p->state = BCJ2_DEC_STATE_ORIG;
141
0
            return SZ_OK;
142
0
          }
143
0
        }
144
       
145
219
        srcLim = src + num;
146
147
219
        if (p->temp[3] == 0x0F && (src[0] & 0xF0) == 0x80)
148
0
          *dest = src[0];
149
219
        else for (;;)
150
4.03k
        {
151
4.03k
          Byte b = *src;
152
4.03k
          *dest = b;
153
4.03k
          if (b != 0x0F)
154
3.46k
          {
155
3.46k
            if ((b & 0xFE) == 0xE8)
156
102
              break;
157
3.35k
            dest++;
158
3.35k
            if (++src != srcLim)
159
3.31k
              continue;
160
48
            break;
161
3.35k
          }
162
569
          dest++;
163
569
          if (++src == srcLim)
164
3
            break;
165
566
          if ((*src & 0xF0) != 0x80)
166
500
            continue;
167
66
          *dest = *src;
168
66
          break;
169
566
        }
170
        
171
219
        num = src - p->bufs[BCJ2_STREAM_MAIN];
172
        
173
219
        if (src == srcLim)
174
51
        {
175
51
          p->temp[3] = src[-1];
176
51
          p->bufs[BCJ2_STREAM_MAIN] = src;
177
51
          p->ip += (UInt32)num;
178
51
          p->dest += num;
179
51
          p->state =
180
51
            p->bufs[BCJ2_STREAM_MAIN] ==
181
51
            p->lims[BCJ2_STREAM_MAIN] ?
182
51
              (unsigned)BCJ2_STREAM_MAIN :
183
51
              (unsigned)BCJ2_DEC_STATE_ORIG;
184
51
          return SZ_OK;
185
51
        }
186
        
187
168
        {
188
168
          UInt32 bound, ttt;
189
168
          CProb *prob;
190
168
          Byte b = src[0];
191
168
          Byte prev = (Byte)(num == 0 ? p->temp[3] : src[-1]);
192
          
193
168
          p->temp[3] = b;
194
168
          p->bufs[BCJ2_STREAM_MAIN] = src + 1;
195
168
          num++;
196
168
          p->ip += (UInt32)num;
197
168
          p->dest += num;
198
          
199
168
          prob = p->probs + (unsigned)(b == 0xE8 ? 2 + (unsigned)prev : (b == 0xE9 ? 1 : 0));
200
          
201
168
          _IF_BIT_0
202
145
          {
203
145
            _UPDATE_0
204
145
            continue;
205
145
          }
206
23
          _UPDATE_1
207
            
208
23
        }
209
23
      }
210
23
    }
211
212
23
    {
213
23
      UInt32 val;
214
23
      unsigned cj = (p->temp[3] == 0xE8) ? BCJ2_STREAM_CALL : BCJ2_STREAM_JUMP;
215
23
      const Byte *cur = p->bufs[cj];
216
23
      Byte *dest;
217
23
      SizeT rem;
218
      
219
23
      if (cur == p->lims[cj])
220
23
      {
221
23
        p->state = cj;
222
23
        break;
223
23
      }
224
      
225
0
      val = GetBe32(cur);
226
0
      p->bufs[cj] = cur + 4;
227
228
0
      p->ip += 4;
229
0
      val -= p->ip;
230
0
      dest = p->dest;
231
0
      rem = p->destLim - dest;
232
      
233
0
      if (rem < 4)
234
0
      {
235
0
        p->temp[0] = (Byte)val; if (rem > 0) dest[0] = (Byte)val; val >>= 8;
236
0
        p->temp[1] = (Byte)val; if (rem > 1) dest[1] = (Byte)val; val >>= 8;
237
0
        p->temp[2] = (Byte)val; if (rem > 2) dest[2] = (Byte)val; val >>= 8;
238
0
        p->temp[3] = (Byte)val;
239
0
        p->dest = dest + rem;
240
0
        p->state = BCJ2_DEC_STATE_ORIG_0 + (unsigned)rem;
241
0
        break;
242
0
      }
243
      
244
0
      SetUi32(dest, val);
245
0
      p->temp[3] = (Byte)(val >> 24);
246
0
      p->dest = dest + 4;
247
0
    }
248
0
  }
249
250
23
  if (p->range < kTopValue && p->bufs[BCJ2_STREAM_RC] != p->lims[BCJ2_STREAM_RC])
251
0
  {
252
0
    p->range <<= 8;
253
0
    p->code = (p->code << 8) | *(p->bufs[BCJ2_STREAM_RC])++;
254
0
  }
255
256
23
  return SZ_OK;
257
78
}