Coverage Report

Created: 2025-08-29 06:07

/src/lzma-fuzz/sdk/C/Bcj2.c
Line
Count
Source (jump to first uncovered line)
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
258
#define CProb UInt16
10
11
392
#define kTopValue ((UInt32)1 << 24)
12
26.5k
#define kNumModelBits 11
13
26.2k
#define kBitModelTotal (1 << kNumModelBits)
14
258
#define kNumMoveBits 5
15
16
258
#define _IF_BIT_0 ttt = *prob; bound = (p->range >> kNumModelBits) * ttt; if (p->code < bound)
17
217
#define _UPDATE_0 p->range = bound; *prob = (CProb)(ttt + ((kBitModelTotal - ttt) >> kNumMoveBits));
18
41
#define _UPDATE_1 p->range -= bound; p->code -= bound; *prob = (CProb)(ttt - (ttt >> kNumMoveBits));
19
20
void Bcj2Dec_Init(CBcj2Dec *p)
21
101
{
22
101
  unsigned i;
23
24
101
  p->state = BCJ2_DEC_STATE_OK;
25
101
  p->ip = 0;
26
101
  p->temp[3] = 0;
27
101
  p->range = 0;
28
101
  p->code = 0;
29
26.1k
  for (i = 0; i < sizeof(p->probs) / sizeof(p->probs[0]); i++)
30
26.0k
    p->probs[i] = kBitModelTotal >> 1;
31
101
}
32
33
SRes Bcj2Dec_Decode(CBcj2Dec *p)
34
101
{
35
101
  if (p->range <= 5)
36
101
  {
37
101
    p->state = BCJ2_DEC_STATE_OK;
38
578
    for (; p->range != 5; p->range++)
39
484
    {
40
484
      if (p->range == 1 && p->code != 0)
41
7
        return SZ_ERROR_DATA;
42
      
43
477
      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
477
      p->code = (p->code << 8) | *(p->bufs[BCJ2_STREAM_RC])++;
50
477
    }
51
    
52
94
    if (p->code == 0xFFFFFFFF)
53
1
      return SZ_ERROR_DATA;
54
    
55
93
    p->range = 0xFFFFFFFF;
56
93
  }
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
93
  for (;;)
106
310
  {
107
310
    if (BCJ2_IS_32BIT_STREAM(p->state))
108
0
      p->state = BCJ2_DEC_STATE_OK;
109
310
    else
110
310
    {
111
310
      if (p->range < kTopValue)
112
6
      {
113
6
        if (p->bufs[BCJ2_STREAM_RC] == p->lims[BCJ2_STREAM_RC])
114
6
        {
115
6
          p->state = BCJ2_STREAM_RC;
116
6
          return SZ_OK;
117
6
        }
118
0
        p->range <<= 8;
119
0
        p->code = (p->code << 8) | *(p->bufs[BCJ2_STREAM_RC])++;
120
0
      }
121
122
304
      {
123
304
        const Byte *src = p->bufs[BCJ2_STREAM_MAIN];
124
304
        const Byte *srcLim;
125
304
        Byte *dest;
126
304
        SizeT num = p->lims[BCJ2_STREAM_MAIN] - src;
127
        
128
304
        if (num == 0)
129
3
        {
130
3
          p->state = BCJ2_STREAM_MAIN;
131
3
          return SZ_OK;
132
3
        }
133
        
134
301
        dest = p->dest;
135
301
        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
301
        srcLim = src + num;
146
147
301
        if (p->temp[3] == 0x0F && (src[0] & 0xF0) == 0x80)
148
0
          *dest = src[0];
149
301
        else for (;;)
150
4.15k
        {
151
4.15k
          Byte b = *src;
152
4.15k
          *dest = b;
153
4.15k
          if (b != 0x0F)
154
3.84k
          {
155
3.84k
            if ((b & 0xFE) == 0xE8)
156
198
              break;
157
3.65k
            dest++;
158
3.65k
            if (++src != srcLim)
159
3.61k
              continue;
160
33
            break;
161
3.65k
          }
162
309
          dest++;
163
309
          if (++src == srcLim)
164
10
            break;
165
299
          if ((*src & 0xF0) != 0x80)
166
239
            continue;
167
60
          *dest = *src;
168
60
          break;
169
299
        }
170
        
171
301
        num = src - p->bufs[BCJ2_STREAM_MAIN];
172
        
173
301
        if (src == srcLim)
174
43
        {
175
43
          p->temp[3] = src[-1];
176
43
          p->bufs[BCJ2_STREAM_MAIN] = src;
177
43
          p->ip += (UInt32)num;
178
43
          p->dest += num;
179
43
          p->state =
180
43
            p->bufs[BCJ2_STREAM_MAIN] ==
181
43
            p->lims[BCJ2_STREAM_MAIN] ?
182
43
              (unsigned)BCJ2_STREAM_MAIN :
183
43
              (unsigned)BCJ2_DEC_STATE_ORIG;
184
43
          return SZ_OK;
185
43
        }
186
        
187
258
        {
188
258
          UInt32 bound, ttt;
189
258
          CProb *prob;
190
258
          Byte b = src[0];
191
258
          Byte prev = (Byte)(num == 0 ? p->temp[3] : src[-1]);
192
          
193
258
          p->temp[3] = b;
194
258
          p->bufs[BCJ2_STREAM_MAIN] = src + 1;
195
258
          num++;
196
258
          p->ip += (UInt32)num;
197
258
          p->dest += num;
198
          
199
258
          prob = p->probs + (unsigned)(b == 0xE8 ? 2 + (unsigned)prev : (b == 0xE9 ? 1 : 0));
200
          
201
258
          _IF_BIT_0
202
217
          {
203
217
            _UPDATE_0
204
217
            continue;
205
217
          }
206
41
          _UPDATE_1
207
            
208
41
        }
209
41
      }
210
41
    }
211
212
41
    {
213
41
      UInt32 val;
214
41
      unsigned cj = (p->temp[3] == 0xE8) ? BCJ2_STREAM_CALL : BCJ2_STREAM_JUMP;
215
41
      const Byte *cur = p->bufs[cj];
216
41
      Byte *dest;
217
41
      SizeT rem;
218
      
219
41
      if (cur == p->lims[cj])
220
41
      {
221
41
        p->state = cj;
222
41
        break;
223
41
      }
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
41
  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
41
  return SZ_OK;
257
93
}