Coverage Report

Created: 2026-02-26 07:01

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/src/lzma-fuzz/sdk/C/7zDec.c
Line
Count
Source
1
/* 7zDec.c -- Decoding from 7z folder
2
2019-02-02 : Igor Pavlov : Public domain */
3
4
#include "Precomp.h"
5
6
#include <string.h>
7
8
/* #define _7ZIP_PPMD_SUPPPORT */
9
10
#include "7z.h"
11
#include "7zCrc.h"
12
13
#include "Bcj2.h"
14
#include "Bra.h"
15
#include "CpuArch.h"
16
#include "Delta.h"
17
#include "LzmaDec.h"
18
#include "Lzma2Dec.h"
19
#ifdef _7ZIP_PPMD_SUPPPORT
20
#include "Ppmd7.h"
21
#endif
22
23
4.71k
#define k_Copy 0
24
49
#define k_Delta 3
25
9.60k
#define k_LZMA2 0x21
26
12.4k
#define k_LZMA  0x30101
27
13
#define k_BCJ   0x3030103
28
355
#define k_BCJ2  0x303011B
29
26
#define k_PPC   0x3030205
30
48
#define k_IA64  0x3030401
31
67
#define k_ARM   0x3030501
32
71
#define k_ARMT  0x3030701
33
62
#define k_SPARC 0x3030805
34
35
36
#ifdef _7ZIP_PPMD_SUPPPORT
37
38
9.74k
#define k_PPMD 0x30401
39
40
typedef struct
41
{
42
  IByteIn vt;
43
  const Byte *cur;
44
  const Byte *end;
45
  const Byte *begin;
46
  UInt64 processed;
47
  BoolInt extra;
48
  SRes res;
49
  const ILookInStream *inStream;
50
} CByteInToLook;
51
52
static Byte ReadByte(const IByteIn *pp)
53
12.1k
{
54
12.1k
  CByteInToLook *p = CONTAINER_FROM_VTBL(pp, CByteInToLook, vt);
55
12.1k
  if (p->cur != p->end)
56
11.8k
    return *p->cur++;
57
319
  if (p->res == SZ_OK)
58
319
  {
59
319
    size_t size = p->cur - p->begin;
60
319
    p->processed += size;
61
319
    p->res = ILookInStream_Skip(p->inStream, size);
62
319
    size = (1 << 25);
63
319
    p->res = ILookInStream_Look(p->inStream, (const void **)&p->begin, &size);
64
319
    p->cur = p->begin;
65
319
    p->end = p->begin + size;
66
319
    if (size != 0)
67
319
      return *p->cur++;;
68
0
  }
69
0
  p->extra = True;
70
0
  return 0;
71
319
}
72
73
static SRes SzDecodePpmd(const Byte *props, unsigned propsSize, UInt64 inSize, const ILookInStream *inStream,
74
    Byte *outBuffer, SizeT outSize, ISzAllocPtr allocMain)
75
319
{
76
319
  CPpmd7 ppmd;
77
319
  CByteInToLook s;
78
319
  SRes res = SZ_OK;
79
80
319
  s.vt.Read = ReadByte;
81
319
  s.inStream = inStream;
82
319
  s.begin = s.end = s.cur = NULL;
83
319
  s.extra = False;
84
319
  s.res = SZ_OK;
85
319
  s.processed = 0;
86
87
319
  if (propsSize != 5)
88
0
    return SZ_ERROR_UNSUPPORTED;
89
90
319
  {
91
319
    unsigned order = props[0];
92
319
    UInt32 memSize = GetUi32(props + 1);
93
319
    if (order < PPMD7_MIN_ORDER ||
94
319
        order > PPMD7_MAX_ORDER ||
95
319
        memSize < PPMD7_MIN_MEM_SIZE ||
96
319
        memSize > PPMD7_MAX_MEM_SIZE)
97
0
      return SZ_ERROR_UNSUPPORTED;
98
319
    Ppmd7_Construct(&ppmd);
99
319
    if (!Ppmd7_Alloc(&ppmd, memSize, allocMain))
100
0
      return SZ_ERROR_MEM;
101
319
    Ppmd7_Init(&ppmd, order);
102
319
  }
103
0
  {
104
319
    CPpmd7z_RangeDec rc;
105
319
    Ppmd7z_RangeDec_CreateVTable(&rc);
106
319
    rc.Stream = &s.vt;
107
319
    if (!Ppmd7z_RangeDec_Init(&rc))
108
2
      res = SZ_ERROR_DATA;
109
317
    else if (s.extra)
110
0
      res = (s.res != SZ_OK ? s.res : SZ_ERROR_DATA);
111
317
    else
112
317
    {
113
317
      SizeT i;
114
18.8k
      for (i = 0; i < outSize; i++)
115
18.5k
      {
116
18.5k
        int sym = Ppmd7_DecodeSymbol(&ppmd, &rc.vt);
117
18.5k
        if (s.extra || sym < 0)
118
49
          break;
119
18.5k
        outBuffer[i] = (Byte)sym;
120
18.5k
      }
121
317
      if (i != outSize)
122
49
        res = (s.res != SZ_OK ? s.res : SZ_ERROR_DATA);
123
268
      else if (s.processed + (s.cur - s.begin) != inSize || !Ppmd7z_RangeDec_IsFinishedOK(&rc))
124
267
        res = SZ_ERROR_DATA;
125
317
    }
126
319
  }
127
319
  Ppmd7_Free(&ppmd, allocMain);
128
319
  return res;
129
319
}
130
131
#endif
132
133
134
static SRes SzDecodeLzma(const Byte *props, unsigned propsSize, UInt64 inSize, ILookInStream *inStream,
135
    Byte *outBuffer, SizeT outSize, ISzAllocPtr allocMain)
136
3.87k
{
137
3.87k
  CLzmaDec state;
138
3.87k
  SRes res = SZ_OK;
139
140
3.87k
  LzmaDec_Construct(&state);
141
3.87k
  RINOK(LzmaDec_AllocateProbs(&state, props, propsSize, allocMain));
142
3.87k
  state.dic = outBuffer;
143
3.87k
  state.dicBufSize = outSize;
144
3.87k
  LzmaDec_Init(&state);
145
146
3.87k
  for (;;)
147
6.10k
  {
148
6.10k
    const void *inBuf = NULL;
149
6.10k
    size_t lookahead = (1 << 18);
150
6.10k
    if (lookahead > inSize)
151
6.10k
      lookahead = (size_t)inSize;
152
6.10k
    res = ILookInStream_Look(inStream, &inBuf, &lookahead);
153
6.10k
    if (res != SZ_OK)
154
0
      break;
155
156
6.10k
    {
157
6.10k
      SizeT inProcessed = (SizeT)lookahead, dicPos = state.dicPos;
158
6.10k
      ELzmaStatus status;
159
6.10k
      res = LzmaDec_DecodeToDic(&state, outSize, (const Byte *)inBuf, &inProcessed, LZMA_FINISH_END, &status);
160
6.10k
      lookahead -= inProcessed;
161
6.10k
      inSize -= inProcessed;
162
6.10k
      if (res != SZ_OK)
163
722
        break;
164
165
5.37k
      if (status == LZMA_STATUS_FINISHED_WITH_MARK)
166
15
      {
167
15
        if (outSize != state.dicPos || inSize != 0)
168
15
          res = SZ_ERROR_DATA;
169
15
        break;
170
15
      }
171
172
5.36k
      if (outSize == state.dicPos && inSize == 0 && status == LZMA_STATUS_MAYBE_FINISHED_WITHOUT_MARK)
173
906
        break;
174
175
4.45k
      if (inProcessed == 0 && dicPos == state.dicPos)
176
2.23k
      {
177
2.23k
        res = SZ_ERROR_DATA;
178
2.23k
        break;
179
2.23k
      }
180
181
2.22k
      res = ILookInStream_Skip(inStream, inProcessed);
182
2.22k
      if (res != SZ_OK)
183
0
        break;
184
2.22k
    }
185
2.22k
  }
186
187
3.87k
  LzmaDec_FreeProbs(&state, allocMain);
188
3.87k
  return res;
189
3.87k
}
190
191
192
#ifndef _7Z_NO_METHOD_LZMA2
193
194
static SRes SzDecodeLzma2(const Byte *props, unsigned propsSize, UInt64 inSize, ILookInStream *inStream,
195
    Byte *outBuffer, SizeT outSize, ISzAllocPtr allocMain)
196
495
{
197
495
  CLzma2Dec state;
198
495
  SRes res = SZ_OK;
199
200
495
  Lzma2Dec_Construct(&state);
201
495
  if (propsSize != 1)
202
0
    return SZ_ERROR_DATA;
203
495
  RINOK(Lzma2Dec_AllocateProbs(&state, props[0], allocMain));
204
495
  state.decoder.dic = outBuffer;
205
495
  state.decoder.dicBufSize = outSize;
206
495
  Lzma2Dec_Init(&state);
207
208
495
  for (;;)
209
621
  {
210
621
    const void *inBuf = NULL;
211
621
    size_t lookahead = (1 << 18);
212
621
    if (lookahead > inSize)
213
621
      lookahead = (size_t)inSize;
214
621
    res = ILookInStream_Look(inStream, &inBuf, &lookahead);
215
621
    if (res != SZ_OK)
216
0
      break;
217
218
621
    {
219
621
      SizeT inProcessed = (SizeT)lookahead, dicPos = state.decoder.dicPos;
220
621
      ELzmaStatus status;
221
621
      res = Lzma2Dec_DecodeToDic(&state, outSize, (const Byte *)inBuf, &inProcessed, LZMA_FINISH_END, &status);
222
621
      lookahead -= inProcessed;
223
621
      inSize -= inProcessed;
224
621
      if (res != SZ_OK)
225
204
        break;
226
227
417
      if (status == LZMA_STATUS_FINISHED_WITH_MARK)
228
165
      {
229
165
        if (outSize != state.decoder.dicPos || inSize != 0)
230
12
          res = SZ_ERROR_DATA;
231
165
        break;
232
165
      }
233
234
252
      if (inProcessed == 0 && dicPos == state.decoder.dicPos)
235
126
      {
236
126
        res = SZ_ERROR_DATA;
237
126
        break;
238
126
      }
239
240
126
      res = ILookInStream_Skip(inStream, inProcessed);
241
126
      if (res != SZ_OK)
242
0
        break;
243
126
    }
244
126
  }
245
246
495
  Lzma2Dec_FreeProbs(&state, allocMain);
247
495
  return res;
248
495
}
249
250
#endif
251
252
253
static SRes SzDecodeCopy(UInt64 inSize, ILookInStream *inStream, Byte *outBuffer)
254
94
{
255
188
  while (inSize > 0)
256
94
  {
257
94
    const void *inBuf;
258
94
    size_t curSize = (1 << 18);
259
94
    if (curSize > inSize)
260
94
      curSize = (size_t)inSize;
261
94
    RINOK(ILookInStream_Look(inStream, &inBuf, &curSize));
262
94
    if (curSize == 0)
263
0
      return SZ_ERROR_INPUT_EOF;
264
94
    memcpy(outBuffer, inBuf, curSize);
265
94
    outBuffer += curSize;
266
94
    inSize -= curSize;
267
94
    RINOK(ILookInStream_Skip(inStream, curSize));
268
94
  }
269
94
  return SZ_OK;
270
94
}
271
272
static BoolInt IS_MAIN_METHOD(UInt32 m)
273
9.56k
{
274
9.56k
  switch (m)
275
9.56k
  {
276
12
    case k_Copy:
277
7.78k
    case k_LZMA:
278
7.78k
    #ifndef _7Z_NO_METHOD_LZMA2
279
8.78k
    case k_LZMA2:
280
8.78k
    #endif
281
8.78k
    #ifdef _7ZIP_PPMD_SUPPPORT
282
9.42k
    case k_PPMD:
283
9.42k
    #endif
284
9.42k
      return True;
285
9.56k
  }
286
137
  return False;
287
9.56k
}
288
289
static BoolInt IS_SUPPORTED_CODER(const CSzCoderInfo *c)
290
4.72k
{
291
4.72k
  return
292
4.72k
      c->NumStreams == 1
293
      /* && c->MethodID <= (UInt32)0xFFFFFFFF */
294
4.72k
      && IS_MAIN_METHOD((UInt32)c->MethodID);
295
4.72k
}
296
297
109
#define IS_BCJ2(c) ((c)->MethodID == k_BCJ2 && (c)->NumStreams == 4)
298
299
static SRes CheckSupportedFolder(const CSzFolder *f)
300
4.51k
{
301
4.51k
  if (f->NumCoders < 1 || f->NumCoders > 4)
302
0
    return SZ_ERROR_UNSUPPORTED;
303
4.51k
  if (!IS_SUPPORTED_CODER(&f->Coders[0]))
304
0
    return SZ_ERROR_UNSUPPORTED;
305
4.51k
  if (f->NumCoders == 1)
306
4.33k
  {
307
4.33k
    if (f->NumPackStreams != 1 || f->PackStreams[0] != 0 || f->NumBonds != 0)
308
0
      return SZ_ERROR_UNSUPPORTED;
309
4.33k
    return SZ_OK;
310
4.33k
  }
311
  
312
  
313
175
  #ifndef _7Z_NO_METHODS_FILTERS
314
315
175
  if (f->NumCoders == 2)
316
66
  {
317
66
    const CSzCoderInfo *c = &f->Coders[1];
318
66
    if (
319
        /* c->MethodID > (UInt32)0xFFFFFFFF || */
320
66
        c->NumStreams != 1
321
66
        || f->NumPackStreams != 1
322
66
        || f->PackStreams[0] != 0
323
66
        || f->NumBonds != 1
324
66
        || f->Bonds[0].InIndex != 1
325
66
        || f->Bonds[0].OutIndex != 0)
326
0
      return SZ_ERROR_UNSUPPORTED;
327
66
    switch ((UInt32)c->MethodID)
328
66
    {
329
0
      case k_Delta:
330
7
      case k_BCJ:
331
18
      case k_PPC:
332
34
      case k_IA64:
333
53
      case k_SPARC:
334
60
      case k_ARM:
335
66
      case k_ARMT:
336
66
        break;
337
0
      default:
338
0
        return SZ_ERROR_UNSUPPORTED;
339
66
    }
340
66
    return SZ_OK;
341
66
  }
342
343
109
  #endif
344
345
  
346
109
  if (f->NumCoders == 4)
347
109
  {
348
109
    if (!IS_SUPPORTED_CODER(&f->Coders[1])
349
109
        || !IS_SUPPORTED_CODER(&f->Coders[2])
350
109
        || !IS_BCJ2(&f->Coders[3]))
351
0
      return SZ_ERROR_UNSUPPORTED;
352
109
    if (f->NumPackStreams != 4
353
109
        || f->PackStreams[0] != 2
354
109
        || f->PackStreams[1] != 6
355
109
        || f->PackStreams[2] != 1
356
109
        || f->PackStreams[3] != 0
357
109
        || f->NumBonds != 3
358
109
        || f->Bonds[0].InIndex != 5 || f->Bonds[0].OutIndex != 0
359
109
        || f->Bonds[1].InIndex != 4 || f->Bonds[1].OutIndex != 1
360
109
        || f->Bonds[2].InIndex != 3 || f->Bonds[2].OutIndex != 2)
361
0
      return SZ_ERROR_UNSUPPORTED;
362
109
    return SZ_OK;
363
109
  }
364
  
365
0
  return SZ_ERROR_UNSUPPORTED;
366
109
}
367
368
43
#define CASE_BRA_CONV(isa) case k_ ## isa: isa ## _Convert(outBuffer, outSize, 0, 0); break;
369
370
static SRes SzFolder_Decode2(const CSzFolder *folder,
371
    const Byte *propsData,
372
    const UInt64 *unpackSizes,
373
    const UInt64 *packPositions,
374
    ILookInStream *inStream, UInt64 startPos,
375
    Byte *outBuffer, SizeT outSize, ISzAllocPtr allocMain,
376
    Byte *tempBuf[])
377
4.51k
{
378
4.51k
  UInt32 ci;
379
4.51k
  SizeT tempSizes[3] = { 0, 0, 0};
380
4.51k
  SizeT tempSize3 = 0;
381
4.51k
  Byte *tempBuf3 = 0;
382
383
4.51k
  RINOK(CheckSupportedFolder(folder));
384
385
5.62k
  for (ci = 0; ci < folder->NumCoders; ci++)
386
4.83k
  {
387
4.83k
    const CSzCoderInfo *coder = &folder->Coders[ci];
388
389
4.83k
    if (IS_MAIN_METHOD((UInt32)coder->MethodID))
390
4.69k
    {
391
4.69k
      UInt32 si = 0;
392
4.69k
      UInt64 offset;
393
4.69k
      UInt64 inSize;
394
4.69k
      Byte *outBufCur = outBuffer;
395
4.69k
      SizeT outSizeCur = outSize;
396
4.69k
      if (folder->NumCoders == 4)
397
298
      {
398
298
        UInt32 indices[] = { 3, 2, 0 };
399
298
        UInt64 unpackSize = unpackSizes[ci];
400
298
        si = indices[ci];
401
298
        if (ci < 2)
402
207
        {
403
207
          Byte *temp;
404
207
          outSizeCur = (SizeT)unpackSize;
405
207
          if (outSizeCur != unpackSize)
406
0
            return SZ_ERROR_MEM;
407
207
          temp = (Byte *)ISzAlloc_Alloc(allocMain, outSizeCur);
408
207
          if (!temp && outSizeCur != 0)
409
0
            return SZ_ERROR_MEM;
410
207
          outBufCur = tempBuf[1 - ci] = temp;
411
207
          tempSizes[1 - ci] = outSizeCur;
412
207
        }
413
91
        else if (ci == 2)
414
91
        {
415
91
          if (unpackSize > outSize) /* check it */
416
0
            return SZ_ERROR_PARAM;
417
91
          tempBuf3 = outBufCur = outBuffer + (outSize - (size_t)unpackSize);
418
91
          tempSize3 = outSizeCur = (SizeT)unpackSize;
419
91
        }
420
0
        else
421
0
          return SZ_ERROR_UNSUPPORTED;
422
298
      }
423
4.69k
      offset = packPositions[si];
424
4.69k
      inSize = packPositions[(size_t)si + 1] - offset;
425
4.69k
      RINOK(LookInStream_SeekTo(inStream, startPos + offset));
426
427
4.69k
      if (coder->MethodID == k_Copy)
428
6
      {
429
6
        if (inSize != outSizeCur) /* check it */
430
0
          return SZ_ERROR_DATA;
431
6
        RINOK(SzDecodeCopy(inSize, inStream, outBufCur));
432
6
      }
433
4.69k
      else if (coder->MethodID == k_LZMA)
434
3.87k
      {
435
3.87k
        RINOK(SzDecodeLzma(propsData + coder->PropsOffset, coder->PropsSize, inSize, inStream, outBufCur, outSizeCur, allocMain));
436
906
      }
437
814
      #ifndef _7Z_NO_METHOD_LZMA2
438
814
      else if (coder->MethodID == k_LZMA2)
439
495
      {
440
495
        RINOK(SzDecodeLzma2(propsData + coder->PropsOffset, coder->PropsSize, inSize, inStream, outBufCur, outSizeCur, allocMain));
441
153
      }
442
319
      #endif
443
319
      #ifdef _7ZIP_PPMD_SUPPPORT
444
319
      else if (coder->MethodID == k_PPMD)
445
319
      {
446
319
        RINOK(SzDecodePpmd(propsData + coder->PropsOffset, coder->PropsSize, inSize, inStream, outBufCur, outSizeCur, allocMain));
447
1
      }
448
0
      #endif
449
0
      else
450
0
        return SZ_ERROR_UNSUPPORTED;
451
4.69k
    }
452
137
    else if (coder->MethodID == k_BCJ2)
453
88
    {
454
88
      UInt64 offset = packPositions[1];
455
88
      UInt64 s3Size = packPositions[2] - offset;
456
      
457
88
      if (ci != 3)
458
0
        return SZ_ERROR_UNSUPPORTED;
459
      
460
88
      tempSizes[2] = (SizeT)s3Size;
461
88
      if (tempSizes[2] != s3Size)
462
0
        return SZ_ERROR_MEM;
463
88
      tempBuf[2] = (Byte *)ISzAlloc_Alloc(allocMain, tempSizes[2]);
464
88
      if (!tempBuf[2] && tempSizes[2] != 0)
465
0
        return SZ_ERROR_MEM;
466
      
467
88
      RINOK(LookInStream_SeekTo(inStream, startPos + offset));
468
88
      RINOK(SzDecodeCopy(s3Size, inStream, tempBuf[2]));
469
470
88
      if ((tempSizes[0] & 3) != 0 ||
471
88
          (tempSizes[1] & 3) != 0 ||
472
88
          tempSize3 + tempSizes[0] + tempSizes[1] != outSize)
473
0
        return SZ_ERROR_DATA;
474
475
88
      {
476
88
        CBcj2Dec p;
477
        
478
88
        p.bufs[0] = tempBuf3;   p.lims[0] = tempBuf3 + tempSize3;
479
88
        p.bufs[1] = tempBuf[0]; p.lims[1] = tempBuf[0] + tempSizes[0];
480
88
        p.bufs[2] = tempBuf[1]; p.lims[2] = tempBuf[1] + tempSizes[1];
481
88
        p.bufs[3] = tempBuf[2]; p.lims[3] = tempBuf[2] + tempSizes[2];
482
        
483
88
        p.dest = outBuffer;
484
88
        p.destLim = outBuffer + outSize;
485
        
486
88
        Bcj2Dec_Init(&p);
487
88
        RINOK(Bcj2Dec_Decode(&p));
488
489
86
        {
490
86
          unsigned i;
491
334
          for (i = 0; i < 4; i++)
492
272
            if (p.bufs[i] != p.lims[i])
493
24
              return SZ_ERROR_DATA;
494
          
495
62
          if (!Bcj2Dec_IsFinished(&p))
496
59
            return SZ_ERROR_DATA;
497
498
3
          if (p.dest != p.destLim
499
3
             || p.state != BCJ2_STREAM_MAIN)
500
2
            return SZ_ERROR_DATA;
501
3
        }
502
3
      }
503
3
    }
504
49
    #ifndef _7Z_NO_METHODS_FILTERS
505
49
    else if (ci == 1)
506
49
    {
507
49
      if (coder->MethodID == k_Delta)
508
0
      {
509
0
        if (coder->PropsSize != 1)
510
0
          return SZ_ERROR_UNSUPPORTED;
511
0
        {
512
0
          Byte state[DELTA_STATE_SIZE];
513
0
          Delta_Init(state);
514
0
          Delta_Decode(state, (unsigned)(propsData[coder->PropsOffset]) + 1, outBuffer, outSize);
515
0
        }
516
0
      }
517
49
      else
518
49
      {
519
49
        if (coder->PropsSize != 0)
520
0
          return SZ_ERROR_UNSUPPORTED;
521
49
        switch (coder->MethodID)
522
49
        {
523
6
          case k_BCJ:
524
6
          {
525
6
            UInt32 state;
526
6
            x86_Convert_Init(state);
527
6
            x86_Convert(outBuffer, outSize, 0, &state, 0);
528
6
            break;
529
0
          }
530
8
          CASE_BRA_CONV(PPC)
531
14
          CASE_BRA_CONV(IA64)
532
9
          CASE_BRA_CONV(SPARC)
533
7
          CASE_BRA_CONV(ARM)
534
5
          CASE_BRA_CONV(ARMT)
535
0
          default:
536
0
            return SZ_ERROR_UNSUPPORTED;
537
49
        }
538
49
      }
539
49
    }
540
0
    #endif
541
0
    else
542
0
      return SZ_ERROR_UNSUPPORTED;
543
4.83k
  }
544
545
790
  return SZ_OK;
546
4.51k
}
547
548
549
SRes SzAr_DecodeFolder(const CSzAr *p, UInt32 folderIndex,
550
    ILookInStream *inStream, UInt64 startPos,
551
    Byte *outBuffer, size_t outSize,
552
    ISzAllocPtr allocMain)
553
4.51k
{
554
4.51k
  SRes res;
555
4.51k
  CSzFolder folder;
556
4.51k
  CSzData sd;
557
  
558
4.51k
  const Byte *data = p->CodersData + p->FoCodersOffsets[folderIndex];
559
4.51k
  sd.Data = data;
560
4.51k
  sd.Size = p->FoCodersOffsets[(size_t)folderIndex + 1] - p->FoCodersOffsets[folderIndex];
561
  
562
4.51k
  res = SzGetNextFolderItem(&folder, &sd);
563
  
564
4.51k
  if (res != SZ_OK)
565
0
    return res;
566
567
4.51k
  if (sd.Size != 0
568
4.51k
      || folder.UnpackStream != p->FoToMainUnpackSizeIndex[folderIndex]
569
4.51k
      || outSize != SzAr_GetFolderUnpackSize(p, folderIndex))
570
0
    return SZ_ERROR_FAIL;
571
4.51k
  {
572
4.51k
    unsigned i;
573
4.51k
    Byte *tempBuf[3] = { 0, 0, 0};
574
575
4.51k
    res = SzFolder_Decode2(&folder, data,
576
4.51k
        &p->CoderUnpackSizes[p->FoToCoderUnpackSizes[folderIndex]],
577
4.51k
        p->PackPositions + p->FoStartPackStreamIndex[folderIndex],
578
4.51k
        inStream, startPos,
579
4.51k
        outBuffer, (SizeT)outSize, allocMain, tempBuf);
580
    
581
18.0k
    for (i = 0; i < 3; i++)
582
13.5k
      ISzAlloc_Free(allocMain, tempBuf[i]);
583
584
4.51k
    if (res == SZ_OK)
585
790
      if (SzBitWithVals_Check(&p->FolderCRCs, folderIndex))
586
709
        if (CrcCalc(outBuffer, outSize) != p->FolderCRCs.Vals[folderIndex])
587
17
          res = SZ_ERROR_CRC;
588
589
4.51k
    return res;
590
4.51k
  }
591
4.51k
}