XzDec.c (67749B)
1 /* XzDec.c -- Xz Decode 2 2018-04-24 : Igor Pavlov : Public domain */ 3 4 #include "Precomp.h" 5 6 // #include <stdio.h> 7 8 // #define XZ_DUMP 9 10 /* #define XZ_DUMP */ 11 12 #ifdef XZ_DUMP 13 #include <stdio.h> 14 #endif 15 16 // #define SHOW_DEBUG_INFO 17 18 #ifdef SHOW_DEBUG_INFO 19 #include <stdio.h> 20 #endif 21 22 #ifdef SHOW_DEBUG_INFO 23 #define PRF(x) x 24 #else 25 #define PRF(x) 26 #endif 27 28 #define PRF_STR(s) PRF(printf("\n" s "\n")) 29 #define PRF_STR_INT(s, d) PRF(printf("\n" s " %d\n", (unsigned)d)) 30 31 #include <stdlib.h> 32 #include <string.h> 33 34 #include "7zCrc.h" 35 #include "Alloc.h" 36 #include "Bra.h" 37 #include "CpuArch.h" 38 #include "Delta.h" 39 #include "Lzma2Dec.h" 40 41 // #define USE_SUBBLOCK 42 43 #ifdef USE_SUBBLOCK 44 #include "Bcj3Dec.c" 45 #include "SbDec.h" 46 #endif 47 48 #include "Xz.h" 49 50 #define XZ_CHECK_SIZE_MAX 64 51 52 #define CODER_BUF_SIZE ((size_t)1 << 17) 53 54 unsigned Xz_ReadVarInt(const Byte *p, size_t maxSize, UInt64 *value) 55 { 56 unsigned i, limit; 57 *value = 0; 58 limit = (maxSize > 9) ? 9 : (unsigned)maxSize; 59 60 for (i = 0; i < limit;) 61 { 62 Byte b = p[i]; 63 *value |= (UInt64)(b & 0x7F) << (7 * i++); 64 if ((b & 0x80) == 0) 65 return (b == 0 && i != 1) ? 0 : i; 66 } 67 return 0; 68 } 69 70 /* ---------- BraState ---------- */ 71 72 #define BRA_BUF_SIZE (1 << 14) 73 74 typedef struct 75 { 76 size_t bufPos; 77 size_t bufConv; 78 size_t bufTotal; 79 80 int encodeMode; 81 82 UInt32 methodId; 83 UInt32 delta; 84 UInt32 ip; 85 UInt32 x86State; 86 Byte deltaState[DELTA_STATE_SIZE]; 87 88 Byte buf[BRA_BUF_SIZE]; 89 } CBraState; 90 91 static void BraState_Free(void *pp, ISzAllocPtr alloc) 92 { 93 ISzAlloc_Free(alloc, pp); 94 } 95 96 static SRes BraState_SetProps(void *pp, const Byte *props, size_t propSize, ISzAllocPtr alloc) 97 { 98 CBraState *p = ((CBraState *)pp); 99 UNUSED_VAR(alloc); 100 p->ip = 0; 101 if (p->methodId == XZ_ID_Delta) 102 { 103 if (propSize != 1) 104 return SZ_ERROR_UNSUPPORTED; 105 p->delta = (unsigned)props[0] + 1; 106 } 107 else 108 { 109 if (propSize == 4) 110 { 111 UInt32 v = GetUi32(props); 112 switch (p->methodId) 113 { 114 case XZ_ID_PPC: 115 case XZ_ID_ARM: 116 case XZ_ID_SPARC: 117 if ((v & 3) != 0) 118 return SZ_ERROR_UNSUPPORTED; 119 break; 120 case XZ_ID_ARMT: 121 if ((v & 1) != 0) 122 return SZ_ERROR_UNSUPPORTED; 123 break; 124 case XZ_ID_IA64: 125 if ((v & 0xF) != 0) 126 return SZ_ERROR_UNSUPPORTED; 127 break; 128 } 129 p->ip = v; 130 } 131 else if (propSize != 0) 132 return SZ_ERROR_UNSUPPORTED; 133 } 134 return SZ_OK; 135 } 136 137 static void BraState_Init(void *pp) 138 { 139 CBraState *p = ((CBraState *)pp); 140 p->bufPos = p->bufConv = p->bufTotal = 0; 141 x86_Convert_Init(p->x86State); 142 if (p->methodId == XZ_ID_Delta) 143 Delta_Init(p->deltaState); 144 } 145 146 147 #define CASE_BRA_CONV(isa) case XZ_ID_ ## isa: size = isa ## _Convert(data, size, p->ip, p->encodeMode); break; 148 149 static SizeT BraState_Filter(void *pp, Byte *data, SizeT size) 150 { 151 CBraState *p = ((CBraState *)pp); 152 switch (p->methodId) 153 { 154 case XZ_ID_Delta: 155 if (p->encodeMode) 156 Delta_Encode(p->deltaState, p->delta, data, size); 157 else 158 Delta_Decode(p->deltaState, p->delta, data, size); 159 break; 160 case XZ_ID_X86: 161 size = x86_Convert(data, size, p->ip, &p->x86State, p->encodeMode); 162 break; 163 CASE_BRA_CONV(PPC) 164 CASE_BRA_CONV(IA64) 165 CASE_BRA_CONV(ARM) 166 CASE_BRA_CONV(ARMT) 167 CASE_BRA_CONV(SPARC) 168 } 169 p->ip += (UInt32)size; 170 return size; 171 } 172 173 174 static SRes BraState_Code2(void *pp, 175 Byte *dest, SizeT *destLen, 176 const Byte *src, SizeT *srcLen, int srcWasFinished, 177 ECoderFinishMode finishMode, 178 // int *wasFinished 179 ECoderStatus *status) 180 { 181 CBraState *p = ((CBraState *)pp); 182 SizeT destRem = *destLen; 183 SizeT srcRem = *srcLen; 184 UNUSED_VAR(finishMode); 185 186 *destLen = 0; 187 *srcLen = 0; 188 // *wasFinished = False; 189 *status = CODER_STATUS_NOT_FINISHED; 190 191 while (destRem > 0) 192 { 193 if (p->bufPos != p->bufConv) 194 { 195 size_t size = p->bufConv - p->bufPos; 196 if (size > destRem) 197 size = destRem; 198 memcpy(dest, p->buf + p->bufPos, size); 199 p->bufPos += size; 200 *destLen += size; 201 dest += size; 202 destRem -= size; 203 continue; 204 } 205 206 p->bufTotal -= p->bufPos; 207 memmove(p->buf, p->buf + p->bufPos, p->bufTotal); 208 p->bufPos = 0; 209 p->bufConv = 0; 210 { 211 size_t size = BRA_BUF_SIZE - p->bufTotal; 212 if (size > srcRem) 213 size = srcRem; 214 memcpy(p->buf + p->bufTotal, src, size); 215 *srcLen += size; 216 src += size; 217 srcRem -= size; 218 p->bufTotal += size; 219 } 220 if (p->bufTotal == 0) 221 break; 222 223 p->bufConv = BraState_Filter(pp, p->buf, p->bufTotal); 224 225 if (p->bufConv == 0) 226 { 227 if (!srcWasFinished) 228 break; 229 p->bufConv = p->bufTotal; 230 } 231 } 232 233 if (p->bufTotal == p->bufPos && srcRem == 0 && srcWasFinished) 234 { 235 *status = CODER_STATUS_FINISHED_WITH_MARK; 236 // *wasFinished = 1; 237 } 238 239 return SZ_OK; 240 } 241 242 243 SRes BraState_SetFromMethod(IStateCoder *p, UInt64 id, int encodeMode, ISzAllocPtr alloc) 244 { 245 CBraState *decoder; 246 if (id < XZ_ID_Delta || id > XZ_ID_SPARC) 247 return SZ_ERROR_UNSUPPORTED; 248 decoder = p->p; 249 if (!decoder) 250 { 251 decoder = (CBraState *)ISzAlloc_Alloc(alloc, sizeof(CBraState)); 252 if (!decoder) 253 return SZ_ERROR_MEM; 254 p->p = decoder; 255 p->Free = BraState_Free; 256 p->SetProps = BraState_SetProps; 257 p->Init = BraState_Init; 258 p->Code2 = BraState_Code2; 259 p->Filter = BraState_Filter; 260 } 261 decoder->methodId = (UInt32)id; 262 decoder->encodeMode = encodeMode; 263 return SZ_OK; 264 } 265 266 267 268 /* ---------- SbState ---------- */ 269 270 #ifdef USE_SUBBLOCK 271 272 static void SbState_Free(void *pp, ISzAllocPtr alloc) 273 { 274 CSbDec *p = (CSbDec *)pp; 275 SbDec_Free(p); 276 ISzAlloc_Free(alloc, pp); 277 } 278 279 static SRes SbState_SetProps(void *pp, const Byte *props, size_t propSize, ISzAllocPtr alloc) 280 { 281 UNUSED_VAR(pp); 282 UNUSED_VAR(props); 283 UNUSED_VAR(alloc); 284 return (propSize == 0) ? SZ_OK : SZ_ERROR_UNSUPPORTED; 285 } 286 287 static void SbState_Init(void *pp) 288 { 289 SbDec_Init((CSbDec *)pp); 290 } 291 292 static SRes SbState_Code2(void *pp, Byte *dest, SizeT *destLen, const Byte *src, SizeT *srcLen, 293 int srcWasFinished, ECoderFinishMode finishMode, 294 // int *wasFinished 295 ECoderStatus *status) 296 { 297 CSbDec *p = (CSbDec *)pp; 298 SRes res; 299 UNUSED_VAR(srcWasFinished); 300 p->dest = dest; 301 p->destLen = *destLen; 302 p->src = src; 303 p->srcLen = *srcLen; 304 p->finish = finishMode; /* change it */ 305 res = SbDec_Decode((CSbDec *)pp); 306 *destLen -= p->destLen; 307 *srcLen -= p->srcLen; 308 // *wasFinished = (*destLen == 0 && *srcLen == 0); /* change it */ 309 *status = (*destLen == 0 && *srcLen == 0) ? 310 CODER_STATUS_FINISHED_WITH_MARK : 311 CODER_STATUS_NOT_FINISHED; 312 return res; 313 } 314 315 static SRes SbState_SetFromMethod(IStateCoder *p, ISzAllocPtr alloc) 316 { 317 CSbDec *decoder = (CSbDec *)p->p; 318 if (!decoder) 319 { 320 decoder = (CSbDec *)ISzAlloc_Alloc(alloc, sizeof(CSbDec)); 321 if (!decoder) 322 return SZ_ERROR_MEM; 323 p->p = decoder; 324 p->Free = SbState_Free; 325 p->SetProps = SbState_SetProps; 326 p->Init = SbState_Init; 327 p->Code2 = SbState_Code2; 328 p->Filter = NULL; 329 } 330 SbDec_Construct(decoder); 331 SbDec_SetAlloc(decoder, alloc); 332 return SZ_OK; 333 } 334 335 #endif 336 337 338 339 /* ---------- Lzma2 ---------- */ 340 341 typedef struct 342 { 343 CLzma2Dec decoder; 344 Bool outBufMode; 345 } CLzma2Dec_Spec; 346 347 348 static void Lzma2State_Free(void *pp, ISzAllocPtr alloc) 349 { 350 CLzma2Dec_Spec *p = (CLzma2Dec_Spec *)pp; 351 if (p->outBufMode) 352 Lzma2Dec_FreeProbs(&p->decoder, alloc); 353 else 354 Lzma2Dec_Free(&p->decoder, alloc); 355 ISzAlloc_Free(alloc, pp); 356 } 357 358 static SRes Lzma2State_SetProps(void *pp, const Byte *props, size_t propSize, ISzAllocPtr alloc) 359 { 360 if (propSize != 1) 361 return SZ_ERROR_UNSUPPORTED; 362 { 363 CLzma2Dec_Spec *p = (CLzma2Dec_Spec *)pp; 364 if (p->outBufMode) 365 return Lzma2Dec_AllocateProbs(&p->decoder, props[0], alloc); 366 else 367 return Lzma2Dec_Allocate(&p->decoder, props[0], alloc); 368 } 369 } 370 371 static void Lzma2State_Init(void *pp) 372 { 373 Lzma2Dec_Init(&((CLzma2Dec_Spec *)pp)->decoder); 374 } 375 376 377 /* 378 if (outBufMode), then (dest) is not used. Use NULL. 379 Data is unpacked to (spec->decoder.decoder.dic) output buffer. 380 */ 381 382 static SRes Lzma2State_Code2(void *pp, Byte *dest, SizeT *destLen, const Byte *src, SizeT *srcLen, 383 int srcWasFinished, ECoderFinishMode finishMode, 384 // int *wasFinished, 385 ECoderStatus *status) 386 { 387 CLzma2Dec_Spec *spec = (CLzma2Dec_Spec *)pp; 388 ELzmaStatus status2; 389 /* ELzmaFinishMode fm = (finishMode == LZMA_FINISH_ANY) ? LZMA_FINISH_ANY : LZMA_FINISH_END; */ 390 SRes res; 391 UNUSED_VAR(srcWasFinished); 392 if (spec->outBufMode) 393 { 394 SizeT dicPos = spec->decoder.decoder.dicPos; 395 SizeT dicLimit = dicPos + *destLen; 396 res = Lzma2Dec_DecodeToDic(&spec->decoder, dicLimit, src, srcLen, (ELzmaFinishMode)finishMode, &status2); 397 *destLen = spec->decoder.decoder.dicPos - dicPos; 398 } 399 else 400 res = Lzma2Dec_DecodeToBuf(&spec->decoder, dest, destLen, src, srcLen, (ELzmaFinishMode)finishMode, &status2); 401 // *wasFinished = (status2 == LZMA_STATUS_FINISHED_WITH_MARK); 402 // ECoderStatus values are identical to ELzmaStatus values of LZMA2 decoder 403 *status = status2; 404 return res; 405 } 406 407 408 static SRes Lzma2State_SetFromMethod(IStateCoder *p, Byte *outBuf, size_t outBufSize, ISzAllocPtr alloc) 409 { 410 CLzma2Dec_Spec *spec = (CLzma2Dec_Spec *)p->p; 411 if (!spec) 412 { 413 spec = (CLzma2Dec_Spec *)ISzAlloc_Alloc(alloc, sizeof(CLzma2Dec_Spec)); 414 if (!spec) 415 return SZ_ERROR_MEM; 416 p->p = spec; 417 p->Free = Lzma2State_Free; 418 p->SetProps = Lzma2State_SetProps; 419 p->Init = Lzma2State_Init; 420 p->Code2 = Lzma2State_Code2; 421 p->Filter = NULL; 422 Lzma2Dec_Construct(&spec->decoder); 423 } 424 spec->outBufMode = False; 425 if (outBuf) 426 { 427 spec->outBufMode = True; 428 spec->decoder.decoder.dic = outBuf; 429 spec->decoder.decoder.dicBufSize = outBufSize; 430 } 431 return SZ_OK; 432 } 433 434 435 static SRes Lzma2State_ResetOutBuf(IStateCoder *p, Byte *outBuf, size_t outBufSize) 436 { 437 CLzma2Dec_Spec *spec = (CLzma2Dec_Spec *)p->p; 438 if ((spec->outBufMode && !outBuf) || (!spec->outBufMode && outBuf)) 439 return SZ_ERROR_FAIL; 440 if (outBuf) 441 { 442 spec->decoder.decoder.dic = outBuf; 443 spec->decoder.decoder.dicBufSize = outBufSize; 444 } 445 return SZ_OK; 446 } 447 448 449 450 static void MixCoder_Construct(CMixCoder *p, ISzAllocPtr alloc) 451 { 452 unsigned i; 453 p->alloc = alloc; 454 p->buf = NULL; 455 p->numCoders = 0; 456 457 p->outBufSize = 0; 458 p->outBuf = NULL; 459 // p->SingleBufMode = False; 460 461 for (i = 0; i < MIXCODER_NUM_FILTERS_MAX; i++) 462 p->coders[i].p = NULL; 463 } 464 465 466 static void MixCoder_Free(CMixCoder *p) 467 { 468 unsigned i; 469 p->numCoders = 0; 470 for (i = 0; i < MIXCODER_NUM_FILTERS_MAX; i++) 471 { 472 IStateCoder *sc = &p->coders[i]; 473 if (sc->p) 474 { 475 sc->Free(sc->p, p->alloc); 476 sc->p = NULL; 477 } 478 } 479 if (p->buf) 480 { 481 ISzAlloc_Free(p->alloc, p->buf); 482 p->buf = NULL; /* 9.31: the BUG was fixed */ 483 } 484 } 485 486 static void MixCoder_Init(CMixCoder *p) 487 { 488 unsigned i; 489 for (i = 0; i < MIXCODER_NUM_FILTERS_MAX - 1; i++) 490 { 491 p->size[i] = 0; 492 p->pos[i] = 0; 493 p->finished[i] = 0; 494 } 495 for (i = 0; i < p->numCoders; i++) 496 { 497 IStateCoder *coder = &p->coders[i]; 498 coder->Init(coder->p); 499 p->results[i] = SZ_OK; 500 } 501 p->outWritten = 0; 502 p->wasFinished = False; 503 p->res = SZ_OK; 504 p->status = CODER_STATUS_NOT_SPECIFIED; 505 } 506 507 508 static SRes MixCoder_SetFromMethod(CMixCoder *p, unsigned coderIndex, UInt64 methodId, Byte *outBuf, size_t outBufSize) 509 { 510 IStateCoder *sc = &p->coders[coderIndex]; 511 p->ids[coderIndex] = methodId; 512 switch (methodId) 513 { 514 case XZ_ID_LZMA2: return Lzma2State_SetFromMethod(sc, outBuf, outBufSize, p->alloc); 515 #ifdef USE_SUBBLOCK 516 case XZ_ID_Subblock: return SbState_SetFromMethod(sc, p->alloc); 517 #endif 518 } 519 if (coderIndex == 0) 520 return SZ_ERROR_UNSUPPORTED; 521 return BraState_SetFromMethod(sc, methodId, 0, p->alloc); 522 } 523 524 525 static SRes MixCoder_ResetFromMethod(CMixCoder *p, unsigned coderIndex, UInt64 methodId, Byte *outBuf, size_t outBufSize) 526 { 527 IStateCoder *sc = &p->coders[coderIndex]; 528 switch (methodId) 529 { 530 case XZ_ID_LZMA2: return Lzma2State_ResetOutBuf(sc, outBuf, outBufSize); 531 } 532 return SZ_ERROR_UNSUPPORTED; 533 } 534 535 536 537 /* 538 if (destFinish) - then unpack data block is finished at (*destLen) position, 539 and we can return data that were not processed by filter 540 541 output (status) can be : 542 CODER_STATUS_NOT_FINISHED 543 CODER_STATUS_FINISHED_WITH_MARK 544 CODER_STATUS_NEEDS_MORE_INPUT - not implemented still 545 */ 546 547 static SRes MixCoder_Code(CMixCoder *p, 548 Byte *dest, SizeT *destLen, int destFinish, 549 const Byte *src, SizeT *srcLen, int srcWasFinished, 550 ECoderFinishMode finishMode) 551 { 552 SizeT destLenOrig = *destLen; 553 SizeT srcLenOrig = *srcLen; 554 555 *destLen = 0; 556 *srcLen = 0; 557 558 if (p->wasFinished) 559 return p->res; 560 561 p->status = CODER_STATUS_NOT_FINISHED; 562 563 // if (p->SingleBufMode) 564 if (p->outBuf) 565 { 566 SRes res; 567 SizeT destLen2, srcLen2; 568 int wasFinished; 569 570 PRF_STR("------- MixCoder Single ----------"); 571 572 srcLen2 = srcLenOrig; 573 destLen2 = destLenOrig; 574 575 { 576 IStateCoder *coder = &p->coders[0]; 577 res = coder->Code2(coder->p, NULL, &destLen2, src, &srcLen2, srcWasFinished, finishMode, 578 // &wasFinished, 579 &p->status); 580 wasFinished = (p->status == CODER_STATUS_FINISHED_WITH_MARK); 581 } 582 583 p->res = res; 584 585 /* 586 if (wasFinished) 587 p->status = CODER_STATUS_FINISHED_WITH_MARK; 588 else 589 { 590 if (res == SZ_OK) 591 if (destLen2 != destLenOrig) 592 p->status = CODER_STATUS_NEEDS_MORE_INPUT; 593 } 594 */ 595 596 597 *srcLen = srcLen2; 598 src += srcLen2; 599 p->outWritten += destLen2; 600 601 if (res != SZ_OK || srcWasFinished || wasFinished) 602 p->wasFinished = True; 603 604 if (p->numCoders == 1) 605 *destLen = destLen2; 606 else if (p->wasFinished) 607 { 608 unsigned i; 609 size_t processed = p->outWritten; 610 611 for (i = 1; i < p->numCoders; i++) 612 { 613 IStateCoder *coder = &p->coders[i]; 614 processed = coder->Filter(coder->p, p->outBuf, processed); 615 if (wasFinished || (destFinish && p->outWritten == destLenOrig)) 616 processed = p->outWritten; 617 PRF_STR_INT("filter", i); 618 } 619 *destLen = processed; 620 } 621 return res; 622 } 623 624 PRF_STR("standard mix"); 625 626 if (p->numCoders != 1) 627 { 628 if (!p->buf) 629 { 630 p->buf = (Byte *)ISzAlloc_Alloc(p->alloc, CODER_BUF_SIZE * (MIXCODER_NUM_FILTERS_MAX - 1)); 631 if (!p->buf) 632 return SZ_ERROR_MEM; 633 } 634 635 finishMode = CODER_FINISH_ANY; 636 } 637 638 for (;;) 639 { 640 Bool processed = False; 641 Bool allFinished = True; 642 SRes resMain = SZ_OK; 643 unsigned i; 644 645 p->status = CODER_STATUS_NOT_FINISHED; 646 /* 647 if (p->numCoders == 1 && *destLen == destLenOrig && finishMode == LZMA_FINISH_ANY) 648 break; 649 */ 650 651 for (i = 0; i < p->numCoders; i++) 652 { 653 SRes res; 654 IStateCoder *coder = &p->coders[i]; 655 Byte *dest2; 656 SizeT destLen2, srcLen2; // destLen2_Orig; 657 const Byte *src2; 658 int srcFinished2; 659 int encodingWasFinished; 660 ECoderStatus status2; 661 662 if (i == 0) 663 { 664 src2 = src; 665 srcLen2 = srcLenOrig - *srcLen; 666 srcFinished2 = srcWasFinished; 667 } 668 else 669 { 670 size_t k = i - 1; 671 src2 = p->buf + (CODER_BUF_SIZE * k) + p->pos[k]; 672 srcLen2 = p->size[k] - p->pos[k]; 673 srcFinished2 = p->finished[k]; 674 } 675 676 if (i == p->numCoders - 1) 677 { 678 dest2 = dest; 679 destLen2 = destLenOrig - *destLen; 680 } 681 else 682 { 683 if (p->pos[i] != p->size[i]) 684 continue; 685 dest2 = p->buf + (CODER_BUF_SIZE * i); 686 destLen2 = CODER_BUF_SIZE; 687 } 688 689 // destLen2_Orig = destLen2; 690 691 if (p->results[i] != SZ_OK) 692 { 693 if (resMain == SZ_OK) 694 resMain = p->results[i]; 695 continue; 696 } 697 698 res = coder->Code2(coder->p, 699 dest2, &destLen2, 700 src2, &srcLen2, srcFinished2, 701 finishMode, 702 // &encodingWasFinished, 703 &status2); 704 705 if (res != SZ_OK) 706 { 707 p->results[i] = res; 708 if (resMain == SZ_OK) 709 resMain = res; 710 } 711 712 encodingWasFinished = (status2 == CODER_STATUS_FINISHED_WITH_MARK); 713 714 if (!encodingWasFinished) 715 { 716 allFinished = False; 717 if (p->numCoders == 1 && res == SZ_OK) 718 p->status = status2; 719 } 720 721 if (i == 0) 722 { 723 *srcLen += srcLen2; 724 src += srcLen2; 725 } 726 else 727 p->pos[(size_t)i - 1] += srcLen2; 728 729 if (i == p->numCoders - 1) 730 { 731 *destLen += destLen2; 732 dest += destLen2; 733 } 734 else 735 { 736 p->size[i] = destLen2; 737 p->pos[i] = 0; 738 p->finished[i] = encodingWasFinished; 739 } 740 741 if (destLen2 != 0 || srcLen2 != 0) 742 processed = True; 743 } 744 745 if (!processed) 746 { 747 if (allFinished) 748 p->status = CODER_STATUS_FINISHED_WITH_MARK; 749 return resMain; 750 } 751 } 752 } 753 754 755 SRes Xz_ParseHeader(CXzStreamFlags *p, const Byte *buf) 756 { 757 *p = (CXzStreamFlags)GetBe16(buf + XZ_SIG_SIZE); 758 if (CrcCalc(buf + XZ_SIG_SIZE, XZ_STREAM_FLAGS_SIZE) != 759 GetUi32(buf + XZ_SIG_SIZE + XZ_STREAM_FLAGS_SIZE)) 760 return SZ_ERROR_NO_ARCHIVE; 761 return XzFlags_IsSupported(*p) ? SZ_OK : SZ_ERROR_UNSUPPORTED; 762 } 763 764 static Bool Xz_CheckFooter(CXzStreamFlags flags, UInt64 indexSize, const Byte *buf) 765 { 766 return indexSize == (((UInt64)GetUi32(buf + 4) + 1) << 2) 767 && GetUi32(buf) == CrcCalc(buf + 4, 6) 768 && flags == GetBe16(buf + 8) 769 && buf[10] == XZ_FOOTER_SIG_0 770 && buf[11] == XZ_FOOTER_SIG_1; 771 } 772 773 #define READ_VARINT_AND_CHECK(buf, pos, size, res) \ 774 { unsigned s = Xz_ReadVarInt(buf + pos, size - pos, res); \ 775 if (s == 0) return SZ_ERROR_ARCHIVE; pos += s; } 776 777 778 static Bool XzBlock_AreSupportedFilters(const CXzBlock *p) 779 { 780 unsigned numFilters = XzBlock_GetNumFilters(p) - 1; 781 unsigned i; 782 { 783 const CXzFilter *f = &p->filters[numFilters]; 784 if (f->id != XZ_ID_LZMA2 || f->propsSize != 1 || f->props[0] > 40) 785 return False; 786 } 787 788 for (i = 0; i < numFilters; i++) 789 { 790 const CXzFilter *f = &p->filters[i]; 791 if (f->id == XZ_ID_Delta) 792 { 793 if (f->propsSize != 1) 794 return False; 795 } 796 else if (f->id < XZ_ID_Delta 797 || f->id > XZ_ID_SPARC 798 || (f->propsSize != 0 && f->propsSize != 4)) 799 return False; 800 } 801 return True; 802 } 803 804 805 SRes XzBlock_Parse(CXzBlock *p, const Byte *header) 806 { 807 unsigned pos; 808 unsigned numFilters, i; 809 unsigned headerSize = (unsigned)header[0] << 2; 810 811 /* (headerSize != 0) : another code checks */ 812 813 if (CrcCalc(header, headerSize) != GetUi32(header + headerSize)) 814 return SZ_ERROR_ARCHIVE; 815 816 pos = 1; 817 p->flags = header[pos++]; 818 819 p->packSize = (UInt64)(Int64)-1; 820 if (XzBlock_HasPackSize(p)) 821 { 822 READ_VARINT_AND_CHECK(header, pos, headerSize, &p->packSize); 823 if (p->packSize == 0 || p->packSize + headerSize >= (UInt64)1 << 63) 824 return SZ_ERROR_ARCHIVE; 825 } 826 827 p->unpackSize = (UInt64)(Int64)-1; 828 if (XzBlock_HasUnpackSize(p)) 829 READ_VARINT_AND_CHECK(header, pos, headerSize, &p->unpackSize); 830 831 numFilters = XzBlock_GetNumFilters(p); 832 for (i = 0; i < numFilters; i++) 833 { 834 CXzFilter *filter = p->filters + i; 835 UInt64 size; 836 READ_VARINT_AND_CHECK(header, pos, headerSize, &filter->id); 837 READ_VARINT_AND_CHECK(header, pos, headerSize, &size); 838 if (size > headerSize - pos || size > XZ_FILTER_PROPS_SIZE_MAX) 839 return SZ_ERROR_ARCHIVE; 840 filter->propsSize = (UInt32)size; 841 memcpy(filter->props, header + pos, (size_t)size); 842 pos += (unsigned)size; 843 844 #ifdef XZ_DUMP 845 printf("\nf[%u] = %2X: ", i, (unsigned)filter->id); 846 { 847 unsigned i; 848 for (i = 0; i < size; i++) 849 printf(" %2X", filter->props[i]); 850 } 851 #endif 852 } 853 854 if (XzBlock_HasUnsupportedFlags(p)) 855 return SZ_ERROR_UNSUPPORTED; 856 857 while (pos < headerSize) 858 if (header[pos++] != 0) 859 return SZ_ERROR_ARCHIVE; 860 return SZ_OK; 861 } 862 863 864 865 866 static SRes XzDecMix_Init(CMixCoder *p, const CXzBlock *block, Byte *outBuf, size_t outBufSize) 867 { 868 unsigned i; 869 Bool needReInit = True; 870 unsigned numFilters = XzBlock_GetNumFilters(block); 871 872 if (numFilters == p->numCoders && ((p->outBuf && outBuf) || (!p->outBuf && !outBuf))) 873 { 874 needReInit = False; 875 for (i = 0; i < numFilters; i++) 876 if (p->ids[i] != block->filters[numFilters - 1 - i].id) 877 { 878 needReInit = True; 879 break; 880 } 881 } 882 883 // p->SingleBufMode = (outBuf != NULL); 884 p->outBuf = outBuf; 885 p->outBufSize = outBufSize; 886 887 // p->SingleBufMode = False; 888 // outBuf = NULL; 889 890 if (needReInit) 891 { 892 MixCoder_Free(p); 893 for (i = 0; i < numFilters; i++) 894 { 895 RINOK(MixCoder_SetFromMethod(p, i, block->filters[numFilters - 1 - i].id, outBuf, outBufSize)); 896 } 897 p->numCoders = numFilters; 898 } 899 else 900 { 901 RINOK(MixCoder_ResetFromMethod(p, 0, block->filters[numFilters - 1].id, outBuf, outBufSize)); 902 } 903 904 for (i = 0; i < numFilters; i++) 905 { 906 const CXzFilter *f = &block->filters[numFilters - 1 - i]; 907 IStateCoder *sc = &p->coders[i]; 908 RINOK(sc->SetProps(sc->p, f->props, f->propsSize, p->alloc)); 909 } 910 911 MixCoder_Init(p); 912 return SZ_OK; 913 } 914 915 916 917 void XzUnpacker_Init(CXzUnpacker *p) 918 { 919 p->state = XZ_STATE_STREAM_HEADER; 920 p->pos = 0; 921 p->numStartedStreams = 0; 922 p->numFinishedStreams = 0; 923 p->numTotalBlocks = 0; 924 p->padSize = 0; 925 p->decodeOnlyOneBlock = 0; 926 927 p->parseMode = False; 928 p->decodeToStreamSignature = False; 929 930 // p->outBuf = NULL; 931 // p->outBufSize = 0; 932 p->outDataWritten = 0; 933 } 934 935 936 void XzUnpacker_SetOutBuf(CXzUnpacker *p, Byte *outBuf, size_t outBufSize) 937 { 938 p->outBuf = outBuf; 939 p->outBufSize = outBufSize; 940 } 941 942 943 void XzUnpacker_Construct(CXzUnpacker *p, ISzAllocPtr alloc) 944 { 945 MixCoder_Construct(&p->decoder, alloc); 946 p->outBuf = NULL; 947 p->outBufSize = 0; 948 XzUnpacker_Init(p); 949 } 950 951 952 void XzUnpacker_Free(CXzUnpacker *p) 953 { 954 MixCoder_Free(&p->decoder); 955 } 956 957 958 void XzUnpacker_PrepareToRandomBlockDecoding(CXzUnpacker *p) 959 { 960 p->indexSize = 0; 961 p->numBlocks = 0; 962 Sha256_Init(&p->sha); 963 p->state = XZ_STATE_BLOCK_HEADER; 964 p->pos = 0; 965 p->decodeOnlyOneBlock = 1; 966 } 967 968 969 static void XzUnpacker_UpdateIndex(CXzUnpacker *p, UInt64 packSize, UInt64 unpackSize) 970 { 971 Byte temp[32]; 972 unsigned num = Xz_WriteVarInt(temp, packSize); 973 num += Xz_WriteVarInt(temp + num, unpackSize); 974 Sha256_Update(&p->sha, temp, num); 975 p->indexSize += num; 976 p->numBlocks++; 977 } 978 979 980 981 SRes XzUnpacker_Code(CXzUnpacker *p, Byte *dest, SizeT *destLen, 982 const Byte *src, SizeT *srcLen, int srcFinished, 983 ECoderFinishMode finishMode, ECoderStatus *status) 984 { 985 SizeT destLenOrig = *destLen; 986 SizeT srcLenOrig = *srcLen; 987 *destLen = 0; 988 *srcLen = 0; 989 *status = CODER_STATUS_NOT_SPECIFIED; 990 991 for (;;) 992 { 993 SizeT srcRem; 994 995 if (p->state == XZ_STATE_BLOCK) 996 { 997 SizeT destLen2 = destLenOrig - *destLen; 998 SizeT srcLen2 = srcLenOrig - *srcLen; 999 SRes res; 1000 1001 ECoderFinishMode finishMode2 = finishMode; 1002 Bool srcFinished2 = srcFinished; 1003 Bool destFinish = False; 1004 1005 if (p->block.packSize != (UInt64)(Int64)-1) 1006 { 1007 UInt64 rem = p->block.packSize - p->packSize; 1008 if (srcLen2 >= rem) 1009 { 1010 srcFinished2 = True; 1011 srcLen2 = (SizeT)rem; 1012 } 1013 if (rem == 0 && p->block.unpackSize == p->unpackSize) 1014 return SZ_ERROR_DATA; 1015 } 1016 1017 if (p->block.unpackSize != (UInt64)(Int64)-1) 1018 { 1019 UInt64 rem = p->block.unpackSize - p->unpackSize; 1020 if (destLen2 >= rem) 1021 { 1022 destFinish = True; 1023 finishMode2 = CODER_FINISH_END; 1024 destLen2 = (SizeT)rem; 1025 } 1026 } 1027 1028 /* 1029 if (srcLen2 == 0 && destLen2 == 0) 1030 { 1031 *status = CODER_STATUS_NOT_FINISHED; 1032 return SZ_OK; 1033 } 1034 */ 1035 1036 { 1037 res = MixCoder_Code(&p->decoder, 1038 (p->outBuf ? NULL : dest), &destLen2, destFinish, 1039 src, &srcLen2, srcFinished2, 1040 finishMode2); 1041 1042 *status = p->decoder.status; 1043 XzCheck_Update(&p->check, (p->outBuf ? p->outBuf + p->outDataWritten : dest), destLen2); 1044 if (!p->outBuf) 1045 dest += destLen2; 1046 p->outDataWritten += destLen2; 1047 } 1048 1049 (*srcLen) += srcLen2; 1050 src += srcLen2; 1051 p->packSize += srcLen2; 1052 (*destLen) += destLen2; 1053 p->unpackSize += destLen2; 1054 1055 RINOK(res); 1056 1057 if (*status != CODER_STATUS_FINISHED_WITH_MARK) 1058 { 1059 if (p->block.packSize == p->packSize 1060 && *status == CODER_STATUS_NEEDS_MORE_INPUT) 1061 { 1062 PRF_STR("CODER_STATUS_NEEDS_MORE_INPUT"); 1063 *status = CODER_STATUS_NOT_SPECIFIED; 1064 return SZ_ERROR_DATA; 1065 } 1066 1067 return SZ_OK; 1068 } 1069 { 1070 XzUnpacker_UpdateIndex(p, XzUnpacker_GetPackSizeForIndex(p), p->unpackSize); 1071 p->state = XZ_STATE_BLOCK_FOOTER; 1072 p->pos = 0; 1073 p->alignPos = 0; 1074 *status = CODER_STATUS_NOT_SPECIFIED; 1075 1076 if ((p->block.packSize != (UInt64)(Int64)-1 && p->block.packSize != p->packSize) 1077 || (p->block.unpackSize != (UInt64)(Int64)-1 && p->block.unpackSize != p->unpackSize)) 1078 { 1079 PRF_STR("ERROR: block.size mismatch"); 1080 return SZ_ERROR_DATA; 1081 } 1082 } 1083 // continue; 1084 } 1085 1086 srcRem = srcLenOrig - *srcLen; 1087 1088 // XZ_STATE_BLOCK_FOOTER can transit to XZ_STATE_BLOCK_HEADER without input bytes 1089 if (srcRem == 0 && p->state != XZ_STATE_BLOCK_FOOTER) 1090 { 1091 *status = CODER_STATUS_NEEDS_MORE_INPUT; 1092 return SZ_OK; 1093 } 1094 1095 switch (p->state) 1096 { 1097 case XZ_STATE_STREAM_HEADER: 1098 { 1099 if (p->pos < XZ_STREAM_HEADER_SIZE) 1100 { 1101 if (p->pos < XZ_SIG_SIZE && *src != XZ_SIG[p->pos]) 1102 return SZ_ERROR_NO_ARCHIVE; 1103 if (p->decodeToStreamSignature) 1104 return SZ_OK; 1105 p->buf[p->pos++] = *src++; 1106 (*srcLen)++; 1107 } 1108 else 1109 { 1110 RINOK(Xz_ParseHeader(&p->streamFlags, p->buf)); 1111 p->numStartedStreams++; 1112 p->indexSize = 0; 1113 p->numBlocks = 0; 1114 Sha256_Init(&p->sha); 1115 p->state = XZ_STATE_BLOCK_HEADER; 1116 p->pos = 0; 1117 } 1118 break; 1119 } 1120 1121 case XZ_STATE_BLOCK_HEADER: 1122 { 1123 if (p->pos == 0) 1124 { 1125 p->buf[p->pos++] = *src++; 1126 (*srcLen)++; 1127 if (p->buf[0] == 0) 1128 { 1129 if (p->decodeOnlyOneBlock) 1130 return SZ_ERROR_DATA; 1131 p->indexPreSize = 1 + Xz_WriteVarInt(p->buf + 1, p->numBlocks); 1132 p->indexPos = p->indexPreSize; 1133 p->indexSize += p->indexPreSize; 1134 Sha256_Final(&p->sha, p->shaDigest); 1135 Sha256_Init(&p->sha); 1136 p->crc = CrcUpdate(CRC_INIT_VAL, p->buf, p->indexPreSize); 1137 p->state = XZ_STATE_STREAM_INDEX; 1138 break; 1139 } 1140 p->blockHeaderSize = ((UInt32)p->buf[0] << 2) + 4; 1141 break; 1142 } 1143 1144 if (p->pos != p->blockHeaderSize) 1145 { 1146 UInt32 cur = p->blockHeaderSize - p->pos; 1147 if (cur > srcRem) 1148 cur = (UInt32)srcRem; 1149 memcpy(p->buf + p->pos, src, cur); 1150 p->pos += cur; 1151 (*srcLen) += cur; 1152 src += cur; 1153 } 1154 else 1155 { 1156 RINOK(XzBlock_Parse(&p->block, p->buf)); 1157 if (!XzBlock_AreSupportedFilters(&p->block)) 1158 return SZ_ERROR_UNSUPPORTED; 1159 p->numTotalBlocks++; 1160 p->state = XZ_STATE_BLOCK; 1161 p->packSize = 0; 1162 p->unpackSize = 0; 1163 XzCheck_Init(&p->check, XzFlags_GetCheckType(p->streamFlags)); 1164 if (p->parseMode) 1165 { 1166 p->headerParsedOk = True; 1167 return SZ_OK; 1168 } 1169 RINOK(XzDecMix_Init(&p->decoder, &p->block, p->outBuf, p->outBufSize)); 1170 } 1171 break; 1172 } 1173 1174 case XZ_STATE_BLOCK_FOOTER: 1175 { 1176 if ((((unsigned)p->packSize + p->alignPos) & 3) != 0) 1177 { 1178 if (srcRem == 0) 1179 { 1180 *status = CODER_STATUS_NEEDS_MORE_INPUT; 1181 return SZ_OK; 1182 } 1183 (*srcLen)++; 1184 p->alignPos++; 1185 if (*src++ != 0) 1186 return SZ_ERROR_CRC; 1187 } 1188 else 1189 { 1190 UInt32 checkSize = XzFlags_GetCheckSize(p->streamFlags); 1191 UInt32 cur = checkSize - p->pos; 1192 if (cur != 0) 1193 { 1194 if (srcRem == 0) 1195 { 1196 *status = CODER_STATUS_NEEDS_MORE_INPUT; 1197 return SZ_OK; 1198 } 1199 if (cur > srcRem) 1200 cur = (UInt32)srcRem; 1201 memcpy(p->buf + p->pos, src, cur); 1202 p->pos += cur; 1203 (*srcLen) += cur; 1204 src += cur; 1205 if (checkSize != p->pos) 1206 break; 1207 } 1208 { 1209 Byte digest[XZ_CHECK_SIZE_MAX]; 1210 p->state = XZ_STATE_BLOCK_HEADER; 1211 p->pos = 0; 1212 if (XzCheck_Final(&p->check, digest) && memcmp(digest, p->buf, checkSize) != 0) 1213 return SZ_ERROR_CRC; 1214 if (p->decodeOnlyOneBlock) 1215 { 1216 *status = CODER_STATUS_FINISHED_WITH_MARK; 1217 return SZ_OK; 1218 } 1219 } 1220 } 1221 break; 1222 } 1223 1224 case XZ_STATE_STREAM_INDEX: 1225 { 1226 if (p->pos < p->indexPreSize) 1227 { 1228 (*srcLen)++; 1229 if (*src++ != p->buf[p->pos++]) 1230 return SZ_ERROR_CRC; 1231 } 1232 else 1233 { 1234 if (p->indexPos < p->indexSize) 1235 { 1236 UInt64 cur = p->indexSize - p->indexPos; 1237 if (srcRem > cur) 1238 srcRem = (SizeT)cur; 1239 p->crc = CrcUpdate(p->crc, src, srcRem); 1240 Sha256_Update(&p->sha, src, srcRem); 1241 (*srcLen) += srcRem; 1242 src += srcRem; 1243 p->indexPos += srcRem; 1244 } 1245 else if ((p->indexPos & 3) != 0) 1246 { 1247 Byte b = *src++; 1248 p->crc = CRC_UPDATE_BYTE(p->crc, b); 1249 (*srcLen)++; 1250 p->indexPos++; 1251 p->indexSize++; 1252 if (b != 0) 1253 return SZ_ERROR_CRC; 1254 } 1255 else 1256 { 1257 Byte digest[SHA256_DIGEST_SIZE]; 1258 p->state = XZ_STATE_STREAM_INDEX_CRC; 1259 p->indexSize += 4; 1260 p->pos = 0; 1261 Sha256_Final(&p->sha, digest); 1262 if (memcmp(digest, p->shaDigest, SHA256_DIGEST_SIZE) != 0) 1263 return SZ_ERROR_CRC; 1264 } 1265 } 1266 break; 1267 } 1268 1269 case XZ_STATE_STREAM_INDEX_CRC: 1270 { 1271 if (p->pos < 4) 1272 { 1273 (*srcLen)++; 1274 p->buf[p->pos++] = *src++; 1275 } 1276 else 1277 { 1278 p->state = XZ_STATE_STREAM_FOOTER; 1279 p->pos = 0; 1280 if (CRC_GET_DIGEST(p->crc) != GetUi32(p->buf)) 1281 return SZ_ERROR_CRC; 1282 } 1283 break; 1284 } 1285 1286 case XZ_STATE_STREAM_FOOTER: 1287 { 1288 UInt32 cur = XZ_STREAM_FOOTER_SIZE - p->pos; 1289 if (cur > srcRem) 1290 cur = (UInt32)srcRem; 1291 memcpy(p->buf + p->pos, src, cur); 1292 p->pos += cur; 1293 (*srcLen) += cur; 1294 src += cur; 1295 if (p->pos == XZ_STREAM_FOOTER_SIZE) 1296 { 1297 p->state = XZ_STATE_STREAM_PADDING; 1298 p->numFinishedStreams++; 1299 p->padSize = 0; 1300 if (!Xz_CheckFooter(p->streamFlags, p->indexSize, p->buf)) 1301 return SZ_ERROR_CRC; 1302 } 1303 break; 1304 } 1305 1306 case XZ_STATE_STREAM_PADDING: 1307 { 1308 if (*src != 0) 1309 { 1310 if (((UInt32)p->padSize & 3) != 0) 1311 return SZ_ERROR_NO_ARCHIVE; 1312 p->pos = 0; 1313 p->state = XZ_STATE_STREAM_HEADER; 1314 } 1315 else 1316 { 1317 (*srcLen)++; 1318 src++; 1319 p->padSize++; 1320 } 1321 break; 1322 } 1323 1324 case XZ_STATE_BLOCK: break; /* to disable GCC warning */ 1325 } 1326 } 1327 /* 1328 if (p->state == XZ_STATE_FINISHED) 1329 *status = CODER_STATUS_FINISHED_WITH_MARK; 1330 return SZ_OK; 1331 */ 1332 } 1333 1334 1335 SRes XzUnpacker_CodeFull(CXzUnpacker *p, Byte *dest, SizeT *destLen, 1336 const Byte *src, SizeT *srcLen, 1337 ECoderFinishMode finishMode, ECoderStatus *status) 1338 { 1339 XzUnpacker_Init(p); 1340 XzUnpacker_SetOutBuf(p, dest, *destLen); 1341 1342 return XzUnpacker_Code(p, 1343 NULL, destLen, 1344 src, srcLen, True, 1345 finishMode, status); 1346 } 1347 1348 1349 Bool XzUnpacker_IsBlockFinished(const CXzUnpacker *p) 1350 { 1351 return (p->state == XZ_STATE_BLOCK_HEADER) && (p->pos == 0); 1352 } 1353 1354 Bool XzUnpacker_IsStreamWasFinished(const CXzUnpacker *p) 1355 { 1356 return (p->state == XZ_STATE_STREAM_PADDING) && (((UInt32)p->padSize & 3) == 0); 1357 } 1358 1359 UInt64 XzUnpacker_GetExtraSize(const CXzUnpacker *p) 1360 { 1361 UInt64 num = 0; 1362 if (p->state == XZ_STATE_STREAM_PADDING) 1363 num = p->padSize; 1364 else if (p->state == XZ_STATE_STREAM_HEADER) 1365 num = p->padSize + p->pos; 1366 return num; 1367 } 1368 1369 1370 1371 1372 1373 1374 1375 1376 1377 1378 1379 1380 1381 1382 1383 1384 1385 1386 1387 1388 1389 #ifndef _7ZIP_ST 1390 #include "MtDec.h" 1391 #endif 1392 1393 1394 void XzDecMtProps_Init(CXzDecMtProps *p) 1395 { 1396 p->inBufSize_ST = 1 << 18; 1397 p->outStep_ST = 1 << 20; 1398 p->ignoreErrors = False; 1399 1400 #ifndef _7ZIP_ST 1401 p->numThreads = 1; 1402 p->inBufSize_MT = 1 << 18; 1403 p->memUseMax = sizeof(size_t) << 28; 1404 #endif 1405 } 1406 1407 1408 1409 #ifndef _7ZIP_ST 1410 1411 /* ---------- CXzDecMtThread ---------- */ 1412 1413 typedef struct 1414 { 1415 Byte *outBuf; 1416 size_t outBufSize; 1417 size_t outPreSize; 1418 size_t inPreSize; 1419 size_t inPreHeaderSize; 1420 size_t blockPackSize_for_Index; // including block header and checksum. 1421 size_t blockPackTotal; // including stream header, block header and checksum. 1422 size_t inCodeSize; 1423 size_t outCodeSize; 1424 ECoderStatus status; 1425 SRes codeRes; 1426 Bool skipMode; 1427 // Bool finishedWithMark; 1428 EMtDecParseState parseState; 1429 Bool parsing_Truncated; 1430 Bool atBlockHeader; 1431 CXzStreamFlags streamFlags; 1432 // UInt64 numFinishedStreams 1433 UInt64 numStreams; 1434 UInt64 numTotalBlocks; 1435 UInt64 numBlocks; 1436 1437 Bool dec_created; 1438 CXzUnpacker dec; 1439 1440 Byte mtPad[1 << 7]; 1441 } CXzDecMtThread; 1442 1443 #endif 1444 1445 1446 /* ---------- CXzDecMt ---------- */ 1447 1448 typedef struct 1449 { 1450 CAlignOffsetAlloc alignOffsetAlloc; 1451 ISzAllocPtr allocMid; 1452 1453 CXzDecMtProps props; 1454 size_t unpackBlockMaxSize; 1455 1456 ISeqInStream *inStream; 1457 ISeqOutStream *outStream; 1458 ICompressProgress *progress; 1459 // CXzStatInfo *stat; 1460 1461 Bool finishMode; 1462 Bool outSize_Defined; 1463 UInt64 outSize; 1464 1465 UInt64 outProcessed; 1466 UInt64 inProcessed; 1467 UInt64 readProcessed; 1468 Bool readWasFinished; 1469 SRes readRes; 1470 SRes writeRes; 1471 1472 Byte *outBuf; 1473 size_t outBufSize; 1474 Byte *inBuf; 1475 size_t inBufSize; 1476 Bool dec_created; 1477 CXzUnpacker dec; 1478 1479 ECoderStatus status; 1480 SRes codeRes; 1481 1482 #ifndef _7ZIP_ST 1483 Bool mainDecoderWasCalled; 1484 // int statErrorDefined; 1485 int finishedDecoderIndex; 1486 1487 // global values that are used in Parse stage 1488 CXzStreamFlags streamFlags; 1489 // UInt64 numFinishedStreams 1490 UInt64 numStreams; 1491 UInt64 numTotalBlocks; 1492 UInt64 numBlocks; 1493 1494 // UInt64 numBadBlocks; 1495 SRes mainErrorCode; 1496 1497 Bool isBlockHeaderState_Parse; 1498 Bool isBlockHeaderState_Write; 1499 UInt64 outProcessed_Parse; 1500 Bool parsing_Truncated; 1501 1502 Bool mtc_WasConstructed; 1503 CMtDec mtc; 1504 CXzDecMtThread coders[MTDEC__THREADS_MAX]; 1505 #endif 1506 1507 } CXzDecMt; 1508 1509 1510 1511 CXzDecMtHandle XzDecMt_Create(ISzAllocPtr alloc, ISzAllocPtr allocMid) 1512 { 1513 CXzDecMt *p = (CXzDecMt *)ISzAlloc_Alloc(alloc, sizeof(CXzDecMt)); 1514 if (!p) 1515 return NULL; 1516 1517 AlignOffsetAlloc_CreateVTable(&p->alignOffsetAlloc); 1518 p->alignOffsetAlloc.baseAlloc = alloc; 1519 p->alignOffsetAlloc.numAlignBits = 7; 1520 p->alignOffsetAlloc.offset = 0; 1521 1522 p->allocMid = allocMid; 1523 1524 p->outBuf = NULL; 1525 p->outBufSize = 0; 1526 p->inBuf = NULL; 1527 p->inBufSize = 0; 1528 p->dec_created = False; 1529 1530 p->unpackBlockMaxSize = 0; 1531 1532 XzDecMtProps_Init(&p->props); 1533 1534 #ifndef _7ZIP_ST 1535 p->mtc_WasConstructed = False; 1536 { 1537 unsigned i; 1538 for (i = 0; i < MTDEC__THREADS_MAX; i++) 1539 { 1540 CXzDecMtThread *coder = &p->coders[i]; 1541 coder->dec_created = False; 1542 coder->outBuf = NULL; 1543 coder->outBufSize = 0; 1544 } 1545 } 1546 #endif 1547 1548 return p; 1549 } 1550 1551 1552 #ifndef _7ZIP_ST 1553 1554 static void XzDecMt_FreeOutBufs(CXzDecMt *p) 1555 { 1556 unsigned i; 1557 for (i = 0; i < MTDEC__THREADS_MAX; i++) 1558 { 1559 CXzDecMtThread *coder = &p->coders[i]; 1560 if (coder->outBuf) 1561 { 1562 ISzAlloc_Free(p->allocMid, coder->outBuf); 1563 coder->outBuf = NULL; 1564 coder->outBufSize = 0; 1565 } 1566 } 1567 p->unpackBlockMaxSize = 0; 1568 } 1569 1570 #endif 1571 1572 1573 1574 static void XzDecMt_FreeSt(CXzDecMt *p) 1575 { 1576 if (p->dec_created) 1577 { 1578 XzUnpacker_Free(&p->dec); 1579 p->dec_created = False; 1580 } 1581 1582 if (p->outBuf) 1583 { 1584 ISzAlloc_Free(p->allocMid, p->outBuf); 1585 p->outBuf = NULL; 1586 } 1587 p->outBufSize = 0; 1588 1589 if (p->inBuf) 1590 { 1591 ISzAlloc_Free(p->allocMid, p->inBuf); 1592 p->inBuf = NULL; 1593 } 1594 p->inBufSize = 0; 1595 } 1596 1597 1598 void XzDecMt_Destroy(CXzDecMtHandle pp) 1599 { 1600 CXzDecMt *p = (CXzDecMt *)pp; 1601 1602 XzDecMt_FreeSt(p); 1603 1604 #ifndef _7ZIP_ST 1605 1606 if (p->mtc_WasConstructed) 1607 { 1608 MtDec_Destruct(&p->mtc); 1609 p->mtc_WasConstructed = False; 1610 } 1611 { 1612 unsigned i; 1613 for (i = 0; i < MTDEC__THREADS_MAX; i++) 1614 { 1615 CXzDecMtThread *t = &p->coders[i]; 1616 if (t->dec_created) 1617 { 1618 // we don't need to free dict here 1619 XzUnpacker_Free(&t->dec); 1620 t->dec_created = False; 1621 } 1622 } 1623 } 1624 XzDecMt_FreeOutBufs(p); 1625 1626 #endif 1627 1628 ISzAlloc_Free(p->alignOffsetAlloc.baseAlloc, pp); 1629 } 1630 1631 1632 1633 #ifndef _7ZIP_ST 1634 1635 static void XzDecMt_Callback_Parse(void *obj, unsigned coderIndex, CMtDecCallbackInfo *cc) 1636 { 1637 CXzDecMt *me = (CXzDecMt *)obj; 1638 CXzDecMtThread *coder = &me->coders[coderIndex]; 1639 size_t srcSize = cc->srcSize; 1640 1641 cc->srcSize = 0; 1642 cc->outPos = 0; 1643 cc->state = MTDEC_PARSE_CONTINUE; 1644 1645 cc->canCreateNewThread = True; 1646 1647 if (cc->startCall) 1648 { 1649 coder->outPreSize = 0; 1650 coder->inPreSize = 0; 1651 coder->inPreHeaderSize = 0; 1652 coder->parseState = MTDEC_PARSE_CONTINUE; 1653 coder->parsing_Truncated = False; 1654 coder->skipMode = False; 1655 coder->codeRes = SZ_OK; 1656 coder->status = CODER_STATUS_NOT_SPECIFIED; 1657 coder->inCodeSize = 0; 1658 coder->outCodeSize = 0; 1659 1660 coder->numStreams = me->numStreams; 1661 coder->numTotalBlocks = me->numTotalBlocks; 1662 coder->numBlocks = me->numBlocks; 1663 1664 if (!coder->dec_created) 1665 { 1666 XzUnpacker_Construct(&coder->dec, &me->alignOffsetAlloc.vt); 1667 coder->dec_created = True; 1668 } 1669 1670 XzUnpacker_Init(&coder->dec); 1671 1672 if (me->isBlockHeaderState_Parse) 1673 { 1674 coder->dec.streamFlags = me->streamFlags; 1675 coder->atBlockHeader = True; 1676 XzUnpacker_PrepareToRandomBlockDecoding(&coder->dec); 1677 } 1678 else 1679 { 1680 coder->atBlockHeader = False; 1681 me->isBlockHeaderState_Parse = True; 1682 } 1683 1684 coder->dec.numStartedStreams = me->numStreams; 1685 coder->dec.numTotalBlocks = me->numTotalBlocks; 1686 coder->dec.numBlocks = me->numBlocks; 1687 } 1688 1689 while (!coder->skipMode) 1690 { 1691 ECoderStatus status; 1692 SRes res; 1693 size_t srcSize2 = srcSize; 1694 size_t destSize = (size_t)0 - 1; 1695 1696 coder->dec.parseMode = True; 1697 coder->dec.headerParsedOk = False; 1698 1699 PRF_STR_INT("Parse", srcSize2); 1700 1701 res = XzUnpacker_Code(&coder->dec, 1702 NULL, &destSize, 1703 cc->src, &srcSize2, cc->srcFinished, 1704 CODER_FINISH_END, &status); 1705 1706 // PRF(printf(" res = %d, srcSize2 = %d", res, (unsigned)srcSize2)); 1707 1708 coder->codeRes = res; 1709 coder->status = status; 1710 cc->srcSize += srcSize2; 1711 srcSize -= srcSize2; 1712 coder->inPreHeaderSize += srcSize2; 1713 coder->inPreSize = coder->inPreHeaderSize; 1714 1715 if (res != SZ_OK) 1716 { 1717 cc->state = 1718 coder->parseState = MTDEC_PARSE_END; 1719 /* 1720 if (res == SZ_ERROR_MEM) 1721 return res; 1722 return SZ_OK; 1723 */ 1724 return; // res; 1725 } 1726 1727 if (coder->dec.headerParsedOk) 1728 { 1729 const CXzBlock *block = &coder->dec.block; 1730 if (XzBlock_HasUnpackSize(block) 1731 // && block->unpackSize <= me->props.outBlockMax 1732 && XzBlock_HasPackSize(block)) 1733 { 1734 { 1735 if (block->unpackSize * 2 * me->mtc.numStartedThreads > me->props.memUseMax) 1736 { 1737 cc->state = MTDEC_PARSE_OVERFLOW; 1738 return; // SZ_OK; 1739 } 1740 } 1741 { 1742 UInt64 packSize = block->packSize; 1743 UInt64 packSizeAligned = packSize + ((0 - (unsigned)packSize) & 3); 1744 UInt32 checkSize = XzFlags_GetCheckSize(coder->dec.streamFlags); 1745 UInt64 blockPackSum = coder->inPreSize + packSizeAligned + checkSize; 1746 // if (blockPackSum <= me->props.inBlockMax) 1747 // unpackBlockMaxSize 1748 { 1749 coder->blockPackSize_for_Index = (size_t)(coder->dec.blockHeaderSize + packSize + checkSize); 1750 coder->blockPackTotal = (size_t)blockPackSum; 1751 coder->outPreSize = (size_t)block->unpackSize; 1752 coder->streamFlags = coder->dec.streamFlags; 1753 me->streamFlags = coder->dec.streamFlags; 1754 coder->skipMode = True; 1755 break; 1756 } 1757 } 1758 } 1759 } 1760 else 1761 // if (coder->inPreSize <= me->props.inBlockMax) 1762 { 1763 if (!cc->srcFinished) 1764 return; // SZ_OK; 1765 cc->state = 1766 coder->parseState = MTDEC_PARSE_END; 1767 return; // SZ_OK; 1768 } 1769 cc->state = MTDEC_PARSE_OVERFLOW; 1770 return; // SZ_OK; 1771 } 1772 1773 // ---------- skipMode ---------- 1774 { 1775 UInt64 rem = coder->blockPackTotal - coder->inPreSize; 1776 size_t cur = srcSize; 1777 if (cur > rem) 1778 cur = (size_t)rem; 1779 cc->srcSize += cur; 1780 coder->inPreSize += cur; 1781 srcSize -= cur; 1782 1783 if (coder->inPreSize == coder->blockPackTotal) 1784 { 1785 if (srcSize == 0) 1786 { 1787 if (!cc->srcFinished) 1788 return; // SZ_OK; 1789 cc->state = MTDEC_PARSE_END; 1790 } 1791 else if ((cc->src)[cc->srcSize] == 0) // we check control byte of next block 1792 cc->state = MTDEC_PARSE_END; 1793 else 1794 { 1795 cc->state = MTDEC_PARSE_NEW; 1796 1797 { 1798 size_t blockMax = me->unpackBlockMaxSize; 1799 if (blockMax < coder->outPreSize) 1800 blockMax = coder->outPreSize; 1801 { 1802 UInt64 required = (UInt64)blockMax * (me->mtc.numStartedThreads + 1) * 2; 1803 if (me->props.memUseMax < required) 1804 cc->canCreateNewThread = False; 1805 } 1806 } 1807 1808 if (me->outSize_Defined) 1809 { 1810 // next block can be zero size 1811 const UInt64 rem2 = me->outSize - me->outProcessed_Parse; 1812 if (rem2 < coder->outPreSize) 1813 { 1814 coder->parsing_Truncated = True; 1815 cc->state = MTDEC_PARSE_END; 1816 } 1817 me->outProcessed_Parse += coder->outPreSize; 1818 } 1819 } 1820 } 1821 else if (cc->srcFinished) 1822 cc->state = MTDEC_PARSE_END; 1823 else 1824 return; // SZ_OK; 1825 1826 coder->parseState = cc->state; 1827 cc->outPos = coder->outPreSize; 1828 1829 me->numStreams = coder->dec.numStartedStreams; 1830 me->numTotalBlocks = coder->dec.numTotalBlocks; 1831 me->numBlocks = coder->dec.numBlocks + 1; 1832 return; // SZ_OK; 1833 } 1834 } 1835 1836 1837 static SRes XzDecMt_Callback_PreCode(void *pp, unsigned coderIndex) 1838 { 1839 CXzDecMt *me = (CXzDecMt *)pp; 1840 CXzDecMtThread *coder = &me->coders[coderIndex]; 1841 Byte *dest; 1842 1843 if (!coder->dec.headerParsedOk) 1844 return SZ_OK; 1845 1846 dest = coder->outBuf; 1847 1848 if (!dest || coder->outBufSize < coder->outPreSize) 1849 { 1850 if (dest) 1851 { 1852 ISzAlloc_Free(me->allocMid, dest); 1853 coder->outBuf = NULL; 1854 coder->outBufSize = 0; 1855 } 1856 { 1857 size_t outPreSize = coder->outPreSize; 1858 if (outPreSize == 0) 1859 outPreSize = 1; 1860 dest = (Byte *)ISzAlloc_Alloc(me->allocMid, outPreSize); 1861 } 1862 if (!dest) 1863 return SZ_ERROR_MEM; 1864 coder->outBuf = dest; 1865 coder->outBufSize = coder->outPreSize; 1866 1867 if (coder->outBufSize > me->unpackBlockMaxSize) 1868 me->unpackBlockMaxSize = coder->outBufSize; 1869 } 1870 1871 // return SZ_ERROR_MEM; 1872 1873 XzUnpacker_SetOutBuf(&coder->dec, coder->outBuf, coder->outBufSize); 1874 1875 { 1876 SRes res = XzDecMix_Init(&coder->dec.decoder, &coder->dec.block, coder->outBuf, coder->outBufSize); 1877 // res = SZ_ERROR_UNSUPPORTED; // to test 1878 coder->codeRes = res; 1879 if (res != SZ_OK) 1880 { 1881 // if (res == SZ_ERROR_MEM) return res; 1882 if (me->props.ignoreErrors && res != SZ_ERROR_MEM) 1883 return S_OK; 1884 return res; 1885 } 1886 } 1887 1888 return SZ_OK; 1889 } 1890 1891 1892 static SRes XzDecMt_Callback_Code(void *pp, unsigned coderIndex, 1893 const Byte *src, size_t srcSize, int srcFinished, 1894 // int finished, int blockFinished, 1895 UInt64 *inCodePos, UInt64 *outCodePos, int *stop) 1896 { 1897 CXzDecMt *me = (CXzDecMt *)pp; 1898 CXzDecMtThread *coder = &me->coders[coderIndex]; 1899 1900 *inCodePos = coder->inCodeSize; 1901 *outCodePos = coder->outCodeSize; 1902 *stop = True; 1903 1904 if (coder->inCodeSize < coder->inPreHeaderSize) 1905 { 1906 UInt64 rem = coder->inPreHeaderSize - coder->inCodeSize; 1907 size_t step = srcSize; 1908 if (step > rem) 1909 step = (size_t)rem; 1910 src += step; 1911 srcSize -= step; 1912 coder->inCodeSize += step; 1913 if (coder->inCodeSize < coder->inPreHeaderSize) 1914 { 1915 *stop = False; 1916 return SZ_OK; 1917 } 1918 } 1919 1920 if (!coder->dec.headerParsedOk) 1921 return SZ_OK; 1922 if (!coder->outBuf) 1923 return SZ_OK; 1924 1925 if (coder->codeRes == SZ_OK) 1926 { 1927 ECoderStatus status; 1928 SRes res; 1929 size_t srcProcessed = srcSize; 1930 size_t outSizeCur = coder->outPreSize - coder->dec.outDataWritten; 1931 1932 // PRF(printf("\nCallback_Code: Code %d %d\n", (unsigned)srcSize, (unsigned)outSizeCur)); 1933 1934 res = XzUnpacker_Code(&coder->dec, 1935 NULL, &outSizeCur, 1936 src, &srcProcessed, srcFinished, 1937 // coder->finishedWithMark ? CODER_FINISH_END : CODER_FINISH_ANY, 1938 CODER_FINISH_END, 1939 &status); 1940 1941 // PRF(printf(" res = %d, srcSize2 = %d, outSizeCur = %d", res, (unsigned)srcProcessed, (unsigned)outSizeCur)); 1942 1943 coder->codeRes = res; 1944 coder->status = status; 1945 coder->inCodeSize += srcProcessed; 1946 coder->outCodeSize = coder->dec.outDataWritten; 1947 *inCodePos = coder->inCodeSize; 1948 *outCodePos = coder->outCodeSize; 1949 1950 if (res == SZ_OK) 1951 { 1952 if (srcProcessed == srcSize) 1953 *stop = False; 1954 return SZ_OK; 1955 } 1956 } 1957 1958 if (me->props.ignoreErrors && coder->codeRes != SZ_ERROR_MEM) 1959 { 1960 *inCodePos = coder->inPreSize; 1961 *outCodePos = coder->outPreSize; 1962 return S_OK; 1963 } 1964 return coder->codeRes; 1965 } 1966 1967 1968 #define XZDECMT_STREAM_WRITE_STEP (1 << 24) 1969 1970 static SRes XzDecMt_Callback_Write(void *pp, unsigned coderIndex, 1971 Bool needWriteToStream, 1972 const Byte *src, size_t srcSize, 1973 // int srcFinished, 1974 Bool *needContinue, 1975 Bool *canRecode) 1976 { 1977 CXzDecMt *me = (CXzDecMt *)pp; 1978 const CXzDecMtThread *coder = &me->coders[coderIndex]; 1979 1980 // PRF(printf("\nWrite processed = %d srcSize = %d\n", (unsigned)me->mtc.inProcessed, (unsigned)srcSize)); 1981 1982 *needContinue = False; 1983 *canRecode = True; 1984 1985 if (!needWriteToStream) 1986 return SZ_OK; 1987 1988 if (!coder->dec.headerParsedOk || !coder->outBuf) 1989 { 1990 if (me->finishedDecoderIndex < 0) 1991 me->finishedDecoderIndex = coderIndex; 1992 return SZ_OK; 1993 } 1994 1995 if (me->finishedDecoderIndex >= 0) 1996 return SZ_OK; 1997 1998 me->mtc.inProcessed += coder->inCodeSize; 1999 2000 *canRecode = False; 2001 2002 { 2003 SRes res; 2004 size_t size = coder->outCodeSize; 2005 Byte *data = coder->outBuf; 2006 2007 // we use in me->dec: sha, numBlocks, indexSize 2008 2009 if (!me->isBlockHeaderState_Write) 2010 { 2011 XzUnpacker_PrepareToRandomBlockDecoding(&me->dec); 2012 me->dec.decodeOnlyOneBlock = False; 2013 me->dec.numStartedStreams = coder->dec.numStartedStreams; 2014 me->dec.streamFlags = coder->streamFlags; 2015 2016 me->isBlockHeaderState_Write = True; 2017 } 2018 2019 me->dec.numTotalBlocks = coder->dec.numTotalBlocks; 2020 XzUnpacker_UpdateIndex(&me->dec, coder->blockPackSize_for_Index, coder->outPreSize); 2021 2022 if (coder->outPreSize != size) 2023 { 2024 if (me->props.ignoreErrors) 2025 { 2026 memset(data + size, 0, coder->outPreSize - size); 2027 size = coder->outPreSize; 2028 } 2029 // me->numBadBlocks++; 2030 if (me->mainErrorCode == SZ_OK) 2031 { 2032 if ((int)coder->status == LZMA_STATUS_NEEDS_MORE_INPUT) 2033 me->mainErrorCode = SZ_ERROR_INPUT_EOF; 2034 else 2035 me->mainErrorCode = SZ_ERROR_DATA; 2036 } 2037 } 2038 2039 if (me->writeRes != SZ_OK) 2040 return me->writeRes; 2041 2042 res = SZ_OK; 2043 { 2044 if (me->outSize_Defined) 2045 { 2046 const UInt64 rem = me->outSize - me->outProcessed; 2047 if (size > rem) 2048 size = (SizeT)rem; 2049 } 2050 2051 for (;;) 2052 { 2053 size_t cur = size; 2054 size_t written; 2055 if (cur > XZDECMT_STREAM_WRITE_STEP) 2056 cur = XZDECMT_STREAM_WRITE_STEP; 2057 2058 written = ISeqOutStream_Write(me->outStream, data, cur); 2059 2060 // PRF(printf("\nWritten ask = %d written = %d\n", (unsigned)cur, (unsigned)written)); 2061 2062 me->outProcessed += written; 2063 if (written != cur) 2064 { 2065 me->writeRes = SZ_ERROR_WRITE; 2066 res = me->writeRes; 2067 break; 2068 } 2069 data += cur; 2070 size -= cur; 2071 // PRF_STR_INT("Written size =", size); 2072 if (size == 0) 2073 break; 2074 res = MtProgress_ProgressAdd(&me->mtc.mtProgress, 0, 0); 2075 if (res != SZ_OK) 2076 break; 2077 } 2078 } 2079 2080 if (coder->codeRes != SZ_OK) 2081 if (!me->props.ignoreErrors) 2082 { 2083 me->finishedDecoderIndex = coderIndex; 2084 return res; 2085 } 2086 2087 RINOK(res); 2088 2089 if (coder->inPreSize != coder->inCodeSize 2090 || coder->blockPackTotal != coder->inCodeSize) 2091 { 2092 me->finishedDecoderIndex = coderIndex; 2093 return SZ_OK; 2094 } 2095 2096 if (coder->parseState != MTDEC_PARSE_END) 2097 { 2098 *needContinue = True; 2099 return SZ_OK; 2100 } 2101 } 2102 2103 // (coder->state == MTDEC_PARSE_END) means that there are no other working threads 2104 // so we can use mtc variables without lock 2105 2106 PRF_STR_INT("Write MTDEC_PARSE_END", me->mtc.inProcessed); 2107 2108 me->mtc.mtProgress.totalInSize = me->mtc.inProcessed; 2109 { 2110 CXzUnpacker *dec = &me->dec; 2111 2112 PRF_STR_INT("PostSingle", srcSize); 2113 2114 { 2115 size_t srcProcessed = srcSize; 2116 ECoderStatus status; 2117 size_t outSizeCur = 0; 2118 SRes res; 2119 2120 // dec->decodeOnlyOneBlock = False; 2121 dec->decodeToStreamSignature = True; 2122 2123 me->mainDecoderWasCalled = True; 2124 2125 if (coder->parsing_Truncated) 2126 { 2127 me->parsing_Truncated = True; 2128 return SZ_OK; 2129 } 2130 2131 res = XzUnpacker_Code(dec, 2132 NULL, &outSizeCur, 2133 src, &srcProcessed, 2134 me->mtc.readWasFinished, // srcFinished 2135 CODER_FINISH_END, // CODER_FINISH_ANY, 2136 &status); 2137 2138 me->status = status; 2139 me->codeRes = res; 2140 2141 me->mtc.inProcessed += srcProcessed; 2142 me->mtc.mtProgress.totalInSize = me->mtc.inProcessed; 2143 2144 if (res != SZ_OK) 2145 { 2146 return S_OK; 2147 // return res; 2148 } 2149 2150 if (dec->state == XZ_STATE_STREAM_HEADER) 2151 { 2152 *needContinue = True; 2153 me->isBlockHeaderState_Parse = False; 2154 me->isBlockHeaderState_Write = False; 2155 { 2156 Byte *crossBuf = MtDec_GetCrossBuff(&me->mtc); 2157 if (!crossBuf) 2158 return SZ_ERROR_MEM; 2159 memcpy(crossBuf, src + srcProcessed, srcSize - srcProcessed); 2160 } 2161 me->mtc.crossStart = 0; 2162 me->mtc.crossEnd = srcSize - srcProcessed; 2163 return SZ_OK; 2164 } 2165 2166 if (status != CODER_STATUS_NEEDS_MORE_INPUT) 2167 { 2168 return E_FAIL; 2169 } 2170 2171 if (me->mtc.readWasFinished) 2172 { 2173 return SZ_OK; 2174 } 2175 } 2176 2177 { 2178 size_t inPos; 2179 size_t inLim; 2180 const Byte *inData; 2181 UInt64 inProgressPrev = me->mtc.inProcessed; 2182 2183 // XzDecMt_Prepare_InBuf_ST(p); 2184 Byte *crossBuf = MtDec_GetCrossBuff(&me->mtc); 2185 if (!crossBuf) 2186 return SZ_ERROR_MEM; 2187 2188 inPos = 0; 2189 inLim = 0; 2190 // outProcessed = 0; 2191 2192 inData = crossBuf; 2193 2194 for (;;) 2195 { 2196 SizeT inProcessed; 2197 SizeT outProcessed; 2198 ECoderStatus status; 2199 SRes res; 2200 2201 if (inPos == inLim) 2202 { 2203 if (!me->mtc.readWasFinished) 2204 { 2205 inPos = 0; 2206 inLim = me->mtc.inBufSize; 2207 me->mtc.readRes = ISeqInStream_Read(me->inStream, (void *)inData, &inLim); 2208 me->mtc.readProcessed += inLim; 2209 if (inLim == 0 || me->mtc.readRes != SZ_OK) 2210 me->mtc.readWasFinished = True; 2211 } 2212 } 2213 2214 inProcessed = inLim - inPos; 2215 outProcessed = 0; 2216 2217 res = XzUnpacker_Code(dec, 2218 NULL, &outProcessed, 2219 inData + inPos, &inProcessed, 2220 (inProcessed == 0), // srcFinished 2221 CODER_FINISH_END, &status); 2222 2223 me->codeRes = res; 2224 me->status = status; 2225 inPos += inProcessed; 2226 me->mtc.inProcessed += inProcessed; 2227 me->mtc.mtProgress.totalInSize = me->mtc.inProcessed; 2228 2229 if (res != SZ_OK) 2230 { 2231 return S_OK; 2232 // return res; 2233 } 2234 2235 if (dec->state == XZ_STATE_STREAM_HEADER) 2236 { 2237 *needContinue = True; 2238 me->mtc.crossStart = inPos; 2239 me->mtc.crossEnd = inLim; 2240 me->isBlockHeaderState_Parse = False; 2241 me->isBlockHeaderState_Write = False; 2242 return SZ_OK; 2243 } 2244 2245 if (status != CODER_STATUS_NEEDS_MORE_INPUT) 2246 return E_FAIL; 2247 2248 if (me->mtc.progress) 2249 { 2250 UInt64 inDelta = me->mtc.inProcessed - inProgressPrev; 2251 if (inDelta >= (1 << 22)) 2252 { 2253 RINOK(MtProgress_Progress_ST(&me->mtc.mtProgress)); 2254 inProgressPrev = me->mtc.inProcessed; 2255 } 2256 } 2257 if (me->mtc.readWasFinished) 2258 return SZ_OK; 2259 } 2260 } 2261 } 2262 } 2263 2264 2265 #endif 2266 2267 2268 2269 void XzStatInfo_Clear(CXzStatInfo *p) 2270 { 2271 p->InSize = 0; 2272 p->OutSize = 0; 2273 2274 p->NumStreams = 0; 2275 p->NumBlocks = 0; 2276 2277 p->UnpackSize_Defined = False; 2278 2279 p->NumStreams_Defined = False; 2280 p->NumBlocks_Defined = False; 2281 2282 // p->IsArc = False; 2283 // p->UnexpectedEnd = False; 2284 // p->Unsupported = False; 2285 // p->HeadersError = False; 2286 // p->DataError = False; 2287 // p->CrcError = False; 2288 2289 p->DataAfterEnd = False; 2290 p->DecodingTruncated = False; 2291 2292 p->DecodeRes = SZ_OK; 2293 p->ReadRes = SZ_OK; 2294 p->ProgressRes = SZ_OK; 2295 2296 p->CombinedRes = SZ_OK; 2297 p->CombinedRes_Type = SZ_OK; 2298 } 2299 2300 2301 2302 2303 static SRes XzDecMt_Decode_ST(CXzDecMt *p 2304 #ifndef _7ZIP_ST 2305 , Bool tMode 2306 #endif 2307 , CXzStatInfo *stat) 2308 { 2309 size_t outPos; 2310 size_t inPos, inLim; 2311 const Byte *inData; 2312 UInt64 inPrev, outPrev; 2313 2314 CXzUnpacker *dec; 2315 2316 #ifndef _7ZIP_ST 2317 if (tMode) 2318 { 2319 XzDecMt_FreeOutBufs(p); 2320 tMode = MtDec_PrepareRead(&p->mtc); 2321 } 2322 #endif 2323 2324 if (!p->outBuf || p->outBufSize != p->props.outStep_ST) 2325 { 2326 ISzAlloc_Free(p->allocMid, p->outBuf); 2327 p->outBufSize = 0; 2328 p->outBuf = (Byte *)ISzAlloc_Alloc(p->allocMid, p->props.outStep_ST); 2329 if (!p->outBuf) 2330 return SZ_ERROR_MEM; 2331 p->outBufSize = p->props.outStep_ST; 2332 } 2333 2334 if (!p->inBuf || p->inBufSize != p->props.inBufSize_ST) 2335 { 2336 ISzAlloc_Free(p->allocMid, p->inBuf); 2337 p->inBufSize = 0; 2338 p->inBuf = (Byte *)ISzAlloc_Alloc(p->allocMid, p->props.inBufSize_ST); 2339 if (!p->inBuf) 2340 return SZ_ERROR_MEM; 2341 p->inBufSize = p->props.inBufSize_ST; 2342 } 2343 2344 dec = &p->dec; 2345 dec->decodeToStreamSignature = False; 2346 // dec->decodeOnlyOneBlock = False; 2347 2348 XzUnpacker_SetOutBuf(dec, NULL, 0); 2349 2350 inPrev = p->inProcessed; 2351 outPrev = p->outProcessed; 2352 2353 inPos = 0; 2354 inLim = 0; 2355 inData = NULL; 2356 outPos = 0; 2357 2358 for (;;) 2359 { 2360 SizeT outSize; 2361 Bool finished; 2362 ECoderFinishMode finishMode; 2363 SizeT inProcessed; 2364 ECoderStatus status; 2365 SRes res; 2366 2367 SizeT outProcessed; 2368 2369 2370 2371 if (inPos == inLim) 2372 { 2373 #ifndef _7ZIP_ST 2374 if (tMode) 2375 { 2376 inData = MtDec_Read(&p->mtc, &inLim); 2377 inPos = 0; 2378 if (inData) 2379 continue; 2380 tMode = False; 2381 inLim = 0; 2382 } 2383 #endif 2384 2385 if (!p->readWasFinished) 2386 { 2387 inPos = 0; 2388 inLim = p->inBufSize; 2389 inData = p->inBuf; 2390 p->readRes = ISeqInStream_Read(p->inStream, (void *)inData, &inLim); 2391 p->readProcessed += inLim; 2392 if (inLim == 0 || p->readRes != SZ_OK) 2393 p->readWasFinished = True; 2394 } 2395 } 2396 2397 outSize = p->props.outStep_ST - outPos; 2398 2399 finishMode = CODER_FINISH_ANY; 2400 if (p->outSize_Defined) 2401 { 2402 const UInt64 rem = p->outSize - p->outProcessed; 2403 if (outSize >= rem) 2404 { 2405 outSize = (SizeT)rem; 2406 if (p->finishMode) 2407 finishMode = CODER_FINISH_END; 2408 } 2409 } 2410 2411 inProcessed = inLim - inPos; 2412 outProcessed = outSize; 2413 2414 res = XzUnpacker_Code(dec, p->outBuf + outPos, &outProcessed, 2415 inData + inPos, &inProcessed, 2416 (inPos == inLim), // srcFinished 2417 finishMode, &status); 2418 2419 p->codeRes = res; 2420 p->status = status; 2421 2422 inPos += inProcessed; 2423 outPos += outProcessed; 2424 p->inProcessed += inProcessed; 2425 p->outProcessed += outProcessed; 2426 2427 finished = ((inProcessed == 0 && outProcessed == 0) || res != SZ_OK); 2428 2429 if (finished || outProcessed >= outSize) 2430 if (outPos != 0) 2431 { 2432 size_t written = ISeqOutStream_Write(p->outStream, p->outBuf, outPos); 2433 p->outProcessed += written; 2434 if (written != outPos) 2435 { 2436 stat->CombinedRes_Type = SZ_ERROR_WRITE; 2437 return SZ_ERROR_WRITE; 2438 } 2439 outPos = 0; 2440 } 2441 2442 if (p->progress && res == SZ_OK) 2443 { 2444 UInt64 inDelta = p->inProcessed - inPrev; 2445 UInt64 outDelta = p->outProcessed - outPrev; 2446 if (inDelta >= (1 << 22) || outDelta >= (1 << 22)) 2447 { 2448 res = ICompressProgress_Progress(p->progress, p->inProcessed, p->outProcessed); 2449 if (res != SZ_OK) 2450 { 2451 stat->CombinedRes_Type = SZ_ERROR_PROGRESS; 2452 stat->ProgressRes = res; 2453 return res; 2454 } 2455 inPrev = p->inProcessed; 2456 outPrev = p->outProcessed; 2457 } 2458 } 2459 2460 if (finished) 2461 return res; 2462 } 2463 } 2464 2465 static SRes XzStatInfo_SetStat(const CXzUnpacker *dec, 2466 int finishMode, 2467 UInt64 readProcessed, UInt64 inProcessed, 2468 SRes res, ECoderStatus status, 2469 Bool decodingTruncated, 2470 CXzStatInfo *stat) 2471 { 2472 UInt64 extraSize; 2473 2474 stat->DecodingTruncated = (Byte)(decodingTruncated ? 1 : 0); 2475 stat->InSize = inProcessed; 2476 stat->NumStreams = dec->numStartedStreams; 2477 stat->NumBlocks = dec->numTotalBlocks; 2478 2479 stat->UnpackSize_Defined = True; 2480 stat->NumStreams_Defined = True; 2481 stat->NumBlocks_Defined = True; 2482 2483 extraSize = XzUnpacker_GetExtraSize(dec); 2484 2485 if (res == SZ_OK) 2486 { 2487 if (status == CODER_STATUS_NEEDS_MORE_INPUT) 2488 { 2489 // CODER_STATUS_NEEDS_MORE_INPUT is expected status for correct xz streams 2490 extraSize = 0; 2491 if (!XzUnpacker_IsStreamWasFinished(dec)) 2492 res = SZ_ERROR_INPUT_EOF; 2493 } 2494 else if (!decodingTruncated || finishMode) // (status == CODER_STATUS_NOT_FINISHED) 2495 res = SZ_ERROR_DATA; 2496 } 2497 else if (res == SZ_ERROR_NO_ARCHIVE) 2498 { 2499 /* 2500 SZ_ERROR_NO_ARCHIVE is possible for 2 states: 2501 XZ_STATE_STREAM_HEADER - if bad signature or bad CRC 2502 XZ_STATE_STREAM_PADDING - if non-zero padding data 2503 extraSize / inProcessed don't include "bad" byte 2504 */ 2505 if (inProcessed != extraSize) // if good streams before error 2506 if (extraSize != 0 || readProcessed != inProcessed) 2507 { 2508 stat->DataAfterEnd = True; 2509 // there is some good xz stream before. So we set SZ_OK 2510 res = SZ_OK; 2511 } 2512 } 2513 2514 stat->DecodeRes = res; 2515 2516 stat->InSize -= extraSize; 2517 return res; 2518 } 2519 2520 2521 SRes XzDecMt_Decode(CXzDecMtHandle pp, 2522 const CXzDecMtProps *props, 2523 const UInt64 *outDataSize, int finishMode, 2524 ISeqOutStream *outStream, 2525 // Byte *outBuf, size_t *outBufSize, 2526 ISeqInStream *inStream, 2527 // const Byte *inData, size_t inDataSize, 2528 CXzStatInfo *stat, 2529 int *isMT, 2530 ICompressProgress *progress) 2531 { 2532 CXzDecMt *p = (CXzDecMt *)pp; 2533 #ifndef _7ZIP_ST 2534 Bool tMode; 2535 #endif 2536 2537 XzStatInfo_Clear(stat); 2538 2539 p->props = *props; 2540 2541 p->inStream = inStream; 2542 p->outStream = outStream; 2543 p->progress = progress; 2544 // p->stat = stat; 2545 2546 p->outSize = 0; 2547 p->outSize_Defined = False; 2548 if (outDataSize) 2549 { 2550 p->outSize_Defined = True; 2551 p->outSize = *outDataSize; 2552 } 2553 2554 p->finishMode = finishMode; 2555 2556 // p->outSize = 457; p->outSize_Defined = True; p->finishMode = False; // for test 2557 2558 p->writeRes = SZ_OK; 2559 p->outProcessed = 0; 2560 p->inProcessed = 0; 2561 p->readProcessed = 0; 2562 p->readWasFinished = False; 2563 2564 p->codeRes = 0; 2565 p->status = CODER_STATUS_NOT_SPECIFIED; 2566 2567 if (!p->dec_created) 2568 { 2569 XzUnpacker_Construct(&p->dec, &p->alignOffsetAlloc.vt); 2570 p->dec_created = True; 2571 } 2572 XzUnpacker_Init(&p->dec); 2573 2574 2575 *isMT = False; 2576 2577 /* 2578 p->outBuf = NULL; 2579 p->outBufSize = 0; 2580 if (!outStream) 2581 { 2582 p->outBuf = outBuf; 2583 p->outBufSize = *outBufSize; 2584 *outBufSize = 0; 2585 } 2586 */ 2587 2588 2589 #ifndef _7ZIP_ST 2590 2591 p->isBlockHeaderState_Parse = False; 2592 p->isBlockHeaderState_Write = False; 2593 // p->numBadBlocks = 0; 2594 p->mainErrorCode = SZ_OK; 2595 p->mainDecoderWasCalled = False; 2596 2597 tMode = False; 2598 2599 if (p->props.numThreads > 1) 2600 { 2601 IMtDecCallback vt; 2602 2603 XzDecMt_FreeSt(p); 2604 2605 p->outProcessed_Parse = 0; 2606 p->parsing_Truncated = False; 2607 2608 p->numStreams = 0; 2609 p->numTotalBlocks = 0; 2610 p->numBlocks = 0; 2611 p->finishedDecoderIndex = -1; 2612 2613 if (!p->mtc_WasConstructed) 2614 { 2615 p->mtc_WasConstructed = True; 2616 MtDec_Construct(&p->mtc); 2617 } 2618 2619 p->mtc.mtCallback = &vt; 2620 p->mtc.mtCallbackObject = p; 2621 2622 p->mtc.progress = progress; 2623 p->mtc.inStream = inStream; 2624 p->mtc.alloc = &p->alignOffsetAlloc.vt; 2625 // p->mtc.inData = inData; 2626 // p->mtc.inDataSize = inDataSize; 2627 p->mtc.inBufSize = p->props.inBufSize_MT; 2628 // p->mtc.inBlockMax = p->props.inBlockMax; 2629 p->mtc.numThreadsMax = p->props.numThreads; 2630 2631 *isMT = True; 2632 2633 vt.Parse = XzDecMt_Callback_Parse; 2634 vt.PreCode = XzDecMt_Callback_PreCode; 2635 vt.Code = XzDecMt_Callback_Code; 2636 vt.Write = XzDecMt_Callback_Write; 2637 2638 { 2639 Bool needContinue; 2640 2641 SRes res = MtDec_Code(&p->mtc); 2642 2643 stat->InSize = p->mtc.inProcessed; 2644 2645 p->inProcessed = p->mtc.inProcessed; 2646 p->readRes = p->mtc.readRes; 2647 p->readWasFinished = p->mtc.readWasFinished; 2648 p->readProcessed = p->mtc.readProcessed; 2649 2650 tMode = True; 2651 needContinue = False; 2652 2653 if (res == SZ_OK) 2654 { 2655 if (p->mtc.mtProgress.res != SZ_OK) 2656 { 2657 res = p->mtc.mtProgress.res; 2658 stat->ProgressRes = res; 2659 stat->CombinedRes_Type = SZ_ERROR_PROGRESS; 2660 } 2661 else 2662 needContinue = p->mtc.needContinue; 2663 } 2664 2665 if (!needContinue) 2666 { 2667 SRes codeRes; 2668 Bool truncated = False; 2669 ECoderStatus status; 2670 CXzUnpacker *dec; 2671 2672 stat->OutSize = p->outProcessed; 2673 2674 if (p->finishedDecoderIndex >= 0) 2675 { 2676 CXzDecMtThread *coder = &p->coders[(unsigned)p->finishedDecoderIndex]; 2677 codeRes = coder->codeRes; 2678 dec = &coder->dec; 2679 status = coder->status; 2680 } 2681 else if (p->mainDecoderWasCalled) 2682 { 2683 codeRes = p->codeRes; 2684 dec = &p->dec; 2685 status = p->status; 2686 truncated = p->parsing_Truncated; 2687 } 2688 else 2689 return E_FAIL; 2690 2691 XzStatInfo_SetStat(dec, p->finishMode, 2692 p->mtc.readProcessed, p->mtc.inProcessed, 2693 codeRes, status, 2694 truncated, 2695 stat); 2696 2697 if (res == SZ_OK) 2698 { 2699 if (p->writeRes != SZ_OK) 2700 { 2701 res = p->writeRes; 2702 stat->CombinedRes_Type = SZ_ERROR_WRITE; 2703 } 2704 else if (p->mtc.readRes != SZ_OK && p->mtc.inProcessed == p->mtc.readProcessed) 2705 { 2706 res = p->mtc.readRes; 2707 stat->ReadRes = res; 2708 stat->CombinedRes_Type = SZ_ERROR_READ; 2709 } 2710 else if (p->mainErrorCode != SZ_OK) 2711 { 2712 res = p->mainErrorCode; 2713 } 2714 } 2715 2716 stat->CombinedRes = res; 2717 if (stat->CombinedRes_Type == SZ_OK) 2718 stat->CombinedRes_Type = res; 2719 return res; 2720 } 2721 2722 PRF_STR("----- decoding ST -----"); 2723 } 2724 } 2725 2726 #endif 2727 2728 2729 *isMT = False; 2730 2731 { 2732 SRes res = XzDecMt_Decode_ST(p 2733 #ifndef _7ZIP_ST 2734 , tMode 2735 #endif 2736 , stat 2737 ); 2738 2739 XzStatInfo_SetStat(&p->dec, 2740 p->finishMode, 2741 p->readProcessed, p->inProcessed, 2742 p->codeRes, p->status, 2743 False, // truncated 2744 stat); 2745 2746 if (res == SZ_OK) 2747 { 2748 /* 2749 if (p->writeRes != SZ_OK) 2750 { 2751 res = p->writeRes; 2752 stat->CombinedRes_Type = SZ_ERROR_WRITE; 2753 } 2754 else 2755 */ 2756 if (p->readRes != SZ_OK && p->inProcessed == p->readProcessed) 2757 { 2758 res = p->readRes; 2759 stat->ReadRes = res; 2760 stat->CombinedRes_Type = SZ_ERROR_READ; 2761 } 2762 #ifndef _7ZIP_ST 2763 else if (p->mainErrorCode != SZ_OK) 2764 res = p->mainErrorCode; 2765 #endif 2766 } 2767 2768 stat->CombinedRes = res; 2769 if (stat->CombinedRes_Type == SZ_OK) 2770 stat->CombinedRes_Type = res; 2771 return res; 2772 } 2773 }