1
/* XzDec.c -- Xz Decode
2
2010-04-16 : Igor Pavlov : Public domain */
26
#define XZ_CHECK_SIZE_MAX 64
28
#define CODER_BUF_SIZE (1 << 17)
30
unsigned Xz_ReadVarInt(const Byte *p, size_t maxSize, UInt64 *value)
34
limit = (maxSize > 9) ? 9 : (int)maxSize;
36
for (i = 0; i < limit;)
39
*value |= (UInt64)(b & 0x7F) << (7 * i++);
41
return (b == 0 && i != 1) ? 0 : i;
46
/* ---------- BraState ---------- */
48
#define BRA_BUF_SIZE (1 << 14)
61
Byte deltaState[DELTA_STATE_SIZE];
63
Byte buf[BRA_BUF_SIZE];
66
void BraState_Free(void *pp, ISzAlloc *alloc)
68
alloc->Free(alloc, pp);
71
SRes BraState_SetProps(void *pp, const Byte *props, size_t propSize, ISzAlloc *alloc)
73
CBraState *p = ((CBraState *)pp);
77
if (p->methodId == XZ_ID_Delta)
80
return SZ_ERROR_UNSUPPORTED;
81
p->delta = (unsigned)props[0] + 1;
87
UInt32 v = GetUi32(props);
94
return SZ_ERROR_UNSUPPORTED;
98
return SZ_ERROR_UNSUPPORTED;
102
return SZ_ERROR_UNSUPPORTED;
107
else if (propSize != 0)
108
return SZ_ERROR_UNSUPPORTED;
113
void BraState_Init(void *pp)
115
CBraState *p = ((CBraState *)pp);
116
p->bufPos = p->bufConv = p->bufTotal = 0;
117
x86_Convert_Init(p->x86State);
118
if (p->methodId == XZ_ID_Delta)
119
Delta_Init(p->deltaState);
122
#define CASE_BRA_CONV(isa) case XZ_ID_ ## isa: p->bufConv = isa ## _Convert(p->buf, p->bufTotal, p->ip, p->encodeMode); break;
124
static SRes BraState_Code(void *pp, Byte *dest, SizeT *destLen, const Byte *src, SizeT *srcLen,
125
int srcWasFinished, ECoderFinishMode finishMode, int *wasFinished)
127
CBraState *p = ((CBraState *)pp);
128
SizeT destLenOrig = *destLen;
129
SizeT srcLenOrig = *srcLen;
132
finishMode = finishMode;
134
while (destLenOrig > 0)
136
if (p->bufPos != p->bufConv)
138
size_t curSize = p->bufConv - p->bufPos;
139
if (curSize > destLenOrig)
140
curSize = destLenOrig;
141
memcpy(dest, p->buf + p->bufPos, curSize);
142
p->bufPos += curSize;
145
destLenOrig -= curSize;
148
p->bufTotal -= p->bufPos;
149
memmove(p->buf, p->buf + p->bufPos, p->bufTotal);
153
size_t curSize = BRA_BUF_SIZE - p->bufTotal;
154
if (curSize > srcLenOrig)
155
curSize = srcLenOrig;
156
memcpy(p->buf + p->bufTotal, src, curSize);
159
srcLenOrig -= curSize;
160
p->bufTotal += curSize;
162
if (p->bufTotal == 0)
168
Delta_Encode(p->deltaState, p->delta, p->buf, p->bufTotal);
170
Delta_Decode(p->deltaState, p->delta, p->buf, p->bufTotal);
171
p->bufConv = p->bufTotal;
174
p->bufConv = x86_Convert(p->buf, p->bufTotal, p->ip, &p->x86State, p->encodeMode);
182
return SZ_ERROR_UNSUPPORTED;
184
p->ip += (UInt32)p->bufConv;
190
p->bufConv = p->bufTotal;
193
if (p->bufTotal == p->bufPos && srcLenOrig == 0 && srcWasFinished)
198
SRes BraState_SetFromMethod(IStateCoder *p, UInt64 id, ISzAlloc *alloc)
201
if (id != XZ_ID_Delta &&
208
return SZ_ERROR_UNSUPPORTED;
210
decoder = alloc->Alloc(alloc, sizeof(CBraState));
213
decoder->methodId = (UInt32)id;
215
p->Free = BraState_Free;
216
p->SetProps = BraState_SetProps;
217
p->Init = BraState_Init;
218
p->Code = BraState_Code;
222
/* ---------- SbState ---------- */
226
static void SbState_Free(void *pp, ISzAlloc *alloc)
228
CSubblockDec *p = (CSubblockDec *)pp;
229
SubblockDec_Free(p, alloc);
230
alloc->Free(alloc, pp);
233
static SRes SbState_SetProps(void *pp, const Byte *props, size_t propSize, ISzAlloc *alloc)
238
return (propSize == 0) ? SZ_OK : SZ_ERROR_UNSUPPORTED;
241
static void SbState_Init(void *pp)
243
SubblockDec_Init((CSubblockDec *)pp);
246
static SRes SbState_Code(void *pp, Byte *dest, SizeT *destLen, const Byte *src, SizeT *srcLen,
247
int srcWasFinished, ECoderFinishMode finishMode, int *wasFinished)
250
SRes res = SubblockDec_Decode((CSubblockDec *)pp, dest, destLen, src, srcLen, finishMode, &status);
251
srcWasFinished = srcWasFinished;
252
*wasFinished = (status == LZMA_STATUS_FINISHED_WITH_MARK);
256
SRes SbState_SetFromMethod(IStateCoder *p, ISzAlloc *alloc)
258
CSubblockDec *decoder;
260
decoder = alloc->Alloc(alloc, sizeof(CSubblockDec));
264
p->Free = SbState_Free;
265
p->SetProps = SbState_SetProps;
266
p->Init = SbState_Init;
267
p->Code = SbState_Code;
268
SubblockDec_Construct(decoder);
273
/* ---------- Lzma2State ---------- */
275
static void Lzma2State_Free(void *pp, ISzAlloc *alloc)
277
Lzma2Dec_Free((CLzma2Dec *)pp, alloc);
278
alloc->Free(alloc, pp);
281
static SRes Lzma2State_SetProps(void *pp, const Byte *props, size_t propSize, ISzAlloc *alloc)
284
return SZ_ERROR_UNSUPPORTED;
285
return Lzma2Dec_Allocate((CLzma2Dec *)pp, props[0], alloc);
288
static void Lzma2State_Init(void *pp)
290
Lzma2Dec_Init((CLzma2Dec *)pp);
293
static SRes Lzma2State_Code(void *pp, Byte *dest, SizeT *destLen, const Byte *src, SizeT *srcLen,
294
int srcWasFinished, ECoderFinishMode finishMode, int *wasFinished)
297
/* ELzmaFinishMode fm = (finishMode == LZMA_FINISH_ANY) ? LZMA_FINISH_ANY : LZMA_FINISH_END; */
298
SRes res = Lzma2Dec_DecodeToBuf((CLzma2Dec *)pp, dest, destLen, src, srcLen, finishMode, &status);
299
srcWasFinished = srcWasFinished;
300
*wasFinished = (status == LZMA_STATUS_FINISHED_WITH_MARK);
304
static SRes Lzma2State_SetFromMethod(IStateCoder *p, ISzAlloc *alloc)
306
CLzma2Dec *decoder = alloc->Alloc(alloc, sizeof(CLzma2Dec));
310
p->Free = Lzma2State_Free;
311
p->SetProps = Lzma2State_SetProps;
312
p->Init = Lzma2State_Init;
313
p->Code = Lzma2State_Code;
314
Lzma2Dec_Construct(decoder);
319
void MixCoder_Construct(CMixCoder *p, ISzAlloc *alloc)
325
for (i = 0; i < MIXCODER_NUM_FILTERS_MAX; i++)
326
p->coders[i].p = NULL;
329
void MixCoder_Free(CMixCoder *p)
332
for (i = 0; i < p->numCoders; i++)
334
IStateCoder *sc = &p->coders[i];
335
if (p->alloc && sc->p)
336
sc->Free(sc->p, p->alloc);
340
p->alloc->Free(p->alloc, p->buf);
343
void MixCoder_Init(CMixCoder *p)
346
for (i = 0; i < p->numCoders - 1; i++)
352
for (i = 0; i < p->numCoders; i++)
354
IStateCoder *coder = &p->coders[i];
355
coder->Init(coder->p);
359
SRes MixCoder_SetFromMethod(CMixCoder *p, int coderIndex, UInt64 methodId)
361
IStateCoder *sc = &p->coders[coderIndex];
362
p->ids[coderIndex] = methodId;
365
case XZ_ID_LZMA2: return Lzma2State_SetFromMethod(sc, p->alloc);
367
case XZ_ID_Subblock: return SbState_SetFromMethod(sc, p->alloc);
371
return SZ_ERROR_UNSUPPORTED;
372
return BraState_SetFromMethod(sc, methodId, p->alloc);
375
SRes MixCoder_Code(CMixCoder *p, Byte *dest, SizeT *destLen,
376
const Byte *src, SizeT *srcLen, int srcWasFinished,
377
ECoderFinishMode finishMode, ECoderStatus *status)
379
SizeT destLenOrig = *destLen;
380
SizeT srcLenOrig = *srcLen;
381
Bool allFinished = True;
384
*status = CODER_STATUS_NOT_FINISHED;
388
p->buf = p->alloc->Alloc(p->alloc, CODER_BUF_SIZE * (MIXCODER_NUM_FILTERS_MAX - 1));
393
if (p->numCoders != 1)
394
finishMode = CODER_FINISH_ANY;
398
Bool processed = False;
401
if (p->numCoders == 1 && *destLen == destLenOrig && finishMode == LZMA_FINISH_ANY)
405
for (i = 0; i < p->numCoders; i++)
408
IStateCoder *coder = &p->coders[i];
410
SizeT destLenCur, srcLenCur;
413
int encodingWasFinished;
418
srcLenCur = srcLenOrig - *srcLen;
419
srcFinishedCur = srcWasFinished;
423
srcCur = p->buf + (CODER_BUF_SIZE * (i - 1)) + p->pos[i - 1];
424
srcLenCur = p->size[i - 1] - p->pos[i - 1];
425
srcFinishedCur = p->finished[i - 1];
428
if (i == p->numCoders - 1)
431
destLenCur = destLenOrig - *destLen;
435
if (p->pos[i] != p->size[i])
437
destCur = p->buf + (CODER_BUF_SIZE * i);
438
destLenCur = CODER_BUF_SIZE;
441
res = coder->Code(coder->p, destCur, &destLenCur, srcCur, &srcLenCur, srcFinishedCur, finishMode, &encodingWasFinished);
443
if (!encodingWasFinished)
448
*srcLen += srcLenCur;
453
p->pos[i - 1] += srcLenCur;
456
if (i == p->numCoders - 1)
458
*destLen += destLenCur;
463
p->size[i] = destLenCur;
465
p->finished[i] = encodingWasFinished;
471
if (destLenCur != 0 || srcLenCur != 0)
478
*status = CODER_STATUS_FINISHED_WITH_MARK;
482
SRes Xz_ParseHeader(CXzStreamFlags *p, const Byte *buf)
484
*p = (CXzStreamFlags)GetBe16(buf + XZ_SIG_SIZE);
485
if (CrcCalc(buf + XZ_SIG_SIZE, XZ_STREAM_FLAGS_SIZE) !=
486
GetUi32(buf + XZ_SIG_SIZE + XZ_STREAM_FLAGS_SIZE))
487
return SZ_ERROR_NO_ARCHIVE;
488
return XzFlags_IsSupported(*p) ? SZ_OK : SZ_ERROR_UNSUPPORTED;
491
static Bool Xz_CheckFooter(CXzStreamFlags flags, UInt64 indexSize, const Byte *buf)
494
indexSize == (((UInt64)GetUi32(buf + 4) + 1) << 2) &&
495
(GetUi32(buf) == CrcCalc(buf + 4, 6) &&
496
flags == GetBe16(buf + 8) &&
497
memcmp(buf + 10, XZ_FOOTER_SIG, XZ_FOOTER_SIG_SIZE) == 0);
500
#define READ_VARINT_AND_CHECK(buf, pos, size, res) \
501
{ unsigned s = Xz_ReadVarInt(buf + pos, size - pos, res); \
502
if (s == 0) return SZ_ERROR_ARCHIVE; pos += s; }
505
SRes XzBlock_Parse(CXzBlock *p, const Byte *header)
509
UInt32 headerSize = (UInt32)header[0] << 2;
511
if (CrcCalc(header, headerSize) != GetUi32(header + headerSize))
512
return SZ_ERROR_ARCHIVE;
515
if (pos == headerSize)
516
return SZ_ERROR_ARCHIVE;
517
p->flags = header[pos++];
519
if (XzBlock_HasPackSize(p))
521
READ_VARINT_AND_CHECK(header, pos, headerSize, &p->packSize);
522
if (p->packSize == 0 || p->packSize + headerSize >= (UInt64)1 << 63)
523
return SZ_ERROR_ARCHIVE;
526
if (XzBlock_HasUnpackSize(p))
527
READ_VARINT_AND_CHECK(header, pos, headerSize, &p->unpackSize);
529
numFilters = XzBlock_GetNumFilters(p);
530
for (i = 0; i < numFilters; i++)
532
CXzFilter *filter = p->filters + i;
534
READ_VARINT_AND_CHECK(header, pos, headerSize, &filter->id);
535
READ_VARINT_AND_CHECK(header, pos, headerSize, &size);
536
if (size > headerSize - pos || size > XZ_FILTER_PROPS_SIZE_MAX)
537
return SZ_ERROR_ARCHIVE;
538
filter->propsSize = (UInt32)size;
539
memcpy(filter->props, header + pos, (size_t)size);
540
pos += (unsigned)size;
543
printf("\nf[%d] = %2X: ", i, filter->id);
546
for (i = 0; i < size; i++)
547
printf(" %2X", filter->props[i]);
552
while (pos < headerSize)
553
if (header[pos++] != 0)
554
return SZ_ERROR_ARCHIVE;
558
SRes XzDec_Init(CMixCoder *p, const CXzBlock *block)
561
Bool needReInit = True;
562
int numFilters = XzBlock_GetNumFilters(block);
563
if (numFilters == p->numCoders)
565
for (i = 0; i < numFilters; i++)
566
if (p->ids[i] != block->filters[numFilters - 1 - i].id)
568
needReInit = (i != numFilters);
573
p->numCoders = numFilters;
574
for (i = 0; i < numFilters; i++)
576
const CXzFilter *f = &block->filters[numFilters - 1 - i];
577
RINOK(MixCoder_SetFromMethod(p, i, f->id));
580
for (i = 0; i < numFilters; i++)
582
const CXzFilter *f = &block->filters[numFilters - 1 - i];
583
IStateCoder *sc = &p->coders[i];
584
RINOK(sc->SetProps(sc->p, f->props, f->propsSize, p->alloc));
590
SRes XzUnpacker_Create(CXzUnpacker *p, ISzAlloc *alloc)
592
MixCoder_Construct(&p->decoder, alloc);
593
p->state = XZ_STATE_STREAM_HEADER;
599
void XzUnpacker_Free(CXzUnpacker *p)
601
MixCoder_Free(&p->decoder);
604
SRes XzUnpacker_Code(CXzUnpacker *p, Byte *dest, SizeT *destLen,
605
const Byte *src, SizeT *srcLen, int finishMode, ECoderStatus *status)
607
SizeT destLenOrig = *destLen;
608
SizeT srcLenOrig = *srcLen;
611
*status = CODER_STATUS_NOT_SPECIFIED;
614
SizeT srcRem = srcLenOrig - *srcLen;
616
if (p->state == XZ_STATE_BLOCK)
618
SizeT destLen2 = destLenOrig - *destLen;
619
SizeT srcLen2 = srcLenOrig - *srcLen;
621
if (srcLen2 == 0 && destLen2 == 0)
623
*status = CODER_STATUS_NOT_FINISHED;
627
res = MixCoder_Code(&p->decoder, dest, &destLen2, src, &srcLen2, False, finishMode, status);
628
XzCheck_Update(&p->check, dest, destLen2);
630
(*srcLen) += srcLen2;
632
p->packSize += srcLen2;
634
(*destLen) += destLen2;
636
p->unpackSize += destLen2;
640
if (*status == CODER_STATUS_FINISHED_WITH_MARK)
643
unsigned num = Xz_WriteVarInt(temp, p->packSize + p->blockHeaderSize + XzFlags_GetCheckSize(p->streamFlags));
644
num += Xz_WriteVarInt(temp + num, p->unpackSize);
645
Sha256_Update(&p->sha, temp, num);
649
p->state = XZ_STATE_BLOCK_FOOTER;
653
else if (srcLen2 == 0 && destLen2 == 0)
661
*status = CODER_STATUS_NEEDS_MORE_INPUT;
667
case XZ_STATE_STREAM_HEADER:
669
if (p->pos < XZ_STREAM_HEADER_SIZE)
671
if (p->pos < XZ_SIG_SIZE && *src != XZ_SIG[p->pos])
672
return SZ_ERROR_NO_ARCHIVE;
673
p->buf[p->pos++] = *src++;
678
RINOK(Xz_ParseHeader(&p->streamFlags, p->buf));
679
p->state = XZ_STATE_BLOCK_HEADER;
680
Sha256_Init(&p->sha);
688
case XZ_STATE_BLOCK_HEADER:
692
p->buf[p->pos++] = *src++;
696
p->indexPreSize = 1 + Xz_WriteVarInt(p->buf + 1, p->numBlocks);
697
p->indexPos = p->indexPreSize;
698
p->indexSize += p->indexPreSize;
699
Sha256_Final(&p->sha, p->shaDigest);
700
Sha256_Init(&p->sha);
701
p->crc = CrcUpdate(CRC_INIT_VAL, p->buf, p->indexPreSize);
702
p->state = XZ_STATE_STREAM_INDEX;
704
p->blockHeaderSize = ((UInt32)p->buf[0] << 2) + 4;
706
else if (p->pos != p->blockHeaderSize)
708
UInt32 cur = p->blockHeaderSize - p->pos;
710
cur = (UInt32)srcRem;
711
memcpy(p->buf + p->pos, src, cur);
718
RINOK(XzBlock_Parse(&p->block, p->buf));
719
p->state = XZ_STATE_BLOCK;
722
XzCheck_Init(&p->check, XzFlags_GetCheckType(p->streamFlags));
723
RINOK(XzDec_Init(&p->decoder, &p->block));
728
case XZ_STATE_BLOCK_FOOTER:
730
if (((p->packSize + p->alignPos) & 3) != 0)
739
UInt32 checkSize = XzFlags_GetCheckSize(p->streamFlags);
740
UInt32 cur = checkSize - p->pos;
744
cur = (UInt32)srcRem;
745
memcpy(p->buf + p->pos, src, cur);
752
Byte digest[XZ_CHECK_SIZE_MAX];
753
p->state = XZ_STATE_BLOCK_HEADER;
755
if (XzCheck_Final(&p->check, digest) && memcmp(digest, p->buf, checkSize) != 0)
762
case XZ_STATE_STREAM_INDEX:
764
if (p->pos < p->indexPreSize)
767
if (*src++ != p->buf[p->pos++])
772
if (p->indexPos < p->indexSize)
774
UInt64 cur = p->indexSize - p->indexPos;
777
p->crc = CrcUpdate(p->crc, src, srcRem);
778
Sha256_Update(&p->sha, src, srcRem);
781
p->indexPos += srcRem;
783
else if ((p->indexPos & 3) != 0)
786
p->crc = CRC_UPDATE_BYTE(p->crc, b);
795
Byte digest[SHA256_DIGEST_SIZE];
796
p->state = XZ_STATE_STREAM_INDEX_CRC;
799
Sha256_Final(&p->sha, digest);
800
if (memcmp(digest, p->shaDigest, SHA256_DIGEST_SIZE) != 0)
807
case XZ_STATE_STREAM_INDEX_CRC:
812
p->buf[p->pos++] = *src++;
816
p->state = XZ_STATE_STREAM_FOOTER;
818
if (CRC_GET_DIGEST(p->crc) != GetUi32(p->buf))
824
case XZ_STATE_STREAM_FOOTER:
826
UInt32 cur = XZ_STREAM_FOOTER_SIZE - p->pos;
828
cur = (UInt32)srcRem;
829
memcpy(p->buf + p->pos, src, cur);
833
if (p->pos == XZ_STREAM_FOOTER_SIZE)
835
p->state = XZ_STATE_STREAM_PADDING;
838
if (!Xz_CheckFooter(p->streamFlags, p->indexSize, p->buf))
844
case XZ_STATE_STREAM_PADDING:
848
if (((UInt32)p->padSize & 3) != 0)
849
return SZ_ERROR_NO_ARCHIVE;
851
p->state = XZ_STATE_STREAM_HEADER;
862
case XZ_STATE_BLOCK: break; /* to disable GCC warning */
866
if (p->state == XZ_STATE_FINISHED)
867
*status = CODER_STATUS_FINISHED_WITH_MARK;
872
Bool XzUnpacker_IsStreamWasFinished(CXzUnpacker *p)
874
return (p->state == XZ_STATE_STREAM_PADDING) && (((UInt32)p->padSize & 3) == 0);
1
/* XzDec.c -- Xz Decode
2
2010-04-16 : Igor Pavlov : Public domain */
18
#include <openssl/ssl.h>
19
#include <openssl/err.h>
20
#include "libclamav/crypto.h"
35
#define XZ_CHECK_SIZE_MAX 64
37
#define CODER_BUF_SIZE (1 << 17)
39
unsigned Xz_ReadVarInt(const Byte *p, size_t maxSize, UInt64 *value)
43
limit = (maxSize > 9) ? 9 : (int)maxSize;
45
for (i = 0; i < limit;)
48
*value |= (UInt64)(b & 0x7F) << (7 * i++);
50
return (b == 0 && i != 1) ? 0 : i;
55
/* ---------- BraState ---------- */
57
#define BRA_BUF_SIZE (1 << 14)
70
Byte deltaState[DELTA_STATE_SIZE];
72
Byte buf[BRA_BUF_SIZE];
75
void BraState_Free(void *pp, ISzAlloc *alloc)
77
alloc->Free(alloc, pp);
80
SRes BraState_SetProps(void *pp, const Byte *props, size_t propSize, ISzAlloc *alloc)
82
CBraState *p = ((CBraState *)pp);
86
if (p->methodId == XZ_ID_Delta)
89
return SZ_ERROR_UNSUPPORTED;
90
p->delta = (unsigned)props[0] + 1;
96
UInt32 v = GetUi32(props);
103
return SZ_ERROR_UNSUPPORTED;
107
return SZ_ERROR_UNSUPPORTED;
111
return SZ_ERROR_UNSUPPORTED;
116
else if (propSize != 0)
117
return SZ_ERROR_UNSUPPORTED;
122
void BraState_Init(void *pp)
124
CBraState *p = ((CBraState *)pp);
125
p->bufPos = p->bufConv = p->bufTotal = 0;
126
x86_Convert_Init(p->x86State);
127
if (p->methodId == XZ_ID_Delta)
128
Delta_Init(p->deltaState);
131
#define CASE_BRA_CONV(isa) case XZ_ID_ ## isa: p->bufConv = isa ## _Convert(p->buf, p->bufTotal, p->ip, p->encodeMode); break;
133
static SRes BraState_Code(void *pp, Byte *dest, SizeT *destLen, const Byte *src, SizeT *srcLen,
134
int srcWasFinished, ECoderFinishMode finishMode, int *wasFinished)
136
CBraState *p = ((CBraState *)pp);
137
SizeT destLenOrig = *destLen;
138
SizeT srcLenOrig = *srcLen;
141
finishMode = finishMode;
143
while (destLenOrig > 0)
145
if (p->bufPos != p->bufConv)
147
size_t curSize = p->bufConv - p->bufPos;
148
if (curSize > destLenOrig)
149
curSize = destLenOrig;
150
memcpy(dest, p->buf + p->bufPos, curSize);
151
p->bufPos += curSize;
154
destLenOrig -= curSize;
157
p->bufTotal -= p->bufPos;
158
memmove(p->buf, p->buf + p->bufPos, p->bufTotal);
162
size_t curSize = BRA_BUF_SIZE - p->bufTotal;
163
if (curSize > srcLenOrig)
164
curSize = srcLenOrig;
165
memcpy(p->buf + p->bufTotal, src, curSize);
168
srcLenOrig -= curSize;
169
p->bufTotal += curSize;
171
if (p->bufTotal == 0)
177
Delta_Encode(p->deltaState, p->delta, p->buf, p->bufTotal);
179
Delta_Decode(p->deltaState, p->delta, p->buf, p->bufTotal);
180
p->bufConv = p->bufTotal;
183
p->bufConv = x86_Convert(p->buf, p->bufTotal, p->ip, &p->x86State, p->encodeMode);
191
return SZ_ERROR_UNSUPPORTED;
193
p->ip += (UInt32)p->bufConv;
199
p->bufConv = p->bufTotal;
202
if (p->bufTotal == p->bufPos && srcLenOrig == 0 && srcWasFinished)
207
SRes BraState_SetFromMethod(IStateCoder *p, UInt64 id, ISzAlloc *alloc)
210
if (id != XZ_ID_Delta &&
217
return SZ_ERROR_UNSUPPORTED;
219
decoder = alloc->Alloc(alloc, sizeof(CBraState));
222
decoder->methodId = (UInt32)id;
224
p->Free = BraState_Free;
225
p->SetProps = BraState_SetProps;
226
p->Init = BraState_Init;
227
p->Code = BraState_Code;
231
/* ---------- SbState ---------- */
235
static void SbState_Free(void *pp, ISzAlloc *alloc)
237
CSubblockDec *p = (CSubblockDec *)pp;
238
SubblockDec_Free(p, alloc);
239
alloc->Free(alloc, pp);
242
static SRes SbState_SetProps(void *pp, const Byte *props, size_t propSize, ISzAlloc *alloc)
247
return (propSize == 0) ? SZ_OK : SZ_ERROR_UNSUPPORTED;
250
static void SbState_Init(void *pp)
252
SubblockDec_Init((CSubblockDec *)pp);
255
static SRes SbState_Code(void *pp, Byte *dest, SizeT *destLen, const Byte *src, SizeT *srcLen,
256
int srcWasFinished, ECoderFinishMode finishMode, int *wasFinished)
259
SRes res = SubblockDec_Decode((CSubblockDec *)pp, dest, destLen, src, srcLen, finishMode, &status);
260
srcWasFinished = srcWasFinished;
261
*wasFinished = (status == LZMA_STATUS_FINISHED_WITH_MARK);
265
SRes SbState_SetFromMethod(IStateCoder *p, ISzAlloc *alloc)
267
CSubblockDec *decoder;
269
decoder = alloc->Alloc(alloc, sizeof(CSubblockDec));
273
p->Free = SbState_Free;
274
p->SetProps = SbState_SetProps;
275
p->Init = SbState_Init;
276
p->Code = SbState_Code;
277
SubblockDec_Construct(decoder);
282
/* ---------- Lzma2State ---------- */
284
static void Lzma2State_Free(void *pp, ISzAlloc *alloc)
286
Lzma2Dec_Free((CLzma2Dec *)pp, alloc);
287
alloc->Free(alloc, pp);
290
static SRes Lzma2State_SetProps(void *pp, const Byte *props, size_t propSize, ISzAlloc *alloc)
293
return SZ_ERROR_UNSUPPORTED;
294
return Lzma2Dec_Allocate((CLzma2Dec *)pp, props[0], alloc);
297
static void Lzma2State_Init(void *pp)
299
Lzma2Dec_Init((CLzma2Dec *)pp);
302
static SRes Lzma2State_Code(void *pp, Byte *dest, SizeT *destLen, const Byte *src, SizeT *srcLen,
303
int srcWasFinished, ECoderFinishMode finishMode, int *wasFinished)
306
/* ELzmaFinishMode fm = (finishMode == LZMA_FINISH_ANY) ? LZMA_FINISH_ANY : LZMA_FINISH_END; */
307
SRes res = Lzma2Dec_DecodeToBuf((CLzma2Dec *)pp, dest, destLen, src, srcLen, finishMode, &status);
308
srcWasFinished = srcWasFinished;
309
*wasFinished = (status == LZMA_STATUS_FINISHED_WITH_MARK);
313
static SRes Lzma2State_SetFromMethod(IStateCoder *p, ISzAlloc *alloc)
315
CLzma2Dec *decoder = alloc->Alloc(alloc, sizeof(CLzma2Dec));
319
p->Free = Lzma2State_Free;
320
p->SetProps = Lzma2State_SetProps;
321
p->Init = Lzma2State_Init;
322
p->Code = Lzma2State_Code;
323
Lzma2Dec_Construct(decoder);
328
void MixCoder_Construct(CMixCoder *p, ISzAlloc *alloc)
334
for (i = 0; i < MIXCODER_NUM_FILTERS_MAX; i++)
335
p->coders[i].p = NULL;
338
void MixCoder_Free(CMixCoder *p)
341
for (i = 0; i < p->numCoders; i++)
343
IStateCoder *sc = &p->coders[i];
344
if (p->alloc && sc->p)
345
sc->Free(sc->p, p->alloc);
349
p->alloc->Free(p->alloc, p->buf);
352
void MixCoder_Init(CMixCoder *p)
355
for (i = 0; i < p->numCoders - 1; i++)
361
for (i = 0; i < p->numCoders; i++)
363
IStateCoder *coder = &p->coders[i];
364
coder->Init(coder->p);
368
SRes MixCoder_SetFromMethod(CMixCoder *p, int coderIndex, UInt64 methodId)
370
IStateCoder *sc = &p->coders[coderIndex];
371
p->ids[coderIndex] = methodId;
374
case XZ_ID_LZMA2: return Lzma2State_SetFromMethod(sc, p->alloc);
376
case XZ_ID_Subblock: return SbState_SetFromMethod(sc, p->alloc);
380
return SZ_ERROR_UNSUPPORTED;
381
return BraState_SetFromMethod(sc, methodId, p->alloc);
384
SRes MixCoder_Code(CMixCoder *p, Byte *dest, SizeT *destLen,
385
const Byte *src, SizeT *srcLen, int srcWasFinished,
386
ECoderFinishMode finishMode, ECoderStatus *status)
388
SizeT destLenOrig = *destLen;
389
SizeT srcLenOrig = *srcLen;
390
Bool allFinished = True;
393
*status = CODER_STATUS_NOT_FINISHED;
397
p->buf = p->alloc->Alloc(p->alloc, CODER_BUF_SIZE * (MIXCODER_NUM_FILTERS_MAX - 1));
402
if (p->numCoders != 1)
403
finishMode = CODER_FINISH_ANY;
407
Bool processed = False;
410
if (p->numCoders == 1 && *destLen == destLenOrig && finishMode == LZMA_FINISH_ANY)
414
for (i = 0; i < p->numCoders; i++)
417
IStateCoder *coder = &p->coders[i];
419
SizeT destLenCur, srcLenCur;
422
int encodingWasFinished;
427
srcLenCur = srcLenOrig - *srcLen;
428
srcFinishedCur = srcWasFinished;
432
srcCur = p->buf + (CODER_BUF_SIZE * (i - 1)) + p->pos[i - 1];
433
srcLenCur = p->size[i - 1] - p->pos[i - 1];
434
srcFinishedCur = p->finished[i - 1];
437
if (i == p->numCoders - 1)
440
destLenCur = destLenOrig - *destLen;
444
if (p->pos[i] != p->size[i])
446
destCur = p->buf + (CODER_BUF_SIZE * i);
447
destLenCur = CODER_BUF_SIZE;
450
res = coder->Code(coder->p, destCur, &destLenCur, srcCur, &srcLenCur, srcFinishedCur, finishMode, &encodingWasFinished);
452
if (!encodingWasFinished)
457
*srcLen += srcLenCur;
462
p->pos[i - 1] += srcLenCur;
465
if (i == p->numCoders - 1)
467
*destLen += destLenCur;
472
p->size[i] = destLenCur;
474
p->finished[i] = encodingWasFinished;
480
if (destLenCur != 0 || srcLenCur != 0)
487
*status = CODER_STATUS_FINISHED_WITH_MARK;
491
SRes Xz_ParseHeader(CXzStreamFlags *p, const Byte *buf)
493
*p = (CXzStreamFlags)GetBe16(buf + XZ_SIG_SIZE);
494
if (CrcCalc(buf + XZ_SIG_SIZE, XZ_STREAM_FLAGS_SIZE) !=
495
GetUi32(buf + XZ_SIG_SIZE + XZ_STREAM_FLAGS_SIZE))
496
return SZ_ERROR_NO_ARCHIVE;
497
return XzFlags_IsSupported(*p) ? SZ_OK : SZ_ERROR_UNSUPPORTED;
500
static Bool Xz_CheckFooter(CXzStreamFlags flags, UInt64 indexSize, const Byte *buf)
503
indexSize == (((UInt64)GetUi32(buf + 4) + 1) << 2) &&
504
(GetUi32(buf) == CrcCalc(buf + 4, 6) &&
505
flags == GetBe16(buf + 8) &&
506
memcmp(buf + 10, XZ_FOOTER_SIG, XZ_FOOTER_SIG_SIZE) == 0);
509
#define READ_VARINT_AND_CHECK(buf, pos, size, res) \
510
{ unsigned s = Xz_ReadVarInt(buf + pos, size - pos, res); \
511
if (s == 0) return SZ_ERROR_ARCHIVE; pos += s; }
514
SRes XzBlock_Parse(CXzBlock *p, const Byte *header)
518
UInt32 headerSize = (UInt32)header[0] << 2;
520
if (CrcCalc(header, headerSize) != GetUi32(header + headerSize))
521
return SZ_ERROR_ARCHIVE;
524
if (pos == headerSize)
525
return SZ_ERROR_ARCHIVE;
526
p->flags = header[pos++];
528
if (XzBlock_HasPackSize(p))
530
READ_VARINT_AND_CHECK(header, pos, headerSize, &p->packSize);
531
if (p->packSize == 0 || p->packSize + headerSize >= (UInt64)1 << 63)
532
return SZ_ERROR_ARCHIVE;
535
if (XzBlock_HasUnpackSize(p))
536
READ_VARINT_AND_CHECK(header, pos, headerSize, &p->unpackSize);
538
numFilters = XzBlock_GetNumFilters(p);
539
for (i = 0; i < numFilters; i++)
541
CXzFilter *filter = p->filters + i;
543
READ_VARINT_AND_CHECK(header, pos, headerSize, &filter->id);
544
READ_VARINT_AND_CHECK(header, pos, headerSize, &size);
545
if (size > headerSize - pos || size > XZ_FILTER_PROPS_SIZE_MAX)
546
return SZ_ERROR_ARCHIVE;
547
filter->propsSize = (UInt32)size;
548
memcpy(filter->props, header + pos, (size_t)size);
549
pos += (unsigned)size;
552
printf("\nf[%d] = %2X: ", i, filter->id);
555
for (i = 0; i < size; i++)
556
printf(" %2X", filter->props[i]);
561
while (pos < headerSize)
562
if (header[pos++] != 0)
563
return SZ_ERROR_ARCHIVE;
567
SRes XzDec_Init(CMixCoder *p, const CXzBlock *block)
570
Bool needReInit = True;
571
int numFilters = XzBlock_GetNumFilters(block);
572
if (numFilters == p->numCoders)
574
for (i = 0; i < numFilters; i++)
575
if (p->ids[i] != block->filters[numFilters - 1 - i].id)
577
needReInit = (i != numFilters);
582
p->numCoders = numFilters;
583
for (i = 0; i < numFilters; i++)
585
const CXzFilter *f = &block->filters[numFilters - 1 - i];
586
RINOK(MixCoder_SetFromMethod(p, i, f->id));
589
for (i = 0; i < numFilters; i++)
591
const CXzFilter *f = &block->filters[numFilters - 1 - i];
592
IStateCoder *sc = &p->coders[i];
593
RINOK(sc->SetProps(sc->p, f->props, f->propsSize, p->alloc));
599
SRes XzUnpacker_Create(CXzUnpacker *p, ISzAlloc *alloc)
601
MixCoder_Construct(&p->decoder, alloc);
602
p->state = XZ_STATE_STREAM_HEADER;
608
void XzUnpacker_Free(CXzUnpacker *p)
610
MixCoder_Free(&p->decoder);
613
SRes XzUnpacker_Code(CXzUnpacker *p, Byte *dest, SizeT *destLen,
614
const Byte *src, SizeT *srcLen, int finishMode, ECoderStatus *status)
616
SizeT destLenOrig = *destLen;
617
SizeT srcLenOrig = *srcLen;
620
*status = CODER_STATUS_NOT_SPECIFIED;
623
SizeT srcRem = srcLenOrig - *srcLen;
625
if (p->state == XZ_STATE_BLOCK)
627
SizeT destLen2 = destLenOrig - *destLen;
628
SizeT srcLen2 = srcLenOrig - *srcLen;
630
if (srcLen2 == 0 && destLen2 == 0)
632
*status = CODER_STATUS_NOT_FINISHED;
636
res = MixCoder_Code(&p->decoder, dest, &destLen2, src, &srcLen2, False, finishMode, status);
637
XzCheck_Update(&p->check, dest, destLen2);
639
(*srcLen) += srcLen2;
641
p->packSize += srcLen2;
643
(*destLen) += destLen2;
645
p->unpackSize += destLen2;
649
if (*status == CODER_STATUS_FINISHED_WITH_MARK)
652
unsigned num = Xz_WriteVarInt(temp, p->packSize + p->blockHeaderSize + XzFlags_GetCheckSize(p->streamFlags));
653
num += Xz_WriteVarInt(temp + num, p->unpackSize);
655
cl_update_hash(p->sha, temp, num);
659
p->state = XZ_STATE_BLOCK_FOOTER;
663
else if (srcLen2 == 0 && destLen2 == 0)
671
*status = CODER_STATUS_NEEDS_MORE_INPUT;
677
case XZ_STATE_STREAM_HEADER:
679
if (p->pos < XZ_STREAM_HEADER_SIZE)
681
if (p->pos < XZ_SIG_SIZE && *src != XZ_SIG[p->pos])
682
return SZ_ERROR_NO_ARCHIVE;
683
p->buf[p->pos++] = *src++;
688
RINOK(Xz_ParseHeader(&p->streamFlags, p->buf));
689
p->state = XZ_STATE_BLOCK_HEADER;
690
p->sha = cl_hash_init("sha256");
698
case XZ_STATE_BLOCK_HEADER:
702
p->buf[p->pos++] = *src++;
706
p->indexPreSize = 1 + Xz_WriteVarInt(p->buf + 1, p->numBlocks);
707
p->indexPos = p->indexPreSize;
708
p->indexSize += p->indexPreSize;
710
cl_finish_hash(p->sha, p->shaDigest);
711
p->sha = cl_hash_init("sha256");
713
p->crc = CrcUpdate(CRC_INIT_VAL, p->buf, p->indexPreSize);
714
p->state = XZ_STATE_STREAM_INDEX;
716
p->blockHeaderSize = ((UInt32)p->buf[0] << 2) + 4;
718
else if (p->pos != p->blockHeaderSize)
720
UInt32 cur = p->blockHeaderSize - p->pos;
722
cur = (UInt32)srcRem;
723
memcpy(p->buf + p->pos, src, cur);
730
RINOK(XzBlock_Parse(&p->block, p->buf));
731
p->state = XZ_STATE_BLOCK;
734
XzCheck_Init(&p->check, XzFlags_GetCheckType(p->streamFlags));
735
RINOK(XzDec_Init(&p->decoder, &p->block));
740
case XZ_STATE_BLOCK_FOOTER:
742
if (((p->packSize + p->alignPos) & 3) != 0)
751
UInt32 checkSize = XzFlags_GetCheckSize(p->streamFlags);
752
UInt32 cur = checkSize - p->pos;
756
cur = (UInt32)srcRem;
757
memcpy(p->buf + p->pos, src, cur);
764
Byte digest[XZ_CHECK_SIZE_MAX];
765
p->state = XZ_STATE_BLOCK_HEADER;
767
if (XzCheck_Final(&p->check, digest) && memcmp(digest, p->buf, checkSize) != 0)
774
case XZ_STATE_STREAM_INDEX:
776
if (p->pos < p->indexPreSize)
779
if (*src++ != p->buf[p->pos++])
784
if (p->indexPos < p->indexSize)
786
UInt64 cur = p->indexSize - p->indexPos;
789
p->crc = CrcUpdate(p->crc, src, srcRem);
791
cl_update_hash(p->sha, src, srcRem);
794
p->indexPos += srcRem;
796
else if ((p->indexPos & 3) != 0)
799
p->crc = CRC_UPDATE_BYTE(p->crc, b);
808
Byte digest[SHA256_DIGEST_SIZE];
809
p->state = XZ_STATE_STREAM_INDEX_CRC;
813
cl_finish_hash(p->sha, digest);
815
if (memcmp(digest, p->shaDigest, SHA256_DIGEST_SIZE) != 0)
822
case XZ_STATE_STREAM_INDEX_CRC:
827
p->buf[p->pos++] = *src++;
831
p->state = XZ_STATE_STREAM_FOOTER;
833
if (CRC_GET_DIGEST(p->crc) != GetUi32(p->buf))
839
case XZ_STATE_STREAM_FOOTER:
841
UInt32 cur = XZ_STREAM_FOOTER_SIZE - p->pos;
843
cur = (UInt32)srcRem;
844
memcpy(p->buf + p->pos, src, cur);
848
if (p->pos == XZ_STREAM_FOOTER_SIZE)
850
p->state = XZ_STATE_STREAM_PADDING;
853
if (!Xz_CheckFooter(p->streamFlags, p->indexSize, p->buf))
859
case XZ_STATE_STREAM_PADDING:
863
if (((UInt32)p->padSize & 3) != 0)
864
return SZ_ERROR_NO_ARCHIVE;
866
p->state = XZ_STATE_STREAM_HEADER;
877
case XZ_STATE_BLOCK: break; /* to disable GCC warning */
881
if (p->state == XZ_STATE_FINISHED)
882
*status = CODER_STATUS_FINISHED_WITH_MARK;
887
Bool XzUnpacker_IsStreamWasFinished(CXzUnpacker *p)
889
return (p->state == XZ_STATE_STREAM_PADDING) && (((UInt32)p->padSize & 3) == 0);