1#ifndef _INCLUDE_PHYSFS_LZMASDK_H_
2#define _INCLUDE_PHYSFS_LZMASDK_H_
3
4/* This is just a bunch of the LZMA SDK mushed together into one header.
5This code is all public domain, and mostly (if not entirely) written by
6Igor Pavlov. http://www.7-zip.org/sdk.html
7--ryan. */
8
9
10
11/* 7zTypes.h -- Basic types
122013-11-12 : Igor Pavlov : Public domain */
13
14#ifndef __7Z_TYPES_H
15#define __7Z_TYPES_H
16
17#ifdef _WIN32
18/* #include <windows.h> */
19#endif
20
21#include <stddef.h>
22
23#ifndef EXTERN_C_BEGIN
24#ifdef __cplusplus
25#define EXTERN_C_BEGIN extern "C" {
26#define EXTERN_C_END }
27#else
28#define EXTERN_C_BEGIN
29#define EXTERN_C_END
30#endif
31#endif
32
33EXTERN_C_BEGIN
34
35#define SZ_OK 0
36
37#define SZ_ERROR_DATA 1
38#define SZ_ERROR_MEM 2
39#define SZ_ERROR_CRC 3
40#define SZ_ERROR_UNSUPPORTED 4
41#define SZ_ERROR_PARAM 5
42#define SZ_ERROR_INPUT_EOF 6
43#define SZ_ERROR_OUTPUT_EOF 7
44#define SZ_ERROR_READ 8
45#define SZ_ERROR_WRITE 9
46#define SZ_ERROR_PROGRESS 10
47#define SZ_ERROR_FAIL 11
48#define SZ_ERROR_THREAD 12
49
50#define SZ_ERROR_ARCHIVE 16
51#define SZ_ERROR_NO_ARCHIVE 17
52
53typedef int SRes;
54
55#ifdef _WIN32
56/* typedef DWORD WRes; */
57typedef unsigned WRes;
58#else
59typedef int WRes;
60#endif
61
62#ifndef RINOK
63#define RINOK(x) { int __result__ = (x); if (__result__ != 0) return __result__; }
64#endif
65
66typedef unsigned char Byte;
67typedef short Int16;
68typedef unsigned short UInt16;
69
70#ifdef _LZMA_UINT32_IS_ULONG
71typedef long Int32;
72typedef unsigned long UInt32;
73#else
74typedef int Int32;
75typedef unsigned int UInt32;
76#endif
77
78#ifdef _SZ_NO_INT_64
79
80/* define _SZ_NO_INT_64, if your compiler doesn't support 64-bit integers.
81 NOTES: Some code will work incorrectly in that case! */
82
83typedef long Int64;
84typedef unsigned long UInt64;
85
86#else
87
88#if defined(_MSC_VER) || defined(__BORLANDC__) || defined(__WATCOMC__)
89typedef __int64 Int64;
90typedef unsigned __int64 UInt64;
91#define UINT64_CONST(n) n ## ui64
92#else
93typedef long long int Int64;
94typedef unsigned long long int UInt64;
95#define UINT64_CONST(n) n ## ULL
96#endif
97
98#endif
99
100#ifdef _LZMA_NO_SYSTEM_SIZE_T
101typedef UInt32 SizeT;
102#else
103typedef size_t SizeT;
104#endif
105
106typedef int Bool;
107#define True 1
108#define False 0
109
110
111#ifdef _WIN32
112#define MY_STD_CALL __stdcall
113#else
114#define MY_STD_CALL
115#endif
116
117#ifdef _MSC_VER
118
119#if _MSC_VER >= 1300
120#define MY_NO_INLINE __declspec(noinline)
121#else
122#define MY_NO_INLINE
123#endif
124
125#define MY_CDECL __cdecl
126#define MY_FAST_CALL __fastcall
127
128#else
129
130#define MY_NO_INLINE
131#define MY_CDECL
132#define MY_FAST_CALL
133
134#endif
135
136
137/* The following interfaces use first parameter as pointer to structure */
138
139typedef struct
140{
141 Byte (*Read)(void *p); /* reads one byte, returns 0 in case of EOF or error */
142} IByteIn;
143
144typedef struct
145{
146 void (*Write)(void *p, Byte b);
147} IByteOut;
148
149typedef struct
150{
151 SRes (*Read)(void *p, void *buf, size_t *size);
152 /* if (input(*size) != 0 && output(*size) == 0) means end_of_stream.
153 (output(*size) < input(*size)) is allowed */
154} ISeqInStream;
155
156typedef struct
157{
158 size_t (*Write)(void *p, const void *buf, size_t size);
159 /* Returns: result - the number of actually written bytes.
160 (result < size) means error */
161} ISeqOutStream;
162
163typedef enum
164{
165 SZ_SEEK_SET = 0,
166 SZ_SEEK_CUR = 1,
167 SZ_SEEK_END = 2
168} ESzSeek;
169
170typedef struct
171{
172 SRes (*Read)(void *p, void *buf, size_t *size); /* same as ISeqInStream::Read */
173 SRes (*Seek)(void *p, Int64 *pos, ESzSeek origin);
174} ISeekInStream;
175
176typedef struct
177{
178 SRes (*Look)(void *p, const void **buf, size_t *size);
179 /* if (input(*size) != 0 && output(*size) == 0) means end_of_stream.
180 (output(*size) > input(*size)) is not allowed
181 (output(*size) < input(*size)) is allowed */
182 SRes (*Skip)(void *p, size_t offset);
183 /* offset must be <= output(*size) of Look */
184
185 SRes (*Read)(void *p, void *buf, size_t *size);
186 /* reads directly (without buffer). It's same as ISeqInStream::Read */
187 SRes (*Seek)(void *p, Int64 *pos, ESzSeek origin);
188} ILookInStream;
189
190static SRes LookInStream_SeekTo(ILookInStream *stream, UInt64 offset);
191
192/* reads via ILookInStream::Read */
193static SRes LookInStream_Read2(ILookInStream *stream, void *buf, size_t size, SRes errorType);
194static SRes LookInStream_Read(ILookInStream *stream, void *buf, size_t size);
195
196#define LookToRead_BUF_SIZE (1 << 14)
197
198typedef struct
199{
200 ILookInStream s;
201 ISeekInStream *realStream;
202 size_t pos;
203 size_t size;
204 Byte buf[LookToRead_BUF_SIZE];
205} CLookToRead;
206
207static void LookToRead_CreateVTable(CLookToRead *p, int lookahead);
208static void LookToRead_Init(CLookToRead *p);
209
210typedef struct
211{
212 ISeqInStream s;
213 ILookInStream *realStream;
214} CSecToLook;
215
216typedef struct
217{
218 ISeqInStream s;
219 ILookInStream *realStream;
220} CSecToRead;
221
222typedef struct
223{
224 SRes (*Progress)(void *p, UInt64 inSize, UInt64 outSize);
225 /* Returns: result. (result != SZ_OK) means break.
226 Value (UInt64)(Int64)-1 for size means unknown value. */
227} ICompressProgress;
228
229typedef struct
230{
231 void *(*Alloc)(void *p, size_t size);
232 void (*Free)(void *p, void *address); /* address can be 0 */
233} ISzAlloc;
234
235#define IAlloc_Alloc(p, size) (p)->Alloc((p), size)
236#define IAlloc_Free(p, a) (p)->Free((p), a)
237
238#ifdef _WIN32
239
240#define CHAR_PATH_SEPARATOR '\\'
241#define WCHAR_PATH_SEPARATOR L'\\'
242#define STRING_PATH_SEPARATOR "\\"
243#define WSTRING_PATH_SEPARATOR L"\\"
244
245#else
246
247#define CHAR_PATH_SEPARATOR '/'
248#define WCHAR_PATH_SEPARATOR L'/'
249#define STRING_PATH_SEPARATOR "/"
250#define WSTRING_PATH_SEPARATOR L"/"
251
252#endif
253
254EXTERN_C_END
255
256#endif
257
258/* 7z.h -- 7z interface
2592015-11-18 : Igor Pavlov : Public domain */
260
261#ifndef __7Z_H
262#define __7Z_H
263
264/*#include "7zTypes.h"*/
265
266EXTERN_C_BEGIN
267
268#define k7zStartHeaderSize 0x20
269#define k7zSignatureSize 6
270
271static const Byte k7zSignature[k7zSignatureSize];
272
273typedef struct
274{
275 const Byte *Data;
276 size_t Size;
277} CSzData;
278
279/* CSzCoderInfo & CSzFolder support only default methods */
280
281typedef struct
282{
283 size_t PropsOffset;
284 UInt32 MethodID;
285 Byte NumStreams;
286 Byte PropsSize;
287} CSzCoderInfo;
288
289typedef struct
290{
291 UInt32 InIndex;
292 UInt32 OutIndex;
293} CSzBond;
294
295#define SZ_NUM_CODERS_IN_FOLDER_MAX 4
296#define SZ_NUM_BONDS_IN_FOLDER_MAX 3
297#define SZ_NUM_PACK_STREAMS_IN_FOLDER_MAX 4
298
299typedef struct
300{
301 UInt32 NumCoders;
302 UInt32 NumBonds;
303 UInt32 NumPackStreams;
304 UInt32 UnpackStream;
305 UInt32 PackStreams[SZ_NUM_PACK_STREAMS_IN_FOLDER_MAX];
306 CSzBond Bonds[SZ_NUM_BONDS_IN_FOLDER_MAX];
307 CSzCoderInfo Coders[SZ_NUM_CODERS_IN_FOLDER_MAX];
308} CSzFolder;
309
310
311static SRes SzGetNextFolderItem(CSzFolder *f, CSzData *sd);
312
313typedef struct
314{
315 UInt32 Low;
316 UInt32 High;
317} CNtfsFileTime;
318
319typedef struct
320{
321 Byte *Defs; /* MSB 0 bit numbering */
322 UInt32 *Vals;
323} CSzBitUi32s;
324
325typedef struct
326{
327 Byte *Defs; /* MSB 0 bit numbering */
328 /* UInt64 *Vals; */
329 CNtfsFileTime *Vals;
330} CSzBitUi64s;
331
332#define SzBitArray_Check(p, i) (((p)[(i) >> 3] & (0x80 >> ((i) & 7))) != 0)
333
334#define SzBitWithVals_Check(p, i) ((p)->Defs && ((p)->Defs[(i) >> 3] & (0x80 >> ((i) & 7))) != 0)
335
336typedef struct
337{
338 UInt32 NumPackStreams;
339 UInt32 NumFolders;
340
341 UInt64 *PackPositions; /* NumPackStreams + 1 */
342 CSzBitUi32s FolderCRCs; /* NumFolders */
343
344 size_t *FoCodersOffsets; /* NumFolders + 1 */
345 UInt32 *FoStartPackStreamIndex; /* NumFolders + 1 */
346 UInt32 *FoToCoderUnpackSizes; /* NumFolders + 1 */
347 Byte *FoToMainUnpackSizeIndex; /* NumFolders */
348 UInt64 *CoderUnpackSizes; /* for all coders in all folders */
349
350 Byte *CodersData;
351} CSzAr;
352
353static UInt64 SzAr_GetFolderUnpackSize(const CSzAr *p, UInt32 folderIndex);
354
355static SRes SzAr_DecodeFolder(const CSzAr *p, UInt32 folderIndex,
356 ILookInStream *stream, UInt64 startPos,
357 Byte *outBuffer, size_t outSize,
358 ISzAlloc *allocMain);
359
360typedef struct
361{
362 CSzAr db;
363
364 UInt64 startPosAfterHeader;
365 UInt64 dataPos;
366
367 UInt32 NumFiles;
368
369 UInt64 *UnpackPositions; /* NumFiles + 1 */
370 /* Byte *IsEmptyFiles; */
371 Byte *IsDirs;
372 CSzBitUi32s CRCs;
373
374 CSzBitUi32s Attribs;
375 /* CSzBitUi32s Parents; */
376 CSzBitUi64s MTime;
377 CSzBitUi64s CTime;
378
379 UInt32 *FolderToFile; /* NumFolders + 1 */
380 UInt32 *FileToFolder; /* NumFiles */
381
382 size_t *FileNameOffsets; /* in 2-byte steps */
383 Byte *FileNames; /* UTF-16-LE */
384} CSzArEx;
385
386#define SzArEx_IsDir(p, i) (SzBitArray_Check((p)->IsDirs, i))
387
388#define SzArEx_GetFileSize(p, i) ((p)->UnpackPositions[(i) + 1] - (p)->UnpackPositions[i])
389
390static void SzArEx_Init(CSzArEx *p);
391static void SzArEx_Free(CSzArEx *p, ISzAlloc *alloc);
392
393/*
394if dest == NULL, the return value specifies the required size of the buffer,
395 in 16-bit characters, including the null-terminating character.
396if dest != NULL, the return value specifies the number of 16-bit characters that
397 are written to the dest, including the null-terminating character. */
398
399static size_t SzArEx_GetFileNameUtf16(const CSzArEx *p, size_t fileIndex, UInt16 *dest);
400
401/*
402size_t SzArEx_GetFullNameLen(const CSzArEx *p, size_t fileIndex);
403UInt16 *SzArEx_GetFullNameUtf16_Back(const CSzArEx *p, size_t fileIndex, UInt16 *dest);
404*/
405
406
407
408/*
409 SzArEx_Extract extracts file from archive
410
411 *outBuffer must be 0 before first call for each new archive.
412
413 Extracting cache:
414 If you need to decompress more than one file, you can send
415 these values from previous call:
416 *blockIndex,
417 *outBuffer,
418 *outBufferSize
419 You can consider "*outBuffer" as cache of solid block. If your archive is solid,
420 it will increase decompression speed.
421
422 If you use external function, you can declare these 3 cache variables
423 (blockIndex, outBuffer, outBufferSize) as static in that external function.
424
425 Free *outBuffer and set *outBuffer to 0, if you want to flush cache.
426*/
427
428static SRes SzArEx_Extract(
429 const CSzArEx *db,
430 ILookInStream *inStream,
431 UInt32 fileIndex, /* index of file */
432 UInt32 *blockIndex, /* index of solid block */
433 Byte **outBuffer, /* pointer to pointer to output buffer (allocated with allocMain) */
434 size_t *outBufferSize, /* buffer size for output buffer */
435 size_t *offset, /* offset of stream for required file in *outBuffer */
436 size_t *outSizeProcessed, /* size of file in *outBuffer */
437 ISzAlloc *allocMain,
438 ISzAlloc *allocTemp);
439
440
441/*
442SzArEx_Open Errors:
443SZ_ERROR_NO_ARCHIVE
444SZ_ERROR_ARCHIVE
445SZ_ERROR_UNSUPPORTED
446SZ_ERROR_MEM
447SZ_ERROR_CRC
448SZ_ERROR_INPUT_EOF
449SZ_ERROR_FAIL
450*/
451
452static SRes SzArEx_Open(CSzArEx *p, ILookInStream *inStream,
453 ISzAlloc *allocMain, ISzAlloc *allocTemp);
454
455EXTERN_C_END
456
457#endif
458
459/* 7zCrc.h -- CRC32 calculation
4602013-01-18 : Igor Pavlov : Public domain */
461
462#ifndef __7Z_CRC_H
463#define __7Z_CRC_H
464
465/*#include "7zTypes.h" */
466
467EXTERN_C_BEGIN
468
469/* Call CrcGenerateTable one time before other CRC functions */
470static void MY_FAST_CALL CrcGenerateTable(void);
471
472#define CRC_INIT_VAL 0xFFFFFFFF
473#define CRC_GET_DIGEST(crc) ((crc) ^ CRC_INIT_VAL)
474#define CRC_UPDATE_BYTE(crc, b) (g_CrcTable[((crc) ^ (b)) & 0xFF] ^ ((crc) >> 8))
475
476static UInt32 MY_FAST_CALL CrcCalc(const void *data, size_t size);
477
478EXTERN_C_END
479
480#endif
481
482/* CpuArch.h -- CPU specific code
4832016-06-09: Igor Pavlov : Public domain */
484
485#ifndef __CPU_ARCH_H
486#define __CPU_ARCH_H
487
488/*#include "7zTypes.h"*/
489
490EXTERN_C_BEGIN
491
492/*
493MY_CPU_LE means that CPU is LITTLE ENDIAN.
494MY_CPU_BE means that CPU is BIG ENDIAN.
495If MY_CPU_LE and MY_CPU_BE are not defined, we don't know about ENDIANNESS of platform.
496
497MY_CPU_LE_UNALIGN means that CPU is LITTLE ENDIAN and CPU supports unaligned memory accesses.
498*/
499
500#if defined(_M_X64) \
501 || defined(_M_AMD64) \
502 || defined(__x86_64__) \
503 || defined(__AMD64__) \
504 || defined(__amd64__)
505 #define MY_CPU_AMD64
506#endif
507
508#if defined(MY_CPU_AMD64) \
509 || defined(_M_ARM64) \
510 || defined(_M_IA64) \
511 || defined(__AARCH64EL__) \
512 || defined(__AARCH64EB__)
513 #define MY_CPU_64BIT
514#endif
515
516#if defined(_M_IX86) || defined(__i386__)
517#define MY_CPU_X86
518#endif
519
520#if defined(MY_CPU_X86) || defined(MY_CPU_AMD64)
521#define MY_CPU_X86_OR_AMD64
522#endif
523
524#if defined(MY_CPU_X86) \
525 || defined(_M_ARM) \
526 || defined(__ARMEL__) \
527 || defined(__THUMBEL__) \
528 || defined(__ARMEB__) \
529 || defined(__THUMBEB__)
530 #define MY_CPU_32BIT
531#endif
532
533#if defined(_WIN32) && defined(_M_ARM)
534#define MY_CPU_ARM_LE
535#elif defined(_WIN64) && defined(_M_ARM64)
536#define MY_CPU_ARM_LE
537#endif
538
539#if defined(_WIN32) && defined(_M_IA64)
540#define MY_CPU_IA64_LE
541#endif
542
543#if defined(MY_CPU_X86_OR_AMD64) \
544 || defined(MY_CPU_ARM_LE) \
545 || defined(MY_CPU_IA64_LE) \
546 || defined(__LITTLE_ENDIAN__) \
547 || defined(__ARMEL__) \
548 || defined(__THUMBEL__) \
549 || defined(__AARCH64EL__) \
550 || defined(__MIPSEL__) \
551 || defined(__MIPSEL) \
552 || defined(_MIPSEL) \
553 || defined(__BFIN__) \
554 || (defined(__BYTE_ORDER__) && (__BYTE_ORDER__ == __ORDER_LITTLE_ENDIAN__))
555 #define MY_CPU_LE
556#endif
557
558#if defined(__BIG_ENDIAN__) \
559 || defined(__ARMEB__) \
560 || defined(__THUMBEB__) \
561 || defined(__AARCH64EB__) \
562 || defined(__MIPSEB__) \
563 || defined(__MIPSEB) \
564 || defined(_MIPSEB) \
565 || defined(__m68k__) \
566 || defined(__s390__) \
567 || defined(__s390x__) \
568 || defined(__zarch__) \
569 || (defined(__BYTE_ORDER__) && (__BYTE_ORDER__ == __ORDER_BIG_ENDIAN__))
570 #define MY_CPU_BE
571#endif
572
573#if defined(MY_CPU_LE) && defined(MY_CPU_BE)
574Stop_Compiling_Bad_Endian
575#endif
576
577
578#ifdef MY_CPU_LE
579 #if defined(MY_CPU_X86_OR_AMD64) \
580 /* || defined(__AARCH64EL__) */
581 /*#define MY_CPU_LE_UNALIGN*/
582 #endif
583#endif
584
585
586#ifdef MY_CPU_LE_UNALIGN
587
588#define GetUi16(p) (*(const UInt16 *)(const void *)(p))
589#define GetUi32(p) (*(const UInt32 *)(const void *)(p))
590#define GetUi64(p) (*(const UInt64 *)(const void *)(p))
591
592#define SetUi16(p, v) { *(UInt16 *)(p) = (v); }
593#define SetUi32(p, v) { *(UInt32 *)(p) = (v); }
594#define SetUi64(p, v) { *(UInt64 *)(p) = (v); }
595
596#else
597
598#define GetUi16(p) ( (UInt16) ( \
599 ((const Byte *)(p))[0] | \
600 ((UInt16)((const Byte *)(p))[1] << 8) ))
601
602#define GetUi32(p) ( \
603 ((const Byte *)(p))[0] | \
604 ((UInt32)((const Byte *)(p))[1] << 8) | \
605 ((UInt32)((const Byte *)(p))[2] << 16) | \
606 ((UInt32)((const Byte *)(p))[3] << 24))
607
608#define GetUi64(p) (GetUi32(p) | ((UInt64)GetUi32(((const Byte *)(p)) + 4) << 32))
609
610#define SetUi16(p, v) { Byte *_ppp_ = (Byte *)(p); UInt32 _vvv_ = (v); \
611 _ppp_[0] = (Byte)_vvv_; \
612 _ppp_[1] = (Byte)(_vvv_ >> 8); }
613
614#define SetUi32(p, v) { Byte *_ppp_ = (Byte *)(p); UInt32 _vvv_ = (v); \
615 _ppp_[0] = (Byte)_vvv_; \
616 _ppp_[1] = (Byte)(_vvv_ >> 8); \
617 _ppp_[2] = (Byte)(_vvv_ >> 16); \
618 _ppp_[3] = (Byte)(_vvv_ >> 24); }
619
620#define SetUi64(p, v) { Byte *_ppp2_ = (Byte *)(p); UInt64 _vvv2_ = (v); \
621 SetUi32(_ppp2_ , (UInt32)_vvv2_); \
622 SetUi32(_ppp2_ + 4, (UInt32)(_vvv2_ >> 32)); }
623
624#endif
625
626
627#if defined(MY_CPU_LE_UNALIGN) && /* defined(_WIN64) && */ (_MSC_VER >= 1300)
628
629/* Note: we use bswap instruction, that is unsupported in 386 cpu */
630
631#include <stdlib.h>
632
633#pragma intrinsic(_byteswap_ulong)
634#pragma intrinsic(_byteswap_uint64)
635#define GetBe32(p) _byteswap_ulong(*(const UInt32 *)(const Byte *)(p))
636#define GetBe64(p) _byteswap_uint64(*(const UInt64 *)(const Byte *)(p))
637
638#define SetBe32(p, v) (*(UInt32 *)(void *)(p)) = _byteswap_ulong(v)
639
640#elif defined(MY_CPU_LE_UNALIGN) && defined (__GNUC__) && (__GNUC__ > 4 || (__GNUC__ == 4 && __GNUC_MINOR__ >= 3))
641
642#define GetBe32(p) __builtin_bswap32(*(const UInt32 *)(const Byte *)(p))
643#define GetBe64(p) __builtin_bswap64(*(const UInt64 *)(const Byte *)(p))
644
645#define SetBe32(p, v) (*(UInt32 *)(void *)(p)) = __builtin_bswap32(v)
646
647#else
648
649#define GetBe32(p) ( \
650 ((UInt32)((const Byte *)(p))[0] << 24) | \
651 ((UInt32)((const Byte *)(p))[1] << 16) | \
652 ((UInt32)((const Byte *)(p))[2] << 8) | \
653 ((const Byte *)(p))[3] )
654
655#define GetBe64(p) (((UInt64)GetBe32(p) << 32) | GetBe32(((const Byte *)(p)) + 4))
656
657#define SetBe32(p, v) { Byte *_ppp_ = (Byte *)(p); UInt32 _vvv_ = (v); \
658 _ppp_[0] = (Byte)(_vvv_ >> 24); \
659 _ppp_[1] = (Byte)(_vvv_ >> 16); \
660 _ppp_[2] = (Byte)(_vvv_ >> 8); \
661 _ppp_[3] = (Byte)_vvv_; }
662
663#endif
664
665
666#define GetBe16(p) ( (UInt16) ( \
667 ((UInt16)((const Byte *)(p))[0] << 8) | \
668 ((const Byte *)(p))[1] ))
669
670
671
672#ifdef MY_CPU_X86_OR_AMD64
673
674typedef struct
675{
676 UInt32 maxFunc;
677 UInt32 vendor[3];
678 UInt32 ver;
679 UInt32 b;
680 UInt32 c;
681 UInt32 d;
682} Cx86cpuid;
683
684enum
685{
686 CPU_FIRM_INTEL,
687 CPU_FIRM_AMD,
688 CPU_FIRM_VIA
689};
690
691static void MyCPUID(UInt32 function, UInt32 *a, UInt32 *b, UInt32 *c, UInt32 *d);
692
693static Bool x86cpuid_CheckAndRead(Cx86cpuid *p);
694static int x86cpuid_GetFirm(const Cx86cpuid *p);
695
696#define x86cpuid_GetFamily(ver) (((ver >> 16) & 0xFF0) | ((ver >> 8) & 0xF))
697#define x86cpuid_GetModel(ver) (((ver >> 12) & 0xF0) | ((ver >> 4) & 0xF))
698#define x86cpuid_GetStepping(ver) (ver & 0xF)
699
700static Bool CPU_Is_InOrder();
701
702#endif
703
704EXTERN_C_END
705
706#endif
707
708/* 7zBuf.h -- Byte Buffer
7092013-01-18 : Igor Pavlov : Public domain */
710
711#ifndef __7Z_BUF_H
712#define __7Z_BUF_H
713
714/*#include "7zTypes.h" */
715
716EXTERN_C_BEGIN
717
718typedef struct
719{
720 Byte *data;
721 size_t size;
722} CBuf;
723
724static void Buf_Init(CBuf *p);
725static int Buf_Create(CBuf *p, size_t size, ISzAlloc *alloc);
726static void Buf_Free(CBuf *p, ISzAlloc *alloc);
727
728EXTERN_C_END
729
730#endif
731
732
733/* Bcj2.h -- BCJ2 Converter for x86 code
7342014-11-10 : Igor Pavlov : Public domain */
735
736#ifndef __BCJ2_H
737#define __BCJ2_H
738
739/*#include "7zTypes.h" */
740
741EXTERN_C_BEGIN
742
743#define BCJ2_NUM_STREAMS 4
744
745enum
746{
747 BCJ2_STREAM_MAIN,
748 BCJ2_STREAM_CALL,
749 BCJ2_STREAM_JUMP,
750 BCJ2_STREAM_RC
751};
752
753enum
754{
755 BCJ2_DEC_STATE_ORIG_0 = BCJ2_NUM_STREAMS,
756 BCJ2_DEC_STATE_ORIG_1,
757 BCJ2_DEC_STATE_ORIG_2,
758 BCJ2_DEC_STATE_ORIG_3,
759
760 BCJ2_DEC_STATE_ORIG,
761 BCJ2_DEC_STATE_OK
762};
763
764enum
765{
766 BCJ2_ENC_STATE_ORIG = BCJ2_NUM_STREAMS,
767 BCJ2_ENC_STATE_OK
768};
769
770
771#define BCJ2_IS_32BIT_STREAM(s) ((s) == BCJ2_STREAM_CALL || (s) == BCJ2_STREAM_JUMP)
772
773/*
774CBcj2Dec / CBcj2Enc
775bufs sizes:
776 BUF_SIZE(n) = lims[n] - bufs[n]
777bufs sizes for BCJ2_STREAM_CALL and BCJ2_STREAM_JUMP must be mutliply of 4:
778 (BUF_SIZE(BCJ2_STREAM_CALL) & 3) == 0
779 (BUF_SIZE(BCJ2_STREAM_JUMP) & 3) == 0
780*/
781
782/*
783CBcj2Dec:
784dest is allowed to overlap with bufs[BCJ2_STREAM_MAIN], with the following conditions:
785 bufs[BCJ2_STREAM_MAIN] >= dest &&
786 bufs[BCJ2_STREAM_MAIN] - dest >= tempReserv +
787 BUF_SIZE(BCJ2_STREAM_CALL) +
788 BUF_SIZE(BCJ2_STREAM_JUMP)
789 tempReserv = 0 : for first call of Bcj2Dec_Decode
790 tempReserv = 4 : for any other calls of Bcj2Dec_Decode
791 overlap with offset = 1 is not allowed
792*/
793
794typedef struct
795{
796 const Byte *bufs[BCJ2_NUM_STREAMS];
797 const Byte *lims[BCJ2_NUM_STREAMS];
798 Byte *dest;
799 const Byte *destLim;
800
801 unsigned state; /* BCJ2_STREAM_MAIN has more priority than BCJ2_STATE_ORIG */
802
803 UInt32 ip;
804 Byte temp[4];
805 UInt32 range;
806 UInt32 code;
807 UInt16 probs[2 + 256];
808} CBcj2Dec;
809
810static void Bcj2Dec_Init(CBcj2Dec *p);
811
812/* Returns: SZ_OK or SZ_ERROR_DATA */
813static SRes Bcj2Dec_Decode(CBcj2Dec *p);
814
815#define Bcj2Dec_IsFinished(_p_) ((_p_)->code == 0)
816
817#define BCJ2_RELAT_LIMIT_NUM_BITS 26
818#define BCJ2_RELAT_LIMIT ((UInt32)1 << BCJ2_RELAT_LIMIT_NUM_BITS)
819
820/* limit for CBcj2Enc::fileSize variable */
821#define BCJ2_FileSize_MAX ((UInt32)1 << 31)
822
823EXTERN_C_END
824
825#endif
826
827/* Bra.h -- Branch converters for executables
8282013-01-18 : Igor Pavlov : Public domain */
829
830#ifndef __BRA_H
831#define __BRA_H
832
833/*#include "7zTypes.h"*/
834
835EXTERN_C_BEGIN
836
837/*
838These functions convert relative addresses to absolute addresses
839in CALL instructions to increase the compression ratio.
840
841 In:
842 data - data buffer
843 size - size of data
844 ip - current virtual Instruction Pinter (IP) value
845 state - state variable for x86 converter
846 encoding - 0 (for decoding), 1 (for encoding)
847
848 Out:
849 state - state variable for x86 converter
850
851 Returns:
852 The number of processed bytes. If you call these functions with multiple calls,
853 you must start next call with first byte after block of processed bytes.
854
855 Type Endian Alignment LookAhead
856
857 x86 little 1 4
858 ARMT little 2 2
859 ARM little 4 0
860 PPC big 4 0
861 SPARC big 4 0
862 IA64 little 16 0
863
864 size must be >= Alignment + LookAhead, if it's not last block.
865 If (size < Alignment + LookAhead), converter returns 0.
866
867 Example:
868
869 UInt32 ip = 0;
870 for ()
871 {
872 ; size must be >= Alignment + LookAhead, if it's not last block
873 SizeT processed = Convert(data, size, ip, 1);
874 data += processed;
875 size -= processed;
876 ip += processed;
877 }
878*/
879
880#define x86_Convert_Init(state) { state = 0; }
881static SizeT x86_Convert(Byte *data, SizeT size, UInt32 ip, UInt32 *state, int encoding);
882static SizeT ARM_Convert(Byte *data, SizeT size, UInt32 ip, int encoding);
883static SizeT ARMT_Convert(Byte *data, SizeT size, UInt32 ip, int encoding);
884static SizeT PPC_Convert(Byte *data, SizeT size, UInt32 ip, int encoding);
885static SizeT SPARC_Convert(Byte *data, SizeT size, UInt32 ip, int encoding);
886static SizeT IA64_Convert(Byte *data, SizeT size, UInt32 ip, int encoding);
887
888EXTERN_C_END
889
890#endif
891
892/* Delta.h -- Delta converter
8932013-01-18 : Igor Pavlov : Public domain */
894
895#ifndef __DELTA_H
896#define __DELTA_H
897
898/*#include "7zTypes.h" */
899
900EXTERN_C_BEGIN
901
902#define DELTA_STATE_SIZE 256
903
904static void Delta_Init(Byte *state);
905static void Delta_Decode(Byte *state, unsigned delta, Byte *data, SizeT size);
906
907EXTERN_C_END
908
909#endif
910
911/* LzmaDec.h -- LZMA Decoder
9122013-01-18 : Igor Pavlov : Public domain */
913
914#ifndef __LZMA_DEC_H
915#define __LZMA_DEC_H
916
917/*#include "7zTypes.h"*/
918
919EXTERN_C_BEGIN
920
921/* #define _LZMA_PROB32 */
922/* _LZMA_PROB32 can increase the speed on some CPUs,
923 but memory usage for CLzmaDec::probs will be doubled in that case */
924
925#ifdef _LZMA_PROB32
926#define CLzmaProb UInt32
927#else
928#define CLzmaProb UInt16
929#endif
930
931
932/* ---------- LZMA Properties ---------- */
933
934#define LZMA_PROPS_SIZE 5
935
936typedef struct _CLzmaProps
937{
938 unsigned lc, lp, pb;
939 UInt32 dicSize;
940} CLzmaProps;
941
942/* LzmaProps_Decode - decodes properties
943Returns:
944 SZ_OK
945 SZ_ERROR_UNSUPPORTED - Unsupported properties
946*/
947
948static SRes LzmaProps_Decode(CLzmaProps *p, const Byte *data, unsigned size);
949
950
951/* ---------- LZMA Decoder state ---------- */
952
953/* LZMA_REQUIRED_INPUT_MAX = number of required input bytes for worst case.
954 Num bits = log2((2^11 / 31) ^ 22) + 26 < 134 + 26 = 160; */
955
956#define LZMA_REQUIRED_INPUT_MAX 20
957
958typedef struct
959{
960 CLzmaProps prop;
961 CLzmaProb *probs;
962 Byte *dic;
963 const Byte *buf;
964 UInt32 range, code;
965 SizeT dicPos;
966 SizeT dicBufSize;
967 UInt32 processedPos;
968 UInt32 checkDicSize;
969 unsigned state;
970 UInt32 reps[4];
971 unsigned remainLen;
972 int needFlush;
973 int needInitState;
974 UInt32 numProbs;
975 unsigned tempBufSize;
976 Byte tempBuf[LZMA_REQUIRED_INPUT_MAX];
977} CLzmaDec;
978
979#define LzmaDec_Construct(p) { (p)->dic = 0; (p)->probs = 0; }
980
981static void LzmaDec_Init(CLzmaDec *p);
982
983/* There are two types of LZMA streams:
984 0) Stream with end mark. That end mark adds about 6 bytes to compressed size.
985 1) Stream without end mark. You must know exact uncompressed size to decompress such stream. */
986
987typedef enum
988{
989 LZMA_FINISH_ANY, /* finish at any point */
990 LZMA_FINISH_END /* block must be finished at the end */
991} ELzmaFinishMode;
992
993/* ELzmaFinishMode has meaning only if the decoding reaches output limit !!!
994
995 You must use LZMA_FINISH_END, when you know that current output buffer
996 covers last bytes of block. In other cases you must use LZMA_FINISH_ANY.
997
998 If LZMA decoder sees end marker before reaching output limit, it returns SZ_OK,
999 and output value of destLen will be less than output buffer size limit.
1000 You can check status result also.
1001
1002 You can use multiple checks to test data integrity after full decompression:
1003 1) Check Result and "status" variable.
1004 2) Check that output(destLen) = uncompressedSize, if you know real uncompressedSize.
1005 3) Check that output(srcLen) = compressedSize, if you know real compressedSize.
1006 You must use correct finish mode in that case. */
1007
1008typedef enum
1009{
1010 LZMA_STATUS_NOT_SPECIFIED, /* use main error code instead */
1011 LZMA_STATUS_FINISHED_WITH_MARK, /* stream was finished with end mark. */
1012 LZMA_STATUS_NOT_FINISHED, /* stream was not finished */
1013 LZMA_STATUS_NEEDS_MORE_INPUT, /* you must provide more input bytes */
1014 LZMA_STATUS_MAYBE_FINISHED_WITHOUT_MARK /* there is probability that stream was finished without end mark */
1015} ELzmaStatus;
1016
1017/* ELzmaStatus is used only as output value for function call */
1018
1019
1020/* ---------- Interfaces ---------- */
1021
1022/* There are 3 levels of interfaces:
1023 1) Dictionary Interface
1024 2) Buffer Interface
1025 3) One Call Interface
1026 You can select any of these interfaces, but don't mix functions from different
1027 groups for same object. */
1028
1029
1030/* There are two variants to allocate state for Dictionary Interface:
1031 1) LzmaDec_Allocate / LzmaDec_Free
1032 2) LzmaDec_AllocateProbs / LzmaDec_FreeProbs
1033 You can use variant 2, if you set dictionary buffer manually.
1034 For Buffer Interface you must always use variant 1.
1035
1036LzmaDec_Allocate* can return:
1037 SZ_OK
1038 SZ_ERROR_MEM - Memory allocation error
1039 SZ_ERROR_UNSUPPORTED - Unsupported properties
1040*/
1041
1042static SRes LzmaDec_AllocateProbs(CLzmaDec *p, const Byte *props, unsigned propsSize, ISzAlloc *alloc);
1043static void LzmaDec_FreeProbs(CLzmaDec *p, ISzAlloc *alloc);
1044
1045/* ---------- Dictionary Interface ---------- */
1046
1047/* You can use it, if you want to eliminate the overhead for data copying from
1048 dictionary to some other external buffer.
1049 You must work with CLzmaDec variables directly in this interface.
1050
1051 STEPS:
1052 LzmaDec_Constr()
1053 LzmaDec_Allocate()
1054 for (each new stream)
1055 {
1056 LzmaDec_Init()
1057 while (it needs more decompression)
1058 {
1059 LzmaDec_DecodeToDic()
1060 use data from CLzmaDec::dic and update CLzmaDec::dicPos
1061 }
1062 }
1063 LzmaDec_Free()
1064*/
1065
1066/* LzmaDec_DecodeToDic
1067
1068 The decoding to internal dictionary buffer (CLzmaDec::dic).
1069 You must manually update CLzmaDec::dicPos, if it reaches CLzmaDec::dicBufSize !!!
1070
1071finishMode:
1072 It has meaning only if the decoding reaches output limit (dicLimit).
1073 LZMA_FINISH_ANY - Decode just dicLimit bytes.
1074 LZMA_FINISH_END - Stream must be finished after dicLimit.
1075
1076Returns:
1077 SZ_OK
1078 status:
1079 LZMA_STATUS_FINISHED_WITH_MARK
1080 LZMA_STATUS_NOT_FINISHED
1081 LZMA_STATUS_NEEDS_MORE_INPUT
1082 LZMA_STATUS_MAYBE_FINISHED_WITHOUT_MARK
1083 SZ_ERROR_DATA - Data error
1084*/
1085
1086static SRes LzmaDec_DecodeToDic(CLzmaDec *p, SizeT dicLimit,
1087 const Byte *src, SizeT *srcLen, ELzmaFinishMode finishMode, ELzmaStatus *status);
1088
1089EXTERN_C_END
1090
1091#endif
1092
1093/* Lzma2Dec.h -- LZMA2 Decoder
10942015-05-13 : Igor Pavlov : Public domain */
1095
1096#ifndef __LZMA2_DEC_H
1097#define __LZMA2_DEC_H
1098
1099/*#include "LzmaDec.h"*/
1100
1101EXTERN_C_BEGIN
1102
1103/* ---------- State Interface ---------- */
1104
1105typedef struct
1106{
1107 CLzmaDec decoder;
1108 UInt32 packSize;
1109 UInt32 unpackSize;
1110 unsigned state;
1111 Byte control;
1112 Bool needInitDic;
1113 Bool needInitState;
1114 Bool needInitProp;
1115} CLzma2Dec;
1116
1117#define Lzma2Dec_Construct(p) LzmaDec_Construct(&(p)->decoder)
1118#define Lzma2Dec_FreeProbs(p, alloc) LzmaDec_FreeProbs(&(p)->decoder, alloc);
1119#define Lzma2Dec_Free(p, alloc) LzmaDec_Free(&(p)->decoder, alloc);
1120
1121static SRes Lzma2Dec_AllocateProbs(CLzma2Dec *p, Byte prop, ISzAlloc *alloc);
1122static void Lzma2Dec_Init(CLzma2Dec *p);
1123
1124
1125/*
1126finishMode:
1127 It has meaning only if the decoding reaches output limit (*destLen or dicLimit).
1128 LZMA_FINISH_ANY - use smallest number of input bytes
1129 LZMA_FINISH_END - read EndOfStream marker after decoding
1130
1131Returns:
1132 SZ_OK
1133 status:
1134 LZMA_STATUS_FINISHED_WITH_MARK
1135 LZMA_STATUS_NOT_FINISHED
1136 LZMA_STATUS_NEEDS_MORE_INPUT
1137 SZ_ERROR_DATA - Data error
1138*/
1139
1140static SRes Lzma2Dec_DecodeToDic(CLzma2Dec *p, SizeT dicLimit,
1141 const Byte *src, SizeT *srcLen, ELzmaFinishMode finishMode, ELzmaStatus *status);
1142
1143
1144EXTERN_C_END
1145
1146#endif
1147
1148
1149/* END HEADERS */
1150
1151
1152/* 7zCrc.c -- CRC32 init
11532015-03-10 : Igor Pavlov : Public domain */
1154
1155/*
1156#include "Precomp.h"
1157
1158#include "7zCrc.h"
1159#include "CpuArch.h"
1160*/
1161#define UNUSED_VAR(x) (void)x;
1162
1163#define kCrcPoly 0xEDB88320
1164
1165#ifdef MY_CPU_LE
1166 #define CRC_NUM_TABLES 8
1167#else
1168 #define CRC_NUM_TABLES 9
1169
1170 #define CRC_UINT32_SWAP(v) ((v >> 24) | ((v >> 8) & 0xFF00) | ((v << 8) & 0xFF0000) | (v << 24))
1171
1172 static UInt32 MY_FAST_CALL CrcUpdateT1_BeT4(UInt32 v, const void *data, size_t size, const UInt32 *table);
1173 static UInt32 MY_FAST_CALL CrcUpdateT1_BeT8(UInt32 v, const void *data, size_t size, const UInt32 *table);
1174#endif
1175
1176#ifndef MY_CPU_BE
1177 static UInt32 MY_FAST_CALL CrcUpdateT4(UInt32 v, const void *data, size_t size, const UInt32 *table);
1178 static UInt32 MY_FAST_CALL CrcUpdateT8(UInt32 v, const void *data, size_t size, const UInt32 *table);
1179#endif
1180
1181typedef UInt32 (MY_FAST_CALL *CRC_FUNC)(UInt32 v, const void *data, size_t size, const UInt32 *table);
1182
1183static CRC_FUNC g_CrcUpdateT4;
1184static CRC_FUNC g_CrcUpdateT8;
1185static CRC_FUNC g_CrcUpdate;
1186
1187static UInt32 g_CrcTable[256 * CRC_NUM_TABLES];
1188
1189static UInt32 MY_FAST_CALL CrcCalc(const void *data, size_t size)
1190{
1191 return g_CrcUpdate(CRC_INIT_VAL, data, size, g_CrcTable) ^ CRC_INIT_VAL;
1192}
1193
1194#define CRC_UPDATE_BYTE_2(crc, b) (table[((crc) ^ (b)) & 0xFF] ^ ((crc) >> 8))
1195
1196#if CRC_NUM_TABLES < 4
1197static UInt32 MY_FAST_CALL CrcUpdateT1(UInt32 v, const void *data, size_t size, const UInt32 *table)
1198{
1199 const Byte *p = (const Byte *)data;
1200 const Byte *pEnd = p + size;
1201 for (; p != pEnd; p++)
1202 v = CRC_UPDATE_BYTE_2(v, *p);
1203 return v;
1204}
1205#endif
1206
1207static void MY_FAST_CALL CrcGenerateTable()
1208{
1209 UInt32 i;
1210 for (i = 0; i < 256; i++)
1211 {
1212 UInt32 r = i;
1213 unsigned j;
1214 for (j = 0; j < 8; j++)
1215 r = (r >> 1) ^ (kCrcPoly & ~((r & 1) - 1));
1216 g_CrcTable[i] = r;
1217 }
1218 for (; i < 256 * CRC_NUM_TABLES; i++)
1219 {
1220 UInt32 r = g_CrcTable[i - 256];
1221 g_CrcTable[i] = g_CrcTable[r & 0xFF] ^ (r >> 8);
1222 }
1223
1224 #if CRC_NUM_TABLES < 4
1225
1226 g_CrcUpdate = CrcUpdateT1;
1227
1228 #else
1229
1230 #ifdef MY_CPU_LE
1231
1232 g_CrcUpdateT4 = CrcUpdateT4;
1233 g_CrcUpdate = CrcUpdateT4;
1234
1235 #if CRC_NUM_TABLES >= 8
1236 g_CrcUpdateT8 = CrcUpdateT8;
1237
1238 #ifdef MY_CPU_X86_OR_AMD64
1239 if (!CPU_Is_InOrder())
1240 g_CrcUpdate = CrcUpdateT8;
1241 #endif
1242 #endif
1243
1244 #else
1245 {
1246 #ifndef MY_CPU_BE
1247 UInt32 k = 0x01020304;
1248 const Byte *p = (const Byte *)&k;
1249 if (p[0] == 4 && p[1] == 3)
1250 {
1251 g_CrcUpdateT4 = CrcUpdateT4;
1252 g_CrcUpdate = CrcUpdateT4;
1253 #if CRC_NUM_TABLES >= 8
1254 g_CrcUpdateT8 = CrcUpdateT8;
1255 /* g_CrcUpdate = CrcUpdateT8; */
1256 #endif
1257 }
1258 else if (p[0] != 1 || p[1] != 2)
1259 g_CrcUpdate = CrcUpdateT1;
1260 else
1261 #endif
1262 {
1263 for (i = 256 * CRC_NUM_TABLES - 1; i >= 256; i--)
1264 {
1265 UInt32 x = g_CrcTable[i - 256];
1266 g_CrcTable[i] = CRC_UINT32_SWAP(x);
1267 }
1268 g_CrcUpdateT4 = CrcUpdateT1_BeT4;
1269 g_CrcUpdate = CrcUpdateT1_BeT4;
1270 #if CRC_NUM_TABLES >= 8
1271 g_CrcUpdateT8 = CrcUpdateT1_BeT8;
1272 /* g_CrcUpdate = CrcUpdateT1_BeT8; */
1273 #endif
1274 }
1275 }
1276 #endif
1277
1278 #endif
1279}
1280
1281/* 7zCrcOpt.c -- CRC32 calculation
12822015-03-01 : Igor Pavlov : Public domain */
1283
1284/*
1285#include "Precomp.h"
1286
1287#include "CpuArch.h"
1288*/
1289
1290#ifndef MY_CPU_BE
1291
1292#define CRC_UPDATE_BYTE_2(crc, b) (table[((crc) ^ (b)) & 0xFF] ^ ((crc) >> 8))
1293
1294static UInt32 MY_FAST_CALL CrcUpdateT4(UInt32 v, const void *data, size_t size, const UInt32 *table)
1295{
1296 const Byte *p = (const Byte *)data;
1297 for (; size > 0 && ((unsigned)(ptrdiff_t)p & 3) != 0; size--, p++)
1298 v = CRC_UPDATE_BYTE_2(v, *p);
1299 for (; size >= 4; size -= 4, p += 4)
1300 {
1301 v ^= *(const UInt32 *)p;
1302 v =
1303 table[0x300 + ((v ) & 0xFF)]
1304 ^ table[0x200 + ((v >> 8) & 0xFF)]
1305 ^ table[0x100 + ((v >> 16) & 0xFF)]
1306 ^ table[0x000 + ((v >> 24))];
1307 }
1308 for (; size > 0; size--, p++)
1309 v = CRC_UPDATE_BYTE_2(v, *p);
1310 return v;
1311}
1312
1313static UInt32 MY_FAST_CALL CrcUpdateT8(UInt32 v, const void *data, size_t size, const UInt32 *table)
1314{
1315 const Byte *p = (const Byte *)data;
1316 for (; size > 0 && ((unsigned)(ptrdiff_t)p & 7) != 0; size--, p++)
1317 v = CRC_UPDATE_BYTE_2(v, *p);
1318 for (; size >= 8; size -= 8, p += 8)
1319 {
1320 UInt32 d;
1321 v ^= *(const UInt32 *)p;
1322 v =
1323 table[0x700 + ((v ) & 0xFF)]
1324 ^ table[0x600 + ((v >> 8) & 0xFF)]
1325 ^ table[0x500 + ((v >> 16) & 0xFF)]
1326 ^ table[0x400 + ((v >> 24))];
1327 d = *((const UInt32 *)p + 1);
1328 v ^=
1329 table[0x300 + ((d ) & 0xFF)]
1330 ^ table[0x200 + ((d >> 8) & 0xFF)]
1331 ^ table[0x100 + ((d >> 16) & 0xFF)]
1332 ^ table[0x000 + ((d >> 24))];
1333 }
1334 for (; size > 0; size--, p++)
1335 v = CRC_UPDATE_BYTE_2(v, *p);
1336 return v;
1337}
1338
1339#endif
1340
1341
1342#ifndef MY_CPU_LE
1343
1344#define CRC_UINT32_SWAP(v) ((v >> 24) | ((v >> 8) & 0xFF00) | ((v << 8) & 0xFF0000) | (v << 24))
1345
1346#define CRC_UPDATE_BYTE_2_BE(crc, b) (table[(((crc) >> 24) ^ (b))] ^ ((crc) << 8))
1347
1348static UInt32 MY_FAST_CALL CrcUpdateT1_BeT4(UInt32 v, const void *data, size_t size, const UInt32 *table)
1349{
1350 const Byte *p = (const Byte *)data;
1351 table += 0x100;
1352 v = CRC_UINT32_SWAP(v);
1353 for (; size > 0 && ((unsigned)(ptrdiff_t)p & 3) != 0; size--, p++)
1354 v = CRC_UPDATE_BYTE_2_BE(v, *p);
1355 for (; size >= 4; size -= 4, p += 4)
1356 {
1357 v ^= *(const UInt32 *)p;
1358 v =
1359 table[0x000 + ((v ) & 0xFF)]
1360 ^ table[0x100 + ((v >> 8) & 0xFF)]
1361 ^ table[0x200 + ((v >> 16) & 0xFF)]
1362 ^ table[0x300 + ((v >> 24))];
1363 }
1364 for (; size > 0; size--, p++)
1365 v = CRC_UPDATE_BYTE_2_BE(v, *p);
1366 return CRC_UINT32_SWAP(v);
1367}
1368
1369static UInt32 MY_FAST_CALL CrcUpdateT1_BeT8(UInt32 v, const void *data, size_t size, const UInt32 *table)
1370{
1371 const Byte *p = (const Byte *)data;
1372 table += 0x100;
1373 v = CRC_UINT32_SWAP(v);
1374 for (; size > 0 && ((unsigned)(ptrdiff_t)p & 7) != 0; size--, p++)
1375 v = CRC_UPDATE_BYTE_2_BE(v, *p);
1376 for (; size >= 8; size -= 8, p += 8)
1377 {
1378 UInt32 d;
1379 v ^= *(const UInt32 *)p;
1380 v =
1381 table[0x400 + ((v ) & 0xFF)]
1382 ^ table[0x500 + ((v >> 8) & 0xFF)]
1383 ^ table[0x600 + ((v >> 16) & 0xFF)]
1384 ^ table[0x700 + ((v >> 24))];
1385 d = *((const UInt32 *)p + 1);
1386 v ^=
1387 table[0x000 + ((d ) & 0xFF)]
1388 ^ table[0x100 + ((d >> 8) & 0xFF)]
1389 ^ table[0x200 + ((d >> 16) & 0xFF)]
1390 ^ table[0x300 + ((d >> 24))];
1391 }
1392 for (; size > 0; size--, p++)
1393 v = CRC_UPDATE_BYTE_2_BE(v, *p);
1394 return CRC_UINT32_SWAP(v);
1395}
1396
1397#endif
1398
1399/* CpuArch.c -- CPU specific code
14002016-02-25: Igor Pavlov : Public domain */
1401
1402/*
1403#include "Precomp.h"
1404
1405#include "CpuArch.h"
1406*/
1407
1408#ifdef MY_CPU_X86_OR_AMD64
1409
1410#if (defined(_MSC_VER) && !defined(MY_CPU_AMD64)) || defined(__GNUC__)
1411#define USE_ASM
1412#endif
1413
1414#if !defined(USE_ASM) && _MSC_VER >= 1500
1415#include <intrin.h>
1416#endif
1417
1418#if defined(USE_ASM) && !defined(MY_CPU_AMD64)
1419static UInt32 CheckFlag(UInt32 flag)
1420{
1421 #ifdef _MSC_VER
1422 __asm pushfd;
1423 __asm pop EAX;
1424 __asm mov EDX, EAX;
1425 __asm xor EAX, flag;
1426 __asm push EAX;
1427 __asm popfd;
1428 __asm pushfd;
1429 __asm pop EAX;
1430 __asm xor EAX, EDX;
1431 __asm push EDX;
1432 __asm popfd;
1433 __asm and flag, EAX;
1434 #else
1435 __asm__ __volatile__ (
1436 "pushf\n\t"
1437 "pop %%EAX\n\t"
1438 "movl %%EAX,%%EDX\n\t"
1439 "xorl %0,%%EAX\n\t"
1440 "push %%EAX\n\t"
1441 "popf\n\t"
1442 "pushf\n\t"
1443 "pop %%EAX\n\t"
1444 "xorl %%EDX,%%EAX\n\t"
1445 "push %%EDX\n\t"
1446 "popf\n\t"
1447 "andl %%EAX, %0\n\t":
1448 "=c" (flag) : "c" (flag) :
1449 "%eax", "%edx");
1450 #endif
1451 return flag;
1452}
1453#define CHECK_CPUID_IS_SUPPORTED if (CheckFlag(1 << 18) == 0 || CheckFlag(1 << 21) == 0) return False;
1454#else
1455#define CHECK_CPUID_IS_SUPPORTED
1456#endif
1457
1458#if defined(__WATCOMC__)
1459static void __cpuid(int *cpuinfo, const UInt32 infotype);
1460#pragma aux __cpuid = \
1461 ".586" \
1462 "cpuid" \
1463 "mov [esi+0],eax" \
1464 "mov [esi+4],ebx" \
1465 "mov [esi+8],ecx" \
1466 "mov [esi+12],edx" \
1467 parm [esi] [eax] modify [ebx ecx edx];
1468#endif
1469
1470
1471static void MyCPUID(UInt32 function, UInt32 *a, UInt32 *b, UInt32 *c, UInt32 *d)
1472{
1473 #ifdef USE_ASM
1474
1475 #ifdef _MSC_VER
1476
1477 UInt32 a2, b2, c2, d2;
1478 __asm xor EBX, EBX;
1479 __asm xor ECX, ECX;
1480 __asm xor EDX, EDX;
1481 __asm mov EAX, function;
1482 __asm cpuid;
1483 __asm mov a2, EAX;
1484 __asm mov b2, EBX;
1485 __asm mov c2, ECX;
1486 __asm mov d2, EDX;
1487
1488 *a = a2;
1489 *b = b2;
1490 *c = c2;
1491 *d = d2;
1492
1493 #else
1494
1495 __asm__ __volatile__ (
1496 #if defined(MY_CPU_AMD64) && defined(__PIC__)
1497 "mov %%rbx, %%rdi;"
1498 "cpuid;"
1499 "xchg %%rbx, %%rdi;"
1500 : "=a" (*a) ,
1501 "=D" (*b) ,
1502 #elif defined(MY_CPU_X86) && defined(__PIC__)
1503 "mov %%ebx, %%edi;"
1504 "cpuid;"
1505 "xchgl %%ebx, %%edi;"
1506 : "=a" (*a) ,
1507 "=D" (*b) ,
1508 #else
1509 "cpuid"
1510 : "=a" (*a) ,
1511 "=b" (*b) ,
1512 #endif
1513 "=c" (*c) ,
1514 "=d" (*d)
1515 : "0" (function)) ;
1516
1517 #endif
1518
1519 #else
1520
1521 int CPUInfo[4];
1522 __cpuid(CPUInfo, function);
1523 *a = CPUInfo[0];
1524 *b = CPUInfo[1];
1525 *c = CPUInfo[2];
1526 *d = CPUInfo[3];
1527
1528 #endif
1529}
1530
1531static Bool x86cpuid_CheckAndRead(Cx86cpuid *p)
1532{
1533 CHECK_CPUID_IS_SUPPORTED
1534 MyCPUID(0, &p->maxFunc, &p->vendor[0], &p->vendor[2], &p->vendor[1]);
1535 MyCPUID(1, &p->ver, &p->b, &p->c, &p->d);
1536 return True;
1537}
1538
1539static const UInt32 kVendors[][3] =
1540{
1541 { 0x756E6547, 0x49656E69, 0x6C65746E},
1542 { 0x68747541, 0x69746E65, 0x444D4163},
1543 { 0x746E6543, 0x48727561, 0x736C7561}
1544};
1545
1546static int x86cpuid_GetFirm(const Cx86cpuid *p)
1547{
1548 unsigned i;
1549 for (i = 0; i < sizeof(kVendors) / sizeof(kVendors[i]); i++)
1550 {
1551 const UInt32 *v = kVendors[i];
1552 if (v[0] == p->vendor[0] &&
1553 v[1] == p->vendor[1] &&
1554 v[2] == p->vendor[2])
1555 return (int)i;
1556 }
1557 return -1;
1558}
1559
1560static Bool CPU_Is_InOrder()
1561{
1562 Cx86cpuid p;
1563 int firm;
1564 UInt32 family, model;
1565 if (!x86cpuid_CheckAndRead(&p))
1566 return True;
1567
1568 family = x86cpuid_GetFamily(p.ver);
1569 model = x86cpuid_GetModel(p.ver);
1570
1571 firm = x86cpuid_GetFirm(&p);
1572
1573 switch (firm)
1574 {
1575 case CPU_FIRM_INTEL: return (family < 6 || (family == 6 && (
1576 /* In-Order Atom CPU */
1577 model == 0x1C /* 45 nm, N4xx, D4xx, N5xx, D5xx, 230, 330 */
1578 || model == 0x26 /* 45 nm, Z6xx */
1579 || model == 0x27 /* 32 nm, Z2460 */
1580 || model == 0x35 /* 32 nm, Z2760 */
1581 || model == 0x36 /* 32 nm, N2xxx, D2xxx */
1582 )));
1583 case CPU_FIRM_AMD: return (family < 5 || (family == 5 && (model < 6 || model == 0xA)));
1584 case CPU_FIRM_VIA: return (family < 6 || (family == 6 && model < 0xF));
1585 }
1586 return True;
1587}
1588
1589#endif
1590
1591/* 7zStream.c -- 7z Stream functions
15922013-11-12 : Igor Pavlov : Public domain */
1593
1594/*#include "Precomp.h"*/
1595
1596#include <string.h>
1597
1598/*#include "7zTypes.h"*/
1599
1600static SRes LookInStream_SeekTo(ILookInStream *stream, UInt64 offset)
1601{
1602 Int64 t = offset;
1603 return stream->Seek(stream, &t, SZ_SEEK_SET);
1604}
1605
1606static SRes LookInStream_Read2(ILookInStream *stream, void *buf, size_t size, SRes errorType)
1607{
1608 while (size != 0)
1609 {
1610 size_t processed = size;
1611 RINOK(stream->Read(stream, buf, &processed));
1612 if (processed == 0)
1613 return errorType;
1614 buf = (void *)((Byte *)buf + processed);
1615 size -= processed;
1616 }
1617 return SZ_OK;
1618}
1619
1620static SRes LookInStream_Read(ILookInStream *stream, void *buf, size_t size)
1621{
1622 return LookInStream_Read2(stream, buf, size, SZ_ERROR_INPUT_EOF);
1623}
1624
1625static SRes LookToRead_Look_Lookahead(void *pp, const void **buf, size_t *size)
1626{
1627 SRes res = SZ_OK;
1628 CLookToRead *p = (CLookToRead *)pp;
1629 size_t size2 = p->size - p->pos;
1630 if (size2 == 0 && *size > 0)
1631 {
1632 p->pos = 0;
1633 size2 = LookToRead_BUF_SIZE;
1634 res = p->realStream->Read(p->realStream, p->buf, &size2);
1635 p->size = size2;
1636 }
1637 if (size2 < *size)
1638 *size = size2;
1639 *buf = p->buf + p->pos;
1640 return res;
1641}
1642
1643static SRes LookToRead_Look_Exact(void *pp, const void **buf, size_t *size)
1644{
1645 SRes res = SZ_OK;
1646 CLookToRead *p = (CLookToRead *)pp;
1647 size_t size2 = p->size - p->pos;
1648 if (size2 == 0 && *size > 0)
1649 {
1650 p->pos = 0;
1651 if (*size > LookToRead_BUF_SIZE)
1652 *size = LookToRead_BUF_SIZE;
1653 res = p->realStream->Read(p->realStream, p->buf, size);
1654 size2 = p->size = *size;
1655 }
1656 if (size2 < *size)
1657 *size = size2;
1658 *buf = p->buf + p->pos;
1659 return res;
1660}
1661
1662static SRes LookToRead_Skip(void *pp, size_t offset)
1663{
1664 CLookToRead *p = (CLookToRead *)pp;
1665 p->pos += offset;
1666 return SZ_OK;
1667}
1668
1669static SRes LookToRead_Read(void *pp, void *buf, size_t *size)
1670{
1671 CLookToRead *p = (CLookToRead *)pp;
1672 size_t rem = p->size - p->pos;
1673 if (rem == 0)
1674 return p->realStream->Read(p->realStream, buf, size);
1675 if (rem > *size)
1676 rem = *size;
1677 memcpy(buf, p->buf + p->pos, rem);
1678 p->pos += rem;
1679 *size = rem;
1680 return SZ_OK;
1681}
1682
1683static SRes LookToRead_Seek(void *pp, Int64 *pos, ESzSeek origin)
1684{
1685 CLookToRead *p = (CLookToRead *)pp;
1686 p->pos = p->size = 0;
1687 return p->realStream->Seek(p->realStream, pos, origin);
1688}
1689
1690static void LookToRead_CreateVTable(CLookToRead *p, int lookahead)
1691{
1692 p->s.Look = lookahead ?
1693 LookToRead_Look_Lookahead :
1694 LookToRead_Look_Exact;
1695 p->s.Skip = LookToRead_Skip;
1696 p->s.Read = LookToRead_Read;
1697 p->s.Seek = LookToRead_Seek;
1698}
1699
1700static void LookToRead_Init(CLookToRead *p)
1701{
1702 p->pos = p->size = 0;
1703}
1704
1705
1706/* 7zArcIn.c -- 7z Input functions
17072016-05-16 : Igor Pavlov : Public domain */
1708
1709/*
1710#include "Precomp.h"
1711
1712#include <string.h>
1713
1714#include "7z.h"
1715#include "7zBuf.h"
1716#include "7zCrc.h"
1717#include "CpuArch.h"
1718*/
1719
1720#define MY_ALLOC(T, p, size, alloc) { \
1721 if ((p = (T *)IAlloc_Alloc(alloc, (size) * sizeof(T))) == NULL) return SZ_ERROR_MEM; }
1722
1723#define MY_ALLOC_ZE(T, p, size, alloc) { if ((size) == 0) p = NULL; else MY_ALLOC(T, p, size, alloc) }
1724
1725#define MY_ALLOC_AND_CPY(to, size, from, alloc) \
1726 { MY_ALLOC(Byte, to, size, alloc); memcpy(to, from, size); }
1727
1728#define MY_ALLOC_ZE_AND_CPY(to, size, from, alloc) \
1729 { if ((size) == 0) p = NULL; else { MY_ALLOC_AND_CPY(to, size, from, alloc) } }
1730
1731#define k7zMajorVersion 0
1732
1733enum EIdEnum
1734{
1735 k7zIdEnd,
1736 k7zIdHeader,
1737 k7zIdArchiveProperties,
1738 k7zIdAdditionalStreamsInfo,
1739 k7zIdMainStreamsInfo,
1740 k7zIdFilesInfo,
1741 k7zIdPackInfo,
1742 k7zIdUnpackInfo,
1743 k7zIdSubStreamsInfo,
1744 k7zIdSize,
1745 k7zIdCRC,
1746 k7zIdFolder,
1747 k7zIdCodersUnpackSize,
1748 k7zIdNumUnpackStream,
1749 k7zIdEmptyStream,
1750 k7zIdEmptyFile,
1751 k7zIdAnti,
1752 k7zIdName,
1753 k7zIdCTime,
1754 k7zIdATime,
1755 k7zIdMTime,
1756 k7zIdWinAttrib,
1757 k7zIdComment,
1758 k7zIdEncodedHeader,
1759 k7zIdStartPos,
1760 k7zIdDummy
1761 /* k7zNtSecure, */
1762 /* k7zParent, */
1763 /* k7zIsReal */
1764};
1765
1766static const Byte k7zSignature[k7zSignatureSize] = {'7', 'z', 0xBC, 0xAF, 0x27, 0x1C};
1767
1768#define SzBitUi32s_Init(p) { (p)->Defs = NULL; (p)->Vals = NULL; }
1769
1770static SRes SzBitUi32s_Alloc(CSzBitUi32s *p, size_t num, ISzAlloc *alloc)
1771{
1772 if (num == 0)
1773 {
1774 p->Defs = NULL;
1775 p->Vals = NULL;
1776 }
1777 else
1778 {
1779 MY_ALLOC(Byte, p->Defs, (num + 7) >> 3, alloc);
1780 MY_ALLOC(UInt32, p->Vals, num, alloc);
1781 }
1782 return SZ_OK;
1783}
1784
1785static void SzBitUi32s_Free(CSzBitUi32s *p, ISzAlloc *alloc)
1786{
1787 IAlloc_Free(alloc, p->Defs); p->Defs = NULL;
1788 IAlloc_Free(alloc, p->Vals); p->Vals = NULL;
1789}
1790
1791#define SzBitUi64s_Init(p) { (p)->Defs = NULL; (p)->Vals = NULL; }
1792
1793static void SzBitUi64s_Free(CSzBitUi64s *p, ISzAlloc *alloc)
1794{
1795 IAlloc_Free(alloc, p->Defs); p->Defs = NULL;
1796 IAlloc_Free(alloc, p->Vals); p->Vals = NULL;
1797}
1798
1799
1800static void SzAr_Init(CSzAr *p)
1801{
1802 p->NumPackStreams = 0;
1803 p->NumFolders = 0;
1804
1805 p->PackPositions = NULL;
1806 SzBitUi32s_Init(&p->FolderCRCs);
1807
1808 p->FoCodersOffsets = NULL;
1809 p->FoStartPackStreamIndex = NULL;
1810 p->FoToCoderUnpackSizes = NULL;
1811 p->FoToMainUnpackSizeIndex = NULL;
1812 p->CoderUnpackSizes = NULL;
1813
1814 p->CodersData = NULL;
1815}
1816
1817static void SzAr_Free(CSzAr *p, ISzAlloc *alloc)
1818{
1819 IAlloc_Free(alloc, p->PackPositions);
1820 SzBitUi32s_Free(&p->FolderCRCs, alloc);
1821
1822 IAlloc_Free(alloc, p->FoCodersOffsets);
1823 IAlloc_Free(alloc, p->FoStartPackStreamIndex);
1824 IAlloc_Free(alloc, p->FoToCoderUnpackSizes);
1825 IAlloc_Free(alloc, p->FoToMainUnpackSizeIndex);
1826 IAlloc_Free(alloc, p->CoderUnpackSizes);
1827
1828 IAlloc_Free(alloc, p->CodersData);
1829
1830 SzAr_Init(p);
1831}
1832
1833
1834static void SzArEx_Init(CSzArEx *p)
1835{
1836 SzAr_Init(&p->db);
1837
1838 p->NumFiles = 0;
1839 p->dataPos = 0;
1840
1841 p->UnpackPositions = NULL;
1842 p->IsDirs = NULL;
1843
1844 p->FolderToFile = NULL;
1845 p->FileToFolder = NULL;
1846
1847 p->FileNameOffsets = NULL;
1848 p->FileNames = NULL;
1849
1850 SzBitUi32s_Init(&p->CRCs);
1851 SzBitUi32s_Init(&p->Attribs);
1852 /* SzBitUi32s_Init(&p->Parents); */
1853 SzBitUi64s_Init(&p->MTime);
1854 SzBitUi64s_Init(&p->CTime);
1855}
1856
1857static void SzArEx_Free(CSzArEx *p, ISzAlloc *alloc)
1858{
1859 IAlloc_Free(alloc, p->UnpackPositions);
1860 IAlloc_Free(alloc, p->IsDirs);
1861
1862 IAlloc_Free(alloc, p->FolderToFile);
1863 IAlloc_Free(alloc, p->FileToFolder);
1864
1865 IAlloc_Free(alloc, p->FileNameOffsets);
1866 IAlloc_Free(alloc, p->FileNames);
1867
1868 SzBitUi32s_Free(&p->CRCs, alloc);
1869 SzBitUi32s_Free(&p->Attribs, alloc);
1870 /* SzBitUi32s_Free(&p->Parents, alloc); */
1871 SzBitUi64s_Free(&p->MTime, alloc);
1872 SzBitUi64s_Free(&p->CTime, alloc);
1873
1874 SzAr_Free(&p->db, alloc);
1875 SzArEx_Init(p);
1876}
1877
1878
1879static int TestSignatureCandidate(const Byte *testBytes)
1880{
1881 unsigned i;
1882 for (i = 0; i < k7zSignatureSize; i++)
1883 if (testBytes[i] != k7zSignature[i])
1884 return 0;
1885 return 1;
1886}
1887
1888#define SzData_Clear(p) { (p)->Data = NULL; (p)->Size = 0; }
1889
1890#define SZ_READ_BYTE_SD(_sd_, dest) if ((_sd_)->Size == 0) return SZ_ERROR_ARCHIVE; (_sd_)->Size--; dest = *(_sd_)->Data++;
1891#define SZ_READ_BYTE(dest) SZ_READ_BYTE_SD(sd, dest)
1892#define SZ_READ_BYTE_2(dest) if (sd.Size == 0) return SZ_ERROR_ARCHIVE; sd.Size--; dest = *sd.Data++;
1893
1894#define SKIP_DATA(sd, size) { sd->Size -= (size_t)(size); sd->Data += (size_t)(size); }
1895#define SKIP_DATA2(sd, size) { sd.Size -= (size_t)(size); sd.Data += (size_t)(size); }
1896
1897#define SZ_READ_32(dest) if (sd.Size < 4) return SZ_ERROR_ARCHIVE; \
1898 dest = GetUi32(sd.Data); SKIP_DATA2(sd, 4);
1899
1900static MY_NO_INLINE SRes ReadNumber(CSzData *sd, UInt64 *value)
1901{
1902 Byte firstByte, mask;
1903 unsigned i;
1904 UInt32 v;
1905
1906 SZ_READ_BYTE(firstByte);
1907 if ((firstByte & 0x80) == 0)
1908 {
1909 *value = firstByte;
1910 return SZ_OK;
1911 }
1912 SZ_READ_BYTE(v);
1913 if ((firstByte & 0x40) == 0)
1914 {
1915 *value = (((UInt32)firstByte & 0x3F) << 8) | v;
1916 return SZ_OK;
1917 }
1918 SZ_READ_BYTE(mask);
1919 *value = v | ((UInt32)mask << 8);
1920 mask = 0x20;
1921 for (i = 2; i < 8; i++)
1922 {
1923 Byte b;
1924 if ((firstByte & mask) == 0)
1925 {
1926 UInt64 highPart = (unsigned)firstByte & (unsigned)(mask - 1);
1927 *value |= (highPart << (8 * i));
1928 return SZ_OK;
1929 }
1930 SZ_READ_BYTE(b);
1931 *value |= ((UInt64)b << (8 * i));
1932 mask >>= 1;
1933 }
1934 return SZ_OK;
1935}
1936
1937
1938static MY_NO_INLINE SRes SzReadNumber32(CSzData *sd, UInt32 *value)
1939{
1940 Byte firstByte;
1941 UInt64 value64;
1942 if (sd->Size == 0)
1943 return SZ_ERROR_ARCHIVE;
1944 firstByte = *sd->Data;
1945 if ((firstByte & 0x80) == 0)
1946 {
1947 *value = firstByte;
1948 sd->Data++;
1949 sd->Size--;
1950 return SZ_OK;
1951 }
1952 RINOK(ReadNumber(sd, &value64));
1953 if (value64 >= (UInt32)0x80000000 - 1)
1954 return SZ_ERROR_UNSUPPORTED;
1955 if (value64 >= ((UInt64)(1) << ((sizeof(size_t) - 1) * 8 + 4)))
1956 return SZ_ERROR_UNSUPPORTED;
1957 *value = (UInt32)value64;
1958 return SZ_OK;
1959}
1960
1961#define ReadID(sd, value) ReadNumber(sd, value)
1962
1963static SRes SkipData(CSzData *sd)
1964{
1965 UInt64 size;
1966 RINOK(ReadNumber(sd, &size));
1967 if (size > sd->Size)
1968 return SZ_ERROR_ARCHIVE;
1969 SKIP_DATA(sd, size);
1970 return SZ_OK;
1971}
1972
1973static SRes WaitId(CSzData *sd, UInt32 id)
1974{
1975 for (;;)
1976 {
1977 UInt64 type;
1978 RINOK(ReadID(sd, &type));
1979 if (type == id)
1980 return SZ_OK;
1981 if (type == k7zIdEnd)
1982 return SZ_ERROR_ARCHIVE;
1983 RINOK(SkipData(sd));
1984 }
1985}
1986
1987static SRes RememberBitVector(CSzData *sd, UInt32 numItems, const Byte **v)
1988{
1989 UInt32 numBytes = (numItems + 7) >> 3;
1990 if (numBytes > sd->Size)
1991 return SZ_ERROR_ARCHIVE;
1992 *v = sd->Data;
1993 SKIP_DATA(sd, numBytes);
1994 return SZ_OK;
1995}
1996
1997static UInt32 CountDefinedBits(const Byte *bits, UInt32 numItems)
1998{
1999 Byte b = 0;
2000 unsigned m = 0;
2001 UInt32 sum = 0;
2002 for (; numItems != 0; numItems--)
2003 {
2004 if (m == 0)
2005 {
2006 b = *bits++;
2007 m = 8;
2008 }
2009 m--;
2010 sum += ((b >> m) & 1);
2011 }
2012 return sum;
2013}
2014
2015static MY_NO_INLINE SRes ReadBitVector(CSzData *sd, UInt32 numItems, Byte **v, ISzAlloc *alloc)
2016{
2017 Byte allAreDefined;
2018 Byte *v2;
2019 UInt32 numBytes = (numItems + 7) >> 3;
2020 *v = NULL;
2021 SZ_READ_BYTE(allAreDefined);
2022 if (numBytes == 0)
2023 return SZ_OK;
2024 if (allAreDefined == 0)
2025 {
2026 if (numBytes > sd->Size)
2027 return SZ_ERROR_ARCHIVE;
2028 MY_ALLOC_AND_CPY(*v, numBytes, sd->Data, alloc);
2029 SKIP_DATA(sd, numBytes);
2030 return SZ_OK;
2031 }
2032 MY_ALLOC(Byte, *v, numBytes, alloc);
2033 v2 = *v;
2034 memset(v2, 0xFF, (size_t)numBytes);
2035 {
2036 unsigned numBits = (unsigned)numItems & 7;
2037 if (numBits != 0)
2038 v2[numBytes - 1] = (Byte)((((UInt32)1 << numBits) - 1) << (8 - numBits));
2039 }
2040 return SZ_OK;
2041}
2042
2043static MY_NO_INLINE SRes ReadUi32s(CSzData *sd2, UInt32 numItems, CSzBitUi32s *crcs, ISzAlloc *alloc)
2044{
2045 UInt32 i;
2046 CSzData sd;
2047 UInt32 *vals;
2048 const Byte *defs;
2049 MY_ALLOC_ZE(UInt32, crcs->Vals, numItems, alloc);
2050 sd = *sd2;
2051 defs = crcs->Defs;
2052 vals = crcs->Vals;
2053 for (i = 0; i < numItems; i++)
2054 if (SzBitArray_Check(defs, i))
2055 {
2056 SZ_READ_32(vals[i]);
2057 }
2058 else
2059 vals[i] = 0;
2060 *sd2 = sd;
2061 return SZ_OK;
2062}
2063
2064static SRes ReadBitUi32s(CSzData *sd, UInt32 numItems, CSzBitUi32s *crcs, ISzAlloc *alloc)
2065{
2066 SzBitUi32s_Free(crcs, alloc);
2067 RINOK(ReadBitVector(sd, numItems, &crcs->Defs, alloc));
2068 return ReadUi32s(sd, numItems, crcs, alloc);
2069}
2070
2071static SRes SkipBitUi32s(CSzData *sd, UInt32 numItems)
2072{
2073 Byte allAreDefined;
2074 UInt32 numDefined = numItems;
2075 SZ_READ_BYTE(allAreDefined);
2076 if (!allAreDefined)
2077 {
2078 size_t numBytes = (numItems + 7) >> 3;
2079 if (numBytes > sd->Size)
2080 return SZ_ERROR_ARCHIVE;
2081 numDefined = CountDefinedBits(sd->Data, numItems);
2082 SKIP_DATA(sd, numBytes);
2083 }
2084 if (numDefined > (sd->Size >> 2))
2085 return SZ_ERROR_ARCHIVE;
2086 SKIP_DATA(sd, (size_t)numDefined * 4);
2087 return SZ_OK;
2088}
2089
2090static SRes ReadPackInfo(CSzAr *p, CSzData *sd, ISzAlloc *alloc)
2091{
2092 RINOK(SzReadNumber32(sd, &p->NumPackStreams));
2093
2094 RINOK(WaitId(sd, k7zIdSize));
2095 MY_ALLOC(UInt64, p->PackPositions, (size_t)p->NumPackStreams + 1, alloc);
2096 {
2097 UInt64 sum = 0;
2098 UInt32 i;
2099 UInt32 numPackStreams = p->NumPackStreams;
2100 for (i = 0; i < numPackStreams; i++)
2101 {
2102 UInt64 packSize;
2103 p->PackPositions[i] = sum;
2104 RINOK(ReadNumber(sd, &packSize));
2105 sum += packSize;
2106 if (sum < packSize)
2107 return SZ_ERROR_ARCHIVE;
2108 }
2109 p->PackPositions[i] = sum;
2110 }
2111
2112 for (;;)
2113 {
2114 UInt64 type;
2115 RINOK(ReadID(sd, &type));
2116 if (type == k7zIdEnd)
2117 return SZ_OK;
2118 if (type == k7zIdCRC)
2119 {
2120 /* CRC of packed streams is unused now */
2121 RINOK(SkipBitUi32s(sd, p->NumPackStreams));
2122 continue;
2123 }
2124 RINOK(SkipData(sd));
2125 }
2126}
2127
2128/*
2129static SRes SzReadSwitch(CSzData *sd)
2130{
2131 Byte external;
2132 RINOK(SzReadByte(sd, &external));
2133 return (external == 0) ? SZ_OK: SZ_ERROR_UNSUPPORTED;
2134}
2135*/
2136
2137#define k_NumCodersStreams_in_Folder_MAX (SZ_NUM_BONDS_IN_FOLDER_MAX + SZ_NUM_PACK_STREAMS_IN_FOLDER_MAX)
2138
2139static SRes SzGetNextFolderItem(CSzFolder *f, CSzData *sd)
2140{
2141 UInt32 numCoders, i;
2142 UInt32 numInStreams = 0;
2143 const Byte *dataStart = sd->Data;
2144
2145 f->NumCoders = 0;
2146 f->NumBonds = 0;
2147 f->NumPackStreams = 0;
2148 f->UnpackStream = 0;
2149
2150 RINOK(SzReadNumber32(sd, &numCoders));
2151 if (numCoders == 0 || numCoders > SZ_NUM_CODERS_IN_FOLDER_MAX)
2152 return SZ_ERROR_UNSUPPORTED;
2153
2154 for (i = 0; i < numCoders; i++)
2155 {
2156 Byte mainByte;
2157 CSzCoderInfo *coder = f->Coders + i;
2158 unsigned idSize, j;
2159 UInt64 id;
2160
2161 SZ_READ_BYTE(mainByte);
2162 if ((mainByte & 0xC0) != 0)
2163 return SZ_ERROR_UNSUPPORTED;
2164
2165 idSize = (unsigned)(mainByte & 0xF);
2166 if (idSize > sizeof(id))
2167 return SZ_ERROR_UNSUPPORTED;
2168 if (idSize > sd->Size)
2169 return SZ_ERROR_ARCHIVE;
2170 id = 0;
2171 for (j = 0; j < idSize; j++)
2172 {
2173 id = ((id << 8) | *sd->Data);
2174 sd->Data++;
2175 sd->Size--;
2176 }
2177 if (id > UINT64_CONST(0xFFFFFFFF))
2178 return SZ_ERROR_UNSUPPORTED;
2179 coder->MethodID = (UInt32)id;
2180
2181 coder->NumStreams = 1;
2182 coder->PropsOffset = 0;
2183 coder->PropsSize = 0;
2184
2185 if ((mainByte & 0x10) != 0)
2186 {
2187 UInt32 numStreams;
2188
2189 RINOK(SzReadNumber32(sd, &numStreams));
2190 if (numStreams > k_NumCodersStreams_in_Folder_MAX)
2191 return SZ_ERROR_UNSUPPORTED;
2192 coder->NumStreams = (Byte)numStreams;
2193
2194 RINOK(SzReadNumber32(sd, &numStreams));
2195 if (numStreams != 1)
2196 return SZ_ERROR_UNSUPPORTED;
2197 }
2198
2199 numInStreams += coder->NumStreams;
2200
2201 if (numInStreams > k_NumCodersStreams_in_Folder_MAX)
2202 return SZ_ERROR_UNSUPPORTED;
2203
2204 if ((mainByte & 0x20) != 0)
2205 {
2206 UInt32 propsSize = 0;
2207 RINOK(SzReadNumber32(sd, &propsSize));
2208 if (propsSize > sd->Size)
2209 return SZ_ERROR_ARCHIVE;
2210 if (propsSize >= 0x80)
2211 return SZ_ERROR_UNSUPPORTED;
2212 coder->PropsOffset = sd->Data - dataStart;
2213 coder->PropsSize = (Byte)propsSize;
2214 sd->Data += (size_t)propsSize;
2215 sd->Size -= (size_t)propsSize;
2216 }
2217 }
2218
2219 /*
2220 if (numInStreams == 1 && numCoders == 1)
2221 {
2222 f->NumPackStreams = 1;
2223 f->PackStreams[0] = 0;
2224 }
2225 else
2226 */
2227 {
2228 Byte streamUsed[k_NumCodersStreams_in_Folder_MAX];
2229 UInt32 numBonds, numPackStreams;
2230
2231 numBonds = numCoders - 1;
2232 if (numInStreams < numBonds)
2233 return SZ_ERROR_ARCHIVE;
2234 if (numBonds > SZ_NUM_BONDS_IN_FOLDER_MAX)
2235 return SZ_ERROR_UNSUPPORTED;
2236 f->NumBonds = numBonds;
2237
2238 numPackStreams = numInStreams - numBonds;
2239 if (numPackStreams > SZ_NUM_PACK_STREAMS_IN_FOLDER_MAX)
2240 return SZ_ERROR_UNSUPPORTED;
2241 f->NumPackStreams = numPackStreams;
2242
2243 for (i = 0; i < numInStreams; i++)
2244 streamUsed[i] = False;
2245
2246 if (numBonds != 0)
2247 {
2248 Byte coderUsed[SZ_NUM_CODERS_IN_FOLDER_MAX];
2249
2250 for (i = 0; i < numCoders; i++)
2251 coderUsed[i] = False;
2252
2253 for (i = 0; i < numBonds; i++)
2254 {
2255 CSzBond *bp = f->Bonds + i;
2256
2257 RINOK(SzReadNumber32(sd, &bp->InIndex));
2258 if (bp->InIndex >= numInStreams || streamUsed[bp->InIndex])
2259 return SZ_ERROR_ARCHIVE;
2260 streamUsed[bp->InIndex] = True;
2261
2262 RINOK(SzReadNumber32(sd, &bp->OutIndex));
2263 if (bp->OutIndex >= numCoders || coderUsed[bp->OutIndex])
2264 return SZ_ERROR_ARCHIVE;
2265 coderUsed[bp->OutIndex] = True;
2266 }
2267
2268 for (i = 0; i < numCoders; i++)
2269 if (!coderUsed[i])
2270 {
2271 f->UnpackStream = i;
2272 break;
2273 }
2274
2275 if (i == numCoders)
2276 return SZ_ERROR_ARCHIVE;
2277 }
2278
2279 if (numPackStreams == 1)
2280 {
2281 for (i = 0; i < numInStreams; i++)
2282 if (!streamUsed[i])
2283 break;
2284 if (i == numInStreams)
2285 return SZ_ERROR_ARCHIVE;
2286 f->PackStreams[0] = i;
2287 }
2288 else
2289 for (i = 0; i < numPackStreams; i++)
2290 {
2291 UInt32 index;
2292 RINOK(SzReadNumber32(sd, &index));
2293 if (index >= numInStreams || streamUsed[index])
2294 return SZ_ERROR_ARCHIVE;
2295 streamUsed[index] = True;
2296 f->PackStreams[i] = index;
2297 }
2298 }
2299
2300 f->NumCoders = numCoders;
2301
2302 return SZ_OK;
2303}
2304
2305
2306static MY_NO_INLINE SRes SkipNumbers(CSzData *sd2, UInt32 num)
2307{
2308 CSzData sd;
2309 sd = *sd2;
2310 for (; num != 0; num--)
2311 {
2312 Byte firstByte, mask;
2313 unsigned i;
2314 SZ_READ_BYTE_2(firstByte);
2315 if ((firstByte & 0x80) == 0)
2316 continue;
2317 if ((firstByte & 0x40) == 0)
2318 {
2319 if (sd.Size == 0)
2320 return SZ_ERROR_ARCHIVE;
2321 sd.Size--;
2322 sd.Data++;
2323 continue;
2324 }
2325 mask = 0x20;
2326 for (i = 2; i < 8 && (firstByte & mask) != 0; i++)
2327 mask >>= 1;
2328 if (i > sd.Size)
2329 return SZ_ERROR_ARCHIVE;
2330 SKIP_DATA2(sd, i);
2331 }
2332 *sd2 = sd;
2333 return SZ_OK;
2334}
2335
2336
2337#define k_Scan_NumCoders_MAX 64
2338#define k_Scan_NumCodersStreams_in_Folder_MAX 64
2339
2340
2341static SRes ReadUnpackInfo(CSzAr *p,
2342 CSzData *sd2,
2343 UInt32 numFoldersMax,
2344 const CBuf *tempBufs, UInt32 numTempBufs,
2345 ISzAlloc *alloc)
2346{
2347 CSzData sd;
2348
2349 UInt32 fo, numFolders, numCodersOutStreams, packStreamIndex;
2350 const Byte *startBufPtr;
2351 Byte external;
2352
2353 RINOK(WaitId(sd2, k7zIdFolder));
2354
2355 RINOK(SzReadNumber32(sd2, &numFolders));
2356 if (numFolders > numFoldersMax)
2357 return SZ_ERROR_UNSUPPORTED;
2358 p->NumFolders = numFolders;
2359
2360 SZ_READ_BYTE_SD(sd2, external);
2361 if (external == 0)
2362 sd = *sd2;
2363 else
2364 {
2365 UInt32 index;
2366 RINOK(SzReadNumber32(sd2, &index));
2367 if (index >= numTempBufs)
2368 return SZ_ERROR_ARCHIVE;
2369 sd.Data = tempBufs[index].data;
2370 sd.Size = tempBufs[index].size;
2371 }
2372
2373 MY_ALLOC(size_t, p->FoCodersOffsets, (size_t)numFolders + 1, alloc);
2374 MY_ALLOC(UInt32, p->FoStartPackStreamIndex, (size_t)numFolders + 1, alloc);
2375 MY_ALLOC(UInt32, p->FoToCoderUnpackSizes, (size_t)numFolders + 1, alloc);
2376 MY_ALLOC(Byte, p->FoToMainUnpackSizeIndex, (size_t)numFolders, alloc);
2377
2378 startBufPtr = sd.Data;
2379
2380 packStreamIndex = 0;
2381 numCodersOutStreams = 0;
2382
2383 for (fo = 0; fo < numFolders; fo++)
2384 {
2385 UInt32 numCoders, ci, numInStreams = 0;
2386
2387 p->FoCodersOffsets[fo] = sd.Data - startBufPtr;
2388
2389 RINOK(SzReadNumber32(&sd, &numCoders));
2390 if (numCoders == 0 || numCoders > k_Scan_NumCoders_MAX)
2391 return SZ_ERROR_UNSUPPORTED;
2392
2393 for (ci = 0; ci < numCoders; ci++)
2394 {
2395 Byte mainByte;
2396 unsigned idSize;
2397 UInt32 coderInStreams;
2398
2399 SZ_READ_BYTE_2(mainByte);
2400 if ((mainByte & 0xC0) != 0)
2401 return SZ_ERROR_UNSUPPORTED;
2402 idSize = (mainByte & 0xF);
2403 if (idSize > 8)
2404 return SZ_ERROR_UNSUPPORTED;
2405 if (idSize > sd.Size)
2406 return SZ_ERROR_ARCHIVE;
2407 SKIP_DATA2(sd, idSize);
2408
2409 coderInStreams = 1;
2410
2411 if ((mainByte & 0x10) != 0)
2412 {
2413 UInt32 coderOutStreams;
2414 RINOK(SzReadNumber32(&sd, &coderInStreams));
2415 RINOK(SzReadNumber32(&sd, &coderOutStreams));
2416 if (coderInStreams > k_Scan_NumCodersStreams_in_Folder_MAX || coderOutStreams != 1)
2417 return SZ_ERROR_UNSUPPORTED;
2418 }
2419
2420 numInStreams += coderInStreams;
2421
2422 if ((mainByte & 0x20) != 0)
2423 {
2424 UInt32 propsSize;
2425 RINOK(SzReadNumber32(&sd, &propsSize));
2426 if (propsSize > sd.Size)
2427 return SZ_ERROR_ARCHIVE;
2428 SKIP_DATA2(sd, propsSize);
2429 }
2430 }
2431
2432 {
2433 UInt32 indexOfMainStream = 0;
2434 UInt32 numPackStreams = 1;
2435
2436 if (numCoders != 1 || numInStreams != 1)
2437 {
2438 Byte streamUsed[k_Scan_NumCodersStreams_in_Folder_MAX];
2439 Byte coderUsed[k_Scan_NumCoders_MAX];
2440
2441 UInt32 i;
2442 UInt32 numBonds = numCoders - 1;
2443 if (numInStreams < numBonds)
2444 return SZ_ERROR_ARCHIVE;
2445
2446 if (numInStreams > k_Scan_NumCodersStreams_in_Folder_MAX)
2447 return SZ_ERROR_UNSUPPORTED;
2448
2449 for (i = 0; i < numInStreams; i++)
2450 streamUsed[i] = False;
2451 for (i = 0; i < numCoders; i++)
2452 coderUsed[i] = False;
2453
2454 for (i = 0; i < numBonds; i++)
2455 {
2456 UInt32 index;
2457
2458 RINOK(SzReadNumber32(&sd, &index));
2459 if (index >= numInStreams || streamUsed[index])
2460 return SZ_ERROR_ARCHIVE;
2461 streamUsed[index] = True;
2462
2463 RINOK(SzReadNumber32(&sd, &index));
2464 if (index >= numCoders || coderUsed[index])
2465 return SZ_ERROR_ARCHIVE;
2466 coderUsed[index] = True;
2467 }
2468
2469 numPackStreams = numInStreams - numBonds;
2470
2471 if (numPackStreams != 1)
2472 for (i = 0; i < numPackStreams; i++)
2473 {
2474 UInt32 index;
2475 RINOK(SzReadNumber32(&sd, &index));
2476 if (index >= numInStreams || streamUsed[index])
2477 return SZ_ERROR_ARCHIVE;
2478 streamUsed[index] = True;
2479 }
2480
2481 for (i = 0; i < numCoders; i++)
2482 if (!coderUsed[i])
2483 {
2484 indexOfMainStream = i;
2485 break;
2486 }
2487
2488 if (i == numCoders)
2489 return SZ_ERROR_ARCHIVE;
2490 }
2491
2492 p->FoStartPackStreamIndex[fo] = packStreamIndex;
2493 p->FoToCoderUnpackSizes[fo] = numCodersOutStreams;
2494 p->FoToMainUnpackSizeIndex[fo] = (Byte)indexOfMainStream;
2495 numCodersOutStreams += numCoders;
2496 if (numCodersOutStreams < numCoders)
2497 return SZ_ERROR_UNSUPPORTED;
2498 if (numPackStreams > p->NumPackStreams - packStreamIndex)
2499 return SZ_ERROR_ARCHIVE;
2500 packStreamIndex += numPackStreams;
2501 }
2502 }
2503
2504 p->FoToCoderUnpackSizes[fo] = numCodersOutStreams;
2505
2506 {
2507 size_t dataSize = sd.Data - startBufPtr;
2508 p->FoStartPackStreamIndex[fo] = packStreamIndex;
2509 p->FoCodersOffsets[fo] = dataSize;
2510 MY_ALLOC_ZE_AND_CPY(p->CodersData, dataSize, startBufPtr, alloc);
2511 }
2512
2513 if (external != 0)
2514 {
2515 if (sd.Size != 0)
2516 return SZ_ERROR_ARCHIVE;
2517 sd = *sd2;
2518 }
2519
2520 RINOK(WaitId(&sd, k7zIdCodersUnpackSize));
2521
2522 MY_ALLOC_ZE(UInt64, p->CoderUnpackSizes, (size_t)numCodersOutStreams, alloc);
2523 {
2524 UInt32 i;
2525 for (i = 0; i < numCodersOutStreams; i++)
2526 {
2527 RINOK(ReadNumber(&sd, p->CoderUnpackSizes + i));
2528 }
2529 }
2530
2531 for (;;)
2532 {
2533 UInt64 type;
2534 RINOK(ReadID(&sd, &type));
2535 if (type == k7zIdEnd)
2536 {
2537 *sd2 = sd;
2538 return SZ_OK;
2539 }
2540 if (type == k7zIdCRC)
2541 {
2542 RINOK(ReadBitUi32s(&sd, numFolders, &p->FolderCRCs, alloc));
2543 continue;
2544 }
2545 RINOK(SkipData(&sd));
2546 }
2547}
2548
2549
2550static UInt64 SzAr_GetFolderUnpackSize(const CSzAr *p, UInt32 folderIndex)
2551{
2552 return p->CoderUnpackSizes[p->FoToCoderUnpackSizes[folderIndex] + p->FoToMainUnpackSizeIndex[folderIndex]];
2553}
2554
2555
2556typedef struct
2557{
2558 UInt32 NumTotalSubStreams;
2559 UInt32 NumSubDigests;
2560 CSzData sdNumSubStreams;
2561 CSzData sdSizes;
2562 CSzData sdCRCs;
2563} CSubStreamInfo;
2564
2565
2566static SRes ReadSubStreamsInfo(CSzAr *p, CSzData *sd, CSubStreamInfo *ssi)
2567{
2568 UInt64 type = 0;
2569 UInt32 numSubDigests = 0;
2570 UInt32 numFolders = p->NumFolders;
2571 UInt32 numUnpackStreams = numFolders;
2572 UInt32 numUnpackSizesInData = 0;
2573
2574 for (;;)
2575 {
2576 RINOK(ReadID(sd, &type));
2577 if (type == k7zIdNumUnpackStream)
2578 {
2579 UInt32 i;
2580 ssi->sdNumSubStreams.Data = sd->Data;
2581 numUnpackStreams = 0;
2582 numSubDigests = 0;
2583 for (i = 0; i < numFolders; i++)
2584 {
2585 UInt32 numStreams;
2586 RINOK(SzReadNumber32(sd, &numStreams));
2587 if (numUnpackStreams > numUnpackStreams + numStreams)
2588 return SZ_ERROR_UNSUPPORTED;
2589 numUnpackStreams += numStreams;
2590 if (numStreams != 0)
2591 numUnpackSizesInData += (numStreams - 1);
2592 if (numStreams != 1 || !SzBitWithVals_Check(&p->FolderCRCs, i))
2593 numSubDigests += numStreams;
2594 }
2595 ssi->sdNumSubStreams.Size = sd->Data - ssi->sdNumSubStreams.Data;
2596 continue;
2597 }
2598 if (type == k7zIdCRC || type == k7zIdSize || type == k7zIdEnd)
2599 break;
2600 RINOK(SkipData(sd));
2601 }
2602
2603 if (!ssi->sdNumSubStreams.Data)
2604 {
2605 numSubDigests = numFolders;
2606 if (p->FolderCRCs.Defs)
2607 numSubDigests = numFolders - CountDefinedBits(p->FolderCRCs.Defs, numFolders);
2608 }
2609
2610 ssi->NumTotalSubStreams = numUnpackStreams;
2611 ssi->NumSubDigests = numSubDigests;
2612
2613 if (type == k7zIdSize)
2614 {
2615 ssi->sdSizes.Data = sd->Data;
2616 RINOK(SkipNumbers(sd, numUnpackSizesInData));
2617 ssi->sdSizes.Size = sd->Data - ssi->sdSizes.Data;
2618 RINOK(ReadID(sd, &type));
2619 }
2620
2621 for (;;)
2622 {
2623 if (type == k7zIdEnd)
2624 return SZ_OK;
2625 if (type == k7zIdCRC)
2626 {
2627 ssi->sdCRCs.Data = sd->Data;
2628 RINOK(SkipBitUi32s(sd, numSubDigests));
2629 ssi->sdCRCs.Size = sd->Data - ssi->sdCRCs.Data;
2630 }
2631 else
2632 {
2633 RINOK(SkipData(sd));
2634 }
2635 RINOK(ReadID(sd, &type));
2636 }
2637}
2638
2639static SRes SzReadStreamsInfo(CSzAr *p,
2640 CSzData *sd,
2641 UInt32 numFoldersMax, const CBuf *tempBufs, UInt32 numTempBufs,
2642 UInt64 *dataOffset,
2643 CSubStreamInfo *ssi,
2644 ISzAlloc *alloc)
2645{
2646 UInt64 type;
2647
2648 SzData_Clear(&ssi->sdSizes);
2649 SzData_Clear(&ssi->sdCRCs);
2650 SzData_Clear(&ssi->sdNumSubStreams);
2651
2652 *dataOffset = 0;
2653 RINOK(ReadID(sd, &type));
2654 if (type == k7zIdPackInfo)
2655 {
2656 RINOK(ReadNumber(sd, dataOffset));
2657 RINOK(ReadPackInfo(p, sd, alloc));
2658 RINOK(ReadID(sd, &type));
2659 }
2660 if (type == k7zIdUnpackInfo)
2661 {
2662 RINOK(ReadUnpackInfo(p, sd, numFoldersMax, tempBufs, numTempBufs, alloc));
2663 RINOK(ReadID(sd, &type));
2664 }
2665 if (type == k7zIdSubStreamsInfo)
2666 {
2667 RINOK(ReadSubStreamsInfo(p, sd, ssi));
2668 RINOK(ReadID(sd, &type));
2669 }
2670 else
2671 {
2672 ssi->NumTotalSubStreams = p->NumFolders;
2673 /* ssi->NumSubDigests = 0; */
2674 }
2675
2676 return (type == k7zIdEnd ? SZ_OK : SZ_ERROR_UNSUPPORTED);
2677}
2678
2679static SRes SzReadAndDecodePackedStreams(
2680 ILookInStream *inStream,
2681 CSzData *sd,
2682 CBuf *tempBufs,
2683 UInt32 numFoldersMax,
2684 UInt64 baseOffset,
2685 CSzAr *p,
2686 ISzAlloc *allocTemp)
2687{
2688 UInt64 dataStartPos = 0;
2689 UInt32 fo;
2690 CSubStreamInfo ssi;
2691 UInt32 numFolders;
2692
2693 RINOK(SzReadStreamsInfo(p, sd, numFoldersMax, NULL, 0, &dataStartPos, &ssi, allocTemp));
2694
2695 numFolders = p->NumFolders;
2696 if (numFolders == 0)
2697 return SZ_ERROR_ARCHIVE;
2698 else if (numFolders > numFoldersMax)
2699 return SZ_ERROR_UNSUPPORTED;
2700
2701 dataStartPos += baseOffset;
2702
2703 for (fo = 0; fo < numFolders; fo++)
2704 Buf_Init(tempBufs + fo);
2705
2706 for (fo = 0; fo < numFolders; fo++)
2707 {
2708 CBuf *tempBuf = tempBufs + fo;
2709 UInt64 unpackSize = SzAr_GetFolderUnpackSize(p, fo);
2710 if ((size_t)unpackSize != unpackSize)
2711 return SZ_ERROR_MEM;
2712 if (!Buf_Create(tempBuf, (size_t)unpackSize, allocTemp))
2713 return SZ_ERROR_MEM;
2714 }
2715
2716 for (fo = 0; fo < numFolders; fo++)
2717 {
2718 const CBuf *tempBuf = tempBufs + fo;
2719 RINOK(LookInStream_SeekTo(inStream, dataStartPos));
2720 RINOK(SzAr_DecodeFolder(p, fo, inStream, dataStartPos, tempBuf->data, tempBuf->size, allocTemp));
2721 }
2722
2723 return SZ_OK;
2724}
2725
2726static SRes SzReadFileNames(const Byte *data, size_t size, UInt32 numFiles, size_t *offsets)
2727{
2728 size_t pos = 0;
2729 *offsets++ = 0;
2730 if (numFiles == 0)
2731 return (size == 0) ? SZ_OK : SZ_ERROR_ARCHIVE;
2732 if (size < 2)
2733 return SZ_ERROR_ARCHIVE;
2734 if (data[size - 2] != 0 || data[size - 1] != 0)
2735 return SZ_ERROR_ARCHIVE;
2736 do
2737 {
2738 const Byte *p;
2739 if (pos == size)
2740 return SZ_ERROR_ARCHIVE;
2741 for (p = data + pos;
2742 #ifdef _WIN32
2743 *(const UInt16 *)p != 0
2744 #else
2745 p[0] != 0 || p[1] != 0
2746 #endif
2747 ; p += 2);
2748 pos = p - data + 2;
2749 *offsets++ = (pos >> 1);
2750 }
2751 while (--numFiles);
2752 return (pos == size) ? SZ_OK : SZ_ERROR_ARCHIVE;
2753}
2754
2755static MY_NO_INLINE SRes ReadTime(CSzBitUi64s *p, UInt32 num,
2756 CSzData *sd2,
2757 const CBuf *tempBufs, UInt32 numTempBufs,
2758 ISzAlloc *alloc)
2759{
2760 CSzData sd;
2761 UInt32 i;
2762 CNtfsFileTime *vals;
2763 Byte *defs;
2764 Byte external;
2765
2766 RINOK(ReadBitVector(sd2, num, &p->Defs, alloc));
2767
2768 SZ_READ_BYTE_SD(sd2, external);
2769 if (external == 0)
2770 sd = *sd2;
2771 else
2772 {
2773 UInt32 index;
2774 RINOK(SzReadNumber32(sd2, &index));
2775 if (index >= numTempBufs)
2776 return SZ_ERROR_ARCHIVE;
2777 sd.Data = tempBufs[index].data;
2778 sd.Size = tempBufs[index].size;
2779 }
2780
2781 MY_ALLOC_ZE(CNtfsFileTime, p->Vals, num, alloc);
2782 vals = p->Vals;
2783 defs = p->Defs;
2784 for (i = 0; i < num; i++)
2785 if (SzBitArray_Check(defs, i))
2786 {
2787 if (sd.Size < 8)
2788 return SZ_ERROR_ARCHIVE;
2789 vals[i].Low = GetUi32(sd.Data);
2790 vals[i].High = GetUi32(sd.Data + 4);
2791 SKIP_DATA2(sd, 8);
2792 }
2793 else
2794 vals[i].High = vals[i].Low = 0;
2795
2796 if (external == 0)
2797 *sd2 = sd;
2798
2799 return SZ_OK;
2800}
2801
2802
2803#define NUM_ADDITIONAL_STREAMS_MAX 8
2804
2805
2806static SRes SzReadHeader2(
2807 CSzArEx *p, /* allocMain */
2808 CSzData *sd,
2809 ILookInStream *inStream,
2810 CBuf *tempBufs, UInt32 *numTempBufs,
2811 ISzAlloc *allocMain,
2812 ISzAlloc *allocTemp
2813 )
2814{
2815 CSubStreamInfo ssi;
2816
2817{
2818 UInt64 type;
2819
2820 SzData_Clear(&ssi.sdSizes);
2821 SzData_Clear(&ssi.sdCRCs);
2822 SzData_Clear(&ssi.sdNumSubStreams);
2823
2824 ssi.NumSubDigests = 0;
2825 ssi.NumTotalSubStreams = 0;
2826
2827 RINOK(ReadID(sd, &type));
2828
2829 if (type == k7zIdArchiveProperties)
2830 {
2831 for (;;)
2832 {
2833 UInt64 type2;
2834 RINOK(ReadID(sd, &type2));
2835 if (type2 == k7zIdEnd)
2836 break;
2837 RINOK(SkipData(sd));
2838 }
2839 RINOK(ReadID(sd, &type));
2840 }
2841
2842 if (type == k7zIdAdditionalStreamsInfo)
2843 {
2844 CSzAr tempAr;
2845 SRes res;
2846
2847 SzAr_Init(&tempAr);
2848 res = SzReadAndDecodePackedStreams(inStream, sd, tempBufs, NUM_ADDITIONAL_STREAMS_MAX,
2849 p->startPosAfterHeader, &tempAr, allocTemp);
2850 *numTempBufs = tempAr.NumFolders;
2851 SzAr_Free(&tempAr, allocTemp);
2852
2853 if (res != SZ_OK)
2854 return res;
2855 RINOK(ReadID(sd, &type));
2856 }
2857
2858 if (type == k7zIdMainStreamsInfo)
2859 {
2860 RINOK(SzReadStreamsInfo(&p->db, sd, (UInt32)1 << 30, tempBufs, *numTempBufs,
2861 &p->dataPos, &ssi, allocMain));
2862 p->dataPos += p->startPosAfterHeader;
2863 RINOK(ReadID(sd, &type));
2864 }
2865
2866 if (type == k7zIdEnd)
2867 {
2868 return SZ_OK;
2869 }
2870
2871 if (type != k7zIdFilesInfo)
2872 return SZ_ERROR_ARCHIVE;
2873}
2874
2875{
2876 UInt32 numFiles = 0;
2877 UInt32 numEmptyStreams = 0;
2878 const Byte *emptyStreams = NULL;
2879 const Byte *emptyFiles = NULL;
2880
2881 RINOK(SzReadNumber32(sd, &numFiles));
2882 p->NumFiles = numFiles;
2883
2884 for (;;)
2885 {
2886 UInt64 type;
2887 UInt64 size;
2888 RINOK(ReadID(sd, &type));
2889 if (type == k7zIdEnd)
2890 break;
2891 RINOK(ReadNumber(sd, &size));
2892 if (size > sd->Size)
2893 return SZ_ERROR_ARCHIVE;
2894
2895 if (type >= ((UInt32)1 << 8))
2896 {
2897 SKIP_DATA(sd, size);
2898 }
2899 else switch ((unsigned)type)
2900 {
2901 case k7zIdName:
2902 {
2903 size_t namesSize;
2904 const Byte *namesData;
2905 Byte external;
2906
2907 SZ_READ_BYTE(external);
2908 if (external == 0)
2909 {
2910 namesSize = (size_t)size - 1;
2911 namesData = sd->Data;
2912 }
2913 else
2914 {
2915 UInt32 index;
2916 RINOK(SzReadNumber32(sd, &index));
2917 if (index >= *numTempBufs)
2918 return SZ_ERROR_ARCHIVE;
2919 namesData = (tempBufs)[index].data;
2920 namesSize = (tempBufs)[index].size;
2921 }
2922
2923 if ((namesSize & 1) != 0)
2924 return SZ_ERROR_ARCHIVE;
2925 MY_ALLOC(size_t, p->FileNameOffsets, numFiles + 1, allocMain);
2926 MY_ALLOC_ZE_AND_CPY(p->FileNames, namesSize, namesData, allocMain);
2927 RINOK(SzReadFileNames(p->FileNames, namesSize, numFiles, p->FileNameOffsets))
2928 if (external == 0)
2929 {
2930 SKIP_DATA(sd, namesSize);
2931 }
2932 break;
2933 }
2934 case k7zIdEmptyStream:
2935 {
2936 RINOK(RememberBitVector(sd, numFiles, &emptyStreams));
2937 numEmptyStreams = CountDefinedBits(emptyStreams, numFiles);
2938 emptyFiles = NULL;
2939 break;
2940 }
2941 case k7zIdEmptyFile:
2942 {
2943 RINOK(RememberBitVector(sd, numEmptyStreams, &emptyFiles));
2944 break;
2945 }
2946 case k7zIdWinAttrib:
2947 {
2948 Byte external;
2949 CSzData sdSwitch;
2950 CSzData *sdPtr;
2951 SzBitUi32s_Free(&p->Attribs, allocMain);
2952 RINOK(ReadBitVector(sd, numFiles, &p->Attribs.Defs, allocMain));
2953
2954 SZ_READ_BYTE(external);
2955 if (external == 0)
2956 sdPtr = sd;
2957 else
2958 {
2959 UInt32 index;
2960 RINOK(SzReadNumber32(sd, &index));
2961 if (index >= *numTempBufs)
2962 return SZ_ERROR_ARCHIVE;
2963 sdSwitch.Data = (tempBufs)[index].data;
2964 sdSwitch.Size = (tempBufs)[index].size;
2965 sdPtr = &sdSwitch;
2966 }
2967 RINOK(ReadUi32s(sdPtr, numFiles, &p->Attribs, allocMain));
2968 break;
2969 }
2970 /*
2971 case k7zParent:
2972 {
2973 SzBitUi32s_Free(&p->Parents, allocMain);
2974 RINOK(ReadBitVector(sd, numFiles, &p->Parents.Defs, allocMain));
2975 RINOK(SzReadSwitch(sd));
2976 RINOK(ReadUi32s(sd, numFiles, &p->Parents, allocMain));
2977 break;
2978 }
2979 */
2980 case k7zIdMTime: RINOK(ReadTime(&p->MTime, numFiles, sd, tempBufs, *numTempBufs, allocMain)); break;
2981 case k7zIdCTime: RINOK(ReadTime(&p->CTime, numFiles, sd, tempBufs, *numTempBufs, allocMain)); break;
2982 default:
2983 {
2984 SKIP_DATA(sd, size);
2985 }
2986 }
2987 }
2988
2989 if (numFiles - numEmptyStreams != ssi.NumTotalSubStreams)
2990 return SZ_ERROR_ARCHIVE;
2991
2992 for (;;)
2993 {
2994 UInt64 type;
2995 RINOK(ReadID(sd, &type));
2996 if (type == k7zIdEnd)
2997 break;
2998 RINOK(SkipData(sd));
2999 }
3000
3001 {
3002 UInt32 i;
3003 UInt32 emptyFileIndex = 0;
3004 UInt32 folderIndex = 0;
3005 UInt32 remSubStreams = 0;
3006 UInt32 numSubStreams = 0;
3007 UInt64 unpackPos = 0;
3008 const Byte *digestsDefs = NULL;
3009 const Byte *digestsVals = NULL;
3010 UInt32 digestsValsIndex = 0;
3011 UInt32 digestIndex;
3012 Byte allDigestsDefined = 0;
3013 Byte isDirMask = 0;
3014 Byte crcMask = 0;
3015 Byte mask = 0x80;
3016
3017 MY_ALLOC(UInt32, p->FolderToFile, p->db.NumFolders + 1, allocMain);
3018 MY_ALLOC_ZE(UInt32, p->FileToFolder, p->NumFiles, allocMain);
3019 MY_ALLOC(UInt64, p->UnpackPositions, p->NumFiles + 1, allocMain);
3020 MY_ALLOC_ZE(Byte, p->IsDirs, (p->NumFiles + 7) >> 3, allocMain);
3021
3022 RINOK(SzBitUi32s_Alloc(&p->CRCs, p->NumFiles, allocMain));
3023
3024 if (ssi.sdCRCs.Size != 0)
3025 {
3026 SZ_READ_BYTE_SD(&ssi.sdCRCs, allDigestsDefined);
3027 if (allDigestsDefined)
3028 digestsVals = ssi.sdCRCs.Data;
3029 else
3030 {
3031 size_t numBytes = (ssi.NumSubDigests + 7) >> 3;
3032 digestsDefs = ssi.sdCRCs.Data;
3033 digestsVals = digestsDefs + numBytes;
3034 }
3035 }
3036
3037 digestIndex = 0;
3038
3039 for (i = 0; i < numFiles; i++, mask >>= 1)
3040 {
3041 if (mask == 0)
3042 {
3043 UInt32 byteIndex = (i - 1) >> 3;
3044 p->IsDirs[byteIndex] = isDirMask;
3045 p->CRCs.Defs[byteIndex] = crcMask;
3046 isDirMask = 0;
3047 crcMask = 0;
3048 mask = 0x80;
3049 }
3050
3051 p->UnpackPositions[i] = unpackPos;
3052 p->CRCs.Vals[i] = 0;
3053
3054 if (emptyStreams && SzBitArray_Check(emptyStreams, i))
3055 {
3056 if (emptyFiles)
3057 {
3058 if (!SzBitArray_Check(emptyFiles, emptyFileIndex))
3059 isDirMask |= mask;
3060 emptyFileIndex++;
3061 }
3062 else
3063 isDirMask |= mask;
3064 if (remSubStreams == 0)
3065 {
3066 p->FileToFolder[i] = (UInt32)-1;
3067 continue;
3068 }
3069 }
3070
3071 if (remSubStreams == 0)
3072 {
3073 for (;;)
3074 {
3075 if (folderIndex >= p->db.NumFolders)
3076 return SZ_ERROR_ARCHIVE;
3077 p->FolderToFile[folderIndex] = i;
3078 numSubStreams = 1;
3079 if (ssi.sdNumSubStreams.Data)
3080 {
3081 RINOK(SzReadNumber32(&ssi.sdNumSubStreams, &numSubStreams));
3082 }
3083 remSubStreams = numSubStreams;
3084 if (numSubStreams != 0)
3085 break;
3086 {
3087 UInt64 folderUnpackSize = SzAr_GetFolderUnpackSize(&p->db, folderIndex);
3088 unpackPos += folderUnpackSize;
3089 if (unpackPos < folderUnpackSize)
3090 return SZ_ERROR_ARCHIVE;
3091 }
3092
3093 folderIndex++;
3094 }
3095 }
3096
3097 p->FileToFolder[i] = folderIndex;
3098
3099 if (emptyStreams && SzBitArray_Check(emptyStreams, i))
3100 continue;
3101
3102 if (--remSubStreams == 0)
3103 {
3104 UInt64 folderUnpackSize = SzAr_GetFolderUnpackSize(&p->db, folderIndex);
3105 UInt64 startFolderUnpackPos = p->UnpackPositions[p->FolderToFile[folderIndex]];
3106 if (folderUnpackSize < unpackPos - startFolderUnpackPos)
3107 return SZ_ERROR_ARCHIVE;
3108 unpackPos = startFolderUnpackPos + folderUnpackSize;
3109 if (unpackPos < folderUnpackSize)
3110 return SZ_ERROR_ARCHIVE;
3111
3112 if (numSubStreams == 1 && SzBitWithVals_Check(&p->db.FolderCRCs, i))
3113 {
3114 p->CRCs.Vals[i] = p->db.FolderCRCs.Vals[folderIndex];
3115 crcMask |= mask;
3116 }
3117 else if (allDigestsDefined || (digestsDefs && SzBitArray_Check(digestsDefs, digestIndex)))
3118 {
3119 p->CRCs.Vals[i] = GetUi32(digestsVals + (size_t)digestsValsIndex * 4);
3120 digestsValsIndex++;
3121 crcMask |= mask;
3122 }
3123
3124 folderIndex++;
3125 }
3126 else
3127 {
3128 UInt64 v;
3129 RINOK(ReadNumber(&ssi.sdSizes, &v));
3130 unpackPos += v;
3131 if (unpackPos < v)
3132 return SZ_ERROR_ARCHIVE;
3133 if (allDigestsDefined || (digestsDefs && SzBitArray_Check(digestsDefs, digestIndex)))
3134 {
3135 p->CRCs.Vals[i] = GetUi32(digestsVals + (size_t)digestsValsIndex * 4);
3136 digestsValsIndex++;
3137 crcMask |= mask;
3138 }
3139 }
3140 }
3141
3142 if (mask != 0x80)
3143 {
3144 UInt32 byteIndex = (i - 1) >> 3;
3145 p->IsDirs[byteIndex] = isDirMask;
3146 p->CRCs.Defs[byteIndex] = crcMask;
3147 }
3148
3149 p->UnpackPositions[i] = unpackPos;
3150
3151 if (remSubStreams != 0)
3152 return SZ_ERROR_ARCHIVE;
3153
3154 for (;;)
3155 {
3156 p->FolderToFile[folderIndex] = i;
3157 if (folderIndex >= p->db.NumFolders)
3158 break;
3159 if (!ssi.sdNumSubStreams.Data)
3160 return SZ_ERROR_ARCHIVE;
3161 RINOK(SzReadNumber32(&ssi.sdNumSubStreams, &numSubStreams));
3162 if (numSubStreams != 0)
3163 return SZ_ERROR_ARCHIVE;
3164 /*
3165 {
3166 UInt64 folderUnpackSize = SzAr_GetFolderUnpackSize(&p->db, folderIndex);
3167 unpackPos += folderUnpackSize;
3168 if (unpackPos < folderUnpackSize)
3169 return SZ_ERROR_ARCHIVE;
3170 }
3171 */
3172 folderIndex++;
3173 }
3174
3175 if (ssi.sdNumSubStreams.Data && ssi.sdNumSubStreams.Size != 0)
3176 return SZ_ERROR_ARCHIVE;
3177 }
3178}
3179 return SZ_OK;
3180}
3181
3182
3183static SRes SzReadHeader(
3184 CSzArEx *p,
3185 CSzData *sd,
3186 ILookInStream *inStream,
3187 ISzAlloc *allocMain,
3188 ISzAlloc *allocTemp)
3189{
3190 UInt32 i;
3191 UInt32 numTempBufs = 0;
3192 SRes res;
3193 CBuf tempBufs[NUM_ADDITIONAL_STREAMS_MAX];
3194
3195 for (i = 0; i < NUM_ADDITIONAL_STREAMS_MAX; i++)
3196 Buf_Init(tempBufs + i);
3197
3198 res = SzReadHeader2(p, sd, inStream,
3199 tempBufs, &numTempBufs,
3200 allocMain, allocTemp);
3201
3202 for (i = 0; i < NUM_ADDITIONAL_STREAMS_MAX; i++)
3203 Buf_Free(tempBufs + i, allocTemp);
3204
3205 RINOK(res);
3206
3207 if (sd->Size != 0)
3208 return SZ_ERROR_FAIL;
3209
3210 return res;
3211}
3212
3213static SRes SzArEx_Open2(
3214 CSzArEx *p,
3215 ILookInStream *inStream,
3216 ISzAlloc *allocMain,
3217 ISzAlloc *allocTemp)
3218{
3219 Byte header[k7zStartHeaderSize];
3220 Int64 startArcPos;
3221 UInt64 nextHeaderOffset, nextHeaderSize;
3222 size_t nextHeaderSizeT;
3223 UInt32 nextHeaderCRC;
3224 CBuf buf;
3225 SRes res;
3226
3227 startArcPos = 0;
3228 RINOK(inStream->Seek(inStream, &startArcPos, SZ_SEEK_CUR));
3229
3230 RINOK(LookInStream_Read2(inStream, header, k7zStartHeaderSize, SZ_ERROR_NO_ARCHIVE));
3231
3232 if (!TestSignatureCandidate(header))
3233 return SZ_ERROR_NO_ARCHIVE;
3234 if (header[6] != k7zMajorVersion)
3235 return SZ_ERROR_UNSUPPORTED;
3236
3237 nextHeaderOffset = GetUi64(header + 12);
3238 nextHeaderSize = GetUi64(header + 20);
3239 nextHeaderCRC = GetUi32(header + 28);
3240
3241 p->startPosAfterHeader = startArcPos + k7zStartHeaderSize;
3242
3243 if (CrcCalc(header + 12, 20) != GetUi32(header + 8))
3244 return SZ_ERROR_CRC;
3245
3246 nextHeaderSizeT = (size_t)nextHeaderSize;
3247 if (nextHeaderSizeT != nextHeaderSize)
3248 return SZ_ERROR_MEM;
3249 if (nextHeaderSizeT == 0)
3250 return SZ_OK;
3251 if (nextHeaderOffset > nextHeaderOffset + nextHeaderSize ||
3252 nextHeaderOffset > nextHeaderOffset + nextHeaderSize + k7zStartHeaderSize)
3253 return SZ_ERROR_NO_ARCHIVE;
3254
3255 {
3256 Int64 pos = 0;
3257 RINOK(inStream->Seek(inStream, &pos, SZ_SEEK_END));
3258 if ((UInt64)pos < startArcPos + nextHeaderOffset ||
3259 (UInt64)pos < startArcPos + k7zStartHeaderSize + nextHeaderOffset ||
3260 (UInt64)pos < startArcPos + k7zStartHeaderSize + nextHeaderOffset + nextHeaderSize)
3261 return SZ_ERROR_INPUT_EOF;
3262 }
3263
3264 RINOK(LookInStream_SeekTo(inStream, startArcPos + k7zStartHeaderSize + nextHeaderOffset));
3265
3266 if (!Buf_Create(&buf, nextHeaderSizeT, allocTemp))
3267 return SZ_ERROR_MEM;
3268
3269 res = LookInStream_Read(inStream, buf.data, nextHeaderSizeT);
3270
3271 if (res == SZ_OK)
3272 {
3273 res = SZ_ERROR_ARCHIVE;
3274 if (CrcCalc(buf.data, nextHeaderSizeT) == nextHeaderCRC)
3275 {
3276 CSzData sd;
3277 UInt64 type;
3278 sd.Data = buf.data;
3279 sd.Size = buf.size;
3280
3281 res = ReadID(&sd, &type);
3282
3283 if (res == SZ_OK && type == k7zIdEncodedHeader)
3284 {
3285 CSzAr tempAr;
3286 CBuf tempBuf;
3287 Buf_Init(&tempBuf);
3288
3289 SzAr_Init(&tempAr);
3290 res = SzReadAndDecodePackedStreams(inStream, &sd, &tempBuf, 1, p->startPosAfterHeader, &tempAr, allocTemp);
3291 SzAr_Free(&tempAr, allocTemp);
3292
3293 if (res != SZ_OK)
3294 {
3295 Buf_Free(&tempBuf, allocTemp);
3296 }
3297 else
3298 {
3299 Buf_Free(&buf, allocTemp);
3300 buf.data = tempBuf.data;
3301 buf.size = tempBuf.size;
3302 sd.Data = buf.data;
3303 sd.Size = buf.size;
3304 res = ReadID(&sd, &type);
3305 }
3306 }
3307
3308 if (res == SZ_OK)
3309 {
3310 if (type == k7zIdHeader)
3311 {
3312 /*
3313 CSzData sd2;
3314 unsigned ttt;
3315 for (ttt = 0; ttt < 40000; ttt++)
3316 {
3317 SzArEx_Free(p, allocMain);
3318 sd2 = sd;
3319 res = SzReadHeader(p, &sd2, inStream, allocMain, allocTemp);
3320 if (res != SZ_OK)
3321 break;
3322 }
3323 */
3324 res = SzReadHeader(p, &sd, inStream, allocMain, allocTemp);
3325 }
3326 else
3327 res = SZ_ERROR_UNSUPPORTED;
3328 }
3329 }
3330 }
3331
3332 Buf_Free(&buf, allocTemp);
3333 return res;
3334}
3335
3336
3337static SRes SzArEx_Open(CSzArEx *p, ILookInStream *inStream,
3338 ISzAlloc *allocMain, ISzAlloc *allocTemp)
3339{
3340 SRes res = SzArEx_Open2(p, inStream, allocMain, allocTemp);
3341 if (res != SZ_OK)
3342 SzArEx_Free(p, allocMain);
3343 return res;
3344}
3345
3346
3347static SRes SzArEx_Extract(
3348 const CSzArEx *p,
3349 ILookInStream *inStream,
3350 UInt32 fileIndex,
3351 UInt32 *blockIndex,
3352 Byte **tempBuf,
3353 size_t *outBufferSize,
3354 size_t *offset,
3355 size_t *outSizeProcessed,
3356 ISzAlloc *allocMain,
3357 ISzAlloc *allocTemp)
3358{
3359 UInt32 folderIndex = p->FileToFolder[fileIndex];
3360 SRes res = SZ_OK;
3361
3362 *offset = 0;
3363 *outSizeProcessed = 0;
3364
3365 if (folderIndex == (UInt32)-1)
3366 {
3367 IAlloc_Free(allocMain, *tempBuf);
3368 *blockIndex = folderIndex;
3369 *tempBuf = NULL;
3370 *outBufferSize = 0;
3371 return SZ_OK;
3372 }
3373
3374 if (*tempBuf == NULL || *blockIndex != folderIndex)
3375 {
3376 UInt64 unpackSizeSpec = SzAr_GetFolderUnpackSize(&p->db, folderIndex);
3377 /*
3378 UInt64 unpackSizeSpec =
3379 p->UnpackPositions[p->FolderToFile[folderIndex + 1]] -
3380 p->UnpackPositions[p->FolderToFile[folderIndex]];
3381 */
3382 size_t unpackSize = (size_t)unpackSizeSpec;
3383
3384 if (unpackSize != unpackSizeSpec)
3385 return SZ_ERROR_MEM;
3386 *blockIndex = folderIndex;
3387 IAlloc_Free(allocMain, *tempBuf);
3388 *tempBuf = NULL;
3389
3390 if (res == SZ_OK)
3391 {
3392 *outBufferSize = unpackSize;
3393 if (unpackSize != 0)
3394 {
3395 *tempBuf = (Byte *)IAlloc_Alloc(allocMain, unpackSize);
3396 if (*tempBuf == NULL)
3397 res = SZ_ERROR_MEM;
3398 }
3399
3400 if (res == SZ_OK)
3401 {
3402 res = SzAr_DecodeFolder(&p->db, folderIndex,
3403 inStream, p->dataPos, *tempBuf, unpackSize, allocTemp);
3404 }
3405 }
3406 }
3407
3408 if (res == SZ_OK)
3409 {
3410 UInt64 unpackPos = p->UnpackPositions[fileIndex];
3411 *offset = (size_t)(unpackPos - p->UnpackPositions[p->FolderToFile[folderIndex]]);
3412 *outSizeProcessed = (size_t)(p->UnpackPositions[fileIndex + 1] - unpackPos);
3413 if (*offset + *outSizeProcessed > *outBufferSize)
3414 return SZ_ERROR_FAIL;
3415 if (SzBitWithVals_Check(&p->CRCs, fileIndex))
3416 if (CrcCalc(*tempBuf + *offset, *outSizeProcessed) != p->CRCs.Vals[fileIndex])
3417 res = SZ_ERROR_CRC;
3418 }
3419
3420 return res;
3421}
3422
3423
3424static size_t SzArEx_GetFileNameUtf16(const CSzArEx *p, size_t fileIndex, UInt16 *dest)
3425{
3426 size_t offs = p->FileNameOffsets[fileIndex];
3427 size_t len = p->FileNameOffsets[fileIndex + 1] - offs;
3428 if (dest != 0)
3429 {
3430 size_t i;
3431 const Byte *src = p->FileNames + offs * 2;
3432 for (i = 0; i < len; i++)
3433 dest[i] = GetUi16(src + i * 2);
3434 }
3435 return len;
3436}
3437
3438/*
3439static size_t SzArEx_GetFullNameLen(const CSzArEx *p, size_t fileIndex)
3440{
3441 size_t len;
3442 if (!p->FileNameOffsets)
3443 return 1;
3444 len = 0;
3445 for (;;)
3446 {
3447 UInt32 parent = (UInt32)(Int32)-1;
3448 len += p->FileNameOffsets[fileIndex + 1] - p->FileNameOffsets[fileIndex];
3449 if SzBitWithVals_Check(&p->Parents, fileIndex)
3450 parent = p->Parents.Vals[fileIndex];
3451 if (parent == (UInt32)(Int32)-1)
3452 return len;
3453 fileIndex = parent;
3454 }
3455}
3456
3457static UInt16 *SzArEx_GetFullNameUtf16_Back(const CSzArEx *p, size_t fileIndex, UInt16 *dest)
3458{
3459 Bool needSlash;
3460 if (!p->FileNameOffsets)
3461 {
3462 *(--dest) = 0;
3463 return dest;
3464 }
3465 needSlash = False;
3466 for (;;)
3467 {
3468 UInt32 parent = (UInt32)(Int32)-1;
3469 size_t curLen = p->FileNameOffsets[fileIndex + 1] - p->FileNameOffsets[fileIndex];
3470 SzArEx_GetFileNameUtf16(p, fileIndex, dest - curLen);
3471 if (needSlash)
3472 *(dest - 1) = '/';
3473 needSlash = True;
3474 dest -= curLen;
3475
3476 if SzBitWithVals_Check(&p->Parents, fileIndex)
3477 parent = p->Parents.Vals[fileIndex];
3478 if (parent == (UInt32)(Int32)-1)
3479 return dest;
3480 fileIndex = parent;
3481 }
3482}
3483*/
3484
3485/* 7zBuf.c -- Byte Buffer
34862013-01-21 : Igor Pavlov : Public domain */
3487
3488/*
3489#include "Precomp.h"
3490
3491#include "7zBuf.h"
3492*/
3493
3494static void Buf_Init(CBuf *p)
3495{
3496 p->data = 0;
3497 p->size = 0;
3498}
3499
3500static int Buf_Create(CBuf *p, size_t size, ISzAlloc *alloc)
3501{
3502 p->size = 0;
3503 if (size == 0)
3504 {
3505 p->data = 0;
3506 return 1;
3507 }
3508 p->data = (Byte *)alloc->Alloc(alloc, size);
3509 if (p->data != 0)
3510 {
3511 p->size = size;
3512 return 1;
3513 }
3514 return 0;
3515}
3516
3517static void Buf_Free(CBuf *p, ISzAlloc *alloc)
3518{
3519 alloc->Free(alloc, p->data);
3520 p->data = 0;
3521 p->size = 0;
3522}
3523
3524/* 7zDec.c -- Decoding from 7z folder
35252015-11-18 : Igor Pavlov : Public domain */
3526
3527/* #define _7ZIP_PPMD_SUPPPORT */
3528
3529/*
3530#include "Precomp.h"
3531
3532#include <string.h>
3533
3534#include "7z.h"
3535#include "7zCrc.h"
3536
3537#include "Bcj2.h"
3538#include "Bra.h"
3539#include "CpuArch.h"
3540#include "Delta.h"
3541#include "LzmaDec.h"
3542#include "Lzma2Dec.h"
3543#ifdef _7ZIP_PPMD_SUPPPORT
3544#include "Ppmd7.h"
3545#endif
3546*/
3547
3548#define k_Copy 0
3549#define k_Delta 3
3550#define k_LZMA2 0x21
3551#define k_LZMA 0x30101
3552#define k_BCJ 0x3030103
3553#define k_BCJ2 0x303011B
3554#define k_PPC 0x3030205
3555#define k_IA64 0x3030401
3556#define k_ARM 0x3030501
3557#define k_ARMT 0x3030701
3558#define k_SPARC 0x3030805
3559
3560
3561#ifdef _7ZIP_PPMD_SUPPPORT
3562
3563#define k_PPMD 0x30401
3564
3565typedef struct
3566{
3567 IByteIn p;
3568 const Byte *cur;
3569 const Byte *end;
3570 const Byte *begin;
3571 UInt64 processed;
3572 Bool extra;
3573 SRes res;
3574 ILookInStream *inStream;
3575} CByteInToLook;
3576
3577static Byte ReadByte(void *pp)
3578{
3579 CByteInToLook *p = (CByteInToLook *)pp;
3580 if (p->cur != p->end)
3581 return *p->cur++;
3582 if (p->res == SZ_OK)
3583 {
3584 size_t size = p->cur - p->begin;
3585 p->processed += size;
3586 p->res = p->inStream->Skip(p->inStream, size);
3587 size = (1 << 25);
3588 p->res = p->inStream->Look(p->inStream, (const void **)&p->begin, &size);
3589 p->cur = p->begin;
3590 p->end = p->begin + size;
3591 if (size != 0)
3592 return *p->cur++;;
3593 }
3594 p->extra = True;
3595 return 0;
3596}
3597
3598static SRes SzDecodePpmd(const Byte *props, unsigned propsSize, UInt64 inSize, ILookInStream *inStream,
3599 Byte *outBuffer, SizeT outSize, ISzAlloc *allocMain)
3600{
3601 CPpmd7 ppmd;
3602 CByteInToLook s;
3603 SRes res = SZ_OK;
3604
3605 s.p.Read = ReadByte;
3606 s.inStream = inStream;
3607 s.begin = s.end = s.cur = NULL;
3608 s.extra = False;
3609 s.res = SZ_OK;
3610 s.processed = 0;
3611
3612 if (propsSize != 5)
3613 return SZ_ERROR_UNSUPPORTED;
3614
3615 {
3616 unsigned order = props[0];
3617 UInt32 memSize = GetUi32(props + 1);
3618 if (order < PPMD7_MIN_ORDER ||
3619 order > PPMD7_MAX_ORDER ||
3620 memSize < PPMD7_MIN_MEM_SIZE ||
3621 memSize > PPMD7_MAX_MEM_SIZE)
3622 return SZ_ERROR_UNSUPPORTED;
3623 Ppmd7_Construct(&ppmd);
3624 if (!Ppmd7_Alloc(&ppmd, memSize, allocMain))
3625 return SZ_ERROR_MEM;
3626 Ppmd7_Init(&ppmd, order);
3627 }
3628 {
3629 CPpmd7z_RangeDec rc;
3630 Ppmd7z_RangeDec_CreateVTable(&rc);
3631 rc.Stream = &s.p;
3632 if (!Ppmd7z_RangeDec_Init(&rc))
3633 res = SZ_ERROR_DATA;
3634 else if (s.extra)
3635 res = (s.res != SZ_OK ? s.res : SZ_ERROR_DATA);
3636 else
3637 {
3638 SizeT i;
3639 for (i = 0; i < outSize; i++)
3640 {
3641 int sym = Ppmd7_DecodeSymbol(&ppmd, &rc.p);
3642 if (s.extra || sym < 0)
3643 break;
3644 outBuffer[i] = (Byte)sym;
3645 }
3646 if (i != outSize)
3647 res = (s.res != SZ_OK ? s.res : SZ_ERROR_DATA);
3648 else if (s.processed + (s.cur - s.begin) != inSize || !Ppmd7z_RangeDec_IsFinishedOK(&rc))
3649 res = SZ_ERROR_DATA;
3650 }
3651 }
3652 Ppmd7_Free(&ppmd, allocMain);
3653 return res;
3654}
3655
3656#endif
3657
3658
3659static SRes SzDecodeLzma(const Byte *props, unsigned propsSize, UInt64 inSize, ILookInStream *inStream,
3660 Byte *outBuffer, SizeT outSize, ISzAlloc *allocMain)
3661{
3662 CLzmaDec state;
3663 SRes res = SZ_OK;
3664
3665 LzmaDec_Construct(&state);
3666 RINOK(LzmaDec_AllocateProbs(&state, props, propsSize, allocMain));
3667 state.dic = outBuffer;
3668 state.dicBufSize = outSize;
3669 LzmaDec_Init(&state);
3670
3671 for (;;)
3672 {
3673 const void *inBuf = NULL;
3674 size_t lookahead = (1 << 18);
3675 if (lookahead > inSize)
3676 lookahead = (size_t)inSize;
3677 res = inStream->Look(inStream, &inBuf, &lookahead);
3678 if (res != SZ_OK)
3679 break;
3680
3681 {
3682 SizeT inProcessed = (SizeT)lookahead, dicPos = state.dicPos;
3683 ELzmaStatus status;
3684 res = LzmaDec_DecodeToDic(&state, outSize, inBuf, &inProcessed, LZMA_FINISH_END, &status);
3685 lookahead -= inProcessed;
3686 inSize -= inProcessed;
3687 if (res != SZ_OK)
3688 break;
3689
3690 if (status == LZMA_STATUS_FINISHED_WITH_MARK)
3691 {
3692 if (outSize != state.dicPos || inSize != 0)
3693 res = SZ_ERROR_DATA;
3694 break;
3695 }
3696
3697 if (outSize == state.dicPos && inSize == 0 && status == LZMA_STATUS_MAYBE_FINISHED_WITHOUT_MARK)
3698 break;
3699
3700 if (inProcessed == 0 && dicPos == state.dicPos)
3701 {
3702 res = SZ_ERROR_DATA;
3703 break;
3704 }
3705
3706 res = inStream->Skip((void *)inStream, inProcessed);
3707 if (res != SZ_OK)
3708 break;
3709 }
3710 }
3711
3712 LzmaDec_FreeProbs(&state, allocMain);
3713 return res;
3714}
3715
3716
3717#ifndef _7Z_NO_METHOD_LZMA2
3718
3719static SRes SzDecodeLzma2(const Byte *props, unsigned propsSize, UInt64 inSize, ILookInStream *inStream,
3720 Byte *outBuffer, SizeT outSize, ISzAlloc *allocMain)
3721{
3722 CLzma2Dec state;
3723 SRes res = SZ_OK;
3724
3725 Lzma2Dec_Construct(&state);
3726 if (propsSize != 1)
3727 return SZ_ERROR_DATA;
3728 RINOK(Lzma2Dec_AllocateProbs(&state, props[0], allocMain));
3729 state.decoder.dic = outBuffer;
3730 state.decoder.dicBufSize = outSize;
3731 Lzma2Dec_Init(&state);
3732
3733 for (;;)
3734 {
3735 const void *inBuf = NULL;
3736 size_t lookahead = (1 << 18);
3737 if (lookahead > inSize)
3738 lookahead = (size_t)inSize;
3739 res = inStream->Look(inStream, &inBuf, &lookahead);
3740 if (res != SZ_OK)
3741 break;
3742
3743 {
3744 SizeT inProcessed = (SizeT)lookahead, dicPos = state.decoder.dicPos;
3745 ELzmaStatus status;
3746 res = Lzma2Dec_DecodeToDic(&state, outSize, inBuf, &inProcessed, LZMA_FINISH_END, &status);
3747 lookahead -= inProcessed;
3748 inSize -= inProcessed;
3749 if (res != SZ_OK)
3750 break;
3751
3752 if (status == LZMA_STATUS_FINISHED_WITH_MARK)
3753 {
3754 if (outSize != state.decoder.dicPos || inSize != 0)
3755 res = SZ_ERROR_DATA;
3756 break;
3757 }
3758
3759 if (inProcessed == 0 && dicPos == state.decoder.dicPos)
3760 {
3761 res = SZ_ERROR_DATA;
3762 break;
3763 }
3764
3765 res = inStream->Skip((void *)inStream, inProcessed);
3766 if (res != SZ_OK)
3767 break;
3768 }
3769 }
3770
3771 Lzma2Dec_FreeProbs(&state, allocMain);
3772 return res;
3773}
3774
3775#endif
3776
3777
3778static SRes SzDecodeCopy(UInt64 inSize, ILookInStream *inStream, Byte *outBuffer)
3779{
3780 while (inSize > 0)
3781 {
3782 const void *inBuf;
3783 size_t curSize = (1 << 18);
3784 if (curSize > inSize)
3785 curSize = (size_t)inSize;
3786 RINOK(inStream->Look(inStream, &inBuf, &curSize));
3787 if (curSize == 0)
3788 return SZ_ERROR_INPUT_EOF;
3789 memcpy(outBuffer, inBuf, curSize);
3790 outBuffer += curSize;
3791 inSize -= curSize;
3792 RINOK(inStream->Skip((void *)inStream, curSize));
3793 }
3794 return SZ_OK;
3795}
3796
3797static Bool IS_MAIN_METHOD(UInt32 m)
3798{
3799 switch (m)
3800 {
3801 case k_Copy:
3802 case k_LZMA:
3803 #ifndef _7Z_NO_METHOD_LZMA2
3804 case k_LZMA2:
3805 #endif
3806 #ifdef _7ZIP_PPMD_SUPPPORT
3807 case k_PPMD:
3808 #endif
3809 return True;
3810 }
3811 return False;
3812}
3813
3814static Bool IS_SUPPORTED_CODER(const CSzCoderInfo *c)
3815{
3816 return
3817 c->NumStreams == 1
3818 /* && c->MethodID <= (UInt32)0xFFFFFFFF */
3819 && IS_MAIN_METHOD((UInt32)c->MethodID);
3820}
3821
3822#define IS_BCJ2(c) ((c)->MethodID == k_BCJ2 && (c)->NumStreams == 4)
3823
3824static SRes CheckSupportedFolder(const CSzFolder *f)
3825{
3826 if (f->NumCoders < 1 || f->NumCoders > 4)
3827 return SZ_ERROR_UNSUPPORTED;
3828 if (!IS_SUPPORTED_CODER(&f->Coders[0]))
3829 return SZ_ERROR_UNSUPPORTED;
3830 if (f->NumCoders == 1)
3831 {
3832 if (f->NumPackStreams != 1 || f->PackStreams[0] != 0 || f->NumBonds != 0)
3833 return SZ_ERROR_UNSUPPORTED;
3834 return SZ_OK;
3835 }
3836
3837
3838 #ifndef _7Z_NO_METHODS_FILTERS
3839
3840 if (f->NumCoders == 2)
3841 {
3842 const CSzCoderInfo *c = &f->Coders[1];
3843 if (
3844 /* c->MethodID > (UInt32)0xFFFFFFFF || */
3845 c->NumStreams != 1
3846 || f->NumPackStreams != 1
3847 || f->PackStreams[0] != 0
3848 || f->NumBonds != 1
3849 || f->Bonds[0].InIndex != 1
3850 || f->Bonds[0].OutIndex != 0)
3851 return SZ_ERROR_UNSUPPORTED;
3852 switch ((UInt32)c->MethodID)
3853 {
3854 case k_Delta:
3855 case k_BCJ:
3856 case k_PPC:
3857 case k_IA64:
3858 case k_SPARC:
3859 case k_ARM:
3860 case k_ARMT:
3861 break;
3862 default:
3863 return SZ_ERROR_UNSUPPORTED;
3864 }
3865 return SZ_OK;
3866 }
3867
3868 #endif
3869
3870
3871 if (f->NumCoders == 4)
3872 {
3873 if (!IS_SUPPORTED_CODER(&f->Coders[1])
3874 || !IS_SUPPORTED_CODER(&f->Coders[2])
3875 || !IS_BCJ2(&f->Coders[3]))
3876 return SZ_ERROR_UNSUPPORTED;
3877 if (f->NumPackStreams != 4
3878 || f->PackStreams[0] != 2
3879 || f->PackStreams[1] != 6
3880 || f->PackStreams[2] != 1
3881 || f->PackStreams[3] != 0
3882 || f->NumBonds != 3
3883 || f->Bonds[0].InIndex != 5 || f->Bonds[0].OutIndex != 0
3884 || f->Bonds[1].InIndex != 4 || f->Bonds[1].OutIndex != 1
3885 || f->Bonds[2].InIndex != 3 || f->Bonds[2].OutIndex != 2)
3886 return SZ_ERROR_UNSUPPORTED;
3887 return SZ_OK;
3888 }
3889
3890 return SZ_ERROR_UNSUPPORTED;
3891}
3892
3893#define CASE_BRA_CONV(isa) case k_ ## isa: isa ## _Convert(outBuffer, outSize, 0, 0); break;
3894
3895static SRes SzFolder_Decode2(const CSzFolder *folder,
3896 const Byte *propsData,
3897 const UInt64 *unpackSizes,
3898 const UInt64 *packPositions,
3899 ILookInStream *inStream, UInt64 startPos,
3900 Byte *outBuffer, SizeT outSize, ISzAlloc *allocMain,
3901 Byte *tempBuf[])
3902{
3903 UInt32 ci;
3904 SizeT tempSizes[3] = { 0, 0, 0};
3905 SizeT tempSize3 = 0;
3906 Byte *tempBuf3 = 0;
3907
3908 RINOK(CheckSupportedFolder(folder));
3909
3910 for (ci = 0; ci < folder->NumCoders; ci++)
3911 {
3912 const CSzCoderInfo *coder = &folder->Coders[ci];
3913
3914 if (IS_MAIN_METHOD((UInt32)coder->MethodID))
3915 {
3916 UInt32 si = 0;
3917 UInt64 offset;
3918 UInt64 inSize;
3919 Byte *outBufCur = outBuffer;
3920 SizeT outSizeCur = outSize;
3921 if (folder->NumCoders == 4)
3922 {
3923 UInt32 indices[] = { 3, 2, 0 };
3924 UInt64 unpackSize = unpackSizes[ci];
3925 si = indices[ci];
3926 if (ci < 2)
3927 {
3928 Byte *temp;
3929 outSizeCur = (SizeT)unpackSize;
3930 if (outSizeCur != unpackSize)
3931 return SZ_ERROR_MEM;
3932 temp = (Byte *)IAlloc_Alloc(allocMain, outSizeCur);
3933 if (!temp && outSizeCur != 0)
3934 return SZ_ERROR_MEM;
3935 outBufCur = tempBuf[1 - ci] = temp;
3936 tempSizes[1 - ci] = outSizeCur;
3937 }
3938 else if (ci == 2)
3939 {
3940 if (unpackSize > outSize) /* check it */
3941 return SZ_ERROR_PARAM;
3942 tempBuf3 = outBufCur = outBuffer + (outSize - (size_t)unpackSize);
3943 tempSize3 = outSizeCur = (SizeT)unpackSize;
3944 }
3945 else
3946 return SZ_ERROR_UNSUPPORTED;
3947 }
3948 offset = packPositions[si];
3949 inSize = packPositions[si + 1] - offset;
3950 RINOK(LookInStream_SeekTo(inStream, startPos + offset));
3951
3952 if (coder->MethodID == k_Copy)
3953 {
3954 if (inSize != outSizeCur) /* check it */
3955 return SZ_ERROR_DATA;
3956 RINOK(SzDecodeCopy(inSize, inStream, outBufCur));
3957 }
3958 else if (coder->MethodID == k_LZMA)
3959 {
3960 RINOK(SzDecodeLzma(propsData + coder->PropsOffset, coder->PropsSize, inSize, inStream, outBufCur, outSizeCur, allocMain));
3961 }
3962 #ifndef _7Z_NO_METHOD_LZMA2
3963 else if (coder->MethodID == k_LZMA2)
3964 {
3965 RINOK(SzDecodeLzma2(propsData + coder->PropsOffset, coder->PropsSize, inSize, inStream, outBufCur, outSizeCur, allocMain));
3966 }
3967 #endif
3968 #ifdef _7ZIP_PPMD_SUPPPORT
3969 else if (coder->MethodID == k_PPMD)
3970 {
3971 RINOK(SzDecodePpmd(propsData + coder->PropsOffset, coder->PropsSize, inSize, inStream, outBufCur, outSizeCur, allocMain));
3972 }
3973 #endif
3974 else
3975 return SZ_ERROR_UNSUPPORTED;
3976 }
3977 else if (coder->MethodID == k_BCJ2)
3978 {
3979 UInt64 offset = packPositions[1];
3980 UInt64 s3Size = packPositions[2] - offset;
3981
3982 if (ci != 3)
3983 return SZ_ERROR_UNSUPPORTED;
3984
3985 tempSizes[2] = (SizeT)s3Size;
3986 if (tempSizes[2] != s3Size)
3987 return SZ_ERROR_MEM;
3988 tempBuf[2] = (Byte *)IAlloc_Alloc(allocMain, tempSizes[2]);
3989 if (!tempBuf[2] && tempSizes[2] != 0)
3990 return SZ_ERROR_MEM;
3991
3992 RINOK(LookInStream_SeekTo(inStream, startPos + offset));
3993 RINOK(SzDecodeCopy(s3Size, inStream, tempBuf[2]));
3994
3995 if ((tempSizes[0] & 3) != 0 ||
3996 (tempSizes[1] & 3) != 0 ||
3997 tempSize3 + tempSizes[0] + tempSizes[1] != outSize)
3998 return SZ_ERROR_DATA;
3999
4000 {
4001 CBcj2Dec p;
4002
4003 p.bufs[0] = tempBuf3; p.lims[0] = tempBuf3 + tempSize3;
4004 p.bufs[1] = tempBuf[0]; p.lims[1] = tempBuf[0] + tempSizes[0];
4005 p.bufs[2] = tempBuf[1]; p.lims[2] = tempBuf[1] + tempSizes[1];
4006 p.bufs[3] = tempBuf[2]; p.lims[3] = tempBuf[2] + tempSizes[2];
4007
4008 p.dest = outBuffer;
4009 p.destLim = outBuffer + outSize;
4010
4011 Bcj2Dec_Init(&p);
4012 RINOK(Bcj2Dec_Decode(&p));
4013
4014 {
4015 unsigned i;
4016 for (i = 0; i < 4; i++)
4017 if (p.bufs[i] != p.lims[i])
4018 return SZ_ERROR_DATA;
4019
4020 if (!Bcj2Dec_IsFinished(&p))
4021 return SZ_ERROR_DATA;
4022
4023 if (p.dest != p.destLim
4024 || p.state != BCJ2_STREAM_MAIN)
4025 return SZ_ERROR_DATA;
4026 }
4027 }
4028 }
4029 #ifndef _7Z_NO_METHODS_FILTERS
4030 else if (ci == 1)
4031 {
4032 if (coder->MethodID == k_Delta)
4033 {
4034 if (coder->PropsSize != 1)
4035 return SZ_ERROR_UNSUPPORTED;
4036 {
4037 Byte state[DELTA_STATE_SIZE];
4038 Delta_Init(state);
4039 Delta_Decode(state, (unsigned)(propsData[coder->PropsOffset]) + 1, outBuffer, outSize);
4040 }
4041 }
4042 else
4043 {
4044 if (coder->PropsSize != 0)
4045 return SZ_ERROR_UNSUPPORTED;
4046 switch (coder->MethodID)
4047 {
4048 case k_BCJ:
4049 {
4050 UInt32 state;
4051 x86_Convert_Init(state);
4052 x86_Convert(outBuffer, outSize, 0, &state, 0);
4053 break;
4054 }
4055 CASE_BRA_CONV(PPC)
4056 CASE_BRA_CONV(IA64)
4057 CASE_BRA_CONV(SPARC)
4058 CASE_BRA_CONV(ARM)
4059 CASE_BRA_CONV(ARMT)
4060 default:
4061 return SZ_ERROR_UNSUPPORTED;
4062 }
4063 }
4064 }
4065 #endif
4066 else
4067 return SZ_ERROR_UNSUPPORTED;
4068 }
4069
4070 return SZ_OK;
4071}
4072
4073
4074static SRes SzAr_DecodeFolder(const CSzAr *p, UInt32 folderIndex,
4075 ILookInStream *inStream, UInt64 startPos,
4076 Byte *outBuffer, size_t outSize,
4077 ISzAlloc *allocMain)
4078{
4079 SRes res;
4080 CSzFolder folder;
4081 CSzData sd;
4082
4083 const Byte *data = p->CodersData + p->FoCodersOffsets[folderIndex];
4084 sd.Data = data;
4085 sd.Size = p->FoCodersOffsets[folderIndex + 1] - p->FoCodersOffsets[folderIndex];
4086
4087 res = SzGetNextFolderItem(&folder, &sd);
4088
4089 if (res != SZ_OK)
4090 return res;
4091
4092 if (sd.Size != 0
4093 || folder.UnpackStream != p->FoToMainUnpackSizeIndex[folderIndex]
4094 || outSize != SzAr_GetFolderUnpackSize(p, folderIndex))
4095 return SZ_ERROR_FAIL;
4096 {
4097 unsigned i;
4098 Byte *tempBuf[3] = { 0, 0, 0};
4099
4100 res = SzFolder_Decode2(&folder, data,
4101 &p->CoderUnpackSizes[p->FoToCoderUnpackSizes[folderIndex]],
4102 p->PackPositions + p->FoStartPackStreamIndex[folderIndex],
4103 inStream, startPos,
4104 outBuffer, (SizeT)outSize, allocMain, tempBuf);
4105
4106 for (i = 0; i < 3; i++)
4107 IAlloc_Free(allocMain, tempBuf[i]);
4108
4109 if (res == SZ_OK)
4110 if (SzBitWithVals_Check(&p->FolderCRCs, folderIndex))
4111 if (CrcCalc(outBuffer, outSize) != p->FolderCRCs.Vals[folderIndex])
4112 res = SZ_ERROR_CRC;
4113
4114 return res;
4115 }
4116}
4117
4118/* Bcj2.c -- BCJ2 Decoder (Converter for x86 code)
41192015-08-01 : Igor Pavlov : Public domain */
4120
4121/*
4122#include "Precomp.h"
4123
4124#include "Bcj2.h"
4125#include "CpuArch.h"
4126*/
4127
4128#define CProb UInt16
4129
4130#define kTopValue ((UInt32)1 << 24)
4131#define kNumModelBits 11
4132#define kBitModelTotal (1 << kNumModelBits)
4133#define kNumMoveBits 5
4134
4135#define _IF_BIT_0 ttt = *prob; bound = (p->range >> kNumModelBits) * ttt; if (p->code < bound)
4136#define _UPDATE_0 p->range = bound; *prob = (CProb)(ttt + ((kBitModelTotal - ttt) >> kNumMoveBits));
4137#define _UPDATE_1 p->range -= bound; p->code -= bound; *prob = (CProb)(ttt - (ttt >> kNumMoveBits));
4138
4139static void Bcj2Dec_Init(CBcj2Dec *p)
4140{
4141 unsigned i;
4142
4143 p->state = BCJ2_DEC_STATE_OK;
4144 p->ip = 0;
4145 p->temp[3] = 0;
4146 p->range = 0;
4147 p->code = 0;
4148 for (i = 0; i < sizeof(p->probs) / sizeof(p->probs[0]); i++)
4149 p->probs[i] = kBitModelTotal >> 1;
4150}
4151
4152static SRes Bcj2Dec_Decode(CBcj2Dec *p)
4153{
4154 if (p->range <= 5)
4155 {
4156 p->state = BCJ2_DEC_STATE_OK;
4157 for (; p->range != 5; p->range++)
4158 {
4159 if (p->range == 1 && p->code != 0)
4160 return SZ_ERROR_DATA;
4161
4162 if (p->bufs[BCJ2_STREAM_RC] == p->lims[BCJ2_STREAM_RC])
4163 {
4164 p->state = BCJ2_STREAM_RC;
4165 return SZ_OK;
4166 }
4167
4168 p->code = (p->code << 8) | *(p->bufs[BCJ2_STREAM_RC])++;
4169 }
4170
4171 if (p->code == 0xFFFFFFFF)
4172 return SZ_ERROR_DATA;
4173
4174 p->range = 0xFFFFFFFF;
4175 }
4176 else if (p->state >= BCJ2_DEC_STATE_ORIG_0)
4177 {
4178 while (p->state <= BCJ2_DEC_STATE_ORIG_3)
4179 {
4180 Byte *dest = p->dest;
4181 if (dest == p->destLim)
4182 return SZ_OK;
4183 *dest = p->temp[p->state++ - BCJ2_DEC_STATE_ORIG_0];
4184 p->dest = dest + 1;
4185 }
4186 }
4187
4188 /*
4189 if (BCJ2_IS_32BIT_STREAM(p->state))
4190 {
4191 const Byte *cur = p->bufs[p->state];
4192 if (cur == p->lims[p->state])
4193 return SZ_OK;
4194 p->bufs[p->state] = cur + 4;
4195
4196 {
4197 UInt32 val;
4198 Byte *dest;
4199 SizeT rem;
4200
4201 p->ip += 4;
4202 val = GetBe32(cur) - p->ip;
4203 dest = p->dest;
4204 rem = p->destLim - dest;
4205 if (rem < 4)
4206 {
4207 SizeT i;
4208 SetUi32(p->temp, val);
4209 for (i = 0; i < rem; i++)
4210 dest[i] = p->temp[i];
4211 p->dest = dest + rem;
4212 p->state = BCJ2_DEC_STATE_ORIG_0 + (unsigned)rem;
4213 return SZ_OK;
4214 }
4215 SetUi32(dest, val);
4216 p->temp[3] = (Byte)(val >> 24);
4217 p->dest = dest + 4;
4218 p->state = BCJ2_DEC_STATE_OK;
4219 }
4220 }
4221 */
4222
4223 for (;;)
4224 {
4225 if (BCJ2_IS_32BIT_STREAM(p->state))
4226 p->state = BCJ2_DEC_STATE_OK;
4227 else
4228 {
4229 if (p->range < kTopValue)
4230 {
4231 if (p->bufs[BCJ2_STREAM_RC] == p->lims[BCJ2_STREAM_RC])
4232 {
4233 p->state = BCJ2_STREAM_RC;
4234 return SZ_OK;
4235 }
4236 p->range <<= 8;
4237 p->code = (p->code << 8) | *(p->bufs[BCJ2_STREAM_RC])++;
4238 }
4239
4240 {
4241 const Byte *src = p->bufs[BCJ2_STREAM_MAIN];
4242 const Byte *srcLim;
4243 Byte *dest;
4244 SizeT num = p->lims[BCJ2_STREAM_MAIN] - src;
4245
4246 if (num == 0)
4247 {
4248 p->state = BCJ2_STREAM_MAIN;
4249 return SZ_OK;
4250 }
4251
4252 dest = p->dest;
4253 if (num > (SizeT)(p->destLim - dest))
4254 {
4255 num = p->destLim - dest;
4256 if (num == 0)
4257 {
4258 p->state = BCJ2_DEC_STATE_ORIG;
4259 return SZ_OK;
4260 }
4261 }
4262
4263 srcLim = src + num;
4264
4265 if (p->temp[3] == 0x0F && (src[0] & 0xF0) == 0x80)
4266 *dest = src[0];
4267 else for (;;)
4268 {
4269 Byte b = *src;
4270 *dest = b;
4271 if (b != 0x0F)
4272 {
4273 if ((b & 0xFE) == 0xE8)
4274 break;
4275 dest++;
4276 if (++src != srcLim)
4277 continue;
4278 break;
4279 }
4280 dest++;
4281 if (++src == srcLim)
4282 break;
4283 if ((*src & 0xF0) != 0x80)
4284 continue;
4285 *dest = *src;
4286 break;
4287 }
4288
4289 num = src - p->bufs[BCJ2_STREAM_MAIN];
4290
4291 if (src == srcLim)
4292 {
4293 p->temp[3] = src[-1];
4294 p->bufs[BCJ2_STREAM_MAIN] = src;
4295 p->ip += (UInt32)num;
4296 p->dest += num;
4297 p->state =
4298 p->bufs[BCJ2_STREAM_MAIN] ==
4299 p->lims[BCJ2_STREAM_MAIN] ?
4300 (unsigned)BCJ2_STREAM_MAIN :
4301 (unsigned)BCJ2_DEC_STATE_ORIG;
4302 return SZ_OK;
4303 }
4304
4305 {
4306 UInt32 bound, ttt;
4307 CProb *prob;
4308 Byte b = src[0];
4309 Byte prev = (Byte)(num == 0 ? p->temp[3] : src[-1]);
4310
4311 p->temp[3] = b;
4312 p->bufs[BCJ2_STREAM_MAIN] = src + 1;
4313 num++;
4314 p->ip += (UInt32)num;
4315 p->dest += num;
4316
4317 prob = p->probs + (unsigned)(b == 0xE8 ? 2 + (unsigned)prev : (b == 0xE9 ? 1 : 0));
4318
4319 _IF_BIT_0
4320 {
4321 _UPDATE_0
4322 continue;
4323 }
4324 _UPDATE_1
4325
4326 }
4327 }
4328 }
4329
4330 {
4331 UInt32 val;
4332 unsigned cj = (p->temp[3] == 0xE8) ? BCJ2_STREAM_CALL : BCJ2_STREAM_JUMP;
4333 const Byte *cur = p->bufs[cj];
4334 Byte *dest;
4335 SizeT rem;
4336
4337 if (cur == p->lims[cj])
4338 {
4339 p->state = cj;
4340 break;
4341 }
4342
4343 val = GetBe32(cur);
4344 p->bufs[cj] = cur + 4;
4345
4346 p->ip += 4;
4347 val -= p->ip;
4348 dest = p->dest;
4349 rem = p->destLim - dest;
4350
4351 if (rem < 4)
4352 {
4353 SizeT i;
4354 SetUi32(p->temp, val);
4355 for (i = 0; i < rem; i++)
4356 dest[i] = p->temp[i];
4357 p->dest = dest + rem;
4358 p->state = BCJ2_DEC_STATE_ORIG_0 + (unsigned)rem;
4359 break;
4360 }
4361
4362 SetUi32(dest, val);
4363 p->temp[3] = (Byte)(val >> 24);
4364 p->dest = dest + 4;
4365 }
4366 }
4367
4368 if (p->range < kTopValue && p->bufs[BCJ2_STREAM_RC] != p->lims[BCJ2_STREAM_RC])
4369 {
4370 p->range <<= 8;
4371 p->code = (p->code << 8) | *(p->bufs[BCJ2_STREAM_RC])++;
4372 }
4373
4374 return SZ_OK;
4375}
4376
4377#undef kTopValue /* reused later. --ryan. */
4378#undef kBitModelTotal /* reused later. --ryan. */
4379
4380
4381/* Bra.c -- Converters for RISC code
43822010-04-16 : Igor Pavlov : Public domain */
4383
4384/*
4385#include "Precomp.h"
4386
4387#include "Bra.h"
4388*/
4389
4390static SizeT ARM_Convert(Byte *data, SizeT size, UInt32 ip, int encoding)
4391{
4392 SizeT i;
4393 if (size < 4)
4394 return 0;
4395 size -= 4;
4396 ip += 8;
4397 for (i = 0; i <= size; i += 4)
4398 {
4399 if (data[i + 3] == 0xEB)
4400 {
4401 UInt32 dest;
4402 UInt32 src = ((UInt32)data[i + 2] << 16) | ((UInt32)data[i + 1] << 8) | (data[i + 0]);
4403 src <<= 2;
4404 if (encoding)
4405 dest = ip + (UInt32)i + src;
4406 else
4407 dest = src - (ip + (UInt32)i);
4408 dest >>= 2;
4409 data[i + 2] = (Byte)(dest >> 16);
4410 data[i + 1] = (Byte)(dest >> 8);
4411 data[i + 0] = (Byte)dest;
4412 }
4413 }
4414 return i;
4415}
4416
4417static SizeT ARMT_Convert(Byte *data, SizeT size, UInt32 ip, int encoding)
4418{
4419 SizeT i;
4420 if (size < 4)
4421 return 0;
4422 size -= 4;
4423 ip += 4;
4424 for (i = 0; i <= size; i += 2)
4425 {
4426 if ((data[i + 1] & 0xF8) == 0xF0 &&
4427 (data[i + 3] & 0xF8) == 0xF8)
4428 {
4429 UInt32 dest;
4430 UInt32 src =
4431 (((UInt32)data[i + 1] & 0x7) << 19) |
4432 ((UInt32)data[i + 0] << 11) |
4433 (((UInt32)data[i + 3] & 0x7) << 8) |
4434 (data[i + 2]);
4435
4436 src <<= 1;
4437 if (encoding)
4438 dest = ip + (UInt32)i + src;
4439 else
4440 dest = src - (ip + (UInt32)i);
4441 dest >>= 1;
4442
4443 data[i + 1] = (Byte)(0xF0 | ((dest >> 19) & 0x7));
4444 data[i + 0] = (Byte)(dest >> 11);
4445 data[i + 3] = (Byte)(0xF8 | ((dest >> 8) & 0x7));
4446 data[i + 2] = (Byte)dest;
4447 i += 2;
4448 }
4449 }
4450 return i;
4451}
4452
4453static SizeT PPC_Convert(Byte *data, SizeT size, UInt32 ip, int encoding)
4454{
4455 SizeT i;
4456 if (size < 4)
4457 return 0;
4458 size -= 4;
4459 for (i = 0; i <= size; i += 4)
4460 {
4461 if ((data[i] >> 2) == 0x12 && (data[i + 3] & 3) == 1)
4462 {
4463 UInt32 src = ((UInt32)(data[i + 0] & 3) << 24) |
4464 ((UInt32)data[i + 1] << 16) |
4465 ((UInt32)data[i + 2] << 8) |
4466 ((UInt32)data[i + 3] & (~3));
4467
4468 UInt32 dest;
4469 if (encoding)
4470 dest = ip + (UInt32)i + src;
4471 else
4472 dest = src - (ip + (UInt32)i);
4473 data[i + 0] = (Byte)(0x48 | ((dest >> 24) & 0x3));
4474 data[i + 1] = (Byte)(dest >> 16);
4475 data[i + 2] = (Byte)(dest >> 8);
4476 data[i + 3] &= 0x3;
4477 data[i + 3] |= dest;
4478 }
4479 }
4480 return i;
4481}
4482
4483static SizeT SPARC_Convert(Byte *data, SizeT size, UInt32 ip, int encoding)
4484{
4485 UInt32 i;
4486 if (size < 4)
4487 return 0;
4488 size -= 4;
4489 for (i = 0; i <= size; i += 4)
4490 {
4491 if ((data[i] == 0x40 && (data[i + 1] & 0xC0) == 0x00) ||
4492 (data[i] == 0x7F && (data[i + 1] & 0xC0) == 0xC0))
4493 {
4494 UInt32 src =
4495 ((UInt32)data[i + 0] << 24) |
4496 ((UInt32)data[i + 1] << 16) |
4497 ((UInt32)data[i + 2] << 8) |
4498 ((UInt32)data[i + 3]);
4499 UInt32 dest;
4500
4501 src <<= 2;
4502 if (encoding)
4503 dest = ip + i + src;
4504 else
4505 dest = src - (ip + i);
4506 dest >>= 2;
4507
4508 dest = (((0 - ((dest >> 22) & 1)) << 22) & 0x3FFFFFFF) | (dest & 0x3FFFFF) | 0x40000000;
4509
4510 data[i + 0] = (Byte)(dest >> 24);
4511 data[i + 1] = (Byte)(dest >> 16);
4512 data[i + 2] = (Byte)(dest >> 8);
4513 data[i + 3] = (Byte)dest;
4514 }
4515 }
4516 return i;
4517}
4518
4519/* Bra86.c -- Converter for x86 code (BCJ)
45202013-11-12 : Igor Pavlov : Public domain */
4521
4522/*
4523#include "Precomp.h"
4524
4525#include "Bra.h"
4526*/
4527
4528#define Test86MSByte(b) ((((b) + 1) & 0xFE) == 0)
4529
4530static SizeT x86_Convert(Byte *data, SizeT size, UInt32 ip, UInt32 *state, int encoding)
4531{
4532 SizeT pos = 0;
4533 UInt32 mask = *state & 7;
4534 if (size < 5)
4535 return 0;
4536 size -= 4;
4537 ip += 5;
4538
4539 for (;;)
4540 {
4541 Byte *p = data + pos;
4542 const Byte *limit = data + size;
4543 for (; p < limit; p++)
4544 if ((*p & 0xFE) == 0xE8)
4545 break;
4546
4547 {
4548 SizeT d = (SizeT)(p - data - pos);
4549 pos = (SizeT)(p - data);
4550 if (p >= limit)
4551 {
4552 *state = (d > 2 ? 0 : mask >> (unsigned)d);
4553 return pos;
4554 }
4555 if (d > 2)
4556 mask = 0;
4557 else
4558 {
4559 mask >>= (unsigned)d;
4560 if (mask != 0 && (mask > 4 || mask == 3 || Test86MSByte(p[(mask >> 1) + 1])))
4561 {
4562 mask = (mask >> 1) | 4;
4563 pos++;
4564 continue;
4565 }
4566 }
4567 }
4568
4569 if (Test86MSByte(p[4]))
4570 {
4571 UInt32 v = ((UInt32)p[4] << 24) | ((UInt32)p[3] << 16) | ((UInt32)p[2] << 8) | ((UInt32)p[1]);
4572 UInt32 cur = ip + (UInt32)pos;
4573 pos += 5;
4574 if (encoding)
4575 v += cur;
4576 else
4577 v -= cur;
4578 if (mask != 0)
4579 {
4580 unsigned sh = (mask & 6) << 2;
4581 if (Test86MSByte((Byte)(v >> sh)))
4582 {
4583 v ^= (((UInt32)0x100 << sh) - 1);
4584 if (encoding)
4585 v += cur;
4586 else
4587 v -= cur;
4588 }
4589 mask = 0;
4590 }
4591 p[1] = (Byte)v;
4592 p[2] = (Byte)(v >> 8);
4593 p[3] = (Byte)(v >> 16);
4594 p[4] = (Byte)(0 - ((v >> 24) & 1));
4595 }
4596 else
4597 {
4598 mask = (mask >> 1) | 4;
4599 pos++;
4600 }
4601 }
4602}
4603
4604
4605/* BraIA64.c -- Converter for IA-64 code
46062013-11-12 : Igor Pavlov : Public domain */
4607
4608/*
4609#include "Precomp.h"
4610
4611#include "Bra.h"
4612*/
4613static const Byte kBranchTable[32] =
4614{
4615 0, 0, 0, 0, 0, 0, 0, 0,
4616 0, 0, 0, 0, 0, 0, 0, 0,
4617 4, 4, 6, 6, 0, 0, 7, 7,
4618 4, 4, 0, 0, 4, 4, 0, 0
4619};
4620
4621static SizeT IA64_Convert(Byte *data, SizeT size, UInt32 ip, int encoding)
4622{
4623 SizeT i;
4624 if (size < 16)
4625 return 0;
4626 size -= 16;
4627 for (i = 0; i <= size; i += 16)
4628 {
4629 UInt32 instrTemplate = data[i] & 0x1F;
4630 UInt32 mask = kBranchTable[instrTemplate];
4631 UInt32 bitPos = 5;
4632 int slot;
4633 for (slot = 0; slot < 3; slot++, bitPos += 41)
4634 {
4635 UInt32 bytePos, bitRes;
4636 UInt64 instruction, instNorm;
4637 int j;
4638 if (((mask >> slot) & 1) == 0)
4639 continue;
4640 bytePos = (bitPos >> 3);
4641 bitRes = bitPos & 0x7;
4642 instruction = 0;
4643 for (j = 0; j < 6; j++)
4644 instruction += (UInt64)data[i + j + bytePos] << (8 * j);
4645
4646 instNorm = instruction >> bitRes;
4647 if (((instNorm >> 37) & 0xF) == 0x5 && ((instNorm >> 9) & 0x7) == 0)
4648 {
4649 UInt32 src = (UInt32)((instNorm >> 13) & 0xFFFFF);
4650 UInt32 dest;
4651 src |= ((UInt32)(instNorm >> 36) & 1) << 20;
4652
4653 src <<= 4;
4654
4655 if (encoding)
4656 dest = ip + (UInt32)i + src;
4657 else
4658 dest = src - (ip + (UInt32)i);
4659
4660 dest >>= 4;
4661
4662 instNorm &= ~((UInt64)(0x8FFFFF) << 13);
4663 instNorm |= ((UInt64)(dest & 0xFFFFF) << 13);
4664 instNorm |= ((UInt64)(dest & 0x100000) << (36 - 20));
4665
4666 instruction &= (1 << bitRes) - 1;
4667 instruction |= (instNorm << bitRes);
4668 for (j = 0; j < 6; j++)
4669 data[i + j + bytePos] = (Byte)(instruction >> (8 * j));
4670 }
4671 }
4672 }
4673 return i;
4674}
4675
4676
4677/* Delta.c -- Delta converter
46782009-05-26 : Igor Pavlov : Public domain */
4679
4680/*
4681#include "Precomp.h"
4682
4683#include "Delta.h"
4684*/
4685
4686static void Delta_Init(Byte *state)
4687{
4688 unsigned i;
4689 for (i = 0; i < DELTA_STATE_SIZE; i++)
4690 state[i] = 0;
4691}
4692
4693static void MyMemCpy(Byte *dest, const Byte *src, unsigned size)
4694{
4695 unsigned i;
4696 for (i = 0; i < size; i++)
4697 dest[i] = src[i];
4698}
4699
4700static void Delta_Decode(Byte *state, unsigned delta, Byte *data, SizeT size)
4701{
4702 Byte buf[DELTA_STATE_SIZE];
4703 unsigned j = 0;
4704 MyMemCpy(buf, state, delta);
4705 {
4706 SizeT i;
4707 for (i = 0; i < size;)
4708 {
4709 for (j = 0; j < delta && i < size; i++, j++)
4710 {
4711 buf[j] = data[i] = (Byte)(buf[j] + data[i]);
4712 }
4713 }
4714 }
4715 if (j == delta)
4716 j = 0;
4717 MyMemCpy(state, buf + j, delta - j);
4718 MyMemCpy(state + delta - j, buf, j);
4719}
4720
4721/* LzmaDec.c -- LZMA Decoder
47222016-05-16 : Igor Pavlov : Public domain */
4723
4724/*
4725#include "Precomp.h"
4726
4727#include "LzmaDec.h"
4728
4729#include <string.h>
4730*/
4731
4732#define kNumTopBits 24
4733#define kTopValue ((UInt32)1 << kNumTopBits)
4734
4735#define kNumBitModelTotalBits 11
4736#define kBitModelTotal (1 << kNumBitModelTotalBits)
4737#define kNumMoveBits 5
4738
4739#define RC_INIT_SIZE 5
4740
4741#define NORMALIZE if (range < kTopValue) { range <<= 8; code = (code << 8) | (*buf++); }
4742
4743#define IF_BIT_0(p) ttt = *(p); NORMALIZE; bound = (range >> kNumBitModelTotalBits) * ttt; if (code < bound)
4744#define UPDATE_0(p) range = bound; *(p) = (CLzmaProb)(ttt + ((kBitModelTotal - ttt) >> kNumMoveBits));
4745#define UPDATE_1(p) range -= bound; code -= bound; *(p) = (CLzmaProb)(ttt - (ttt >> kNumMoveBits));
4746#define GET_BIT2(p, i, A0, A1) IF_BIT_0(p) \
4747 { UPDATE_0(p); i = (i + i); A0; } else \
4748 { UPDATE_1(p); i = (i + i) + 1; A1; }
4749#define GET_BIT(p, i) GET_BIT2(p, i, ; , ;)
4750
4751#define TREE_GET_BIT(probs, i) { GET_BIT((probs + i), i); }
4752#define TREE_DECODE(probs, limit, i) \
4753 { i = 1; do { TREE_GET_BIT(probs, i); } while (i < limit); i -= limit; }
4754
4755/* #define _LZMA_SIZE_OPT */
4756
4757#ifdef _LZMA_SIZE_OPT
4758#define TREE_6_DECODE(probs, i) TREE_DECODE(probs, (1 << 6), i)
4759#else
4760#define TREE_6_DECODE(probs, i) \
4761 { i = 1; \
4762 TREE_GET_BIT(probs, i); \
4763 TREE_GET_BIT(probs, i); \
4764 TREE_GET_BIT(probs, i); \
4765 TREE_GET_BIT(probs, i); \
4766 TREE_GET_BIT(probs, i); \
4767 TREE_GET_BIT(probs, i); \
4768 i -= 0x40; }
4769#endif
4770
4771#define NORMAL_LITER_DEC GET_BIT(prob + symbol, symbol)
4772#define MATCHED_LITER_DEC \
4773 matchByte <<= 1; \
4774 bit = (matchByte & offs); \
4775 probLit = prob + offs + bit + symbol; \
4776 GET_BIT2(probLit, symbol, offs &= ~bit, offs &= bit)
4777
4778#define NORMALIZE_CHECK if (range < kTopValue) { if (buf >= bufLimit) return DUMMY_ERROR; range <<= 8; code = (code << 8) | (*buf++); }
4779
4780#define IF_BIT_0_CHECK(p) ttt = *(p); NORMALIZE_CHECK; bound = (range >> kNumBitModelTotalBits) * ttt; if (code < bound)
4781#define UPDATE_0_CHECK range = bound;
4782#define UPDATE_1_CHECK range -= bound; code -= bound;
4783#define GET_BIT2_CHECK(p, i, A0, A1) IF_BIT_0_CHECK(p) \
4784 { UPDATE_0_CHECK; i = (i + i); A0; } else \
4785 { UPDATE_1_CHECK; i = (i + i) + 1; A1; }
4786#define GET_BIT_CHECK(p, i) GET_BIT2_CHECK(p, i, ; , ;)
4787#define TREE_DECODE_CHECK(probs, limit, i) \
4788 { i = 1; do { GET_BIT_CHECK(probs + i, i) } while (i < limit); i -= limit; }
4789
4790
4791#define kNumPosBitsMax 4
4792#define kNumPosStatesMax (1 << kNumPosBitsMax)
4793
4794#define kLenNumLowBits 3
4795#define kLenNumLowSymbols (1 << kLenNumLowBits)
4796#define kLenNumMidBits 3
4797#define kLenNumMidSymbols (1 << kLenNumMidBits)
4798#define kLenNumHighBits 8
4799#define kLenNumHighSymbols (1 << kLenNumHighBits)
4800
4801#define LenChoice 0
4802#define LenChoice2 (LenChoice + 1)
4803#define LenLow (LenChoice2 + 1)
4804#define LenMid (LenLow + (kNumPosStatesMax << kLenNumLowBits))
4805#define LenHigh (LenMid + (kNumPosStatesMax << kLenNumMidBits))
4806#define kNumLenProbs (LenHigh + kLenNumHighSymbols)
4807
4808
4809#define kNumStates 12
4810#define kNumLitStates 7
4811
4812#define kStartPosModelIndex 4
4813#define kEndPosModelIndex 14
4814#define kNumFullDistances (1 << (kEndPosModelIndex >> 1))
4815
4816#define kNumPosSlotBits 6
4817#define kNumLenToPosStates 4
4818
4819#define kNumAlignBits 4
4820#define kAlignTableSize (1 << kNumAlignBits)
4821
4822#define kMatchMinLen 2
4823#define kMatchSpecLenStart (kMatchMinLen + kLenNumLowSymbols + kLenNumMidSymbols + kLenNumHighSymbols)
4824
4825#define IsMatch 0
4826#define IsRep (IsMatch + (kNumStates << kNumPosBitsMax))
4827#define IsRepG0 (IsRep + kNumStates)
4828#define IsRepG1 (IsRepG0 + kNumStates)
4829#define IsRepG2 (IsRepG1 + kNumStates)
4830#define IsRep0Long (IsRepG2 + kNumStates)
4831#define PosSlot (IsRep0Long + (kNumStates << kNumPosBitsMax))
4832#define SpecPos (PosSlot + (kNumLenToPosStates << kNumPosSlotBits))
4833#define Align (SpecPos + kNumFullDistances - kEndPosModelIndex)
4834#define LenCoder (Align + kAlignTableSize)
4835#define RepLenCoder (LenCoder + kNumLenProbs)
4836#define Literal (RepLenCoder + kNumLenProbs)
4837
4838#define LZMA_BASE_SIZE 1846
4839#define LZMA_LIT_SIZE 0x300
4840
4841#if Literal != LZMA_BASE_SIZE
4842StopCompilingDueBUG
4843#endif
4844
4845#define LzmaProps_GetNumProbs(p) (Literal + ((UInt32)LZMA_LIT_SIZE << ((p)->lc + (p)->lp)))
4846
4847#define LZMA_DIC_MIN (1 << 12)
4848
4849/* First LZMA-symbol is always decoded.
4850And it decodes new LZMA-symbols while (buf < bufLimit), but "buf" is without last normalization
4851Out:
4852 Result:
4853 SZ_OK - OK
4854 SZ_ERROR_DATA - Error
4855 p->remainLen:
4856 < kMatchSpecLenStart : normal remain
4857 = kMatchSpecLenStart : finished
4858 = kMatchSpecLenStart + 1 : Flush marker (unused now)
4859 = kMatchSpecLenStart + 2 : State Init Marker (unused now)
4860*/
4861
4862static int MY_FAST_CALL LzmaDec_DecodeReal(CLzmaDec *p, SizeT limit, const Byte *bufLimit)
4863{
4864 CLzmaProb *probs = p->probs;
4865
4866 unsigned state = p->state;
4867 UInt32 rep0 = p->reps[0], rep1 = p->reps[1], rep2 = p->reps[2], rep3 = p->reps[3];
4868 unsigned pbMask = ((unsigned)1 << (p->prop.pb)) - 1;
4869 unsigned lpMask = ((unsigned)1 << (p->prop.lp)) - 1;
4870 unsigned lc = p->prop.lc;
4871
4872 Byte *dic = p->dic;
4873 SizeT dicBufSize = p->dicBufSize;
4874 SizeT dicPos = p->dicPos;
4875
4876 UInt32 processedPos = p->processedPos;
4877 UInt32 checkDicSize = p->checkDicSize;
4878 unsigned len = 0;
4879
4880 const Byte *buf = p->buf;
4881 UInt32 range = p->range;
4882 UInt32 code = p->code;
4883
4884 do
4885 {
4886 CLzmaProb *prob;
4887 UInt32 bound;
4888 unsigned ttt;
4889 unsigned posState = processedPos & pbMask;
4890
4891 prob = probs + IsMatch + (state << kNumPosBitsMax) + posState;
4892 IF_BIT_0(prob)
4893 {
4894 unsigned symbol;
4895 UPDATE_0(prob);
4896 prob = probs + Literal;
4897 if (processedPos != 0 || checkDicSize != 0)
4898 prob += ((UInt32)LZMA_LIT_SIZE * (((processedPos & lpMask) << lc) +
4899 (dic[(dicPos == 0 ? dicBufSize : dicPos) - 1] >> (8 - lc))));
4900 processedPos++;
4901
4902 if (state < kNumLitStates)
4903 {
4904 state -= (state < 4) ? state : 3;
4905 symbol = 1;
4906 #ifdef _LZMA_SIZE_OPT
4907 do { NORMAL_LITER_DEC } while (symbol < 0x100);
4908 #else
4909 NORMAL_LITER_DEC
4910 NORMAL_LITER_DEC
4911 NORMAL_LITER_DEC
4912 NORMAL_LITER_DEC
4913 NORMAL_LITER_DEC
4914 NORMAL_LITER_DEC
4915 NORMAL_LITER_DEC
4916 NORMAL_LITER_DEC
4917 #endif
4918 }
4919 else
4920 {
4921 unsigned matchByte = dic[dicPos - rep0 + (dicPos < rep0 ? dicBufSize : 0)];
4922 unsigned offs = 0x100;
4923 state -= (state < 10) ? 3 : 6;
4924 symbol = 1;
4925 #ifdef _LZMA_SIZE_OPT
4926 do
4927 {
4928 unsigned bit;
4929 CLzmaProb *probLit;
4930 MATCHED_LITER_DEC
4931 }
4932 while (symbol < 0x100);
4933 #else
4934 {
4935 unsigned bit;
4936 CLzmaProb *probLit;
4937 MATCHED_LITER_DEC
4938 MATCHED_LITER_DEC
4939 MATCHED_LITER_DEC
4940 MATCHED_LITER_DEC
4941 MATCHED_LITER_DEC
4942 MATCHED_LITER_DEC
4943 MATCHED_LITER_DEC
4944 MATCHED_LITER_DEC
4945 }
4946 #endif
4947 }
4948
4949 dic[dicPos++] = (Byte)symbol;
4950 continue;
4951 }
4952
4953 {
4954 UPDATE_1(prob);
4955 prob = probs + IsRep + state;
4956 IF_BIT_0(prob)
4957 {
4958 UPDATE_0(prob);
4959 state += kNumStates;
4960 prob = probs + LenCoder;
4961 }
4962 else
4963 {
4964 UPDATE_1(prob);
4965 if (checkDicSize == 0 && processedPos == 0)
4966 return SZ_ERROR_DATA;
4967 prob = probs + IsRepG0 + state;
4968 IF_BIT_0(prob)
4969 {
4970 UPDATE_0(prob);
4971 prob = probs + IsRep0Long + (state << kNumPosBitsMax) + posState;
4972 IF_BIT_0(prob)
4973 {
4974 UPDATE_0(prob);
4975 dic[dicPos] = dic[dicPos - rep0 + (dicPos < rep0 ? dicBufSize : 0)];
4976 dicPos++;
4977 processedPos++;
4978 state = state < kNumLitStates ? 9 : 11;
4979 continue;
4980 }
4981 UPDATE_1(prob);
4982 }
4983 else
4984 {
4985 UInt32 distance;
4986 UPDATE_1(prob);
4987 prob = probs + IsRepG1 + state;
4988 IF_BIT_0(prob)
4989 {
4990 UPDATE_0(prob);
4991 distance = rep1;
4992 }
4993 else
4994 {
4995 UPDATE_1(prob);
4996 prob = probs + IsRepG2 + state;
4997 IF_BIT_0(prob)
4998 {
4999 UPDATE_0(prob);
5000 distance = rep2;
5001 }
5002 else
5003 {
5004 UPDATE_1(prob);
5005 distance = rep3;
5006 rep3 = rep2;
5007 }
5008 rep2 = rep1;
5009 }
5010 rep1 = rep0;
5011 rep0 = distance;
5012 }
5013 state = state < kNumLitStates ? 8 : 11;
5014 prob = probs + RepLenCoder;
5015 }
5016
5017 #ifdef _LZMA_SIZE_OPT
5018 {
5019 unsigned lim, offset;
5020 CLzmaProb *probLen = prob + LenChoice;
5021 IF_BIT_0(probLen)
5022 {
5023 UPDATE_0(probLen);
5024 probLen = prob + LenLow + (posState << kLenNumLowBits);
5025 offset = 0;
5026 lim = (1 << kLenNumLowBits);
5027 }
5028 else
5029 {
5030 UPDATE_1(probLen);
5031 probLen = prob + LenChoice2;
5032 IF_BIT_0(probLen)
5033 {
5034 UPDATE_0(probLen);
5035 probLen = prob + LenMid + (posState << kLenNumMidBits);
5036 offset = kLenNumLowSymbols;
5037 lim = (1 << kLenNumMidBits);
5038 }
5039 else
5040 {
5041 UPDATE_1(probLen);
5042 probLen = prob + LenHigh;
5043 offset = kLenNumLowSymbols + kLenNumMidSymbols;
5044 lim = (1 << kLenNumHighBits);
5045 }
5046 }
5047 TREE_DECODE(probLen, lim, len);
5048 len += offset;
5049 }
5050 #else
5051 {
5052 CLzmaProb *probLen = prob + LenChoice;
5053 IF_BIT_0(probLen)
5054 {
5055 UPDATE_0(probLen);
5056 probLen = prob + LenLow + (posState << kLenNumLowBits);
5057 len = 1;
5058 TREE_GET_BIT(probLen, len);
5059 TREE_GET_BIT(probLen, len);
5060 TREE_GET_BIT(probLen, len);
5061 len -= 8;
5062 }
5063 else
5064 {
5065 UPDATE_1(probLen);
5066 probLen = prob + LenChoice2;
5067 IF_BIT_0(probLen)
5068 {
5069 UPDATE_0(probLen);
5070 probLen = prob + LenMid + (posState << kLenNumMidBits);
5071 len = 1;
5072 TREE_GET_BIT(probLen, len);
5073 TREE_GET_BIT(probLen, len);
5074 TREE_GET_BIT(probLen, len);
5075 }
5076 else
5077 {
5078 UPDATE_1(probLen);
5079 probLen = prob + LenHigh;
5080 TREE_DECODE(probLen, (1 << kLenNumHighBits), len);
5081 len += kLenNumLowSymbols + kLenNumMidSymbols;
5082 }
5083 }
5084 }
5085 #endif
5086
5087 if (state >= kNumStates)
5088 {
5089 UInt32 distance;
5090 prob = probs + PosSlot +
5091 ((len < kNumLenToPosStates ? len : kNumLenToPosStates - 1) << kNumPosSlotBits);
5092 TREE_6_DECODE(prob, distance);
5093 if (distance >= kStartPosModelIndex)
5094 {
5095 unsigned posSlot = (unsigned)distance;
5096 unsigned numDirectBits = (unsigned)(((distance >> 1) - 1));
5097 distance = (2 | (distance & 1));
5098 if (posSlot < kEndPosModelIndex)
5099 {
5100 distance <<= numDirectBits;
5101 prob = probs + SpecPos + distance - posSlot - 1;
5102 {
5103 UInt32 mask = 1;
5104 unsigned i = 1;
5105 do
5106 {
5107 GET_BIT2(prob + i, i, ; , distance |= mask);
5108 mask <<= 1;
5109 }
5110 while (--numDirectBits != 0);
5111 }
5112 }
5113 else
5114 {
5115 numDirectBits -= kNumAlignBits;
5116 do
5117 {
5118 NORMALIZE
5119 range >>= 1;
5120
5121 {
5122 UInt32 t;
5123 code -= range;
5124 t = (0 - ((UInt32)code >> 31)); /* (UInt32)((Int32)code >> 31) */
5125 distance = (distance << 1) + (t + 1);
5126 code += range & t;
5127 }
5128 /*
5129 distance <<= 1;
5130 if (code >= range)
5131 {
5132 code -= range;
5133 distance |= 1;
5134 }
5135 */
5136 }
5137 while (--numDirectBits != 0);
5138 prob = probs + Align;
5139 distance <<= kNumAlignBits;
5140 {
5141 unsigned i = 1;
5142 GET_BIT2(prob + i, i, ; , distance |= 1);
5143 GET_BIT2(prob + i, i, ; , distance |= 2);
5144 GET_BIT2(prob + i, i, ; , distance |= 4);
5145 GET_BIT2(prob + i, i, ; , distance |= 8);
5146 }
5147 if (distance == (UInt32)0xFFFFFFFF)
5148 {
5149 len += kMatchSpecLenStart;
5150 state -= kNumStates;
5151 break;
5152 }
5153 }
5154 }
5155
5156 rep3 = rep2;
5157 rep2 = rep1;
5158 rep1 = rep0;
5159 rep0 = distance + 1;
5160 if (checkDicSize == 0)
5161 {
5162 if (distance >= processedPos)
5163 {
5164 p->dicPos = dicPos;
5165 return SZ_ERROR_DATA;
5166 }
5167 }
5168 else if (distance >= checkDicSize)
5169 {
5170 p->dicPos = dicPos;
5171 return SZ_ERROR_DATA;
5172 }
5173 state = (state < kNumStates + kNumLitStates) ? kNumLitStates : kNumLitStates + 3;
5174 }
5175
5176 len += kMatchMinLen;
5177
5178 {
5179 SizeT rem;
5180 unsigned curLen;
5181 SizeT pos;
5182
5183 if ((rem = limit - dicPos) == 0)
5184 {
5185 p->dicPos = dicPos;
5186 return SZ_ERROR_DATA;
5187 }
5188
5189 curLen = ((rem < len) ? (unsigned)rem : len);
5190 pos = dicPos - rep0 + (dicPos < rep0 ? dicBufSize : 0);
5191
5192 processedPos += curLen;
5193
5194 len -= curLen;
5195 if (curLen <= dicBufSize - pos)
5196 {
5197 Byte *dest = dic + dicPos;
5198 ptrdiff_t src = (ptrdiff_t)pos - (ptrdiff_t)dicPos;
5199 const Byte *lim = dest + curLen;
5200 dicPos += curLen;
5201 do
5202 *(dest) = (Byte)*(dest + src);
5203 while (++dest != lim);
5204 }
5205 else
5206 {
5207 do
5208 {
5209 dic[dicPos++] = dic[pos];
5210 if (++pos == dicBufSize)
5211 pos = 0;
5212 }
5213 while (--curLen != 0);
5214 }
5215 }
5216 }
5217 }
5218 while (dicPos < limit && buf < bufLimit);
5219
5220 NORMALIZE;
5221
5222 p->buf = buf;
5223 p->range = range;
5224 p->code = code;
5225 p->remainLen = len;
5226 p->dicPos = dicPos;
5227 p->processedPos = processedPos;
5228 p->reps[0] = rep0;
5229 p->reps[1] = rep1;
5230 p->reps[2] = rep2;
5231 p->reps[3] = rep3;
5232 p->state = state;
5233
5234 return SZ_OK;
5235}
5236
5237static void MY_FAST_CALL LzmaDec_WriteRem(CLzmaDec *p, SizeT limit)
5238{
5239 if (p->remainLen != 0 && p->remainLen < kMatchSpecLenStart)
5240 {
5241 Byte *dic = p->dic;
5242 SizeT dicPos = p->dicPos;
5243 SizeT dicBufSize = p->dicBufSize;
5244 unsigned len = p->remainLen;
5245 SizeT rep0 = p->reps[0]; /* we use SizeT to avoid the BUG of VC14 for AMD64 */
5246 SizeT rem = limit - dicPos;
5247 if (rem < len)
5248 len = (unsigned)(rem);
5249
5250 if (p->checkDicSize == 0 && p->prop.dicSize - p->processedPos <= len)
5251 p->checkDicSize = p->prop.dicSize;
5252
5253 p->processedPos += len;
5254 p->remainLen -= len;
5255 while (len != 0)
5256 {
5257 len--;
5258 dic[dicPos] = dic[dicPos - rep0 + (dicPos < rep0 ? dicBufSize : 0)];
5259 dicPos++;
5260 }
5261 p->dicPos = dicPos;
5262 }
5263}
5264
5265static int MY_FAST_CALL LzmaDec_DecodeReal2(CLzmaDec *p, SizeT limit, const Byte *bufLimit)
5266{
5267 do
5268 {
5269 SizeT limit2 = limit;
5270 if (p->checkDicSize == 0)
5271 {
5272 UInt32 rem = p->prop.dicSize - p->processedPos;
5273 if (limit - p->dicPos > rem)
5274 limit2 = p->dicPos + rem;
5275 }
5276
5277 RINOK(LzmaDec_DecodeReal(p, limit2, bufLimit));
5278
5279 if (p->checkDicSize == 0 && p->processedPos >= p->prop.dicSize)
5280 p->checkDicSize = p->prop.dicSize;
5281
5282 LzmaDec_WriteRem(p, limit);
5283 }
5284 while (p->dicPos < limit && p->buf < bufLimit && p->remainLen < kMatchSpecLenStart);
5285
5286 if (p->remainLen > kMatchSpecLenStart)
5287 p->remainLen = kMatchSpecLenStart;
5288
5289 return 0;
5290}
5291
5292typedef enum
5293{
5294 DUMMY_ERROR, /* unexpected end of input stream */
5295 DUMMY_LIT,
5296 DUMMY_MATCH,
5297 DUMMY_REP
5298} ELzmaDummy;
5299
5300static ELzmaDummy LzmaDec_TryDummy(const CLzmaDec *p, const Byte *buf, SizeT inSize)
5301{
5302 UInt32 range = p->range;
5303 UInt32 code = p->code;
5304 const Byte *bufLimit = buf + inSize;
5305 const CLzmaProb *probs = p->probs;
5306 unsigned state = p->state;
5307 ELzmaDummy res;
5308
5309 {
5310 const CLzmaProb *prob;
5311 UInt32 bound;
5312 unsigned ttt;
5313 unsigned posState = (p->processedPos) & ((1 << p->prop.pb) - 1);
5314
5315 prob = probs + IsMatch + (state << kNumPosBitsMax) + posState;
5316 IF_BIT_0_CHECK(prob)
5317 {
5318 UPDATE_0_CHECK
5319
5320 /* if (bufLimit - buf >= 7) return DUMMY_LIT; */
5321
5322 prob = probs + Literal;
5323 if (p->checkDicSize != 0 || p->processedPos != 0)
5324 prob += ((UInt32)LZMA_LIT_SIZE *
5325 ((((p->processedPos) & ((1 << (p->prop.lp)) - 1)) << p->prop.lc) +
5326 (p->dic[(p->dicPos == 0 ? p->dicBufSize : p->dicPos) - 1] >> (8 - p->prop.lc))));
5327
5328 if (state < kNumLitStates)
5329 {
5330 unsigned symbol = 1;
5331 do { GET_BIT_CHECK(prob + symbol, symbol) } while (symbol < 0x100);
5332 }
5333 else
5334 {
5335 unsigned matchByte = p->dic[p->dicPos - p->reps[0] +
5336 (p->dicPos < p->reps[0] ? p->dicBufSize : 0)];
5337 unsigned offs = 0x100;
5338 unsigned symbol = 1;
5339 do
5340 {
5341 unsigned bit;
5342 const CLzmaProb *probLit;
5343 matchByte <<= 1;
5344 bit = (matchByte & offs);
5345 probLit = prob + offs + bit + symbol;
5346 GET_BIT2_CHECK(probLit, symbol, offs &= ~bit, offs &= bit)
5347 }
5348 while (symbol < 0x100);
5349 }
5350 res = DUMMY_LIT;
5351 }
5352 else
5353 {
5354 unsigned len;
5355 UPDATE_1_CHECK;
5356
5357 prob = probs + IsRep + state;
5358 IF_BIT_0_CHECK(prob)
5359 {
5360 UPDATE_0_CHECK;
5361 state = 0;
5362 prob = probs + LenCoder;
5363 res = DUMMY_MATCH;
5364 }
5365 else
5366 {
5367 UPDATE_1_CHECK;
5368 res = DUMMY_REP;
5369 prob = probs + IsRepG0 + state;
5370 IF_BIT_0_CHECK(prob)
5371 {
5372 UPDATE_0_CHECK;
5373 prob = probs + IsRep0Long + (state << kNumPosBitsMax) + posState;
5374 IF_BIT_0_CHECK(prob)
5375 {
5376 UPDATE_0_CHECK;
5377 NORMALIZE_CHECK;
5378 return DUMMY_REP;
5379 }
5380 else
5381 {
5382 UPDATE_1_CHECK;
5383 }
5384 }
5385 else
5386 {
5387 UPDATE_1_CHECK;
5388 prob = probs + IsRepG1 + state;
5389 IF_BIT_0_CHECK(prob)
5390 {
5391 UPDATE_0_CHECK;
5392 }
5393 else
5394 {
5395 UPDATE_1_CHECK;
5396 prob = probs + IsRepG2 + state;
5397 IF_BIT_0_CHECK(prob)
5398 {
5399 UPDATE_0_CHECK;
5400 }
5401 else
5402 {
5403 UPDATE_1_CHECK;
5404 }
5405 }
5406 }
5407 state = kNumStates;
5408 prob = probs + RepLenCoder;
5409 }
5410 {
5411 unsigned limit, offset;
5412 const CLzmaProb *probLen = prob + LenChoice;
5413 IF_BIT_0_CHECK(probLen)
5414 {
5415 UPDATE_0_CHECK;
5416 probLen = prob + LenLow + (posState << kLenNumLowBits);
5417 offset = 0;
5418 limit = 1 << kLenNumLowBits;
5419 }
5420 else
5421 {
5422 UPDATE_1_CHECK;
5423 probLen = prob + LenChoice2;
5424 IF_BIT_0_CHECK(probLen)
5425 {
5426 UPDATE_0_CHECK;
5427 probLen = prob + LenMid + (posState << kLenNumMidBits);
5428 offset = kLenNumLowSymbols;
5429 limit = 1 << kLenNumMidBits;
5430 }
5431 else
5432 {
5433 UPDATE_1_CHECK;
5434 probLen = prob + LenHigh;
5435 offset = kLenNumLowSymbols + kLenNumMidSymbols;
5436 limit = 1 << kLenNumHighBits;
5437 }
5438 }
5439 TREE_DECODE_CHECK(probLen, limit, len);
5440 len += offset;
5441 }
5442
5443 if (state < 4)
5444 {
5445 unsigned posSlot;
5446 prob = probs + PosSlot +
5447 ((len < kNumLenToPosStates ? len : kNumLenToPosStates - 1) <<
5448 kNumPosSlotBits);
5449 TREE_DECODE_CHECK(prob, 1 << kNumPosSlotBits, posSlot);
5450 if (posSlot >= kStartPosModelIndex)
5451 {
5452 unsigned numDirectBits = ((posSlot >> 1) - 1);
5453
5454 /* if (bufLimit - buf >= 8) return DUMMY_MATCH; */
5455
5456 if (posSlot < kEndPosModelIndex)
5457 {
5458 prob = probs + SpecPos + ((2 | (posSlot & 1)) << numDirectBits) - posSlot - 1;
5459 }
5460 else
5461 {
5462 numDirectBits -= kNumAlignBits;
5463 do
5464 {
5465 NORMALIZE_CHECK
5466 range >>= 1;
5467 code -= range & (((code - range) >> 31) - 1);
5468 /* if (code >= range) code -= range; */
5469 }
5470 while (--numDirectBits != 0);
5471 prob = probs + Align;
5472 numDirectBits = kNumAlignBits;
5473 }
5474 {
5475 unsigned i = 1;
5476 do
5477 {
5478 GET_BIT_CHECK(prob + i, i);
5479 }
5480 while (--numDirectBits != 0);
5481 }
5482 }
5483 }
5484 }
5485 }
5486 NORMALIZE_CHECK;
5487 return res;
5488}
5489
5490
5491static void LzmaDec_InitDicAndState(CLzmaDec *p, Bool initDic, Bool initState)
5492{
5493 p->needFlush = 1;
5494 p->remainLen = 0;
5495 p->tempBufSize = 0;
5496
5497 if (initDic)
5498 {
5499 p->processedPos = 0;
5500 p->checkDicSize = 0;
5501 p->needInitState = 1;
5502 }
5503 if (initState)
5504 p->needInitState = 1;
5505}
5506
5507static void LzmaDec_Init(CLzmaDec *p)
5508{
5509 p->dicPos = 0;
5510 LzmaDec_InitDicAndState(p, True, True);
5511}
5512
5513static void LzmaDec_InitStateReal(CLzmaDec *p)
5514{
5515 SizeT numProbs = LzmaProps_GetNumProbs(&p->prop);
5516 SizeT i;
5517 CLzmaProb *probs = p->probs;
5518 for (i = 0; i < numProbs; i++)
5519 probs[i] = kBitModelTotal >> 1;
5520 p->reps[0] = p->reps[1] = p->reps[2] = p->reps[3] = 1;
5521 p->state = 0;
5522 p->needInitState = 0;
5523}
5524
5525static SRes LzmaDec_DecodeToDic(CLzmaDec *p, SizeT dicLimit, const Byte *src, SizeT *srcLen,
5526 ELzmaFinishMode finishMode, ELzmaStatus *status)
5527{
5528 SizeT inSize = *srcLen;
5529 (*srcLen) = 0;
5530 LzmaDec_WriteRem(p, dicLimit);
5531
5532 *status = LZMA_STATUS_NOT_SPECIFIED;
5533
5534 while (p->remainLen != kMatchSpecLenStart)
5535 {
5536 int checkEndMarkNow;
5537
5538 if (p->needFlush)
5539 {
5540 for (; inSize > 0 && p->tempBufSize < RC_INIT_SIZE; (*srcLen)++, inSize--)
5541 p->tempBuf[p->tempBufSize++] = *src++;
5542 if (p->tempBufSize < RC_INIT_SIZE)
5543 {
5544 *status = LZMA_STATUS_NEEDS_MORE_INPUT;
5545 return SZ_OK;
5546 }
5547 if (p->tempBuf[0] != 0)
5548 return SZ_ERROR_DATA;
5549 p->code =
5550 ((UInt32)p->tempBuf[1] << 24)
5551 | ((UInt32)p->tempBuf[2] << 16)
5552 | ((UInt32)p->tempBuf[3] << 8)
5553 | ((UInt32)p->tempBuf[4]);
5554 p->range = 0xFFFFFFFF;
5555 p->needFlush = 0;
5556 p->tempBufSize = 0;
5557 }
5558
5559 checkEndMarkNow = 0;
5560 if (p->dicPos >= dicLimit)
5561 {
5562 if (p->remainLen == 0 && p->code == 0)
5563 {
5564 *status = LZMA_STATUS_MAYBE_FINISHED_WITHOUT_MARK;
5565 return SZ_OK;
5566 }
5567 if (finishMode == LZMA_FINISH_ANY)
5568 {
5569 *status = LZMA_STATUS_NOT_FINISHED;
5570 return SZ_OK;
5571 }
5572 if (p->remainLen != 0)
5573 {
5574 *status = LZMA_STATUS_NOT_FINISHED;
5575 return SZ_ERROR_DATA;
5576 }
5577 checkEndMarkNow = 1;
5578 }
5579
5580 if (p->needInitState)
5581 LzmaDec_InitStateReal(p);
5582
5583 if (p->tempBufSize == 0)
5584 {
5585 SizeT processed;
5586 const Byte *bufLimit;
5587 if (inSize < LZMA_REQUIRED_INPUT_MAX || checkEndMarkNow)
5588 {
5589 int dummyRes = LzmaDec_TryDummy(p, src, inSize);
5590 if (dummyRes == DUMMY_ERROR)
5591 {
5592 memcpy(p->tempBuf, src, inSize);
5593 p->tempBufSize = (unsigned)inSize;
5594 (*srcLen) += inSize;
5595 *status = LZMA_STATUS_NEEDS_MORE_INPUT;
5596 return SZ_OK;
5597 }
5598 if (checkEndMarkNow && dummyRes != DUMMY_MATCH)
5599 {
5600 *status = LZMA_STATUS_NOT_FINISHED;
5601 return SZ_ERROR_DATA;
5602 }
5603 bufLimit = src;
5604 }
5605 else
5606 bufLimit = src + inSize - LZMA_REQUIRED_INPUT_MAX;
5607 p->buf = src;
5608 if (LzmaDec_DecodeReal2(p, dicLimit, bufLimit) != 0)
5609 return SZ_ERROR_DATA;
5610 processed = (SizeT)(p->buf - src);
5611 (*srcLen) += processed;
5612 src += processed;
5613 inSize -= processed;
5614 }
5615 else
5616 {
5617 unsigned rem = p->tempBufSize, lookAhead = 0;
5618 while (rem < LZMA_REQUIRED_INPUT_MAX && lookAhead < inSize)
5619 p->tempBuf[rem++] = src[lookAhead++];
5620 p->tempBufSize = rem;
5621 if (rem < LZMA_REQUIRED_INPUT_MAX || checkEndMarkNow)
5622 {
5623 int dummyRes = LzmaDec_TryDummy(p, p->tempBuf, rem);
5624 if (dummyRes == DUMMY_ERROR)
5625 {
5626 (*srcLen) += lookAhead;
5627 *status = LZMA_STATUS_NEEDS_MORE_INPUT;
5628 return SZ_OK;
5629 }
5630 if (checkEndMarkNow && dummyRes != DUMMY_MATCH)
5631 {
5632 *status = LZMA_STATUS_NOT_FINISHED;
5633 return SZ_ERROR_DATA;
5634 }
5635 }
5636 p->buf = p->tempBuf;
5637 if (LzmaDec_DecodeReal2(p, dicLimit, p->buf) != 0)
5638 return SZ_ERROR_DATA;
5639
5640 {
5641 unsigned kkk = (unsigned)(p->buf - p->tempBuf);
5642 if (rem < kkk)
5643 return SZ_ERROR_FAIL; /* some internal error */
5644 rem -= kkk;
5645 if (lookAhead < rem)
5646 return SZ_ERROR_FAIL; /* some internal error */
5647 lookAhead -= rem;
5648 }
5649 (*srcLen) += lookAhead;
5650 src += lookAhead;
5651 inSize -= lookAhead;
5652 p->tempBufSize = 0;
5653 }
5654 }
5655 if (p->code == 0)
5656 *status = LZMA_STATUS_FINISHED_WITH_MARK;
5657 return (p->code == 0) ? SZ_OK : SZ_ERROR_DATA;
5658}
5659
5660static void LzmaDec_FreeProbs(CLzmaDec *p, ISzAlloc *alloc)
5661{
5662 alloc->Free(alloc, p->probs);
5663 p->probs = NULL;
5664}
5665
5666static SRes LzmaProps_Decode(CLzmaProps *p, const Byte *data, unsigned size)
5667{
5668 UInt32 dicSize;
5669 Byte d;
5670
5671 if (size < LZMA_PROPS_SIZE)
5672 return SZ_ERROR_UNSUPPORTED;
5673 else
5674 dicSize = data[1] | ((UInt32)data[2] << 8) | ((UInt32)data[3] << 16) | ((UInt32)data[4] << 24);
5675
5676 if (dicSize < LZMA_DIC_MIN)
5677 dicSize = LZMA_DIC_MIN;
5678 p->dicSize = dicSize;
5679
5680 d = data[0];
5681 if (d >= (9 * 5 * 5))
5682 return SZ_ERROR_UNSUPPORTED;
5683
5684 p->lc = d % 9;
5685 d /= 9;
5686 p->pb = d / 5;
5687 p->lp = d % 5;
5688
5689 return SZ_OK;
5690}
5691
5692static SRes LzmaDec_AllocateProbs2(CLzmaDec *p, const CLzmaProps *propNew, ISzAlloc *alloc)
5693{
5694 UInt32 numProbs = LzmaProps_GetNumProbs(propNew);
5695 if (!p->probs || numProbs != p->numProbs)
5696 {
5697 LzmaDec_FreeProbs(p, alloc);
5698 p->probs = (CLzmaProb *)alloc->Alloc(alloc, numProbs * sizeof(CLzmaProb));
5699 p->numProbs = numProbs;
5700 if (!p->probs)
5701 return SZ_ERROR_MEM;
5702 }
5703 return SZ_OK;
5704}
5705
5706static SRes LzmaDec_AllocateProbs(CLzmaDec *p, const Byte *props, unsigned propsSize, ISzAlloc *alloc)
5707{
5708 CLzmaProps propNew;
5709 RINOK(LzmaProps_Decode(&propNew, props, propsSize));
5710 RINOK(LzmaDec_AllocateProbs2(p, &propNew, alloc));
5711 p->prop = propNew;
5712 return SZ_OK;
5713}
5714
5715/* Lzma2Dec.c -- LZMA2 Decoder
57162015-11-09 : Igor Pavlov : Public domain */
5717
5718/* #define SHOW_DEBUG_INFO */
5719
5720/*
5721#include "Precomp.h"
5722
5723#ifdef SHOW_DEBUG_INFO
5724#include <stdio.h>
5725#endif
5726
5727#include <string.h>
5728
5729#include "Lzma2Dec.h"
5730*/
5731
5732/*
573300000000 - EOS
573400000001 U U - Uncompressed Reset Dic
573500000010 U U - Uncompressed No Reset
5736100uuuuu U U P P - LZMA no reset
5737101uuuuu U U P P - LZMA reset state
5738110uuuuu U U P P S - LZMA reset state + new prop
5739111uuuuu U U P P S - LZMA reset state + new prop + reset dic
5740
5741 u, U - Unpack Size
5742 P - Pack Size
5743 S - Props
5744*/
5745
5746#define LZMA2_CONTROL_LZMA (1 << 7)
5747#define LZMA2_CONTROL_COPY_NO_RESET 2
5748#define LZMA2_CONTROL_COPY_RESET_DIC 1
5749#define LZMA2_CONTROL_EOF 0
5750
5751#define LZMA2_IS_UNCOMPRESSED_STATE(p) (((p)->control & LZMA2_CONTROL_LZMA) == 0)
5752
5753#define LZMA2_GET_LZMA_MODE(p) (((p)->control >> 5) & 3)
5754#define LZMA2_IS_THERE_PROP(mode) ((mode) >= 2)
5755
5756#define LZMA2_LCLP_MAX 4
5757#define LZMA2_DIC_SIZE_FROM_PROP(p) (((UInt32)2 | ((p) & 1)) << ((p) / 2 + 11))
5758
5759#ifdef SHOW_DEBUG_INFO
5760#define PRF(x) x
5761#else
5762#define PRF(x)
5763#endif
5764
5765typedef enum
5766{
5767 LZMA2_STATE_CONTROL,
5768 LZMA2_STATE_UNPACK0,
5769 LZMA2_STATE_UNPACK1,
5770 LZMA2_STATE_PACK0,
5771 LZMA2_STATE_PACK1,
5772 LZMA2_STATE_PROP,
5773 LZMA2_STATE_DATA,
5774 LZMA2_STATE_DATA_CONT,
5775 LZMA2_STATE_FINISHED,
5776 LZMA2_STATE_ERROR
5777} ELzma2State;
5778
5779static SRes Lzma2Dec_GetOldProps(Byte prop, Byte *props)
5780{
5781 UInt32 dicSize;
5782 if (prop > 40)
5783 return SZ_ERROR_UNSUPPORTED;
5784 dicSize = (prop == 40) ? 0xFFFFFFFF : LZMA2_DIC_SIZE_FROM_PROP(prop);
5785 props[0] = (Byte)LZMA2_LCLP_MAX;
5786 props[1] = (Byte)(dicSize);
5787 props[2] = (Byte)(dicSize >> 8);
5788 props[3] = (Byte)(dicSize >> 16);
5789 props[4] = (Byte)(dicSize >> 24);
5790 return SZ_OK;
5791}
5792
5793static SRes Lzma2Dec_AllocateProbs(CLzma2Dec *p, Byte prop, ISzAlloc *alloc)
5794{
5795 Byte props[LZMA_PROPS_SIZE];
5796 RINOK(Lzma2Dec_GetOldProps(prop, props));
5797 return LzmaDec_AllocateProbs(&p->decoder, props, LZMA_PROPS_SIZE, alloc);
5798}
5799
5800static void Lzma2Dec_Init(CLzma2Dec *p)
5801{
5802 p->state = LZMA2_STATE_CONTROL;
5803 p->needInitDic = True;
5804 p->needInitState = True;
5805 p->needInitProp = True;
5806 LzmaDec_Init(&p->decoder);
5807}
5808
5809static ELzma2State Lzma2Dec_UpdateState(CLzma2Dec *p, Byte b)
5810{
5811 switch (p->state)
5812 {
5813 case LZMA2_STATE_CONTROL:
5814 p->control = b;
5815 PRF(printf("\n %4X ", (unsigned)p->decoder.dicPos));
5816 PRF(printf(" %2X", (unsigned)b));
5817 if (p->control == 0)
5818 return LZMA2_STATE_FINISHED;
5819 if (LZMA2_IS_UNCOMPRESSED_STATE(p))
5820 {
5821 if ((p->control & 0x7F) > 2)
5822 return LZMA2_STATE_ERROR;
5823 p->unpackSize = 0;
5824 }
5825 else
5826 p->unpackSize = (UInt32)(p->control & 0x1F) << 16;
5827 return LZMA2_STATE_UNPACK0;
5828
5829 case LZMA2_STATE_UNPACK0:
5830 p->unpackSize |= (UInt32)b << 8;
5831 return LZMA2_STATE_UNPACK1;
5832
5833 case LZMA2_STATE_UNPACK1:
5834 p->unpackSize |= (UInt32)b;
5835 p->unpackSize++;
5836 PRF(printf(" %8u", (unsigned)p->unpackSize));
5837 return (LZMA2_IS_UNCOMPRESSED_STATE(p)) ? LZMA2_STATE_DATA : LZMA2_STATE_PACK0;
5838
5839 case LZMA2_STATE_PACK0:
5840 p->packSize = (UInt32)b << 8;
5841 return LZMA2_STATE_PACK1;
5842
5843 case LZMA2_STATE_PACK1:
5844 p->packSize |= (UInt32)b;
5845 p->packSize++;
5846 PRF(printf(" %8u", (unsigned)p->packSize));
5847 return LZMA2_IS_THERE_PROP(LZMA2_GET_LZMA_MODE(p)) ? LZMA2_STATE_PROP:
5848 (p->needInitProp ? LZMA2_STATE_ERROR : LZMA2_STATE_DATA);
5849
5850 case LZMA2_STATE_PROP:
5851 {
5852 unsigned lc, lp;
5853 if (b >= (9 * 5 * 5))
5854 return LZMA2_STATE_ERROR;
5855 lc = b % 9;
5856 b /= 9;
5857 p->decoder.prop.pb = b / 5;
5858 lp = b % 5;
5859 if (lc + lp > LZMA2_LCLP_MAX)
5860 return LZMA2_STATE_ERROR;
5861 p->decoder.prop.lc = lc;
5862 p->decoder.prop.lp = lp;
5863 p->needInitProp = False;
5864 return LZMA2_STATE_DATA;
5865 }
5866 }
5867 return LZMA2_STATE_ERROR;
5868}
5869
5870static void LzmaDec_UpdateWithUncompressed(CLzmaDec *p, const Byte *src, SizeT size)
5871{
5872 memcpy(p->dic + p->dicPos, src, size);
5873 p->dicPos += size;
5874 if (p->checkDicSize == 0 && p->prop.dicSize - p->processedPos <= size)
5875 p->checkDicSize = p->prop.dicSize;
5876 p->processedPos += (UInt32)size;
5877}
5878
5879static void LzmaDec_InitDicAndState(CLzmaDec *p, Bool initDic, Bool initState);
5880
5881static SRes Lzma2Dec_DecodeToDic(CLzma2Dec *p, SizeT dicLimit,
5882 const Byte *src, SizeT *srcLen, ELzmaFinishMode finishMode, ELzmaStatus *status)
5883{
5884 SizeT inSize = *srcLen;
5885 *srcLen = 0;
5886 *status = LZMA_STATUS_NOT_SPECIFIED;
5887
5888 while (p->state != LZMA2_STATE_FINISHED)
5889 {
5890 SizeT dicPos = p->decoder.dicPos;
5891
5892 if (p->state == LZMA2_STATE_ERROR)
5893 return SZ_ERROR_DATA;
5894
5895 if (dicPos == dicLimit && finishMode == LZMA_FINISH_ANY)
5896 {
5897 *status = LZMA_STATUS_NOT_FINISHED;
5898 return SZ_OK;
5899 }
5900
5901 if (p->state != LZMA2_STATE_DATA && p->state != LZMA2_STATE_DATA_CONT)
5902 {
5903 if (*srcLen == inSize)
5904 {
5905 *status = LZMA_STATUS_NEEDS_MORE_INPUT;
5906 return SZ_OK;
5907 }
5908 (*srcLen)++;
5909 p->state = Lzma2Dec_UpdateState(p, *src++);
5910
5911 if (dicPos == dicLimit && p->state != LZMA2_STATE_FINISHED)
5912 {
5913 p->state = LZMA2_STATE_ERROR;
5914 return SZ_ERROR_DATA;
5915 }
5916 continue;
5917 }
5918
5919 {
5920 SizeT destSizeCur = dicLimit - dicPos;
5921 SizeT srcSizeCur = inSize - *srcLen;
5922 ELzmaFinishMode curFinishMode = LZMA_FINISH_ANY;
5923
5924 if (p->unpackSize <= destSizeCur)
5925 {
5926 destSizeCur = (SizeT)p->unpackSize;
5927 curFinishMode = LZMA_FINISH_END;
5928 }
5929
5930 if (LZMA2_IS_UNCOMPRESSED_STATE(p))
5931 {
5932 if (*srcLen == inSize)
5933 {
5934 *status = LZMA_STATUS_NEEDS_MORE_INPUT;
5935 return SZ_OK;
5936 }
5937
5938 if (p->state == LZMA2_STATE_DATA)
5939 {
5940 Bool initDic = (p->control == LZMA2_CONTROL_COPY_RESET_DIC);
5941 if (initDic)
5942 p->needInitProp = p->needInitState = True;
5943 else if (p->needInitDic)
5944 {
5945 p->state = LZMA2_STATE_ERROR;
5946 return SZ_ERROR_DATA;
5947 }
5948 p->needInitDic = False;
5949 LzmaDec_InitDicAndState(&p->decoder, initDic, False);
5950 }
5951
5952 if (srcSizeCur > destSizeCur)
5953 srcSizeCur = destSizeCur;
5954
5955 if (srcSizeCur == 0)
5956 {
5957 p->state = LZMA2_STATE_ERROR;
5958 return SZ_ERROR_DATA;
5959 }
5960
5961 LzmaDec_UpdateWithUncompressed(&p->decoder, src, srcSizeCur);
5962
5963 src += srcSizeCur;
5964 *srcLen += srcSizeCur;
5965 p->unpackSize -= (UInt32)srcSizeCur;
5966 p->state = (p->unpackSize == 0) ? LZMA2_STATE_CONTROL : LZMA2_STATE_DATA_CONT;
5967 }
5968 else
5969 {
5970 SizeT outSizeProcessed;
5971 SRes res;
5972
5973 if (p->state == LZMA2_STATE_DATA)
5974 {
5975 unsigned mode = LZMA2_GET_LZMA_MODE(p);
5976 Bool initDic = (mode == 3);
5977 Bool initState = (mode != 0);
5978 if ((!initDic && p->needInitDic) || (!initState && p->needInitState))
5979 {
5980 p->state = LZMA2_STATE_ERROR;
5981 return SZ_ERROR_DATA;
5982 }
5983
5984 LzmaDec_InitDicAndState(&p->decoder, initDic, initState);
5985 p->needInitDic = False;
5986 p->needInitState = False;
5987 p->state = LZMA2_STATE_DATA_CONT;
5988 }
5989
5990 if (srcSizeCur > p->packSize)
5991 srcSizeCur = (SizeT)p->packSize;
5992
5993 res = LzmaDec_DecodeToDic(&p->decoder, dicPos + destSizeCur, src, &srcSizeCur, curFinishMode, status);
5994
5995 src += srcSizeCur;
5996 *srcLen += srcSizeCur;
5997 p->packSize -= (UInt32)srcSizeCur;
5998
5999 outSizeProcessed = p->decoder.dicPos - dicPos;
6000 p->unpackSize -= (UInt32)outSizeProcessed;
6001
6002 RINOK(res);
6003 if (*status == LZMA_STATUS_NEEDS_MORE_INPUT)
6004 return res;
6005
6006 if (srcSizeCur == 0 && outSizeProcessed == 0)
6007 {
6008 if (*status != LZMA_STATUS_MAYBE_FINISHED_WITHOUT_MARK
6009 || p->unpackSize != 0
6010 || p->packSize != 0)
6011 {
6012 p->state = LZMA2_STATE_ERROR;
6013 return SZ_ERROR_DATA;
6014 }
6015 p->state = LZMA2_STATE_CONTROL;
6016 }
6017
6018 if (*status == LZMA_STATUS_MAYBE_FINISHED_WITHOUT_MARK)
6019 *status = LZMA_STATUS_NOT_FINISHED;
6020 }
6021 }
6022 }
6023
6024 *status = LZMA_STATUS_FINISHED_WITH_MARK;
6025 return SZ_OK;
6026}
6027
6028#endif /* _INCLUDE_PHYSFS_LZMASDK_H_ */
6029
6030/* end of physfs_lzmasdk.h ... */
6031
6032