Coverage Report

Created: 2024-06-17 06:08

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