Coverage Report

Created: 2024-07-27 06:17

/src/lzma-fuzz/sdk/C/Lzma2Dec.c
Line
Count
Source (jump to first uncovered line)
1
/* Lzma2Dec.c -- LZMA2 Decoder
2
2019-02-02 : Igor Pavlov : Public domain */
3
4
/* #define SHOW_DEBUG_INFO */
5
6
#include "Precomp.h"
7
8
#ifdef SHOW_DEBUG_INFO
9
#include <stdio.h>
10
#endif
11
12
#include <string.h>
13
14
#include "Lzma2Dec.h"
15
16
/*
17
00000000  -  End of data
18
00000001 U U  -  Uncompressed, reset dic, need reset state and set new prop
19
00000010 U U  -  Uncompressed, no reset
20
100uuuuu U U P P  -  LZMA, no reset
21
101uuuuu U U P P  -  LZMA, reset state
22
110uuuuu U U P P S  -  LZMA, reset state + set new prop
23
111uuuuu U U P P S  -  LZMA, reset state + set new prop, reset dic
24
25
  u, U - Unpack Size
26
  P - Pack Size
27
  S - Props
28
*/
29
30
8.84k
#define LZMA2_CONTROL_COPY_RESET_DIC 1
31
32
49.3k
#define LZMA2_IS_UNCOMPRESSED_STATE(p) (((p)->control & (1 << 7)) == 0)
33
34
14.0k
#define LZMA2_LCLP_MAX 4
35
15.5k
#define LZMA2_DIC_SIZE_FROM_PROP(p) (((UInt32)2 | ((p) & 1)) << ((p) / 2 + 11))
36
37
#ifdef SHOW_DEBUG_INFO
38
#define PRF(x) x
39
#else
40
#define PRF(x)
41
#endif
42
43
typedef enum
44
{
45
  LZMA2_STATE_CONTROL,
46
  LZMA2_STATE_UNPACK0,
47
  LZMA2_STATE_UNPACK1,
48
  LZMA2_STATE_PACK0,
49
  LZMA2_STATE_PACK1,
50
  LZMA2_STATE_PROP,
51
  LZMA2_STATE_DATA,
52
  LZMA2_STATE_DATA_CONT,
53
  LZMA2_STATE_FINISHED,
54
  LZMA2_STATE_ERROR
55
} ELzma2State;
56
57
static SRes Lzma2Dec_GetOldProps(Byte prop, Byte *props)
58
7.77k
{
59
7.77k
  UInt32 dicSize;
60
7.77k
  if (prop > 40)
61
0
    return SZ_ERROR_UNSUPPORTED;
62
7.77k
  dicSize = (prop == 40) ? 0xFFFFFFFF : LZMA2_DIC_SIZE_FROM_PROP(prop);
63
7.77k
  props[0] = (Byte)LZMA2_LCLP_MAX;
64
7.77k
  props[1] = (Byte)(dicSize);
65
7.77k
  props[2] = (Byte)(dicSize >> 8);
66
7.77k
  props[3] = (Byte)(dicSize >> 16);
67
7.77k
  props[4] = (Byte)(dicSize >> 24);
68
7.77k
  return SZ_OK;
69
7.77k
}
70
71
SRes Lzma2Dec_AllocateProbs(CLzma2Dec *p, Byte prop, ISzAllocPtr alloc)
72
0
{
73
0
  Byte props[LZMA_PROPS_SIZE];
74
0
  RINOK(Lzma2Dec_GetOldProps(prop, props));
75
0
  return LzmaDec_AllocateProbs(&p->decoder, props, LZMA_PROPS_SIZE, alloc);
76
0
}
77
78
SRes Lzma2Dec_Allocate(CLzma2Dec *p, Byte prop, ISzAllocPtr alloc)
79
7.77k
{
80
7.77k
  Byte props[LZMA_PROPS_SIZE];
81
7.77k
  RINOK(Lzma2Dec_GetOldProps(prop, props));
82
7.77k
  return LzmaDec_Allocate(&p->decoder, props, LZMA_PROPS_SIZE, alloc);
83
7.77k
}
84
85
void Lzma2Dec_Init(CLzma2Dec *p)
86
7.77k
{
87
7.77k
  p->state = LZMA2_STATE_CONTROL;
88
7.77k
  p->needInitLevel = 0xE0;
89
7.77k
  p->isExtraMode = False;
90
7.77k
  p->unpackSize = 0;
91
  
92
  // p->decoder.dicPos = 0; // we can use it instead of full init
93
7.77k
  LzmaDec_Init(&p->decoder);
94
7.77k
}
95
96
static ELzma2State Lzma2Dec_UpdateState(CLzma2Dec *p, Byte b)
97
67.7k
{
98
67.7k
  switch (p->state)
99
67.7k
  {
100
20.2k
    case LZMA2_STATE_CONTROL:
101
20.2k
      p->isExtraMode = False;
102
20.2k
      p->control = b;
103
20.2k
      PRF(printf("\n %8X", (unsigned)p->decoder.dicPos));
104
20.2k
      PRF(printf(" %02X", (unsigned)b));
105
20.2k
      if (b == 0)
106
7.77k
        return LZMA2_STATE_FINISHED;
107
12.5k
      if (LZMA2_IS_UNCOMPRESSED_STATE(p))
108
4.42k
      {
109
4.42k
        if (b == LZMA2_CONTROL_COPY_RESET_DIC)
110
1.68k
          p->needInitLevel = 0xC0;
111
2.73k
        else if (b > 2 || p->needInitLevel == 0xE0)
112
0
          return LZMA2_STATE_ERROR;
113
4.42k
      }
114
8.08k
      else
115
8.08k
      {
116
8.08k
        if (b < p->needInitLevel)
117
0
          return LZMA2_STATE_ERROR;
118
8.08k
        p->needInitLevel = 0;
119
8.08k
        p->unpackSize = (UInt32)(b & 0x1F) << 16;
120
8.08k
      }
121
12.5k
      return LZMA2_STATE_UNPACK0;
122
    
123
12.5k
    case LZMA2_STATE_UNPACK0:
124
12.5k
      p->unpackSize |= (UInt32)b << 8;
125
12.5k
      return LZMA2_STATE_UNPACK1;
126
    
127
12.5k
    case LZMA2_STATE_UNPACK1:
128
12.5k
      p->unpackSize |= (UInt32)b;
129
12.5k
      p->unpackSize++;
130
12.5k
      PRF(printf(" %7u", (unsigned)p->unpackSize));
131
12.5k
      return LZMA2_IS_UNCOMPRESSED_STATE(p) ? LZMA2_STATE_DATA : LZMA2_STATE_PACK0;
132
    
133
8.08k
    case LZMA2_STATE_PACK0:
134
8.08k
      p->packSize = (UInt32)b << 8;
135
8.08k
      return LZMA2_STATE_PACK1;
136
137
8.08k
    case LZMA2_STATE_PACK1:
138
8.08k
      p->packSize |= (UInt32)b;
139
8.08k
      p->packSize++;
140
      // if (p->packSize < 5) return LZMA2_STATE_ERROR;
141
8.08k
      PRF(printf(" %5u", (unsigned)p->packSize));
142
8.08k
      return (p->control & 0x40) ? LZMA2_STATE_PROP : LZMA2_STATE_DATA;
143
144
6.23k
    case LZMA2_STATE_PROP:
145
6.23k
    {
146
6.23k
      unsigned lc, lp;
147
6.23k
      if (b >= (9 * 5 * 5))
148
0
        return LZMA2_STATE_ERROR;
149
6.23k
      lc = b % 9;
150
6.23k
      b /= 9;
151
6.23k
      p->decoder.prop.pb = (Byte)(b / 5);
152
6.23k
      lp = b % 5;
153
6.23k
      if (lc + lp > LZMA2_LCLP_MAX)
154
0
        return LZMA2_STATE_ERROR;
155
6.23k
      p->decoder.prop.lc = (Byte)lc;
156
6.23k
      p->decoder.prop.lp = (Byte)lp;
157
6.23k
      return LZMA2_STATE_DATA;
158
6.23k
    }
159
67.7k
  }
160
0
  return LZMA2_STATE_ERROR;
161
67.7k
}
162
163
static void LzmaDec_UpdateWithUncompressed(CLzmaDec *p, const Byte *src, SizeT size)
164
5.18k
{
165
5.18k
  memcpy(p->dic + p->dicPos, src, size);
166
5.18k
  p->dicPos += size;
167
5.18k
  if (p->checkDicSize == 0 && p->prop.dicSize - p->processedPos <= size)
168
0
    p->checkDicSize = p->prop.dicSize;
169
5.18k
  p->processedPos += (UInt32)size;
170
5.18k
}
171
172
void LzmaDec_InitDicAndState(CLzmaDec *p, BoolInt initDic, BoolInt initState);
173
174
175
SRes Lzma2Dec_DecodeToDic(CLzma2Dec *p, SizeT dicLimit,
176
    const Byte *src, SizeT *srcLen, ELzmaFinishMode finishMode, ELzmaStatus *status)
177
26.9k
{
178
26.9k
  SizeT inSize = *srcLen;
179
26.9k
  *srcLen = 0;
180
26.9k
  *status = LZMA_STATUS_NOT_SPECIFIED;
181
182
116k
  while (p->state != LZMA2_STATE_ERROR)
183
116k
  {
184
116k
    SizeT dicPos;
185
186
116k
    if (p->state == LZMA2_STATE_FINISHED)
187
23.1k
    {
188
23.1k
      *status = LZMA_STATUS_FINISHED_WITH_MARK;
189
23.1k
      return SZ_OK;
190
23.1k
    }
191
    
192
93.8k
    dicPos = p->decoder.dicPos;
193
    
194
93.8k
    if (dicPos == dicLimit && finishMode == LZMA_FINISH_ANY)
195
1.71k
    {
196
1.71k
      *status = LZMA_STATUS_NOT_FINISHED;
197
1.71k
      return SZ_OK;
198
1.71k
    }
199
200
92.1k
    if (p->state != LZMA2_STATE_DATA && p->state != LZMA2_STATE_DATA_CONT)
201
67.7k
    {
202
67.7k
      if (*srcLen == inSize)
203
61
      {
204
61
        *status = LZMA_STATUS_NEEDS_MORE_INPUT;
205
61
        return SZ_OK;
206
61
      }
207
67.7k
      (*srcLen)++;
208
67.7k
      p->state = Lzma2Dec_UpdateState(p, *src++);
209
67.7k
      if (dicPos == dicLimit && p->state != LZMA2_STATE_FINISHED)
210
0
        break;
211
67.7k
      continue;
212
67.7k
    }
213
    
214
24.3k
    {
215
24.3k
      SizeT inCur = inSize - *srcLen;
216
24.3k
      SizeT outCur = dicLimit - dicPos;
217
24.3k
      ELzmaFinishMode curFinishMode = LZMA_FINISH_ANY;
218
      
219
24.3k
      if (outCur >= p->unpackSize)
220
22.5k
      {
221
22.5k
        outCur = (SizeT)p->unpackSize;
222
22.5k
        curFinishMode = LZMA_FINISH_END;
223
22.5k
      }
224
225
24.3k
      if (LZMA2_IS_UNCOMPRESSED_STATE(p))
226
6.02k
      {
227
6.02k
        if (inCur == 0)
228
836
        {
229
836
          *status = LZMA_STATUS_NEEDS_MORE_INPUT;
230
836
          return SZ_OK;
231
836
        }
232
233
5.18k
        if (p->state == LZMA2_STATE_DATA)
234
4.42k
        {
235
4.42k
          BoolInt initDic = (p->control == LZMA2_CONTROL_COPY_RESET_DIC);
236
4.42k
          LzmaDec_InitDicAndState(&p->decoder, initDic, False);
237
4.42k
        }
238
239
5.18k
        if (inCur > outCur)
240
4.89k
          inCur = outCur;
241
5.18k
        if (inCur == 0)
242
0
          break;
243
244
5.18k
        LzmaDec_UpdateWithUncompressed(&p->decoder, src, inCur);
245
246
5.18k
        src += inCur;
247
5.18k
        *srcLen += inCur;
248
5.18k
        p->unpackSize -= (UInt32)inCur;
249
5.18k
        p->state = (p->unpackSize == 0) ? LZMA2_STATE_CONTROL : LZMA2_STATE_DATA_CONT;
250
5.18k
      }
251
18.3k
      else
252
18.3k
      {
253
18.3k
        SRes res;
254
255
18.3k
        if (p->state == LZMA2_STATE_DATA)
256
8.08k
        {
257
8.08k
          BoolInt initDic = (p->control >= 0xE0);
258
8.08k
          BoolInt initState = (p->control >= 0xA0);
259
8.08k
          LzmaDec_InitDicAndState(&p->decoder, initDic, initState);
260
8.08k
          p->state = LZMA2_STATE_DATA_CONT;
261
8.08k
        }
262
  
263
18.3k
        if (inCur > p->packSize)
264
16.9k
          inCur = (SizeT)p->packSize;
265
        
266
18.3k
        res = LzmaDec_DecodeToDic(&p->decoder, dicPos + outCur, src, &inCur, curFinishMode, status);
267
268
18.3k
        src += inCur;
269
18.3k
        *srcLen += inCur;
270
18.3k
        p->packSize -= (UInt32)inCur;
271
18.3k
        outCur = p->decoder.dicPos - dicPos;
272
18.3k
        p->unpackSize -= (UInt32)outCur;
273
274
18.3k
        if (res != 0)
275
0
          break;
276
        
277
18.3k
        if (*status == LZMA_STATUS_NEEDS_MORE_INPUT)
278
1.16k
        {
279
1.16k
          if (p->packSize == 0)
280
0
            break;
281
1.16k
          return SZ_OK;
282
1.16k
        }
283
284
17.1k
        if (inCur == 0 && outCur == 0)
285
8.08k
        {
286
8.08k
          if (*status != LZMA_STATUS_MAYBE_FINISHED_WITHOUT_MARK
287
8.08k
              || p->unpackSize != 0
288
8.08k
              || p->packSize != 0)
289
0
            break;
290
8.08k
          p->state = LZMA2_STATE_CONTROL;
291
8.08k
        }
292
        
293
17.1k
        *status = LZMA_STATUS_NOT_SPECIFIED;
294
17.1k
      }
295
24.3k
    }
296
24.3k
  }
297
  
298
0
  *status = LZMA_STATUS_NOT_SPECIFIED;
299
0
  p->state = LZMA2_STATE_ERROR;
300
0
  return SZ_ERROR_DATA;
301
26.9k
}
302
303
304
305
306
ELzma2ParseStatus Lzma2Dec_Parse(CLzma2Dec *p,
307
    SizeT outSize,
308
    const Byte *src, SizeT *srcLen,
309
    int checkFinishBlock)
310
0
{
311
0
  SizeT inSize = *srcLen;
312
0
  *srcLen = 0;
313
314
0
  while (p->state != LZMA2_STATE_ERROR)
315
0
  {
316
0
    if (p->state == LZMA2_STATE_FINISHED)
317
0
      return (ELzma2ParseStatus)LZMA_STATUS_FINISHED_WITH_MARK;
318
319
0
    if (outSize == 0 && !checkFinishBlock)
320
0
      return (ELzma2ParseStatus)LZMA_STATUS_NOT_FINISHED;
321
    
322
0
    if (p->state != LZMA2_STATE_DATA && p->state != LZMA2_STATE_DATA_CONT)
323
0
    {
324
0
      if (*srcLen == inSize)
325
0
        return (ELzma2ParseStatus)LZMA_STATUS_NEEDS_MORE_INPUT;
326
0
      (*srcLen)++;
327
328
0
      p->state = Lzma2Dec_UpdateState(p, *src++);
329
330
0
      if (p->state == LZMA2_STATE_UNPACK0)
331
0
      {
332
        // if (p->decoder.dicPos != 0)
333
0
        if (p->control == LZMA2_CONTROL_COPY_RESET_DIC || p->control >= 0xE0)
334
0
          return LZMA2_PARSE_STATUS_NEW_BLOCK;
335
        // if (outSize == 0) return LZMA_STATUS_NOT_FINISHED;
336
0
      }
337
338
      // The following code can be commented.
339
      // It's not big problem, if we read additional input bytes.
340
      // It will be stopped later in LZMA2_STATE_DATA / LZMA2_STATE_DATA_CONT state.
341
342
0
      if (outSize == 0 && p->state != LZMA2_STATE_FINISHED)
343
0
      {
344
        // checkFinishBlock is true. So we expect that block must be finished,
345
        // We can return LZMA_STATUS_NOT_SPECIFIED or LZMA_STATUS_NOT_FINISHED here
346
        // break;
347
0
        return (ELzma2ParseStatus)LZMA_STATUS_NOT_FINISHED;
348
0
      }
349
350
0
      if (p->state == LZMA2_STATE_DATA)
351
0
        return LZMA2_PARSE_STATUS_NEW_CHUNK;
352
353
0
      continue;
354
0
    }
355
356
0
    if (outSize == 0)
357
0
      return (ELzma2ParseStatus)LZMA_STATUS_NOT_FINISHED;
358
359
0
    {
360
0
      SizeT inCur = inSize - *srcLen;
361
362
0
      if (LZMA2_IS_UNCOMPRESSED_STATE(p))
363
0
      {
364
0
        if (inCur == 0)
365
0
          return (ELzma2ParseStatus)LZMA_STATUS_NEEDS_MORE_INPUT;
366
0
        if (inCur > p->unpackSize)
367
0
          inCur = p->unpackSize;
368
0
        if (inCur > outSize)
369
0
          inCur = outSize;
370
0
        p->decoder.dicPos += inCur;
371
0
        src += inCur;
372
0
        *srcLen += inCur;
373
0
        outSize -= inCur;
374
0
        p->unpackSize -= (UInt32)inCur;
375
0
        p->state = (p->unpackSize == 0) ? LZMA2_STATE_CONTROL : LZMA2_STATE_DATA_CONT;
376
0
      }
377
0
      else
378
0
      {
379
0
        p->isExtraMode = True;
380
381
0
        if (inCur == 0)
382
0
        {
383
0
          if (p->packSize != 0)
384
0
            return (ELzma2ParseStatus)LZMA_STATUS_NEEDS_MORE_INPUT;
385
0
        }
386
0
        else if (p->state == LZMA2_STATE_DATA)
387
0
        {
388
0
          p->state = LZMA2_STATE_DATA_CONT;
389
0
          if (*src != 0)
390
0
          {
391
            // first byte of lzma chunk must be Zero
392
0
            *srcLen += 1;
393
0
            p->packSize--;
394
0
            break;
395
0
          }
396
0
        }
397
  
398
0
        if (inCur > p->packSize)
399
0
          inCur = (SizeT)p->packSize;
400
401
0
        src += inCur;
402
0
        *srcLen += inCur;
403
0
        p->packSize -= (UInt32)inCur;
404
405
0
        if (p->packSize == 0)
406
0
        {
407
0
          SizeT rem = outSize;
408
0
          if (rem > p->unpackSize)
409
0
            rem = p->unpackSize;
410
0
          p->decoder.dicPos += rem;
411
0
          p->unpackSize -= (UInt32)rem;
412
0
          outSize -= rem;
413
0
          if (p->unpackSize == 0)
414
0
            p->state = LZMA2_STATE_CONTROL;
415
0
        }
416
0
      }
417
0
    }
418
0
  }
419
  
420
0
  p->state = LZMA2_STATE_ERROR;
421
0
  return (ELzma2ParseStatus)LZMA_STATUS_NOT_SPECIFIED;
422
0
}
423
424
425
426
427
SRes Lzma2Dec_DecodeToBuf(CLzma2Dec *p, Byte *dest, SizeT *destLen, const Byte *src, SizeT *srcLen, ELzmaFinishMode finishMode, ELzmaStatus *status)
428
18.6k
{
429
18.6k
  SizeT outSize = *destLen, inSize = *srcLen;
430
18.6k
  *srcLen = *destLen = 0;
431
  
432
18.6k
  for (;;)
433
26.9k
  {
434
26.9k
    SizeT inCur = inSize, outCur, dicPos;
435
26.9k
    ELzmaFinishMode curFinishMode;
436
26.9k
    SRes res;
437
    
438
26.9k
    if (p->decoder.dicPos == p->decoder.dicBufSize)
439
0
      p->decoder.dicPos = 0;
440
26.9k
    dicPos = p->decoder.dicPos;
441
26.9k
    curFinishMode = LZMA_FINISH_ANY;
442
26.9k
    outCur = p->decoder.dicBufSize - dicPos;
443
    
444
26.9k
    if (outCur >= outSize)
445
26.9k
    {
446
26.9k
      outCur = outSize;
447
26.9k
      curFinishMode = finishMode;
448
26.9k
    }
449
450
26.9k
    res = Lzma2Dec_DecodeToDic(p, dicPos + outCur, src, &inCur, curFinishMode, status);
451
    
452
26.9k
    src += inCur;
453
26.9k
    inSize -= inCur;
454
26.9k
    *srcLen += inCur;
455
26.9k
    outCur = p->decoder.dicPos - dicPos;
456
26.9k
    memcpy(dest, p->decoder.dic + dicPos, outCur);
457
26.9k
    dest += outCur;
458
26.9k
    outSize -= outCur;
459
26.9k
    *destLen += outCur;
460
26.9k
    if (res != 0)
461
0
      return res;
462
26.9k
    if (outCur == 0 || outSize == 0)
463
18.6k
      return SZ_OK;
464
26.9k
  }
465
18.6k
}
466
467
468
SRes Lzma2Decode(Byte *dest, SizeT *destLen, const Byte *src, SizeT *srcLen,
469
    Byte prop, ELzmaFinishMode finishMode, ELzmaStatus *status, ISzAllocPtr alloc)
470
0
{
471
0
  CLzma2Dec p;
472
0
  SRes res;
473
0
  SizeT outSize = *destLen, inSize = *srcLen;
474
0
  *destLen = *srcLen = 0;
475
0
  *status = LZMA_STATUS_NOT_SPECIFIED;
476
0
  Lzma2Dec_Construct(&p);
477
0
  RINOK(Lzma2Dec_AllocateProbs(&p, prop, alloc));
478
0
  p.decoder.dic = dest;
479
0
  p.decoder.dicBufSize = outSize;
480
0
  Lzma2Dec_Init(&p);
481
0
  *srcLen = inSize;
482
0
  res = Lzma2Dec_DecodeToDic(&p, outSize, src, srcLen, finishMode, status);
483
0
  *destLen = p.decoder.dicPos;
484
0
  if (res == SZ_OK && *status == LZMA_STATUS_NEEDS_MORE_INPUT)
485
0
    res = SZ_ERROR_INPUT_EOF;
486
0
  Lzma2Dec_FreeProbs(&p, alloc);
487
0
  return res;
488
0
}