Team Fortress 2 Source Code as on 22/4/2020
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

909 lines
22 KiB

  1. /* XzDec.c -- Xz Decode
  2. 2014-12-30 : Igor Pavlov : Public domain */
  3. #include "Precomp.h"
  4. /* #define XZ_DUMP */
  5. #ifdef XZ_DUMP
  6. #include <stdio.h>
  7. #endif
  8. #include <stdlib.h>
  9. #include <string.h>
  10. #include "7zCrc.h"
  11. #include "Alloc.h"
  12. #include "Bra.h"
  13. #include "CpuArch.h"
  14. #include "Delta.h"
  15. #include "Lzma2Dec.h"
  16. #ifdef USE_SUBBLOCK
  17. #include "Bcj3Dec.c"
  18. #include "SbDec.c"
  19. #endif
  20. #include "Xz.h"
  21. #define XZ_CHECK_SIZE_MAX 64
  22. #define CODER_BUF_SIZE (1 << 17)
  23. unsigned Xz_ReadVarInt(const Byte *p, size_t maxSize, UInt64 *value)
  24. {
  25. int i, limit;
  26. *value = 0;
  27. limit = (maxSize > 9) ? 9 : (int)maxSize;
  28. for (i = 0; i < limit;)
  29. {
  30. Byte b = p[i];
  31. *value |= (UInt64)(b & 0x7F) << (7 * i++);
  32. if ((b & 0x80) == 0)
  33. return (b == 0 && i != 1) ? 0 : i;
  34. }
  35. return 0;
  36. }
  37. /* ---------- BraState ---------- */
  38. #define BRA_BUF_SIZE (1 << 14)
  39. typedef struct
  40. {
  41. size_t bufPos;
  42. size_t bufConv;
  43. size_t bufTotal;
  44. UInt32 methodId;
  45. int encodeMode;
  46. UInt32 delta;
  47. UInt32 ip;
  48. UInt32 x86State;
  49. Byte deltaState[DELTA_STATE_SIZE];
  50. Byte buf[BRA_BUF_SIZE];
  51. } CBraState;
  52. void BraState_Free(void *pp, ISzAlloc *alloc)
  53. {
  54. alloc->Free(alloc, pp);
  55. }
  56. SRes BraState_SetProps(void *pp, const Byte *props, size_t propSize, ISzAlloc *alloc)
  57. {
  58. CBraState *p = ((CBraState *)pp);
  59. alloc = alloc;
  60. p->ip = 0;
  61. if (p->methodId == XZ_ID_Delta)
  62. {
  63. if (propSize != 1)
  64. return SZ_ERROR_UNSUPPORTED;
  65. p->delta = (unsigned)props[0] + 1;
  66. }
  67. else
  68. {
  69. if (propSize == 4)
  70. {
  71. UInt32 v = GetUi32(props);
  72. switch(p->methodId)
  73. {
  74. case XZ_ID_PPC:
  75. case XZ_ID_ARM:
  76. case XZ_ID_SPARC:
  77. if ((v & 3) != 0)
  78. return SZ_ERROR_UNSUPPORTED;
  79. break;
  80. case XZ_ID_ARMT:
  81. if ((v & 1) != 0)
  82. return SZ_ERROR_UNSUPPORTED;
  83. break;
  84. case XZ_ID_IA64:
  85. if ((v & 0xF) != 0)
  86. return SZ_ERROR_UNSUPPORTED;
  87. break;
  88. }
  89. p->ip = v;
  90. }
  91. else if (propSize != 0)
  92. return SZ_ERROR_UNSUPPORTED;
  93. }
  94. return SZ_OK;
  95. }
  96. void BraState_Init(void *pp)
  97. {
  98. CBraState *p = ((CBraState *)pp);
  99. p->bufPos = p->bufConv = p->bufTotal = 0;
  100. x86_Convert_Init(p->x86State);
  101. if (p->methodId == XZ_ID_Delta)
  102. Delta_Init(p->deltaState);
  103. }
  104. #define CASE_BRA_CONV(isa) case XZ_ID_ ## isa: p->bufConv = isa ## _Convert(p->buf, p->bufTotal, p->ip, p->encodeMode); break;
  105. static SRes BraState_Code(void *pp, Byte *dest, SizeT *destLen, const Byte *src, SizeT *srcLen,
  106. int srcWasFinished, ECoderFinishMode finishMode, int *wasFinished)
  107. {
  108. CBraState *p = ((CBraState *)pp);
  109. SizeT destLenOrig = *destLen;
  110. SizeT srcLenOrig = *srcLen;
  111. *destLen = 0;
  112. *srcLen = 0;
  113. finishMode = finishMode;
  114. *wasFinished = 0;
  115. while (destLenOrig > 0)
  116. {
  117. if (p->bufPos != p->bufConv)
  118. {
  119. size_t curSize = p->bufConv - p->bufPos;
  120. if (curSize > destLenOrig)
  121. curSize = destLenOrig;
  122. memcpy(dest, p->buf + p->bufPos, curSize);
  123. p->bufPos += curSize;
  124. *destLen += curSize;
  125. dest += curSize;
  126. destLenOrig -= curSize;
  127. continue;
  128. }
  129. p->bufTotal -= p->bufPos;
  130. memmove(p->buf, p->buf + p->bufPos, p->bufTotal);
  131. p->bufPos = 0;
  132. p->bufConv = 0;
  133. {
  134. size_t curSize = BRA_BUF_SIZE - p->bufTotal;
  135. if (curSize > srcLenOrig)
  136. curSize = srcLenOrig;
  137. memcpy(p->buf + p->bufTotal, src, curSize);
  138. *srcLen += curSize;
  139. src += curSize;
  140. srcLenOrig -= curSize;
  141. p->bufTotal += curSize;
  142. }
  143. if (p->bufTotal == 0)
  144. break;
  145. switch(p->methodId)
  146. {
  147. case XZ_ID_Delta:
  148. if (p->encodeMode)
  149. Delta_Encode(p->deltaState, p->delta, p->buf, p->bufTotal);
  150. else
  151. Delta_Decode(p->deltaState, p->delta, p->buf, p->bufTotal);
  152. p->bufConv = p->bufTotal;
  153. break;
  154. case XZ_ID_X86:
  155. p->bufConv = x86_Convert(p->buf, p->bufTotal, p->ip, &p->x86State, p->encodeMode);
  156. break;
  157. CASE_BRA_CONV(PPC)
  158. CASE_BRA_CONV(IA64)
  159. CASE_BRA_CONV(ARM)
  160. CASE_BRA_CONV(ARMT)
  161. CASE_BRA_CONV(SPARC)
  162. default:
  163. return SZ_ERROR_UNSUPPORTED;
  164. }
  165. p->ip += (UInt32)p->bufConv;
  166. if (p->bufConv == 0)
  167. {
  168. if (!srcWasFinished)
  169. break;
  170. p->bufConv = p->bufTotal;
  171. }
  172. }
  173. if (p->bufTotal == p->bufPos && srcLenOrig == 0 && srcWasFinished)
  174. *wasFinished = 1;
  175. return SZ_OK;
  176. }
  177. SRes BraState_SetFromMethod(IStateCoder *p, UInt64 id, int encodeMode, ISzAlloc *alloc)
  178. {
  179. CBraState *decoder;
  180. if (id != XZ_ID_Delta &&
  181. id != XZ_ID_X86 &&
  182. id != XZ_ID_PPC &&
  183. id != XZ_ID_IA64 &&
  184. id != XZ_ID_ARM &&
  185. id != XZ_ID_ARMT &&
  186. id != XZ_ID_SPARC)
  187. return SZ_ERROR_UNSUPPORTED;
  188. p->p = 0;
  189. decoder = (CBraState *)alloc->Alloc(alloc, sizeof(CBraState));
  190. if (decoder == 0)
  191. return SZ_ERROR_MEM;
  192. decoder->methodId = (UInt32)id;
  193. decoder->encodeMode = encodeMode;
  194. p->p = decoder;
  195. p->Free = BraState_Free;
  196. p->SetProps = BraState_SetProps;
  197. p->Init = BraState_Init;
  198. p->Code = BraState_Code;
  199. return SZ_OK;
  200. }
  201. /* ---------- SbState ---------- */
  202. #ifdef USE_SUBBLOCK
  203. static void SbState_Free(void *pp, ISzAlloc *alloc)
  204. {
  205. CSbDec *p = (CSbDec *)pp;
  206. SbDec_Free(p);
  207. alloc->Free(alloc, pp);
  208. }
  209. static SRes SbState_SetProps(void *pp, const Byte *props, size_t propSize, ISzAlloc *alloc)
  210. {
  211. pp = pp;
  212. props = props;
  213. alloc = alloc;
  214. return (propSize == 0) ? SZ_OK : SZ_ERROR_UNSUPPORTED;
  215. }
  216. static void SbState_Init(void *pp)
  217. {
  218. SbDec_Init((CSbDec *)pp);
  219. }
  220. static SRes SbState_Code(void *pp, Byte *dest, SizeT *destLen, const Byte *src, SizeT *srcLen,
  221. int srcWasFinished, ECoderFinishMode finishMode, int *wasFinished)
  222. {
  223. CSbDec *p = (CSbDec *)pp;
  224. SRes res;
  225. srcWasFinished = srcWasFinished;
  226. p->dest = dest;
  227. p->destLen = *destLen;
  228. p->src = src;
  229. p->srcLen = *srcLen;
  230. p->finish = finishMode; /* change it */
  231. res = SbDec_Decode((CSbDec *)pp);
  232. *destLen -= p->destLen;
  233. *srcLen -= p->srcLen;
  234. *wasFinished = (*destLen == 0 && *srcLen == 0); /* change it */
  235. return res;
  236. }
  237. SRes SbState_SetFromMethod(IStateCoder *p, ISzAlloc *alloc)
  238. {
  239. CSbDec *decoder;
  240. p->p = 0;
  241. decoder = alloc->Alloc(alloc, sizeof(CSbDec));
  242. if (decoder == 0)
  243. return SZ_ERROR_MEM;
  244. p->p = decoder;
  245. p->Free = SbState_Free;
  246. p->SetProps = SbState_SetProps;
  247. p->Init = SbState_Init;
  248. p->Code = SbState_Code;
  249. SbDec_Construct(decoder);
  250. SbDec_SetAlloc(decoder, alloc);
  251. return SZ_OK;
  252. }
  253. #endif
  254. /* ---------- Lzma2State ---------- */
  255. static void Lzma2State_Free(void *pp, ISzAlloc *alloc)
  256. {
  257. Lzma2Dec_Free((CLzma2Dec *)pp, alloc);
  258. alloc->Free(alloc, pp);
  259. }
  260. static SRes Lzma2State_SetProps(void *pp, const Byte *props, size_t propSize, ISzAlloc *alloc)
  261. {
  262. if (propSize != 1)
  263. return SZ_ERROR_UNSUPPORTED;
  264. return Lzma2Dec_Allocate((CLzma2Dec *)pp, props[0], alloc);
  265. }
  266. static void Lzma2State_Init(void *pp)
  267. {
  268. Lzma2Dec_Init((CLzma2Dec *)pp);
  269. }
  270. static SRes Lzma2State_Code(void *pp, Byte *dest, SizeT *destLen, const Byte *src, SizeT *srcLen,
  271. int srcWasFinished, ECoderFinishMode finishMode, int *wasFinished)
  272. {
  273. ELzmaStatus status;
  274. /* ELzmaFinishMode fm = (finishMode == LZMA_FINISH_ANY) ? LZMA_FINISH_ANY : LZMA_FINISH_END; */
  275. SRes res = Lzma2Dec_DecodeToBuf((CLzma2Dec *)pp, dest, destLen, src, srcLen, (ELzmaFinishMode)finishMode, &status);
  276. srcWasFinished = srcWasFinished;
  277. *wasFinished = (status == LZMA_STATUS_FINISHED_WITH_MARK);
  278. return res;
  279. }
  280. static SRes Lzma2State_SetFromMethod(IStateCoder *p, ISzAlloc *alloc)
  281. {
  282. CLzma2Dec *decoder = (CLzma2Dec *)alloc->Alloc(alloc, sizeof(CLzma2Dec));
  283. p->p = decoder;
  284. if (decoder == 0)
  285. return SZ_ERROR_MEM;
  286. p->Free = Lzma2State_Free;
  287. p->SetProps = Lzma2State_SetProps;
  288. p->Init = Lzma2State_Init;
  289. p->Code = Lzma2State_Code;
  290. Lzma2Dec_Construct(decoder);
  291. return SZ_OK;
  292. }
  293. void MixCoder_Construct(CMixCoder *p, ISzAlloc *alloc)
  294. {
  295. int i;
  296. p->alloc = alloc;
  297. p->buf = 0;
  298. p->numCoders = 0;
  299. for (i = 0; i < MIXCODER_NUM_FILTERS_MAX; i++)
  300. p->coders[i].p = NULL;
  301. }
  302. void MixCoder_Free(CMixCoder *p)
  303. {
  304. int i;
  305. for (i = 0; i < p->numCoders; i++)
  306. {
  307. IStateCoder *sc = &p->coders[i];
  308. if (p->alloc && sc->p)
  309. sc->Free(sc->p, p->alloc);
  310. }
  311. p->numCoders = 0;
  312. if (p->buf)
  313. {
  314. p->alloc->Free(p->alloc, p->buf);
  315. p->buf = 0; /* 9.31: the BUG was fixed */
  316. }
  317. }
  318. void MixCoder_Init(CMixCoder *p)
  319. {
  320. int i;
  321. for (i = 0; i < p->numCoders - 1; i++)
  322. {
  323. p->size[i] = 0;
  324. p->pos[i] = 0;
  325. p->finished[i] = 0;
  326. }
  327. for (i = 0; i < p->numCoders; i++)
  328. {
  329. IStateCoder *coder = &p->coders[i];
  330. coder->Init(coder->p);
  331. }
  332. }
  333. SRes MixCoder_SetFromMethod(CMixCoder *p, int coderIndex, UInt64 methodId)
  334. {
  335. IStateCoder *sc = &p->coders[coderIndex];
  336. p->ids[coderIndex] = methodId;
  337. switch(methodId)
  338. {
  339. case XZ_ID_LZMA2: return Lzma2State_SetFromMethod(sc, p->alloc);
  340. #ifdef USE_SUBBLOCK
  341. case XZ_ID_Subblock: return SbState_SetFromMethod(sc, p->alloc);
  342. #endif
  343. }
  344. if (coderIndex == 0)
  345. return SZ_ERROR_UNSUPPORTED;
  346. return BraState_SetFromMethod(sc, methodId, 0, p->alloc);
  347. }
  348. SRes MixCoder_Code(CMixCoder *p, Byte *dest, SizeT *destLen,
  349. const Byte *src, SizeT *srcLen, int srcWasFinished,
  350. ECoderFinishMode finishMode, ECoderStatus *status)
  351. {
  352. SizeT destLenOrig = *destLen;
  353. SizeT srcLenOrig = *srcLen;
  354. Bool allFinished = True;
  355. *destLen = 0;
  356. *srcLen = 0;
  357. *status = CODER_STATUS_NOT_FINISHED;
  358. if (p->buf == 0)
  359. {
  360. p->buf = (Byte *)p->alloc->Alloc(p->alloc, CODER_BUF_SIZE * (MIXCODER_NUM_FILTERS_MAX - 1));
  361. if (p->buf == 0)
  362. return SZ_ERROR_MEM;
  363. }
  364. if (p->numCoders != 1)
  365. finishMode = CODER_FINISH_ANY;
  366. for (;;)
  367. {
  368. Bool processed = False;
  369. int i;
  370. /*
  371. if (p->numCoders == 1 && *destLen == destLenOrig && finishMode == LZMA_FINISH_ANY)
  372. break;
  373. */
  374. for (i = 0; i < p->numCoders; i++)
  375. {
  376. SRes res;
  377. IStateCoder *coder = &p->coders[i];
  378. Byte *destCur;
  379. SizeT destLenCur, srcLenCur;
  380. const Byte *srcCur;
  381. int srcFinishedCur;
  382. int encodingWasFinished;
  383. if (i == 0)
  384. {
  385. srcCur = src;
  386. srcLenCur = srcLenOrig - *srcLen;
  387. srcFinishedCur = srcWasFinished;
  388. }
  389. else
  390. {
  391. srcCur = p->buf + (CODER_BUF_SIZE * (i - 1)) + p->pos[i - 1];
  392. srcLenCur = p->size[i - 1] - p->pos[i - 1];
  393. srcFinishedCur = p->finished[i - 1];
  394. }
  395. if (i == p->numCoders - 1)
  396. {
  397. destCur = dest;
  398. destLenCur = destLenOrig - *destLen;
  399. }
  400. else
  401. {
  402. if (p->pos[i] != p->size[i])
  403. continue;
  404. destCur = p->buf + (CODER_BUF_SIZE * i);
  405. destLenCur = CODER_BUF_SIZE;
  406. }
  407. res = coder->Code(coder->p, destCur, &destLenCur, srcCur, &srcLenCur, srcFinishedCur, finishMode, &encodingWasFinished);
  408. if (!encodingWasFinished)
  409. allFinished = False;
  410. if (i == 0)
  411. {
  412. *srcLen += srcLenCur;
  413. src += srcLenCur;
  414. }
  415. else
  416. {
  417. p->pos[i - 1] += srcLenCur;
  418. }
  419. if (i == p->numCoders - 1)
  420. {
  421. *destLen += destLenCur;
  422. dest += destLenCur;
  423. }
  424. else
  425. {
  426. p->size[i] = destLenCur;
  427. p->pos[i] = 0;
  428. p->finished[i] = encodingWasFinished;
  429. }
  430. if (res != SZ_OK)
  431. return res;
  432. if (destLenCur != 0 || srcLenCur != 0)
  433. processed = True;
  434. }
  435. if (!processed)
  436. break;
  437. }
  438. if (allFinished)
  439. *status = CODER_STATUS_FINISHED_WITH_MARK;
  440. return SZ_OK;
  441. }
  442. SRes Xz_ParseHeader(CXzStreamFlags *p, const Byte *buf)
  443. {
  444. *p = (CXzStreamFlags)GetBe16(buf + XZ_SIG_SIZE);
  445. if (CrcCalc(buf + XZ_SIG_SIZE, XZ_STREAM_FLAGS_SIZE) !=
  446. GetUi32(buf + XZ_SIG_SIZE + XZ_STREAM_FLAGS_SIZE))
  447. return SZ_ERROR_NO_ARCHIVE;
  448. return XzFlags_IsSupported(*p) ? SZ_OK : SZ_ERROR_UNSUPPORTED;
  449. }
  450. static Bool Xz_CheckFooter(CXzStreamFlags flags, UInt64 indexSize, const Byte *buf)
  451. {
  452. return
  453. indexSize == (((UInt64)GetUi32(buf + 4) + 1) << 2) &&
  454. (GetUi32(buf) == CrcCalc(buf + 4, 6) &&
  455. flags == GetBe16(buf + 8) &&
  456. memcmp(buf + 10, XZ_FOOTER_SIG, XZ_FOOTER_SIG_SIZE) == 0);
  457. }
  458. #define READ_VARINT_AND_CHECK(buf, pos, size, res) \
  459. { unsigned s = Xz_ReadVarInt(buf + pos, size - pos, res); \
  460. if (s == 0) return SZ_ERROR_ARCHIVE; pos += s; }
  461. SRes XzBlock_Parse(CXzBlock *p, const Byte *header)
  462. {
  463. unsigned pos;
  464. int numFilters, i;
  465. UInt32 headerSize = (UInt32)header[0] << 2;
  466. if (CrcCalc(header, headerSize) != GetUi32(header + headerSize))
  467. return SZ_ERROR_ARCHIVE;
  468. pos = 1;
  469. if (pos == headerSize)
  470. return SZ_ERROR_ARCHIVE;
  471. p->flags = header[pos++];
  472. if (XzBlock_HasPackSize(p))
  473. {
  474. READ_VARINT_AND_CHECK(header, pos, headerSize, &p->packSize);
  475. if (p->packSize == 0 || p->packSize + headerSize >= (UInt64)1 << 63)
  476. return SZ_ERROR_ARCHIVE;
  477. }
  478. if (XzBlock_HasUnpackSize(p))
  479. READ_VARINT_AND_CHECK(header, pos, headerSize, &p->unpackSize);
  480. numFilters = XzBlock_GetNumFilters(p);
  481. for (i = 0; i < numFilters; i++)
  482. {
  483. CXzFilter *filter = p->filters + i;
  484. UInt64 size;
  485. READ_VARINT_AND_CHECK(header, pos, headerSize, &filter->id);
  486. READ_VARINT_AND_CHECK(header, pos, headerSize, &size);
  487. if (size > headerSize - pos || size > XZ_FILTER_PROPS_SIZE_MAX)
  488. return SZ_ERROR_ARCHIVE;
  489. filter->propsSize = (UInt32)size;
  490. memcpy(filter->props, header + pos, (size_t)size);
  491. pos += (unsigned)size;
  492. #ifdef XZ_DUMP
  493. printf("\nf[%d] = %2X: ", i, filter->id);
  494. {
  495. int i;
  496. for (i = 0; i < size; i++)
  497. printf(" %2X", filter->props[i]);
  498. }
  499. #endif
  500. }
  501. while (pos < headerSize)
  502. if (header[pos++] != 0)
  503. return SZ_ERROR_ARCHIVE;
  504. return SZ_OK;
  505. }
  506. SRes XzDec_Init(CMixCoder *p, const CXzBlock *block)
  507. {
  508. int i;
  509. Bool needReInit = True;
  510. int numFilters = XzBlock_GetNumFilters(block);
  511. if (numFilters == p->numCoders)
  512. {
  513. for (i = 0; i < numFilters; i++)
  514. if (p->ids[i] != block->filters[numFilters - 1 - i].id)
  515. break;
  516. needReInit = (i != numFilters);
  517. }
  518. if (needReInit)
  519. {
  520. MixCoder_Free(p);
  521. p->numCoders = numFilters;
  522. for (i = 0; i < numFilters; i++)
  523. {
  524. const CXzFilter *f = &block->filters[numFilters - 1 - i];
  525. RINOK(MixCoder_SetFromMethod(p, i, f->id));
  526. }
  527. }
  528. for (i = 0; i < numFilters; i++)
  529. {
  530. const CXzFilter *f = &block->filters[numFilters - 1 - i];
  531. IStateCoder *sc = &p->coders[i];
  532. RINOK(sc->SetProps(sc->p, f->props, f->propsSize, p->alloc));
  533. }
  534. MixCoder_Init(p);
  535. return SZ_OK;
  536. }
  537. void XzUnpacker_Init(CXzUnpacker *p)
  538. {
  539. p->state = XZ_STATE_STREAM_HEADER;
  540. p->pos = 0;
  541. p->numStartedStreams = 0;
  542. p->numFinishedStreams = 0;
  543. p->numTotalBlocks = 0;
  544. p->padSize = 0;
  545. }
  546. void XzUnpacker_Construct(CXzUnpacker *p, ISzAlloc *alloc)
  547. {
  548. MixCoder_Construct(&p->decoder, alloc);
  549. XzUnpacker_Init(p);
  550. }
  551. void XzUnpacker_Free(CXzUnpacker *p)
  552. {
  553. MixCoder_Free(&p->decoder);
  554. }
  555. SRes XzUnpacker_Code(CXzUnpacker *p, Byte *dest, SizeT *destLen,
  556. const Byte *src, SizeT *srcLen, ECoderFinishMode finishMode, ECoderStatus *status)
  557. {
  558. SizeT destLenOrig = *destLen;
  559. SizeT srcLenOrig = *srcLen;
  560. *destLen = 0;
  561. *srcLen = 0;
  562. *status = CODER_STATUS_NOT_SPECIFIED;
  563. for (;;)
  564. {
  565. SizeT srcRem = srcLenOrig - *srcLen;
  566. if (p->state == XZ_STATE_BLOCK)
  567. {
  568. SizeT destLen2 = destLenOrig - *destLen;
  569. SizeT srcLen2 = srcLenOrig - *srcLen;
  570. SRes res;
  571. if (srcLen2 == 0 && destLen2 == 0)
  572. {
  573. *status = CODER_STATUS_NOT_FINISHED;
  574. return SZ_OK;
  575. }
  576. res = MixCoder_Code(&p->decoder, dest, &destLen2, src, &srcLen2, False, finishMode, status);
  577. XzCheck_Update(&p->check, dest, destLen2);
  578. (*srcLen) += srcLen2;
  579. src += srcLen2;
  580. p->packSize += srcLen2;
  581. (*destLen) += destLen2;
  582. dest += destLen2;
  583. p->unpackSize += destLen2;
  584. RINOK(res);
  585. if (*status == CODER_STATUS_FINISHED_WITH_MARK)
  586. {
  587. Byte temp[32];
  588. unsigned num = Xz_WriteVarInt(temp, p->packSize + p->blockHeaderSize + XzFlags_GetCheckSize(p->streamFlags));
  589. num += Xz_WriteVarInt(temp + num, p->unpackSize);
  590. Sha256_Update(&p->sha, temp, num);
  591. p->indexSize += num;
  592. p->numBlocks++;
  593. p->state = XZ_STATE_BLOCK_FOOTER;
  594. p->pos = 0;
  595. p->alignPos = 0;
  596. }
  597. else if (srcLen2 == 0 && destLen2 == 0)
  598. return SZ_OK;
  599. continue;
  600. }
  601. if (srcRem == 0)
  602. {
  603. *status = CODER_STATUS_NEEDS_MORE_INPUT;
  604. return SZ_OK;
  605. }
  606. switch (p->state)
  607. {
  608. case XZ_STATE_STREAM_HEADER:
  609. {
  610. if (p->pos < XZ_STREAM_HEADER_SIZE)
  611. {
  612. if (p->pos < XZ_SIG_SIZE && *src != XZ_SIG[p->pos])
  613. return SZ_ERROR_NO_ARCHIVE;
  614. p->buf[p->pos++] = *src++;
  615. (*srcLen)++;
  616. }
  617. else
  618. {
  619. RINOK(Xz_ParseHeader(&p->streamFlags, p->buf));
  620. p->numStartedStreams++;
  621. p->state = XZ_STATE_BLOCK_HEADER;
  622. Sha256_Init(&p->sha);
  623. p->indexSize = 0;
  624. p->numBlocks = 0;
  625. p->pos = 0;
  626. }
  627. break;
  628. }
  629. case XZ_STATE_BLOCK_HEADER:
  630. {
  631. if (p->pos == 0)
  632. {
  633. p->buf[p->pos++] = *src++;
  634. (*srcLen)++;
  635. if (p->buf[0] == 0)
  636. {
  637. p->indexPreSize = 1 + Xz_WriteVarInt(p->buf + 1, p->numBlocks);
  638. p->indexPos = p->indexPreSize;
  639. p->indexSize += p->indexPreSize;
  640. Sha256_Final(&p->sha, p->shaDigest);
  641. Sha256_Init(&p->sha);
  642. p->crc = CrcUpdate(CRC_INIT_VAL, p->buf, p->indexPreSize);
  643. p->state = XZ_STATE_STREAM_INDEX;
  644. }
  645. p->blockHeaderSize = ((UInt32)p->buf[0] << 2) + 4;
  646. }
  647. else if (p->pos != p->blockHeaderSize)
  648. {
  649. UInt32 cur = p->blockHeaderSize - p->pos;
  650. if (cur > srcRem)
  651. cur = (UInt32)srcRem;
  652. memcpy(p->buf + p->pos, src, cur);
  653. p->pos += cur;
  654. (*srcLen) += cur;
  655. src += cur;
  656. }
  657. else
  658. {
  659. RINOK(XzBlock_Parse(&p->block, p->buf));
  660. p->numTotalBlocks++;
  661. p->state = XZ_STATE_BLOCK;
  662. p->packSize = 0;
  663. p->unpackSize = 0;
  664. XzCheck_Init(&p->check, XzFlags_GetCheckType(p->streamFlags));
  665. RINOK(XzDec_Init(&p->decoder, &p->block));
  666. }
  667. break;
  668. }
  669. case XZ_STATE_BLOCK_FOOTER:
  670. {
  671. if (((p->packSize + p->alignPos) & 3) != 0)
  672. {
  673. (*srcLen)++;
  674. p->alignPos++;
  675. if (*src++ != 0)
  676. return SZ_ERROR_CRC;
  677. }
  678. else
  679. {
  680. UInt32 checkSize = XzFlags_GetCheckSize(p->streamFlags);
  681. UInt32 cur = checkSize - p->pos;
  682. if (cur != 0)
  683. {
  684. if (cur > srcRem)
  685. cur = (UInt32)srcRem;
  686. memcpy(p->buf + p->pos, src, cur);
  687. p->pos += cur;
  688. (*srcLen) += cur;
  689. src += cur;
  690. }
  691. else
  692. {
  693. Byte digest[XZ_CHECK_SIZE_MAX];
  694. p->state = XZ_STATE_BLOCK_HEADER;
  695. p->pos = 0;
  696. if (XzCheck_Final(&p->check, digest) && memcmp(digest, p->buf, checkSize) != 0)
  697. return SZ_ERROR_CRC;
  698. }
  699. }
  700. break;
  701. }
  702. case XZ_STATE_STREAM_INDEX:
  703. {
  704. if (p->pos < p->indexPreSize)
  705. {
  706. (*srcLen)++;
  707. if (*src++ != p->buf[p->pos++])
  708. return SZ_ERROR_CRC;
  709. }
  710. else
  711. {
  712. if (p->indexPos < p->indexSize)
  713. {
  714. UInt64 cur = p->indexSize - p->indexPos;
  715. if (srcRem > cur)
  716. srcRem = (SizeT)cur;
  717. p->crc = CrcUpdate(p->crc, src, srcRem);
  718. Sha256_Update(&p->sha, src, srcRem);
  719. (*srcLen) += srcRem;
  720. src += srcRem;
  721. p->indexPos += srcRem;
  722. }
  723. else if ((p->indexPos & 3) != 0)
  724. {
  725. Byte b = *src++;
  726. p->crc = CRC_UPDATE_BYTE(p->crc, b);
  727. (*srcLen)++;
  728. p->indexPos++;
  729. p->indexSize++;
  730. if (b != 0)
  731. return SZ_ERROR_CRC;
  732. }
  733. else
  734. {
  735. Byte digest[SHA256_DIGEST_SIZE];
  736. p->state = XZ_STATE_STREAM_INDEX_CRC;
  737. p->indexSize += 4;
  738. p->pos = 0;
  739. Sha256_Final(&p->sha, digest);
  740. if (memcmp(digest, p->shaDigest, SHA256_DIGEST_SIZE) != 0)
  741. return SZ_ERROR_CRC;
  742. }
  743. }
  744. break;
  745. }
  746. case XZ_STATE_STREAM_INDEX_CRC:
  747. {
  748. if (p->pos < 4)
  749. {
  750. (*srcLen)++;
  751. p->buf[p->pos++] = *src++;
  752. }
  753. else
  754. {
  755. p->state = XZ_STATE_STREAM_FOOTER;
  756. p->pos = 0;
  757. if (CRC_GET_DIGEST(p->crc) != GetUi32(p->buf))
  758. return SZ_ERROR_CRC;
  759. }
  760. break;
  761. }
  762. case XZ_STATE_STREAM_FOOTER:
  763. {
  764. UInt32 cur = XZ_STREAM_FOOTER_SIZE - p->pos;
  765. if (cur > srcRem)
  766. cur = (UInt32)srcRem;
  767. memcpy(p->buf + p->pos, src, cur);
  768. p->pos += cur;
  769. (*srcLen) += cur;
  770. src += cur;
  771. if (p->pos == XZ_STREAM_FOOTER_SIZE)
  772. {
  773. p->state = XZ_STATE_STREAM_PADDING;
  774. p->numFinishedStreams++;
  775. p->padSize = 0;
  776. if (!Xz_CheckFooter(p->streamFlags, p->indexSize, p->buf))
  777. return SZ_ERROR_CRC;
  778. }
  779. break;
  780. }
  781. case XZ_STATE_STREAM_PADDING:
  782. {
  783. if (*src != 0)
  784. {
  785. if (((UInt32)p->padSize & 3) != 0)
  786. return SZ_ERROR_NO_ARCHIVE;
  787. p->pos = 0;
  788. p->state = XZ_STATE_STREAM_HEADER;
  789. }
  790. else
  791. {
  792. (*srcLen)++;
  793. src++;
  794. p->padSize++;
  795. }
  796. break;
  797. }
  798. case XZ_STATE_BLOCK: break; /* to disable GCC warning */
  799. }
  800. }
  801. /*
  802. if (p->state == XZ_STATE_FINISHED)
  803. *status = CODER_STATUS_FINISHED_WITH_MARK;
  804. return SZ_OK;
  805. */
  806. }
  807. Bool XzUnpacker_IsStreamWasFinished(CXzUnpacker *p)
  808. {
  809. return (p->state == XZ_STATE_STREAM_PADDING) && (((UInt32)p->padSize & 3) == 0);
  810. }
  811. UInt64 XzUnpacker_GetExtraSize(CXzUnpacker *p)
  812. {
  813. UInt64 num = 0;
  814. if (p->state == XZ_STATE_STREAM_PADDING)
  815. num += p->padSize;
  816. else if (p->state == XZ_STATE_STREAM_HEADER)
  817. num += p->padSize + p->pos;
  818. return num;
  819. }