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