Coverage Report

Created: 2024-07-27 06:12

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