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