aboutsummaryrefslogtreecommitdiff
path: root/C
diff options
context:
space:
mode:
authorIgor Pavlov <87184205+ip7z@users.noreply.github.com>2026-06-25 00:00:00 +0000
committerIgor Pavlov <87184205+ip7z@users.noreply.github.com>2026-06-26 11:00:29 +0500
commitf9d78aff31a5f2521ae7ddbdc97c4a8855808959 (patch)
treebf7e13577f75aa4c7c56af1153d6fa15c6052445 /C
parent8c63d71ff886bda90c86db28466287f977374237 (diff)
download7zip-main.tar.gz
7zip-main.tar.bz2
7zip-main.zip
Diffstat (limited to 'C')
-rw-r--r--C/7zArcIn.c651
-rw-r--r--C/7zVersion.h6
-rw-r--r--C/Compiler.h5
-rw-r--r--C/DllSecur.c6
-rw-r--r--C/MtDec.c4
-rw-r--r--C/Util/7z/7zMain.c7
-rw-r--r--C/Util/7zipInstall/7zipInstall.c38
-rw-r--r--C/Util/7zipUninstall/7zipUninstall.c58
-rw-r--r--C/Util/SfxSetup/SfxSetup.c14
-rw-r--r--C/XzDec.c47
10 files changed, 377 insertions, 459 deletions
diff --git a/C/7zArcIn.c b/C/7zArcIn.c
index 4dc3ba1..f6f6e7c 100644
--- a/C/7zArcIn.c
+++ b/C/7zArcIn.c
@@ -11,7 +11,7 @@
11#include "CpuArch.h" 11#include "CpuArch.h"
12 12
13#define MY_ALLOC(T, p, size, alloc) \ 13#define MY_ALLOC(T, p, size, alloc) \
14 { if ((p = (T *)ISzAlloc_Alloc(alloc, (size) * sizeof(T))) == NULL) return SZ_ERROR_MEM; } 14 { if ((p = (T *)ISzAlloc_Alloc(alloc, (size_t)(size) * sizeof(T))) == NULL) return SZ_ERROR_MEM; }
15 15
16#define MY_ALLOC_ZE(T, p, size, alloc) \ 16#define MY_ALLOC_ZE(T, p, size, alloc) \
17 { if ((size) == 0) p = NULL; else MY_ALLOC(T, p, size, alloc) } 17 { if ((size) == 0) p = NULL; else MY_ALLOC(T, p, size, alloc) }
@@ -22,8 +22,6 @@
22#define MY_ALLOC_ZE_AND_CPY(to, size, from, alloc) \ 22#define MY_ALLOC_ZE_AND_CPY(to, size, from, alloc) \
23 { if ((size) == 0) to = NULL; else { MY_ALLOC_AND_CPY(to, size, from, alloc) } } 23 { if ((size) == 0) to = NULL; else { MY_ALLOC_AND_CPY(to, size, from, alloc) } }
24 24
25#define k7zMajorVersion 0
26
27enum EIdEnum 25enum EIdEnum
28{ 26{
29 k7zIdEnd, 27 k7zIdEnd,
@@ -52,15 +50,13 @@ enum EIdEnum
52 k7zIdEncodedHeader, 50 k7zIdEncodedHeader,
53 k7zIdStartPos, 51 k7zIdStartPos,
54 k7zIdDummy 52 k7zIdDummy
55 // k7zNtSecure,
56 // k7zParent,
57 // k7zIsReal
58}; 53};
59 54
60const Byte k7zSignature[k7zSignatureSize] = {'7', 'z', 0xBC, 0xAF, 0x27, 0x1C}; 55const Byte k7zSignature[k7zSignatureSize] = {'7', 'z', 0xBC, 0xAF, 0x27, 0x1C};
61 56
62#define SzBitUi32s_INIT(p) { (p)->Defs = NULL; (p)->Vals = NULL; } 57#define SzBitUi32s_INIT(p) { (p)->Defs = NULL; (p)->Vals = NULL; }
63 58
59Z7_FORCE_INLINE
64static SRes SzBitUi32s_Alloc(CSzBitUi32s *p, size_t num, ISzAllocPtr alloc) 60static SRes SzBitUi32s_Alloc(CSzBitUi32s *p, size_t num, ISzAllocPtr alloc)
65{ 61{
66 if (num == 0) 62 if (num == 0)
@@ -76,6 +72,7 @@ static SRes SzBitUi32s_Alloc(CSzBitUi32s *p, size_t num, ISzAllocPtr alloc)
76 return SZ_OK; 72 return SZ_OK;
77} 73}
78 74
75Z7_FORCE_INLINE
79static void SzBitUi32s_Free(CSzBitUi32s *p, ISzAllocPtr alloc) 76static void SzBitUi32s_Free(CSzBitUi32s *p, ISzAllocPtr alloc)
80{ 77{
81 ISzAlloc_Free(alloc, p->Defs); p->Defs = NULL; 78 ISzAlloc_Free(alloc, p->Defs); p->Defs = NULL;
@@ -84,13 +81,14 @@ static void SzBitUi32s_Free(CSzBitUi32s *p, ISzAllocPtr alloc)
84 81
85#define SzBitUi64s_INIT(p) { (p)->Defs = NULL; (p)->Vals = NULL; } 82#define SzBitUi64s_INIT(p) { (p)->Defs = NULL; (p)->Vals = NULL; }
86 83
84Z7_FORCE_INLINE
87static void SzBitUi64s_Free(CSzBitUi64s *p, ISzAllocPtr alloc) 85static void SzBitUi64s_Free(CSzBitUi64s *p, ISzAllocPtr alloc)
88{ 86{
89 ISzAlloc_Free(alloc, p->Defs); p->Defs = NULL; 87 ISzAlloc_Free(alloc, p->Defs); p->Defs = NULL;
90 ISzAlloc_Free(alloc, p->Vals); p->Vals = NULL; 88 ISzAlloc_Free(alloc, p->Vals); p->Vals = NULL;
91} 89}
92 90
93 91Z7_NO_INLINE
94static void SzAr_Init(CSzAr *p) 92static void SzAr_Init(CSzAr *p)
95{ 93{
96 p->NumPackStreams = 0; 94 p->NumPackStreams = 0;
@@ -110,23 +108,22 @@ static void SzAr_Init(CSzAr *p)
110 p->RangeLimit = 0; 108 p->RangeLimit = 0;
111} 109}
112 110
111Z7_NO_INLINE
113static void SzAr_Free(CSzAr *p, ISzAllocPtr alloc) 112static void SzAr_Free(CSzAr *p, ISzAllocPtr alloc)
114{ 113{
115 ISzAlloc_Free(alloc, p->PackPositions); 114 ISzAlloc_Free(alloc, p->PackPositions);
116 SzBitUi32s_Free(&p->FolderCRCs, alloc); 115 SzBitUi32s_Free(&p->FolderCRCs, alloc);
117
118 ISzAlloc_Free(alloc, p->FoCodersOffsets); 116 ISzAlloc_Free(alloc, p->FoCodersOffsets);
119 ISzAlloc_Free(alloc, p->FoStartPackStreamIndex); 117 ISzAlloc_Free(alloc, p->FoStartPackStreamIndex);
120 ISzAlloc_Free(alloc, p->FoToCoderUnpackSizes); 118 ISzAlloc_Free(alloc, p->FoToCoderUnpackSizes);
121 ISzAlloc_Free(alloc, p->FoToMainUnpackSizeIndex); 119 ISzAlloc_Free(alloc, p->FoToMainUnpackSizeIndex);
122 ISzAlloc_Free(alloc, p->CoderUnpackSizes); 120 ISzAlloc_Free(alloc, p->CoderUnpackSizes);
123
124 ISzAlloc_Free(alloc, p->CodersData); 121 ISzAlloc_Free(alloc, p->CodersData);
125 122
126 SzAr_Init(p); 123 SzAr_Init(p);
127} 124}
128 125
129 126Z7_NO_INLINE
130void SzArEx_Init(CSzArEx *p) 127void SzArEx_Init(CSzArEx *p)
131{ 128{
132 SzAr_Init(&p->db); 129 SzAr_Init(&p->db);
@@ -150,6 +147,7 @@ void SzArEx_Init(CSzArEx *p)
150 SzBitUi64s_INIT(&p->CTime) 147 SzBitUi64s_INIT(&p->CTime)
151} 148}
152 149
150Z7_NO_INLINE
153void SzArEx_Free(CSzArEx *p, ISzAllocPtr alloc) 151void SzArEx_Free(CSzArEx *p, ISzAllocPtr alloc)
154{ 152{
155 ISzAlloc_Free(alloc, p->UnpackPositions); 153 ISzAlloc_Free(alloc, p->UnpackPositions);
@@ -172,15 +170,6 @@ void SzArEx_Free(CSzArEx *p, ISzAllocPtr alloc)
172} 170}
173 171
174 172
175static int TestSignatureCandidate(const Byte *testBytes)
176{
177 unsigned i;
178 for (i = 0; i < k7zSignatureSize; i++)
179 if (testBytes[i] != k7zSignature[i])
180 return 0;
181 return 1;
182}
183
184#define SzData_CLEAR(p) { (p)->Data = NULL; (p)->Size = 0; } 173#define SzData_CLEAR(p) { (p)->Data = NULL; (p)->Size = 0; }
185 174
186#define SZ_READ_BYTE_SD_NOCHECK(_sd_, dest) \ 175#define SZ_READ_BYTE_SD_NOCHECK(_sd_, dest) \
@@ -199,14 +188,9 @@ static int TestSignatureCandidate(const Byte *testBytes)
199#define SKIP_DATA(sd, size) { sd->Size -= (size_t)(size); sd->Data += (size_t)(size); } 188#define SKIP_DATA(sd, size) { sd->Size -= (size_t)(size); sd->Data += (size_t)(size); }
200#define SKIP_DATA2(sd, size) { sd.Size -= (size_t)(size); sd.Data += (size_t)(size); } 189#define SKIP_DATA2(sd, size) { sd.Size -= (size_t)(size); sd.Data += (size_t)(size); }
201 190
202#define SZ_READ_32(dest) if (sd.Size < 4) return SZ_ERROR_ARCHIVE; \
203 dest = GetUi32(sd.Data); SKIP_DATA2(sd, 4);
204
205static Z7_NO_INLINE SRes ReadNumber(CSzData *sd, UInt64 *value) 191static Z7_NO_INLINE SRes ReadNumber(CSzData *sd, UInt64 *value)
206{ 192{
207 Byte firstByte, mask; 193 unsigned firstByte, mask, i, v;
208 unsigned i;
209 UInt32 v;
210 194
211 SZ_READ_BYTE(firstByte) 195 SZ_READ_BYTE(firstByte)
212 if ((firstByte & 0x80) == 0) 196 if ((firstByte & 0x80) == 0)
@@ -223,18 +207,18 @@ static Z7_NO_INLINE SRes ReadNumber(CSzData *sd, UInt64 *value)
223 SZ_READ_BYTE(mask) 207 SZ_READ_BYTE(mask)
224 *value = v | ((UInt32)mask << 8); 208 *value = v | ((UInt32)mask << 8);
225 mask = 0x20; 209 mask = 0x20;
226 for (i = 2; i < 8; i++) 210 for (i = 2 * 8; i < 8 * 8; i += 8)
227 { 211 {
228 Byte b; 212 unsigned b;
229 if ((firstByte & mask) == 0) 213 if ((firstByte & mask) == 0)
230 { 214 {
231 const UInt64 highPart = (unsigned)firstByte & (unsigned)(mask - 1); 215 const UInt64 highPart = (unsigned)firstByte & (unsigned)(mask - 1);
232 *value |= (highPart << (8 * i)); 216 *value |= (highPart << i);
233 return SZ_OK; 217 return SZ_OK;
234 } 218 }
235 SZ_READ_BYTE(b)
236 *value |= ((UInt64)b << (8 * i));
237 mask >>= 1; 219 mask >>= 1;
220 SZ_READ_BYTE(b)
221 *value |= ((UInt64)b << i);
238 } 222 }
239 return SZ_OK; 223 return SZ_OK;
240} 224}
@@ -242,7 +226,7 @@ static Z7_NO_INLINE SRes ReadNumber(CSzData *sd, UInt64 *value)
242 226
243static Z7_NO_INLINE SRes SzReadNumber32(CSzData *sd, UInt32 *value) 227static Z7_NO_INLINE SRes SzReadNumber32(CSzData *sd, UInt32 *value)
244{ 228{
245 Byte firstByte; 229 unsigned firstByte;
246 UInt64 value64; 230 UInt64 value64;
247 if (sd->Size == 0) 231 if (sd->Size == 0)
248 return SZ_ERROR_ARCHIVE; 232 return SZ_ERROR_ARCHIVE;
@@ -265,6 +249,7 @@ static Z7_NO_INLINE SRes SzReadNumber32(CSzData *sd, UInt32 *value)
265 249
266#define ReadID(sd, value) ReadNumber(sd, value) 250#define ReadID(sd, value) ReadNumber(sd, value)
267 251
252Z7_NO_INLINE
268static SRes SkipData(CSzData *sd) 253static SRes SkipData(CSzData *sd)
269{ 254{
270 UInt64 size; 255 UInt64 size;
@@ -275,6 +260,7 @@ static SRes SkipData(CSzData *sd)
275 return SZ_OK; 260 return SZ_OK;
276} 261}
277 262
263Z7_NO_INLINE
278static SRes WaitId(CSzData *sd, UInt32 id) 264static SRes WaitId(CSzData *sd, UInt32 id)
279{ 265{
280 for (;;) 266 for (;;)
@@ -289,16 +275,8 @@ static SRes WaitId(CSzData *sd, UInt32 id)
289 } 275 }
290} 276}
291 277
292static SRes RememberBitVector(CSzData *sd, size_t numItems, const Byte **v)
293{
294 const size_t numBytes = (numItems + 7) >> 3;
295 if (numBytes > sd->Size)
296 return SZ_ERROR_ARCHIVE;
297 *v = sd->Data;
298 SKIP_DATA(sd, numBytes)
299 return SZ_OK;
300}
301 278
279Z7_NO_INLINE
302static UInt32 CountDefinedBits(const Byte *bits, UInt32 numItems) 280static UInt32 CountDefinedBits(const Byte *bits, UInt32 numItems)
303{ 281{
304 unsigned b = 0; 282 unsigned b = 0;
@@ -339,8 +317,8 @@ static Z7_NO_INLINE SRes ReadBitVector(CSzData *sd, size_t numItems, Byte **v, I
339 memset(v2, 0xFF, (size_t)numBytes); 317 memset(v2, 0xFF, (size_t)numBytes);
340 { 318 {
341 const unsigned numBits = (unsigned)numItems & 7; 319 const unsigned numBits = (unsigned)numItems & 7;
342 if (numBits != 0) 320 if (numBits)
343 v2[(size_t)numBytes - 1] = (Byte)((((UInt32)1 << numBits) - 1) << (8 - numBits)); 321 v2[(size_t)numBytes - 1] = (Byte)(0xff00u >> numBits);
344 } 322 }
345 return SZ_OK; 323 return SZ_OK;
346} 324}
@@ -348,31 +326,40 @@ static Z7_NO_INLINE SRes ReadBitVector(CSzData *sd, size_t numItems, Byte **v, I
348static Z7_NO_INLINE SRes ReadUi32s(CSzData *sd2, size_t numItems, CSzBitUi32s *crcs, ISzAllocPtr alloc) 326static Z7_NO_INLINE SRes ReadUi32s(CSzData *sd2, size_t numItems, CSzBitUi32s *crcs, ISzAllocPtr alloc)
349{ 327{
350 size_t i; 328 size_t i;
351 CSzData sd; 329 const Byte *data;
330 size_t size;
352 UInt32 *vals; 331 UInt32 *vals;
353 const Byte *defs; 332 const Byte *defs;
354 MY_ALLOC_ZE(UInt32, crcs->Vals, numItems, alloc) 333 MY_ALLOC_ZE(UInt32, vals, numItems, alloc)
355 sd = *sd2; 334 crcs->Vals = vals;
356 defs = crcs->Defs; 335 defs = crcs->Defs;
357 vals = crcs->Vals; 336 data = sd2->Data;
337 size = sd2->Size;
358 for (i = 0; i < numItems; i++) 338 for (i = 0; i < numItems; i++)
359 if (SzBitArray_Check(defs, i)) 339 if (SzBitArray_Check(defs, i))
360 { 340 {
361 SZ_READ_32(vals[i]) 341 if (size < 4)
342 return SZ_ERROR_ARCHIVE;
343 size -= 4;
344 vals[i] = GetUi32(data);
345 data += 4;
362 } 346 }
363 else 347 else
364 vals[i] = 0; 348 vals[i] = 0;
365 *sd2 = sd; 349 sd2->Data = data;
350 sd2->Size = size;
366 return SZ_OK; 351 return SZ_OK;
367} 352}
368 353
369static SRes ReadBitUi32s(CSzData *sd, size_t numItems, CSzBitUi32s *crcs, ISzAllocPtr alloc) 354static SRes ReadBitUi32s(CSzData *sd, size_t numItems, CSzBitUi32s *crcs, ISzAllocPtr alloc)
370{ 355{
371 SzBitUi32s_Free(crcs, alloc); 356 if (crcs->Defs)
357 return SZ_ERROR_ARCHIVE;
372 RINOK(ReadBitVector(sd, numItems, &crcs->Defs, alloc)) 358 RINOK(ReadBitVector(sd, numItems, &crcs->Defs, alloc))
373 return ReadUi32s(sd, numItems, crcs, alloc); 359 return ReadUi32s(sd, numItems, crcs, alloc);
374} 360}
375 361
362Z7_NO_INLINE
376static SRes SkipBitUi32s(CSzData *sd, UInt32 numItems) 363static SRes SkipBitUi32s(CSzData *sd, UInt32 numItems)
377{ 364{
378 Byte allAreDefined; 365 Byte allAreDefined;
@@ -395,25 +382,26 @@ static SRes SkipBitUi32s(CSzData *sd, UInt32 numItems)
395static SRes ReadPackInfo(CSzAr *p, CSzData *sd, ISzAllocPtr alloc) 382static SRes ReadPackInfo(CSzAr *p, CSzData *sd, ISzAllocPtr alloc)
396{ 383{
397 RINOK(SzReadNumber32(sd, &p->NumPackStreams)) 384 RINOK(SzReadNumber32(sd, &p->NumPackStreams))
398
399 RINOK(WaitId(sd, k7zIdSize)) 385 RINOK(WaitId(sd, k7zIdSize))
400 MY_ALLOC(UInt64, p->PackPositions, (size_t)p->NumPackStreams + 1, alloc)
401 { 386 {
402 UInt64 sum = 0; 387 UInt64 *packPositions;
403 UInt32 i; 388 UInt64 sum;
404 const UInt32 numPackStreams = p->NumPackStreams; 389 size_t num = (size_t)p->NumPackStreams + 1;
405 for (i = 0; i < numPackStreams; i++) 390 MY_ALLOC(UInt64, packPositions, num, alloc)
391 p->PackPositions = packPositions;
392 sum = 0;
393 for (;;)
406 { 394 {
407 UInt64 packSize; 395 UInt64 packSize;
408 p->PackPositions[i] = sum; 396 *packPositions++ = sum;
397 if (--num == 0)
398 break;
409 RINOK(ReadNumber(sd, &packSize)) 399 RINOK(ReadNumber(sd, &packSize))
410 sum += packSize; 400 sum += packSize;
411 if (sum < packSize) 401 if (sum < packSize)
412 return SZ_ERROR_ARCHIVE; 402 return SZ_ERROR_ARCHIVE;
413 } 403 }
414 p->PackPositions[i] = sum;
415 } 404 }
416
417 for (;;) 405 for (;;)
418 { 406 {
419 UInt64 type; 407 UInt64 type;
@@ -430,85 +418,79 @@ static SRes ReadPackInfo(CSzAr *p, CSzData *sd, ISzAllocPtr alloc)
430 } 418 }
431} 419}
432 420
433/*
434static SRes SzReadSwitch(CSzData *sd)
435{
436 Byte external;
437 RINOK(SzReadByte(sd, &external));
438 return (external == 0) ? SZ_OK: SZ_ERROR_UNSUPPORTED;
439}
440*/
441 421
442#define k_NumCodersStreams_in_Folder_MAX (SZ_NUM_BONDS_IN_FOLDER_MAX + SZ_NUM_PACK_STREAMS_IN_FOLDER_MAX) 422#define k_NumCodersStreams_in_Folder_MAX (SZ_NUM_BONDS_IN_FOLDER_MAX + SZ_NUM_PACK_STREAMS_IN_FOLDER_MAX)
443 423
444SRes SzGetNextFolderItem(CSzFolder *f, CSzData *sd) 424SRes SzGetNextFolderItem(CSzFolder *f, CSzData *sd)
445{ 425{
446 UInt32 numCoders, i; 426 UInt32 numCoders, i, numInStreams = 0;
447 UInt32 numInStreams = 0; 427 const Byte * const dataStart = sd->Data;
448 const Byte *dataStart = sd->Data;
449 428
450 f->NumCoders = 0; 429 // f->NumCoders = 0;
451 f->NumBonds = 0; 430 // f->NumBonds = 0;
452 f->NumPackStreams = 0; 431 // f->NumPackStreams = 0;
453 f->UnpackStream = 0; 432 f->UnpackStream = 0;
454 433
455 RINOK(SzReadNumber32(sd, &numCoders)) 434 RINOK(SzReadNumber32(sd, &numCoders))
456 if (numCoders == 0 || numCoders > SZ_NUM_CODERS_IN_FOLDER_MAX) 435 if (numCoders == 0 || numCoders > SZ_NUM_CODERS_IN_FOLDER_MAX)
457 return SZ_ERROR_UNSUPPORTED; 436 return SZ_ERROR_UNSUPPORTED;
437 f->NumCoders = numCoders;
458 438
459 for (i = 0; i < numCoders; i++) 439 for (i = 0; i < numCoders; i++)
460 { 440 {
461 Byte mainByte; 441 Byte mainByte;
462 CSzCoderInfo *coder = f->Coders + i; 442 CSzCoderInfo *coder;
463 unsigned idSize, j;
464 UInt64 id;
465
466 SZ_READ_BYTE(mainByte)
467 if ((mainByte & 0xC0) != 0)
468 return SZ_ERROR_UNSUPPORTED;
469
470 idSize = (unsigned)(mainByte & 0xF);
471 if (idSize > sizeof(id))
472 return SZ_ERROR_UNSUPPORTED;
473 if (idSize > sd->Size)
474 return SZ_ERROR_ARCHIVE;
475 id = 0;
476 for (j = 0; j < idSize; j++)
477 { 443 {
478 id = ((id << 8) | *sd->Data); 444 unsigned idSize, j;
479 sd->Data++; 445 UInt64 id;
446 const Byte *data;
447
448 if (!sd->Size)
449 return SZ_ERROR_ARCHIVE;
480 sd->Size--; 450 sd->Size--;
451 data = sd->Data;
452 mainByte = *data++;
453 if (mainByte & 0xC0)
454 return SZ_ERROR_UNSUPPORTED;
455 idSize = mainByte & 0xF;
456 if (idSize > sizeof(id))
457 return SZ_ERROR_UNSUPPORTED;
458 if (idSize > sd->Size)
459 return SZ_ERROR_ARCHIVE;
460 sd->Size -= idSize;
461 id = 0;
462 for (j = 0; j < idSize; j++)
463 id = (id << 8) | *data++;
464 sd->Data = data;
465 if (id > (UInt32)0xFFFFFFFF)
466 return SZ_ERROR_UNSUPPORTED;
467 coder = f->Coders + i;
468 coder->MethodID = (UInt32)id;
481 } 469 }
482 if (id > (UInt32)0xFFFFFFFF)
483 return SZ_ERROR_UNSUPPORTED;
484 coder->MethodID = (UInt32)id;
485 470
486 coder->NumStreams = 1; 471 coder->NumStreams = 1;
487 coder->PropsOffset = 0; 472 coder->PropsOffset = 0;
488 coder->PropsSize = 0; 473 coder->PropsSize = 0;
489 474
490 if ((mainByte & 0x10) != 0) 475 if (mainByte & 0x10)
491 { 476 {
492 UInt32 numStreams; 477 UInt32 numStreams;
493
494 RINOK(SzReadNumber32(sd, &numStreams)) 478 RINOK(SzReadNumber32(sd, &numStreams))
495 if (numStreams > k_NumCodersStreams_in_Folder_MAX) 479 if (numStreams > k_NumCodersStreams_in_Folder_MAX)
496 return SZ_ERROR_UNSUPPORTED; 480 return SZ_ERROR_UNSUPPORTED;
497 coder->NumStreams = (Byte)numStreams; 481 coder->NumStreams = (Byte)numStreams;
498
499 RINOK(SzReadNumber32(sd, &numStreams)) 482 RINOK(SzReadNumber32(sd, &numStreams))
500 if (numStreams != 1) 483 if (numStreams != 1)
501 return SZ_ERROR_UNSUPPORTED; 484 return SZ_ERROR_UNSUPPORTED;
502 } 485 }
503 486
504 numInStreams += coder->NumStreams; 487 numInStreams += coder->NumStreams;
505
506 if (numInStreams > k_NumCodersStreams_in_Folder_MAX) 488 if (numInStreams > k_NumCodersStreams_in_Folder_MAX)
507 return SZ_ERROR_UNSUPPORTED; 489 return SZ_ERROR_UNSUPPORTED;
508 490
509 if ((mainByte & 0x20) != 0) 491 if (mainByte & 0x20)
510 { 492 {
511 UInt32 propsSize = 0; 493 UInt32 propsSize;
512 RINOK(SzReadNumber32(sd, &propsSize)) 494 RINOK(SzReadNumber32(sd, &propsSize))
513 if (propsSize > sd->Size) 495 if (propsSize > sd->Size)
514 return SZ_ERROR_ARCHIVE; 496 return SZ_ERROR_ARCHIVE;
@@ -521,14 +503,6 @@ SRes SzGetNextFolderItem(CSzFolder *f, CSzData *sd)
521 } 503 }
522 } 504 }
523 505
524 /*
525 if (numInStreams == 1 && numCoders == 1)
526 {
527 f->NumPackStreams = 1;
528 f->PackStreams[0] = 0;
529 }
530 else
531 */
532 { 506 {
533 Byte streamUsed[k_NumCodersStreams_in_Folder_MAX]; 507 Byte streamUsed[k_NumCodersStreams_in_Folder_MAX];
534 UInt32 numBonds, numPackStreams; 508 UInt32 numBonds, numPackStreams;
@@ -545,14 +519,13 @@ SRes SzGetNextFolderItem(CSzFolder *f, CSzData *sd)
545 return SZ_ERROR_UNSUPPORTED; 519 return SZ_ERROR_UNSUPPORTED;
546 f->NumPackStreams = numPackStreams; 520 f->NumPackStreams = numPackStreams;
547 521
548 for (i = 0; i < numInStreams; i++) 522 for (i = 0; i < Z7_ARRAY_SIZE(streamUsed); i++) // numInStreams
549 streamUsed[i] = False; 523 streamUsed[i] = False;
550 524
551 if (numBonds != 0) 525 if (numBonds)
552 { 526 {
553 Byte coderUsed[SZ_NUM_CODERS_IN_FOLDER_MAX]; 527 Byte coderUsed[SZ_NUM_CODERS_IN_FOLDER_MAX];
554 528 for (i = 0; i < Z7_ARRAY_SIZE(coderUsed); i++) // numCoders
555 for (i = 0; i < numCoders; i++)
556 coderUsed[i] = False; 529 coderUsed[i] = False;
557 530
558 for (i = 0; i < numBonds; i++) 531 for (i = 0; i < numBonds; i++)
@@ -570,24 +543,25 @@ SRes SzGetNextFolderItem(CSzFolder *f, CSzData *sd)
570 coderUsed[bp->OutIndex] = True; 543 coderUsed[bp->OutIndex] = True;
571 } 544 }
572 545
573 for (i = 0; i < numCoders; i++) 546 for (i = 0;;)
547 {
574 if (!coderUsed[i]) 548 if (!coderUsed[i])
575 {
576 f->UnpackStream = i;
577 break; 549 break;
578 } 550 if (++i == numCoders)
579 551 return SZ_ERROR_ARCHIVE;
580 if (i == numCoders) 552 }
581 return SZ_ERROR_ARCHIVE; 553 f->UnpackStream = i;
582 } 554 }
583 555
584 if (numPackStreams == 1) 556 if (numPackStreams == 1)
585 { 557 {
586 for (i = 0; i < numInStreams; i++) 558 for (i = 0;; i++)
559 {
560 if (i == numInStreams)
561 return SZ_ERROR_ARCHIVE;
587 if (!streamUsed[i]) 562 if (!streamUsed[i])
588 break; 563 break;
589 if (i == numInStreams) 564 }
590 return SZ_ERROR_ARCHIVE;
591 f->PackStreams[0] = i; 565 f->PackStreams[0] = i;
592 } 566 }
593 else 567 else
@@ -601,40 +575,30 @@ SRes SzGetNextFolderItem(CSzFolder *f, CSzData *sd)
601 f->PackStreams[i] = index; 575 f->PackStreams[i] = index;
602 } 576 }
603 } 577 }
604
605 f->NumCoders = numCoders;
606
607 return SZ_OK; 578 return SZ_OK;
608} 579}
609 580
610 581
611static Z7_NO_INLINE SRes SkipNumbers(CSzData *sd2, UInt32 num) 582static SRes SkipNumbers(CSzData *sd2, UInt32 num)
612{ 583{
613 CSzData sd; 584 const Byte *data = sd2->Data;
614 sd = *sd2; 585 size_t size = sd2->Size;
615 for (; num != 0; num--) 586 for (; num != 0; num--)
616 { 587 {
617 Byte firstByte, mask; 588 unsigned firstByte;
618 unsigned i; 589 unsigned i;
619 SZ_READ_BYTE_2(firstByte) 590 if (size == 0)
620 if ((firstByte & 0x80) == 0)
621 continue;
622 if ((firstByte & 0x40) == 0)
623 {
624 if (sd.Size == 0)
625 return SZ_ERROR_ARCHIVE;
626 sd.Size--;
627 sd.Data++;
628 continue;
629 }
630 mask = 0x20;
631 for (i = 2; i < 8 && (firstByte & mask) != 0; i++)
632 mask >>= 1;
633 if (i > sd.Size)
634 return SZ_ERROR_ARCHIVE; 591 return SZ_ERROR_ARCHIVE;
635 SKIP_DATA2(sd, i) 592 firstByte = *data;
593 for (i = 1; firstByte & 0x80; i++)
594 firstByte <<= 1;
595 if (size < i)
596 return SZ_ERROR_ARCHIVE;
597 size -= i;
598 data += i;
636 } 599 }
637 *sd2 = sd; 600 sd2->Data = data;
601 sd2->Size = size;
638 return SZ_OK; 602 return SZ_OK;
639} 603}
640 604
@@ -642,15 +606,10 @@ static Z7_NO_INLINE SRes SkipNumbers(CSzData *sd2, UInt32 num)
642#define k_Scan_NumCoders_MAX 64 606#define k_Scan_NumCoders_MAX 64
643#define k_Scan_NumCodersStreams_in_Folder_MAX 64 607#define k_Scan_NumCodersStreams_in_Folder_MAX 64
644 608
645 609static SRes ReadUnpackInfo(CSzAr *p, CSzData *sd2, const UInt32 numFoldersMax,
646static SRes ReadUnpackInfo(CSzAr *p, 610 const CBuf *tempBufs, UInt32 numTempBufs, ISzAllocPtr alloc)
647 CSzData *sd2,
648 UInt32 numFoldersMax,
649 const CBuf *tempBufs, UInt32 numTempBufs,
650 ISzAllocPtr alloc)
651{ 611{
652 CSzData sd; 612 CSzData sd;
653
654 UInt32 fo, numFolders, numCodersOutStreams, packStreamIndex; 613 UInt32 fo, numFolders, numCodersOutStreams, packStreamIndex;
655 const Byte *startBufPtr; 614 const Byte *startBufPtr;
656 Byte external; 615 Byte external;
@@ -742,15 +701,12 @@ static SRes ReadUnpackInfo(CSzAr *p,
742 { 701 {
743 Byte streamUsed[k_Scan_NumCodersStreams_in_Folder_MAX]; 702 Byte streamUsed[k_Scan_NumCodersStreams_in_Folder_MAX];
744 Byte coderUsed[k_Scan_NumCoders_MAX]; 703 Byte coderUsed[k_Scan_NumCoders_MAX];
745
746 UInt32 i; 704 UInt32 i;
747 const UInt32 numBonds = numCoders - 1; 705 const UInt32 numBonds = numCoders - 1;
748 if (numInStreams < numBonds) 706 if (numInStreams < numBonds)
749 return SZ_ERROR_ARCHIVE; 707 return SZ_ERROR_ARCHIVE;
750
751 if (numInStreams > k_Scan_NumCodersStreams_in_Folder_MAX) 708 if (numInStreams > k_Scan_NumCodersStreams_in_Folder_MAX)
752 return SZ_ERROR_UNSUPPORTED; 709 return SZ_ERROR_UNSUPPORTED;
753
754 for (i = 0; i < numInStreams; i++) 710 for (i = 0; i < numInStreams; i++)
755 streamUsed[i] = False; 711 streamUsed[i] = False;
756 for (i = 0; i < numCoders; i++) 712 for (i = 0; i < numCoders; i++)
@@ -782,16 +738,15 @@ static SRes ReadUnpackInfo(CSzAr *p,
782 return SZ_ERROR_ARCHIVE; 738 return SZ_ERROR_ARCHIVE;
783 streamUsed[index] = True; 739 streamUsed[index] = True;
784 } 740 }
785 741
786 for (i = 0; i < numCoders; i++) 742 for (i = 0;;)
743 {
787 if (!coderUsed[i]) 744 if (!coderUsed[i])
788 {
789 indexOfMainStream = i;
790 break; 745 break;
791 } 746 if (++i == numCoders)
792 747 return SZ_ERROR_ARCHIVE;
793 if (i == numCoders) 748 }
794 return SZ_ERROR_ARCHIVE; 749 indexOfMainStream = i;
795 } 750 }
796 751
797 p->FoStartPackStreamIndex[fo] = packStreamIndex; 752 p->FoStartPackStreamIndex[fo] = packStreamIndex;
@@ -806,31 +761,38 @@ static SRes ReadUnpackInfo(CSzAr *p,
806 } 761 }
807 } 762 }
808 763
764 {
765 const size_t k_numCodersOutStreams_Limit = (size_t)1 << (sizeof(size_t) * 8 - 4);
766 if (numCodersOutStreams >= k_numCodersOutStreams_Limit)
767 return SZ_ERROR_UNSUPPORTED;
768 }
809 p->FoToCoderUnpackSizes[fo] = numCodersOutStreams; 769 p->FoToCoderUnpackSizes[fo] = numCodersOutStreams;
810 770 p->FoStartPackStreamIndex[fo] = packStreamIndex;
811 { 771 {
812 const size_t dataSize = (size_t)(sd.Data - startBufPtr); 772 const size_t dataSize = (size_t)(sd.Data - startBufPtr);
813 p->FoStartPackStreamIndex[fo] = packStreamIndex;
814 p->FoCodersOffsets[fo] = dataSize; 773 p->FoCodersOffsets[fo] = dataSize;
815 MY_ALLOC_ZE_AND_CPY(p->CodersData, dataSize, startBufPtr, alloc) 774 MY_ALLOC_ZE_AND_CPY(p->CodersData, dataSize, startBufPtr, alloc)
816 } 775 }
817 776
818 if (external != 0) 777 if (external)
819 { 778 {
820 if (sd.Size != 0) 779 if (sd.Size)
821 return SZ_ERROR_ARCHIVE; 780 return SZ_ERROR_ARCHIVE;
822 sd = *sd2; 781 sd = *sd2;
823 } 782 }
824 783
825 RINOK(WaitId(&sd, k7zIdCodersUnpackSize)) 784 RINOK(WaitId(&sd, k7zIdCodersUnpackSize))
826
827 MY_ALLOC_ZE(UInt64, p->CoderUnpackSizes, (size_t)numCodersOutStreams, alloc)
828 { 785 {
829 UInt32 i; 786 UInt64 *sizes;
830 for (i = 0; i < numCodersOutStreams; i++) 787 MY_ALLOC_ZE(UInt64, sizes, (size_t)numCodersOutStreams, alloc)
831 { 788 p->CoderUnpackSizes = sizes;
832 RINOK(ReadNumber(&sd, p->CoderUnpackSizes + i)) 789 if (numCodersOutStreams)
833 } 790 do
791 {
792 RINOK(ReadNumber(&sd, sizes))
793 sizes++;
794 }
795 while (--numCodersOutStreams);
834 } 796 }
835 797
836 for (;;) 798 for (;;)
@@ -838,10 +800,7 @@ static SRes ReadUnpackInfo(CSzAr *p,
838 UInt64 type; 800 UInt64 type;
839 RINOK(ReadID(&sd, &type)) 801 RINOK(ReadID(&sd, &type))
840 if (type == k7zIdEnd) 802 if (type == k7zIdEnd)
841 { 803 break;
842 *sd2 = sd;
843 return SZ_OK;
844 }
845 if (type == k7zIdCRC) 804 if (type == k7zIdCRC)
846 { 805 {
847 RINOK(ReadBitUi32s(&sd, numFolders, &p->FolderCRCs, alloc)) 806 RINOK(ReadBitUi32s(&sd, numFolders, &p->FolderCRCs, alloc))
@@ -849,6 +808,8 @@ static SRes ReadUnpackInfo(CSzAr *p,
849 } 808 }
850 RINOK(SkipData(&sd)) 809 RINOK(SkipData(&sd))
851 } 810 }
811 *sd2 = sd;
812 return SZ_OK;
852} 813}
853 814
854 815
@@ -868,12 +829,12 @@ typedef struct
868} CSubStreamInfo; 829} CSubStreamInfo;
869 830
870 831
871static SRes ReadSubStreamsInfo(CSzAr *p, CSzData *sd, CSubStreamInfo *ssi) 832static SRes ReadSubStreamsInfo(const CSzAr *p, CSzData *sd, CSubStreamInfo *ssi)
872{ 833{
873 UInt64 type = 0; 834 UInt64 type = 0;
874 UInt32 numSubDigests = 0;
875 const UInt32 numFolders = p->NumFolders; 835 const UInt32 numFolders = p->NumFolders;
876 UInt32 numUnpackStreams = numFolders; 836 UInt32 numUnpackStreams = numFolders;
837 UInt32 numSubDigests = numFolders;
877 UInt32 numUnpackSizesInData = 0; 838 UInt32 numUnpackSizesInData = 0;
878 839
879 for (;;) 840 for (;;)
@@ -882,6 +843,8 @@ static SRes ReadSubStreamsInfo(CSzAr *p, CSzData *sd, CSubStreamInfo *ssi)
882 if (type == k7zIdNumUnpackStream) 843 if (type == k7zIdNumUnpackStream)
883 { 844 {
884 UInt32 i; 845 UInt32 i;
846 if (ssi->sdNumSubStreams.Data)
847 return SZ_ERROR_UNSUPPORTED;
885 ssi->sdNumSubStreams.Data = sd->Data; 848 ssi->sdNumSubStreams.Data = sd->Data;
886 numUnpackStreams = 0; 849 numUnpackStreams = 0;
887 numSubDigests = 0; 850 numSubDigests = 0;
@@ -889,10 +852,10 @@ static SRes ReadSubStreamsInfo(CSzAr *p, CSzData *sd, CSubStreamInfo *ssi)
889 { 852 {
890 UInt32 numStreams; 853 UInt32 numStreams;
891 RINOK(SzReadNumber32(sd, &numStreams)) 854 RINOK(SzReadNumber32(sd, &numStreams))
892 if (numUnpackStreams > numUnpackStreams + numStreams)
893 return SZ_ERROR_UNSUPPORTED;
894 numUnpackStreams += numStreams; 855 numUnpackStreams += numStreams;
895 if (numStreams != 0) 856 if (numUnpackStreams < numStreams)
857 return SZ_ERROR_UNSUPPORTED;
858 if (numStreams)
896 numUnpackSizesInData += (numStreams - 1); 859 numUnpackSizesInData += (numStreams - 1);
897 if (numStreams != 1 || !SzBitWithVals_Check(&p->FolderCRCs, i)) 860 if (numStreams != 1 || !SzBitWithVals_Check(&p->FolderCRCs, i))
898 numSubDigests += numStreams; 861 numSubDigests += numStreams;
@@ -905,12 +868,8 @@ static SRes ReadSubStreamsInfo(CSzAr *p, CSzData *sd, CSubStreamInfo *ssi)
905 RINOK(SkipData(sd)) 868 RINOK(SkipData(sd))
906 } 869 }
907 870
908 if (!ssi->sdNumSubStreams.Data) 871 if (!ssi->sdNumSubStreams.Data && p->FolderCRCs.Defs)
909 { 872 numSubDigests = numFolders - CountDefinedBits(p->FolderCRCs.Defs, numFolders);
910 numSubDigests = numFolders;
911 if (p->FolderCRCs.Defs)
912 numSubDigests = numFolders - CountDefinedBits(p->FolderCRCs.Defs, numFolders);
913 }
914 873
915 ssi->NumTotalSubStreams = numUnpackStreams; 874 ssi->NumTotalSubStreams = numUnpackStreams;
916 ssi->NumSubDigests = numSubDigests; 875 ssi->NumSubDigests = numSubDigests;
@@ -929,6 +888,8 @@ static SRes ReadSubStreamsInfo(CSzAr *p, CSzData *sd, CSubStreamInfo *ssi)
929 return SZ_OK; 888 return SZ_OK;
930 if (type == k7zIdCRC) 889 if (type == k7zIdCRC)
931 { 890 {
891 if (ssi->sdCRCs.Data)
892 return SZ_ERROR_UNSUPPORTED;
932 ssi->sdCRCs.Data = sd->Data; 893 ssi->sdCRCs.Data = sd->Data;
933 RINOK(SkipBitUi32s(sd, numSubDigests)) 894 RINOK(SkipBitUi32s(sd, numSubDigests))
934 ssi->sdCRCs.Size = (size_t)(sd->Data - ssi->sdCRCs.Data); 895 ssi->sdCRCs.Size = (size_t)(sd->Data - ssi->sdCRCs.Data);
@@ -941,9 +902,11 @@ static SRes ReadSubStreamsInfo(CSzAr *p, CSzData *sd, CSubStreamInfo *ssi)
941 } 902 }
942} 903}
943 904
905
944static SRes SzReadStreamsInfo(CSzAr *p, 906static SRes SzReadStreamsInfo(CSzAr *p,
945 CSzData *sd, 907 CSzData *sd,
946 UInt32 numFoldersMax, const CBuf *tempBufs, UInt32 numTempBufs, 908 const UInt32 numFoldersMax,
909 const CBuf * const tempBufs, const UInt32 numTempBufs,
947 UInt64 *dataOffset, 910 UInt64 *dataOffset,
948 CSubStreamInfo *ssi, 911 CSubStreamInfo *ssi,
949 ISzAllocPtr alloc) 912 ISzAllocPtr alloc)
@@ -985,12 +948,13 @@ static SRes SzReadStreamsInfo(CSzAr *p,
985 return (type == k7zIdEnd ? SZ_OK : SZ_ERROR_UNSUPPORTED); 948 return (type == k7zIdEnd ? SZ_OK : SZ_ERROR_UNSUPPORTED);
986} 949}
987 950
951
988static SRes SzReadAndDecodePackedStreams( 952static SRes SzReadAndDecodePackedStreams(
989 ILookInStreamPtr inStream, 953 ILookInStreamPtr inStream,
990 CSzData *sd, 954 CSzData *sd,
991 CBuf *tempBufs, 955 CBuf * const tempBufs,
992 UInt32 numFoldersMax, 956 const UInt32 numFoldersMax,
993 UInt64 baseOffset, 957 const UInt64 baseOffset,
994 CSzAr *p, 958 CSzAr *p,
995 ISzAllocPtr allocTemp) 959 ISzAllocPtr allocTemp)
996{ 960{
@@ -1027,6 +991,7 @@ static SRes SzReadAndDecodePackedStreams(
1027 return SZ_OK; 991 return SZ_OK;
1028} 992}
1029 993
994
1030// (size & 1) == 0 995// (size & 1) == 0
1031// (data) is aligned for 2-bytes 996// (data) is aligned for 2-bytes
1032static SRes SzReadFileNames(const Byte *data, size_t size, UInt32 numFiles, size_t *offsets) 997static SRes SzReadFileNames(const Byte *data, size_t size, UInt32 numFiles, size_t *offsets)
@@ -1053,30 +1018,35 @@ static SRes SzReadFileNames(const Byte *data, size_t size, UInt32 numFiles, size
1053 return (p == lim) ? SZ_OK : SZ_ERROR_ARCHIVE; 1018 return (p == lim) ? SZ_OK : SZ_ERROR_ARCHIVE;
1054} 1019}
1055 1020
1056static Z7_NO_INLINE SRes ReadTime(CSzBitUi64s *p, size_t num, 1021
1057 CSzData *sd2, 1022static SRes ReadTime(CSzBitUi64s *p, size_t num, CSzData *sd2,
1058 const CBuf *tempBufs, UInt32 numTempBufs, 1023 const CBuf *tempBufs, UInt32 numTempBufs, ISzAllocPtr alloc)
1059 ISzAllocPtr alloc)
1060{ 1024{
1061 CSzData sd; 1025 const Byte *data;
1026 size_t size;
1062 size_t i; 1027 size_t i;
1063 CNtfsFileTime *vals; 1028 CNtfsFileTime *vals;
1064 Byte *defs; 1029 Byte *defs;
1065 Byte external; 1030 Byte external;
1066 1031
1032 if (p->Defs)
1033 return SZ_ERROR_ARCHIVE;
1067 RINOK(ReadBitVector(sd2, num, &p->Defs, alloc)) 1034 RINOK(ReadBitVector(sd2, num, &p->Defs, alloc))
1068 1035
1069 SZ_READ_BYTE_SD(sd2, external) 1036 SZ_READ_BYTE_SD(sd2, external)
1070 if (external == 0) 1037 if (external == 0)
1071 sd = *sd2; 1038 {
1039 data = sd2->Data;
1040 size = sd2->Size;
1041 }
1072 else 1042 else
1073 { 1043 {
1074 UInt32 index; 1044 UInt32 index;
1075 RINOK(SzReadNumber32(sd2, &index)) 1045 RINOK(SzReadNumber32(sd2, &index))
1076 if (index >= numTempBufs) 1046 if (index >= numTempBufs || sd2->Size)
1077 return SZ_ERROR_ARCHIVE; 1047 return SZ_ERROR_ARCHIVE;
1078 sd.Data = tempBufs[index].data; 1048 data = tempBufs[index].data;
1079 sd.Size = tempBufs[index].size; 1049 size = tempBufs[index].size;
1080 } 1050 }
1081 1051
1082 MY_ALLOC_ZE(CNtfsFileTime, p->Vals, num, alloc) 1052 MY_ALLOC_ZE(CNtfsFileTime, p->Vals, num, alloc)
@@ -1085,18 +1055,18 @@ static Z7_NO_INLINE SRes ReadTime(CSzBitUi64s *p, size_t num,
1085 for (i = 0; i < num; i++) 1055 for (i = 0; i < num; i++)
1086 if (SzBitArray_Check(defs, i)) 1056 if (SzBitArray_Check(defs, i))
1087 { 1057 {
1088 if (sd.Size < 8) 1058 if (size < 8)
1089 return SZ_ERROR_ARCHIVE; 1059 return SZ_ERROR_ARCHIVE;
1090 vals[i].Low = GetUi32(sd.Data); 1060 size -= 8;
1091 vals[i].High = GetUi32(sd.Data + 4); 1061 vals[i].Low = GetUi32(data);
1092 SKIP_DATA2(sd, 8) 1062 vals[i].High = GetUi32(data + 4);
1063 data += 8;
1093 } 1064 }
1094 else 1065 else
1095 vals[i].High = vals[i].Low = 0; 1066 vals[i].High = vals[i].Low = 0;
1096 1067
1097 if (external == 0) 1068 if (size)
1098 *sd2 = sd; 1069 return SZ_ERROR_ARCHIVE;
1099
1100 return SZ_OK; 1070 return SZ_OK;
1101} 1071}
1102 1072
@@ -1104,16 +1074,11 @@ static Z7_NO_INLINE SRes ReadTime(CSzBitUi64s *p, size_t num,
1104#define NUM_ADDITIONAL_STREAMS_MAX 8 1074#define NUM_ADDITIONAL_STREAMS_MAX 8
1105 1075
1106 1076
1107static SRes SzReadHeader2( 1077static SRes SzReadHeader2(CSzArEx *p, CSzData *sd, ILookInStreamPtr inStream,
1108 CSzArEx *p, /* allocMain */ 1078 CBuf * const tempBufs, ISzAllocPtr allocMain, ISzAllocPtr allocTemp)
1109 CSzData *sd,
1110 ILookInStreamPtr inStream,
1111 CBuf *tempBufs, UInt32 *numTempBufs,
1112 ISzAllocPtr allocMain,
1113 ISzAllocPtr allocTemp
1114 )
1115{ 1079{
1116 CSubStreamInfo ssi; 1080 CSubStreamInfo ssi;
1081 UInt32 numTempBufs = 0;
1117 1082
1118{ 1083{
1119 UInt64 type; 1084 UInt64 type;
@@ -1150,7 +1115,7 @@ static SRes SzReadHeader2(
1150 1115
1151 res = SzReadAndDecodePackedStreams(inStream, sd, tempBufs, NUM_ADDITIONAL_STREAMS_MAX, 1116 res = SzReadAndDecodePackedStreams(inStream, sd, tempBufs, NUM_ADDITIONAL_STREAMS_MAX,
1152 p->startPosAfterHeader, &tempAr, allocTemp); 1117 p->startPosAfterHeader, &tempAr, allocTemp);
1153 *numTempBufs = tempAr.NumFolders; 1118 numTempBufs = tempAr.NumFolders;
1154 SzAr_Free(&tempAr, allocTemp); 1119 SzAr_Free(&tempAr, allocTemp);
1155 1120
1156 if (res != SZ_OK) 1121 if (res != SZ_OK)
@@ -1160,24 +1125,21 @@ static SRes SzReadHeader2(
1160 1125
1161 if (type == k7zIdMainStreamsInfo) 1126 if (type == k7zIdMainStreamsInfo)
1162 { 1127 {
1163 RINOK(SzReadStreamsInfo(&p->db, sd, (UInt32)1 << 30, tempBufs, *numTempBufs, 1128 static const UInt32 k_numFoldersMax = (UInt32)1 << 30;
1129 RINOK(SzReadStreamsInfo(&p->db, sd, k_numFoldersMax, tempBufs, numTempBufs,
1164 &p->dataPos, &ssi, allocMain)) 1130 &p->dataPos, &ssi, allocMain))
1165 p->dataPos += p->startPosAfterHeader; 1131 p->dataPos += p->startPosAfterHeader;
1166 RINOK(ReadID(sd, &type)) 1132 RINOK(ReadID(sd, &type))
1167 } 1133 }
1168 1134
1169 if (type == k7zIdEnd) 1135 if (type == k7zIdEnd)
1170 {
1171 return SZ_OK; 1136 return SZ_OK;
1172 }
1173
1174 if (type != k7zIdFilesInfo) 1137 if (type != k7zIdFilesInfo)
1175 return SZ_ERROR_ARCHIVE; 1138 return SZ_ERROR_ARCHIVE;
1176} 1139}
1177 1140
1178{ 1141{
1179 UInt32 numFiles = 0; 1142 UInt32 numFiles, numEmptyStreams = 0;
1180 UInt32 numEmptyStreams = 0;
1181 const Byte *emptyStreams = NULL; 1143 const Byte *emptyStreams = NULL;
1182 const Byte *emptyFiles = NULL; 1144 const Byte *emptyFiles = NULL;
1183 1145
@@ -1186,44 +1148,68 @@ static SRes SzReadHeader2(
1186 1148
1187 for (;;) 1149 for (;;)
1188 { 1150 {
1151 CSzData sdSwitch;
1189 UInt64 type; 1152 UInt64 type;
1190 UInt64 size;
1191 RINOK(ReadID(sd, &type)) 1153 RINOK(ReadID(sd, &type))
1192 if (type == k7zIdEnd) 1154 if (type == k7zIdEnd)
1193 break; 1155 break;
1194 RINOK(ReadNumber(sd, &size))
1195 if (size > sd->Size)
1196 return SZ_ERROR_ARCHIVE;
1197
1198 if (type >= ((UInt32)1 << 8))
1199 { 1156 {
1157 UInt64 size;
1158 RINOK(ReadNumber(sd, &size))
1159 if (size > sd->Size)
1160 return SZ_ERROR_ARCHIVE;
1161 sdSwitch.Data = sd->Data;
1162 sdSwitch.Size = (size_t)size;
1200 SKIP_DATA(sd, size) 1163 SKIP_DATA(sd, size)
1201 } 1164 }
1202 else switch ((unsigned)type) 1165 if (type >= 64)
1166 continue;
1167
1168 switch ((unsigned)type)
1203 { 1169 {
1170 case k7zIdEmptyStream:
1171 {
1172 if (emptyStreams || emptyFiles)
1173 return SZ_ERROR_ARCHIVE;
1174 if ((numFiles + 7) >> 3 != sdSwitch.Size)
1175 return SZ_ERROR_ARCHIVE;
1176 emptyStreams = sdSwitch.Data;
1177 numEmptyStreams = CountDefinedBits(emptyStreams, numFiles);
1178 break;
1179 }
1180
1181 case k7zIdEmptyFile:
1182 {
1183 if (emptyFiles)
1184 return SZ_ERROR_ARCHIVE;
1185 if ((numEmptyStreams + 7) >> 3 != sdSwitch.Size)
1186 return SZ_ERROR_ARCHIVE;
1187 emptyFiles = sdSwitch.Data;
1188 break;
1189 }
1190
1204 case k7zIdName: 1191 case k7zIdName:
1205 { 1192 {
1206 size_t namesSize; 1193 size_t namesSize;
1207 const Byte *namesData; 1194 const Byte *namesData;
1208 Byte external; 1195 Byte external;
1209 1196 if (p->FileNameOffsets)
1210 SZ_READ_BYTE(external) 1197 return SZ_ERROR_ARCHIVE;
1198 SZ_READ_BYTE_SD(&sdSwitch, external)
1211 if (external == 0) 1199 if (external == 0)
1212 { 1200 {
1213 namesSize = (size_t)size - 1; 1201 namesData = sdSwitch.Data;
1214 namesData = sd->Data; 1202 namesSize = sdSwitch.Size;
1215 SKIP_DATA(sd, namesSize)
1216 } 1203 }
1217 else 1204 else
1218 { 1205 {
1219 UInt32 index; 1206 UInt32 index;
1220 RINOK(SzReadNumber32(sd, &index)) 1207 RINOK(SzReadNumber32(&sdSwitch, &index))
1221 if (index >= *numTempBufs) 1208 if (index >= numTempBufs || sdSwitch.Size)
1222 return SZ_ERROR_ARCHIVE; 1209 return SZ_ERROR_ARCHIVE;
1223 namesData = (tempBufs)[index].data; 1210 namesData = tempBufs[index].data;
1224 namesSize = (tempBufs)[index].size; 1211 namesSize = tempBufs[index].size;
1225 } 1212 }
1226
1227 if (namesSize & 1) 1213 if (namesSize & 1)
1228 return SZ_ERROR_ARCHIVE; 1214 return SZ_ERROR_ARCHIVE;
1229 MY_ALLOC(size_t, p->FileNameOffsets, numFiles + 1, allocMain) 1215 MY_ALLOC(size_t, p->FileNameOffsets, numFiles + 1, allocMain)
@@ -1231,58 +1217,38 @@ static SRes SzReadHeader2(
1231 RINOK(SzReadFileNames(p->FileNames, namesSize, numFiles, p->FileNameOffsets)) 1217 RINOK(SzReadFileNames(p->FileNames, namesSize, numFiles, p->FileNameOffsets))
1232 break; 1218 break;
1233 } 1219 }
1234 case k7zIdEmptyStream: 1220
1235 {
1236 RINOK(RememberBitVector(sd, numFiles, &emptyStreams))
1237 numEmptyStreams = CountDefinedBits(emptyStreams, numFiles);
1238 emptyFiles = NULL;
1239 break;
1240 }
1241 case k7zIdEmptyFile:
1242 {
1243 RINOK(RememberBitVector(sd, numEmptyStreams, &emptyFiles))
1244 break;
1245 }
1246 case k7zIdWinAttrib: 1221 case k7zIdWinAttrib:
1247 { 1222 {
1248 Byte external; 1223 Byte external;
1249 CSzData sdSwitch; 1224 if (p->Attribs.Defs)
1250 CSzData *sdPtr; 1225 return SZ_ERROR_ARCHIVE;
1251 SzBitUi32s_Free(&p->Attribs, allocMain); 1226 RINOK(ReadBitVector(&sdSwitch, numFiles, &p->Attribs.Defs, allocMain))
1252 RINOK(ReadBitVector(sd, numFiles, &p->Attribs.Defs, allocMain)) 1227 SZ_READ_BYTE_SD(&sdSwitch, external)
1253 1228 if (external)
1254 SZ_READ_BYTE(external)
1255 if (external == 0)
1256 sdPtr = sd;
1257 else
1258 { 1229 {
1259 UInt32 index; 1230 UInt32 index;
1260 RINOK(SzReadNumber32(sd, &index)) 1231 RINOK(SzReadNumber32(&sdSwitch, &index))
1261 if (index >= *numTempBufs) 1232 if (index >= numTempBufs || sdSwitch.Size)
1262 return SZ_ERROR_ARCHIVE; 1233 return SZ_ERROR_ARCHIVE;
1263 sdSwitch.Data = (tempBufs)[index].data; 1234 sdSwitch.Data = tempBufs[index].data;
1264 sdSwitch.Size = (tempBufs)[index].size; 1235 sdSwitch.Size = tempBufs[index].size;
1265 sdPtr = &sdSwitch;
1266 } 1236 }
1267 RINOK(ReadUi32s(sdPtr, numFiles, &p->Attribs, allocMain)) 1237 RINOK(ReadUi32s(&sdSwitch, numFiles, &p->Attribs, allocMain))
1238 if (sdSwitch.Size)
1239 return SZ_ERROR_ARCHIVE;
1268 break; 1240 break;
1269 } 1241 }
1270 /* 1242
1271 case k7zParent: 1243 case k7zIdMTime:
1244 case k7zIdCTime:
1272 { 1245 {
1273 SzBitUi32s_Free(&p->Parents, allocMain); 1246 RINOK(ReadTime((unsigned)type == k7zIdMTime ? &p->MTime: &p->CTime,
1274 RINOK(ReadBitVector(sd, numFiles, &p->Parents.Defs, allocMain)); 1247 numFiles, &sdSwitch, tempBufs, numTempBufs, allocMain))
1275 RINOK(SzReadSwitch(sd));
1276 RINOK(ReadUi32s(sd, numFiles, &p->Parents, allocMain));
1277 break; 1248 break;
1278 } 1249 }
1279 */ 1250
1280 case k7zIdMTime: RINOK(ReadTime(&p->MTime, numFiles, sd, tempBufs, *numTempBufs, allocMain)) break; 1251 default: break;
1281 case k7zIdCTime: RINOK(ReadTime(&p->CTime, numFiles, sd, tempBufs, *numTempBufs, allocMain)) break;
1282 default:
1283 {
1284 SKIP_DATA(sd, size)
1285 }
1286 } 1252 }
1287 } 1253 }
1288 1254
@@ -1481,25 +1447,19 @@ static SRes SzReadHeader(
1481 ISzAllocPtr allocTemp) 1447 ISzAllocPtr allocTemp)
1482{ 1448{
1483 UInt32 i; 1449 UInt32 i;
1484 UInt32 numTempBufs = 0;
1485 SRes res; 1450 SRes res;
1486 CBuf tempBufs[NUM_ADDITIONAL_STREAMS_MAX]; 1451 CBuf tempBufs[NUM_ADDITIONAL_STREAMS_MAX];
1487 1452
1488 for (i = 0; i < NUM_ADDITIONAL_STREAMS_MAX; i++) 1453 for (i = 0; i < NUM_ADDITIONAL_STREAMS_MAX; i++)
1489 Buf_Init(tempBufs + i); 1454 Buf_Init(tempBufs + i);
1490 1455
1491 res = SzReadHeader2(p, sd, inStream, 1456 res = SzReadHeader2(p, sd, inStream, tempBufs, allocMain, allocTemp);
1492 tempBufs, &numTempBufs,
1493 allocMain, allocTemp);
1494 1457
1495 for (i = 0; i < NUM_ADDITIONAL_STREAMS_MAX; i++) 1458 for (i = 0; i < NUM_ADDITIONAL_STREAMS_MAX; i++)
1496 Buf_Free(tempBufs + i, allocTemp); 1459 Buf_Free(tempBufs + i, allocTemp);
1497 1460
1498 RINOK(res) 1461 if (res == SZ_OK && sd->Size != 0)
1499 1462 return SZ_ERROR_ARCHIVE;
1500 if (sd->Size != 0)
1501 return SZ_ERROR_FAIL;
1502
1503 return res; 1463 return res;
1504} 1464}
1505 1465
@@ -1510,53 +1470,52 @@ static SRes SzArEx_Open2(
1510 ISzAllocPtr allocTemp) 1470 ISzAllocPtr allocTemp)
1511{ 1471{
1512 Byte header[k7zStartHeaderSize]; 1472 Byte header[k7zStartHeaderSize];
1513 Int64 startArcPos; 1473 Int64 startPosAfterHeader;
1514 UInt64 nextHeaderOffset, nextHeaderSize; 1474 UInt64 nextHeaderOffset, nextHeaderSize;
1515 size_t nextHeaderSizeT; 1475 size_t nextHeaderSizeT;
1516 UInt32 nextHeaderCRC; 1476 UInt32 nextHeaderCRC;
1517 CBuf buf; 1477 CBuf buf;
1518 SRes res; 1478 SRes res;
1519 1479
1520 startArcPos = 0;
1521 RINOK(ILookInStream_Seek(inStream, &startArcPos, SZ_SEEK_CUR))
1522
1523 RINOK(LookInStream_Read2(inStream, header, k7zStartHeaderSize, SZ_ERROR_NO_ARCHIVE)) 1480 RINOK(LookInStream_Read2(inStream, header, k7zStartHeaderSize, SZ_ERROR_NO_ARCHIVE))
1524 1481 startPosAfterHeader = 0; // k7zStartHeaderSize
1525 if (!TestSignatureCandidate(header)) 1482 RINOK(ILookInStream_Seek(inStream, &startPosAfterHeader, SZ_SEEK_CUR))
1526 return SZ_ERROR_NO_ARCHIVE; 1483 p->startPosAfterHeader = (UInt64)startPosAfterHeader;
1527 if (header[6] != k7zMajorVersion) 1484 {
1528 return SZ_ERROR_UNSUPPORTED; 1485 unsigned i;
1486 for (i = 0; i < k7zSignatureSize; i++)
1487 if (header[i] != k7zSignature[i])
1488 return SZ_ERROR_NO_ARCHIVE;
1489 if (header[6] != 0) // k7zMajorVersion
1490 return SZ_ERROR_UNSUPPORTED;
1491 }
1492 if (CrcCalc(header + 12, 20) != GetUi32(header + 8))
1493 return SZ_ERROR_CRC;
1529 1494
1530 nextHeaderOffset = GetUi64(header + 12); 1495 nextHeaderOffset = GetUi64(header + 12);
1531 nextHeaderSize = GetUi64(header + 20); 1496 nextHeaderSize = GetUi64(header + 20);
1532 nextHeaderCRC = GetUi32(header + 28); 1497 nextHeaderCRC = GetUi32(header + 28);
1533 1498
1534 p->startPosAfterHeader = (UInt64)startArcPos + k7zStartHeaderSize;
1535
1536 if (CrcCalc(header + 12, 20) != GetUi32(header + 8))
1537 return SZ_ERROR_CRC;
1538
1539 p->db.RangeLimit = nextHeaderOffset; 1499 p->db.RangeLimit = nextHeaderOffset;
1540 1500 if (nextHeaderOffset >= (UInt64)1 << 62 ||
1501 nextHeaderSize >= (UInt64)1 << 48)
1502 return SZ_ERROR_NO_ARCHIVE;
1541 nextHeaderSizeT = (size_t)nextHeaderSize; 1503 nextHeaderSizeT = (size_t)nextHeaderSize;
1542 if (nextHeaderSizeT != nextHeaderSize) 1504 if (nextHeaderSizeT != nextHeaderSize)
1543 return SZ_ERROR_MEM; 1505 return SZ_ERROR_MEM;
1544 if (nextHeaderSizeT == 0) 1506 if (nextHeaderSizeT == 0)
1507 {
1508 if (nextHeaderOffset != 0 || nextHeaderCRC != 0)
1509 return SZ_ERROR_NO_ARCHIVE;
1545 return SZ_OK; 1510 return SZ_OK;
1546 if (nextHeaderOffset > nextHeaderOffset + nextHeaderSize || 1511 }
1547 nextHeaderOffset > nextHeaderOffset + nextHeaderSize + k7zStartHeaderSize)
1548 return SZ_ERROR_NO_ARCHIVE;
1549
1550 { 1512 {
1551 Int64 pos = 0; 1513 Int64 pos = 0;
1552 RINOK(ILookInStream_Seek(inStream, &pos, SZ_SEEK_END)) 1514 RINOK(ILookInStream_Seek(inStream, &pos, SZ_SEEK_END))
1553 if ((UInt64)pos < (UInt64)startArcPos + nextHeaderOffset || 1515 if ((UInt64)(pos - startPosAfterHeader) < nextHeaderOffset + nextHeaderSize)
1554 (UInt64)pos < (UInt64)startArcPos + k7zStartHeaderSize + nextHeaderOffset ||
1555 (UInt64)pos < (UInt64)startArcPos + k7zStartHeaderSize + nextHeaderOffset + nextHeaderSize)
1556 return SZ_ERROR_INPUT_EOF; 1516 return SZ_ERROR_INPUT_EOF;
1557 } 1517 }
1558 1518 RINOK(LookInStream_SeekTo(inStream, (UInt64)startPosAfterHeader + nextHeaderOffset))
1559 RINOK(LookInStream_SeekTo(inStream, (UInt64)startArcPos + k7zStartHeaderSize + nextHeaderOffset))
1560 1519
1561 if (!Buf_Create(&buf, nextHeaderSizeT, allocTemp)) 1520 if (!Buf_Create(&buf, nextHeaderSizeT, allocTemp))
1562 return SZ_ERROR_MEM; 1521 return SZ_ERROR_MEM;
@@ -1720,61 +1679,23 @@ SRes SzArEx_Extract(
1720 1679
1721size_t SzArEx_GetFileNameUtf16(const CSzArEx *p, size_t fileIndex, UInt16 *dest) 1680size_t SzArEx_GetFileNameUtf16(const CSzArEx *p, size_t fileIndex, UInt16 *dest)
1722{ 1681{
1723 const size_t offs = p->FileNameOffsets[fileIndex]; 1682 const size_t * const offsets = p->FileNameOffsets;
1724 const size_t len = p->FileNameOffsets[fileIndex + 1] - offs; 1683 if (!offsets)
1725 if (dest != 0)
1726 { 1684 {
1727 size_t i; 1685 if (dest)
1728 const Byte *src = p->FileNames + offs * 2; 1686 *dest = 0;
1729 for (i = 0; i < len; i++)
1730 dest[i] = GetUi16(src + i * 2);
1731 }
1732 return len;
1733}
1734
1735/*
1736size_t SzArEx_GetFullNameLen(const CSzArEx *p, size_t fileIndex)
1737{
1738 size_t len;
1739 if (!p->FileNameOffsets)
1740 return 1; 1687 return 1;
1741 len = 0;
1742 for (;;)
1743 {
1744 UInt32 parent = (UInt32)(Int32)-1;
1745 len += p->FileNameOffsets[fileIndex + 1] - p->FileNameOffsets[fileIndex];
1746 if SzBitWithVals_Check(&p->Parents, fileIndex)
1747 parent = p->Parents.Vals[fileIndex];
1748 if (parent == (UInt32)(Int32)-1)
1749 return len;
1750 fileIndex = parent;
1751 } 1688 }
1752}
1753
1754UInt16 *SzArEx_GetFullNameUtf16_Back(const CSzArEx *p, size_t fileIndex, UInt16 *dest)
1755{
1756 BoolInt needSlash;
1757 if (!p->FileNameOffsets)
1758 {
1759 *(--dest) = 0;
1760 return dest;
1761 }
1762 needSlash = False;
1763 for (;;)
1764 { 1689 {
1765 UInt32 parent = (UInt32)(Int32)-1; 1690 const size_t offs = offsets[fileIndex];
1766 size_t curLen = p->FileNameOffsets[fileIndex + 1] - p->FileNameOffsets[fileIndex]; 1691 const size_t len = offsets[fileIndex + 1] - offs;
1767 SzArEx_GetFileNameUtf16(p, fileIndex, dest - curLen); 1692 if (dest)
1768 if (needSlash) 1693 {
1769 *(dest - 1) = '/'; 1694 size_t i;
1770 needSlash = True; 1695 const Byte *src = p->FileNames + offs * 2;
1771 dest -= curLen; 1696 for (i = 0; i < len; i++)
1772 1697 dest[i] = GetUi16a(src + i * 2);
1773 if SzBitWithVals_Check(&p->Parents, fileIndex) 1698 }
1774 parent = p->Parents.Vals[fileIndex]; 1699 return len;
1775 if (parent == (UInt32)(Int32)-1)
1776 return dest;
1777 fileIndex = parent;
1778 } 1700 }
1779} 1701}
1780*/
diff --git a/C/7zVersion.h b/C/7zVersion.h
index 387a91c..50ccebb 100644
--- a/C/7zVersion.h
+++ b/C/7zVersion.h
@@ -1,7 +1,7 @@
1#define MY_VER_MAJOR 26 1#define MY_VER_MAJOR 26
2#define MY_VER_MINOR 1 2#define MY_VER_MINOR 2
3#define MY_VER_BUILD 0 3#define MY_VER_BUILD 0
4#define MY_VERSION_NUMBERS "26.01" 4#define MY_VERSION_NUMBERS "26.02"
5#define MY_VERSION MY_VERSION_NUMBERS 5#define MY_VERSION MY_VERSION_NUMBERS
6 6
7#ifdef MY_CPU_NAME 7#ifdef MY_CPU_NAME
@@ -10,7 +10,7 @@
10 #define MY_VERSION_CPU MY_VERSION 10 #define MY_VERSION_CPU MY_VERSION
11#endif 11#endif
12 12
13#define MY_DATE "2026-04-27" 13#define MY_DATE "2026-06-25"
14#undef MY_COPYRIGHT 14#undef MY_COPYRIGHT
15#undef MY_VERSION_COPYRIGHT_DATE 15#undef MY_VERSION_COPYRIGHT_DATE
16#define MY_AUTHOR_NAME "Igor Pavlov" 16#define MY_AUTHOR_NAME "Igor Pavlov"
diff --git a/C/Compiler.h b/C/Compiler.h
index a3577b2..c06b883 100644
--- a/C/Compiler.h
+++ b/C/Compiler.h
@@ -76,6 +76,11 @@
76 #pragma GCC diagnostic ignored "-Wreserved-identifier" 76 #pragma GCC diagnostic ignored "-Wreserved-identifier"
77#endif 77#endif
78 78
79#if __clang_major__ >= 22
80// for "StdAfx.h" and "Precomp.h"
81#pragma GCC diagnostic ignored "-Wshadow-header"
82#endif
83
79#endif // __clang__ 84#endif // __clang__
80 85
81#if defined(__clang__) && __clang_major__ >= 16 86#if defined(__clang__) && __clang_major__ >= 16
diff --git a/C/DllSecur.c b/C/DllSecur.c
index bbbfc0a..d385259 100644
--- a/C/DllSecur.c
+++ b/C/DllSecur.c
@@ -1,5 +1,5 @@
1/* DllSecur.c -- DLL loading security 1/* DllSecur.c -- DLL loading security
22023-12-03 : Igor Pavlov : Public domain */ 2: Igor Pavlov : Public domain */
3 3
4#include "Precomp.h" 4#include "Precomp.h"
5 5
@@ -67,7 +67,7 @@ void LoadSecurityDlls(void)
67 // at Vista (ver 6.0) : CoCreateInstance(CLSID_ShellLink, ...) doesn't work after SetDefaultDllDirectories() : Check it ??? 67 // at Vista (ver 6.0) : CoCreateInstance(CLSID_ShellLink, ...) doesn't work after SetDefaultDllDirectories() : Check it ???
68 IF_NON_VISTA_SET_DLL_DIRS_AND_RETURN 68 IF_NON_VISTA_SET_DLL_DIRS_AND_RETURN
69 { 69 {
70 wchar_t buf[MAX_PATH + 100]; 70 WCHAR buf[MAX_PATH + 100];
71 const char *dll; 71 const char *dll;
72 unsigned pos = GetSystemDirectoryW(buf, MAX_PATH + 2); 72 unsigned pos = GetSystemDirectoryW(buf, MAX_PATH + 2);
73 if (pos == 0 || pos > MAX_PATH) 73 if (pos == 0 || pos > MAX_PATH)
@@ -76,7 +76,7 @@ void LoadSecurityDlls(void)
76 buf[pos++] = '\\'; 76 buf[pos++] = '\\';
77 for (dll = g_Dlls; *dll != 0;) 77 for (dll = g_Dlls; *dll != 0;)
78 { 78 {
79 wchar_t *dest = &buf[pos]; 79 WCHAR *dest = &buf[pos];
80 for (;;) 80 for (;;)
81 { 81 {
82 const char c = *dll++; 82 const char c = *dll++;
diff --git a/C/MtDec.c b/C/MtDec.c
index 96274b6..71fc1ee 100644
--- a/C/MtDec.c
+++ b/C/MtDec.c
@@ -1,5 +1,5 @@
1/* MtDec.c -- Multi-thread Decoder 1/* MtDec.c -- Multi-thread Decoder
22024-02-20 : Igor Pavlov : Public domain */ 2: Igor Pavlov : Public domain */
3 3
4#include "Precomp.h" 4#include "Precomp.h"
5 5
@@ -22,7 +22,7 @@
22#define PRF(x) 22#define PRF(x)
23#endif 23#endif
24 24
25#define PRF_STR_INT(s, d) PRF(printf("\n" s " %d\n", (unsigned)d)) 25#define PRF_STR_INT(s, d) PRF(printf("\n" s " %d\n", (unsigned)d);)
26 26
27void MtProgress_Init(CMtProgress *p, ICompressProgressPtr progress) 27void MtProgress_Init(CMtProgress *p, ICompressProgressPtr progress)
28{ 28{
diff --git a/C/Util/7z/7zMain.c b/C/Util/7z/7zMain.c
index 7048b66..300c363 100644
--- a/C/Util/7z/7zMain.c
+++ b/C/Util/7z/7zMain.c
@@ -960,7 +960,12 @@ int Z7_CDECL main(int numargs, char *args[])
960 if (listCommand == 0 && isDir && !fullPaths) 960 if (listCommand == 0 && isDir && !fullPaths)
961 continue; 961 continue;
962 len = SzArEx_GetFileNameUtf16(&db, i, NULL); 962 len = SzArEx_GetFileNameUtf16(&db, i, NULL);
963 // len = SzArEx_GetFullNameLen(&db, i); 963
964 if (len > (1u << 20))
965 {
966 res = SZ_ERROR_UNSUPPORTED;
967 break;
968 }
964 969
965 if (len > tempSize) 970 if (len > tempSize)
966 { 971 {
diff --git a/C/Util/7zipInstall/7zipInstall.c b/C/Util/7zipInstall/7zipInstall.c
index 7d8e8c4..ce30732 100644
--- a/C/Util/7zipInstall/7zipInstall.c
+++ b/C/Util/7zipInstall/7zipInstall.c
@@ -1,5 +1,5 @@
1/* 7zipInstall.c - 7-Zip Installer 1/* 7zipInstall.c - 7-Zip Installer
22024-04-05 : Igor Pavlov : Public domain */ 2: Igor Pavlov : Public domain */
3 3
4#include "Precomp.h" 4#include "Precomp.h"
5 5
@@ -142,7 +142,7 @@ static WCHAR path[MAX_PATH * 2 + 40];
142 142
143 143
144 144
145static void CpyAscii(wchar_t *dest, const char *s) 145static void CpyAscii(WCHAR *dest, const char *s)
146{ 146{
147 for (;;) 147 for (;;)
148 { 148 {
@@ -153,13 +153,13 @@ static void CpyAscii(wchar_t *dest, const char *s)
153 } 153 }
154} 154}
155 155
156static void CatAscii(wchar_t *dest, const char *s) 156static void CatAscii(WCHAR *dest, const char *s)
157{ 157{
158 dest += wcslen(dest); 158 dest += wcslen(dest);
159 CpyAscii(dest, s); 159 CpyAscii(dest, s);
160} 160}
161 161
162static void PrintErrorMessage(const char *s1, const wchar_t *s2) 162static void PrintErrorMessage(const char *s1, const WCHAR *s2)
163{ 163{
164 WCHAR m[MAX_PATH + 512]; 164 WCHAR m[MAX_PATH + 512];
165 m[0] = 0; 165 m[0] = 0;
@@ -196,7 +196,7 @@ static DWORD GetFileVersion(LPCWSTR s)
196 196
197 if (!g_version_dll_hModule) 197 if (!g_version_dll_hModule)
198 { 198 {
199 wchar_t buf[MAX_PATH + 100]; 199 WCHAR buf[MAX_PATH + 100];
200 { 200 {
201 unsigned len = GetSystemDirectoryW(buf, MAX_PATH + 2); 201 unsigned len = GetSystemDirectoryW(buf, MAX_PATH + 2);
202 if (len == 0 || len > MAX_PATH) 202 if (len == 0 || len > MAX_PATH)
@@ -255,13 +255,13 @@ static WRes MyCreateDir(LPCWSTR name)
255#define IS_LETTER_CHAR(c) (((c) >= 'a' && (c) <= 'z') || ((c) >= 'A' && (c) <= 'Z')) 255#define IS_LETTER_CHAR(c) (((c) >= 'a' && (c) <= 'z') || ((c) >= 'A' && (c) <= 'Z'))
256#define IS_DRIVE_PATH(s) (IS_LETTER_CHAR(s[0]) && s[1] == ':' && IS_SEPAR(s[2])) 256#define IS_DRIVE_PATH(s) (IS_LETTER_CHAR(s[0]) && s[1] == ':' && IS_SEPAR(s[2]))
257 257
258static int ReverseFind_PathSepar(const wchar_t *s) 258static int ReverseFind_PathSepar(const WCHAR *s)
259{ 259{
260 int separ = -1; 260 int separ = -1;
261 int i; 261 int i;
262 for (i = 0;; i++) 262 for (i = 0;; i++)
263 { 263 {
264 wchar_t c = s[i]; 264 WCHAR c = s[i];
265 if (c == 0) 265 if (c == 0)
266 return separ; 266 return separ;
267 if (IS_SEPAR(c)) 267 if (IS_SEPAR(c))
@@ -566,7 +566,7 @@ static void NormalizePrefix(WCHAR *s)
566 566
567 for (;; i++) 567 for (;; i++)
568 { 568 {
569 const wchar_t c = s[i]; 569 const WCHAR c = s[i];
570 if (c == 0) 570 if (c == 0)
571 break; 571 break;
572 if (c == '/') 572 if (c == '/')
@@ -587,10 +587,10 @@ static char MyCharLower_Ascii(char c)
587 return c; 587 return c;
588} 588}
589 589
590static wchar_t MyWCharLower_Ascii(wchar_t c) 590static WCHAR MyWCharLower_Ascii(WCHAR c)
591{ 591{
592 if (c >= 'A' && c <= 'Z') 592 if (c >= 'A' && c <= 'Z')
593 return (wchar_t)(c + 0x20); 593 return (WCHAR)(c + 0x20);
594 return c; 594 return c;
595} 595}
596 596
@@ -976,13 +976,13 @@ static void WriteShellEx(void)
976} 976}
977 977
978 978
979static const wchar_t *GetCmdParam(const wchar_t *s) 979static const WCHAR *GetCmdParam(const WCHAR *s)
980{ 980{
981 unsigned pos = 0; 981 unsigned pos = 0;
982 BoolInt quoteMode = False; 982 BoolInt quoteMode = False;
983 for (;; s++) 983 for (;; s++)
984 { 984 {
985 wchar_t c = *s; 985 WCHAR c = *s;
986 if (c == 0 || (c == L' ' && !quoteMode)) 986 if (c == 0 || (c == L' ' && !quoteMode))
987 break; 987 break;
988 if (c == L'\"') 988 if (c == L'\"')
@@ -999,12 +999,12 @@ static const wchar_t *GetCmdParam(const wchar_t *s)
999} 999}
1000 1000
1001 1001
1002static void RemoveQuotes(wchar_t *s) 1002static void RemoveQuotes(WCHAR *s)
1003{ 1003{
1004 const wchar_t *src = s; 1004 const WCHAR *src = s;
1005 for (;;) 1005 for (;;)
1006 { 1006 {
1007 wchar_t c = *src++; 1007 WCHAR c = *src++;
1008 if (c == '\"') 1008 if (c == '\"')
1009 continue; 1009 continue;
1010 *s++ = c; 1010 *s++ = c;
@@ -1039,7 +1039,7 @@ int APIENTRY WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance,
1039 CrcGenerateTable(); 1039 CrcGenerateTable();
1040 1040
1041 { 1041 {
1042 const wchar_t *s = GetCommandLineW(); 1042 const WCHAR *s = GetCommandLineW();
1043 1043
1044 #ifndef UNDER_CE 1044 #ifndef UNDER_CE
1045 s = GetCmdParam(s); 1045 s = GetCmdParam(s);
@@ -1048,7 +1048,7 @@ int APIENTRY WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance,
1048 for (;;) 1048 for (;;)
1049 { 1049 {
1050 { 1050 {
1051 const wchar_t c = *s; 1051 const WCHAR c = *s;
1052 if (c == 0) 1052 if (c == 0)
1053 break; 1053 break;
1054 if (c == ' ') 1054 if (c == ' ')
@@ -1059,7 +1059,7 @@ int APIENTRY WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance,
1059 } 1059 }
1060 1060
1061 { 1061 {
1062 const wchar_t *s2 = GetCmdParam(s); 1062 const WCHAR *s2 = GetCmdParam(s);
1063 BoolInt error = True; 1063 BoolInt error = True;
1064 if (cmd[0] == '/') 1064 if (cmd[0] == '/')
1065 { 1065 {
@@ -1315,7 +1315,7 @@ if (res == SZ_OK)
1315 1315
1316 for (;;) 1316 for (;;)
1317 { 1317 {
1318 const wchar_t c = path[i++]; 1318 const WCHAR c = path[i++];
1319 if (c == 0) 1319 if (c == 0)
1320 break; 1320 break;
1321 if (c != ' ') 1321 if (c != ' ')
diff --git a/C/Util/7zipUninstall/7zipUninstall.c b/C/Util/7zipUninstall/7zipUninstall.c
index e7051e2..2c1333b 100644
--- a/C/Util/7zipUninstall/7zipUninstall.c
+++ b/C/Util/7zipUninstall/7zipUninstall.c
@@ -1,5 +1,5 @@
1/* 7zipUninstall.c - 7-Zip Uninstaller 1/* 7zipUninstall.c - 7-Zip Uninstaller
22024-03-21 : Igor Pavlov : Public domain */ 2: Igor Pavlov : Public domain */
3 3
4#include "Precomp.h" 4#include "Precomp.h"
5 5
@@ -147,7 +147,7 @@ static LPCWSTR const kUninstallExe = L"Uninstall.exe";
147#define MAKE_CHAR_UPPER(c) ((((c) >= 'a' && (c) <= 'z') ? (c) - 0x20 : (c))) 147#define MAKE_CHAR_UPPER(c) ((((c) >= 'a' && (c) <= 'z') ? (c) - 0x20 : (c)))
148 148
149 149
150static void CpyAscii(wchar_t *dest, const char *s) 150static void CpyAscii(WCHAR *dest, const char *s)
151{ 151{
152 for (;;) 152 for (;;)
153 { 153 {
@@ -158,13 +158,13 @@ static void CpyAscii(wchar_t *dest, const char *s)
158 } 158 }
159} 159}
160 160
161static void CatAscii(wchar_t *dest, const char *s) 161static void CatAscii(WCHAR *dest, const char *s)
162{ 162{
163 dest += wcslen(dest); 163 dest += wcslen(dest);
164 CpyAscii(dest, s); 164 CpyAscii(dest, s);
165} 165}
166 166
167static void PrintErrorMessage(const char *s1, const wchar_t *s2) 167static void PrintErrorMessage(const char *s1, const WCHAR *s2)
168{ 168{
169 WCHAR m[MAX_PATH + 512]; 169 WCHAR m[MAX_PATH + 512];
170 m[0] = 0; 170 m[0] = 0;
@@ -183,12 +183,12 @@ static void PrintErrorMessage(const char *s1, const wchar_t *s2)
183} 183}
184 184
185 185
186static BoolInt AreStringsEqual_NoCase(const wchar_t *s1, const wchar_t *s2) 186static BoolInt AreStringsEqual_NoCase(const WCHAR *s1, const WCHAR *s2)
187{ 187{
188 for (;;) 188 for (;;)
189 { 189 {
190 wchar_t c1 = *s1++; 190 WCHAR c1 = *s1++;
191 wchar_t c2 = *s2++; 191 WCHAR c2 = *s2++;
192 if (c1 != c2 && MAKE_CHAR_UPPER(c1) != MAKE_CHAR_UPPER(c2)) 192 if (c1 != c2 && MAKE_CHAR_UPPER(c1) != MAKE_CHAR_UPPER(c2))
193 return False; 193 return False;
194 if (c2 == 0) 194 if (c2 == 0)
@@ -196,12 +196,12 @@ static BoolInt AreStringsEqual_NoCase(const wchar_t *s1, const wchar_t *s2)
196 } 196 }
197} 197}
198 198
199static BoolInt IsString1PrefixedByString2_NoCase(const wchar_t *s1, const wchar_t *s2) 199static BoolInt IsString1PrefixedByString2_NoCase(const WCHAR *s1, const WCHAR *s2)
200{ 200{
201 for (;;) 201 for (;;)
202 { 202 {
203 wchar_t c1; 203 WCHAR c1;
204 const wchar_t c2 = *s2++; 204 const WCHAR c2 = *s2++;
205 if (c2 == 0) 205 if (c2 == 0)
206 return True; 206 return True;
207 c1 = *s1++; 207 c1 = *s1++;
@@ -446,7 +446,7 @@ static LPCWSTR const k_AppPaths_7zFm = L"Software\\Microsoft\\Windows\\CurrentVe
446static LPCWSTR const k_Uninstall_7zip = k_REG_Uninstall L"7-Zip"; 446static LPCWSTR const k_Uninstall_7zip = k_REG_Uninstall L"7-Zip";
447 447
448 448
449static void RemoveQuotes(wchar_t *s) 449static void RemoveQuotes(WCHAR *s)
450{ 450{
451 const size_t len = wcslen(s); 451 const size_t len = wcslen(s);
452 size_t i; 452 size_t i;
@@ -457,7 +457,7 @@ static void RemoveQuotes(wchar_t *s)
457 s[len - 2] = 0; 457 s[len - 2] = 0;
458} 458}
459 459
460static BoolInt AreEqual_Path_PrefixName(const wchar_t *s, const wchar_t *prefix, const wchar_t *name) 460static BoolInt AreEqual_Path_PrefixName(const WCHAR *s, const WCHAR *prefix, const WCHAR *name)
461{ 461{
462 if (!IsString1PrefixedByString2_NoCase(s, prefix)) 462 if (!IsString1PrefixedByString2_NoCase(s, prefix))
463 return False; 463 return False;
@@ -558,13 +558,13 @@ static void WriteCLSID(void)
558} 558}
559 559
560 560
561static const wchar_t *GetCmdParam(const wchar_t *s) 561static const WCHAR *GetCmdParam(const WCHAR *s)
562{ 562{
563 unsigned pos = 0; 563 unsigned pos = 0;
564 BoolInt quoteMode = False; 564 BoolInt quoteMode = False;
565 for (;; s++) 565 for (;; s++)
566 { 566 {
567 const wchar_t c = *s; 567 const WCHAR c = *s;
568 if (c == 0 || (c == L' ' && !quoteMode)) 568 if (c == 0 || (c == L' ' && !quoteMode))
569 break; 569 break;
570 if (c == L'\"') 570 if (c == L'\"')
@@ -581,12 +581,12 @@ static const wchar_t *GetCmdParam(const wchar_t *s)
581} 581}
582 582
583/* 583/*
584static void RemoveQuotes(wchar_t *s) 584static void RemoveQuotes(WCHAR *s)
585{ 585{
586 const wchar_t *src = s; 586 const WCHAR *src = s;
587 for (;;) 587 for (;;)
588 { 588 {
589 wchar_t c = *src++; 589 WCHAR c = *src++;
590 if (c == '\"') 590 if (c == '\"')
591 continue; 591 continue;
592 *s++ = c; 592 *s++ = c;
@@ -618,11 +618,11 @@ static BOOL RemoveFileAfterReboot(void)
618 618
619// #define IS_LIMIT_CHAR(c) (c == 0 || c == ' ') 619// #define IS_LIMIT_CHAR(c) (c == 0 || c == ' ')
620 620
621static BoolInt IsThereSpace(const wchar_t *s) 621static BoolInt IsThereSpace(const WCHAR *s)
622{ 622{
623 for (;;) 623 for (;;)
624 { 624 {
625 const wchar_t c = *s++; 625 const WCHAR c = *s++;
626 if (c == 0) 626 if (c == 0)
627 return False; 627 return False;
628 if (c == ' ') 628 if (c == ' ')
@@ -630,7 +630,7 @@ static BoolInt IsThereSpace(const wchar_t *s)
630 } 630 }
631} 631}
632 632
633static void AddPathParam(wchar_t *dest, const wchar_t *src) 633static void AddPathParam(WCHAR *dest, const WCHAR *src)
634{ 634{
635 const BoolInt needQuote = IsThereSpace(src); 635 const BoolInt needQuote = IsThereSpace(src);
636 if (needQuote) 636 if (needQuote)
@@ -937,7 +937,7 @@ int APIENTRY WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance,
937 #endif 937 #endif
938 lpCmdLine, int nCmdShow) 938 lpCmdLine, int nCmdShow)
939{ 939{
940 const wchar_t *cmdParams; 940 const WCHAR *cmdParams;
941 BoolInt useTemp = True; 941 BoolInt useTemp = True;
942 942
943 UNUSED_VAR(hPrevInstance) 943 UNUSED_VAR(hPrevInstance)
@@ -957,7 +957,7 @@ int APIENTRY WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance,
957#endif 957#endif
958 958
959 { 959 {
960 const wchar_t *s = GetCommandLineW(); 960 const WCHAR *s = GetCommandLineW();
961 961
962 #ifndef UNDER_CE 962 #ifndef UNDER_CE
963 s = GetCmdParam(s); 963 s = GetCmdParam(s);
@@ -968,7 +968,7 @@ int APIENTRY WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance,
968 for (;;) 968 for (;;)
969 { 969 {
970 { 970 {
971 wchar_t c = *s; 971 WCHAR c = *s;
972 if (c == 0) 972 if (c == 0)
973 break; 973 break;
974 if (c == ' ') 974 if (c == ' ')
@@ -979,7 +979,7 @@ int APIENTRY WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance,
979 } 979 }
980 980
981 { 981 {
982 const wchar_t *s2 = GetCmdParam(s); 982 const WCHAR *s2 = GetCmdParam(s);
983 BoolInt error = True; 983 BoolInt error = True;
984 if (cmd[0] == '/') 984 if (cmd[0] == '/')
985 { 985 {
@@ -1022,7 +1022,7 @@ int APIENTRY WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance,
1022 } 1022 }
1023 1023
1024 { 1024 {
1025 wchar_t *name; 1025 WCHAR *name;
1026 const DWORD len = GetModuleFileNameW(NULL, modulePath, MAX_PATH); 1026 const DWORD len = GetModuleFileNameW(NULL, modulePath, MAX_PATH);
1027 if (len == 0 || len > MAX_PATH) 1027 if (len == 0 || len > MAX_PATH)
1028 return 1; 1028 return 1;
@@ -1031,10 +1031,10 @@ int APIENTRY WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance,
1031 wcscpy(modulePrefix, modulePath); 1031 wcscpy(modulePrefix, modulePath);
1032 1032
1033 { 1033 {
1034 wchar_t *s = modulePrefix; 1034 WCHAR *s = modulePrefix;
1035 for (;;) 1035 for (;;)
1036 { 1036 {
1037 const wchar_t c = *s++; 1037 const WCHAR c = *s++;
1038 if (c == 0) 1038 if (c == 0)
1039 break; 1039 break;
1040 if (c == WCHAR_PATH_SEPARATOR) 1040 if (c == WCHAR_PATH_SEPARATOR)
@@ -1079,14 +1079,14 @@ int APIENTRY WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance,
1079 CpyAscii(path + pathLen, "7z"); 1079 CpyAscii(path + pathLen, "7z");
1080 1080
1081 { 1081 {
1082 wchar_t *s = path + wcslen(path); 1082 WCHAR *s = path + wcslen(path);
1083 UInt32 value = d; 1083 UInt32 value = d;
1084 unsigned k; 1084 unsigned k;
1085 for (k = 0; k < 8; k++) 1085 for (k = 0; k < 8; k++)
1086 { 1086 {
1087 const unsigned t = value & 0xF; 1087 const unsigned t = value & 0xF;
1088 value >>= 4; 1088 value >>= 4;
1089 s[7 - k] = (wchar_t)((t < 10) ? ('0' + t) : ('A' + (t - 10))); 1089 s[7 - k] = (WCHAR)((t < 10) ? ('0' + t) : ('A' + (t - 10)));
1090 } 1090 }
1091 s[k] = 0; 1091 s[k] = 0;
1092 } 1092 }
diff --git a/C/Util/SfxSetup/SfxSetup.c b/C/Util/SfxSetup/SfxSetup.c
index 9b5c1f9..344aa73 100644
--- a/C/Util/SfxSetup/SfxSetup.c
+++ b/C/Util/SfxSetup/SfxSetup.c
@@ -1,5 +1,5 @@
1/* SfxSetup.c - 7z SFX Setup 1/* SfxSetup.c - 7z SFX Setup
22024-01-24 : Igor Pavlov : Public domain */ 2: Igor Pavlov : Public domain */
3 3
4#include "Precomp.h" 4#include "Precomp.h"
5 5
@@ -54,7 +54,7 @@ static const char * const kNames[] =
54 , "start" 54 , "start"
55}; 55};
56 56
57static unsigned FindExt(const wchar_t *s, unsigned *extLen) 57static unsigned FindExt(const WCHAR *s, unsigned *extLen)
58{ 58{
59 unsigned len = (unsigned)wcslen(s); 59 unsigned len = (unsigned)wcslen(s);
60 unsigned i; 60 unsigned i;
@@ -72,7 +72,7 @@ static unsigned FindExt(const wchar_t *s, unsigned *extLen)
72 72
73#define MAKE_CHAR_UPPER(c) ((((c) >= 'a' && (c) <= 'z') ? (c) - 0x20 : (c))) 73#define MAKE_CHAR_UPPER(c) ((((c) >= 'a' && (c) <= 'z') ? (c) - 0x20 : (c)))
74 74
75static unsigned FindItem(const char * const *items, unsigned num, const wchar_t *s, unsigned len) 75static unsigned FindItem(const char * const *items, unsigned num, const WCHAR *s, unsigned len)
76{ 76{
77 unsigned i; 77 unsigned i;
78 for (i = 0; i < num; i++) 78 for (i = 0; i < num; i++)
@@ -268,7 +268,7 @@ int APIENTRY WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance,
268 #endif 268 #endif
269 size_t pathLen; 269 size_t pathLen;
270 DWORD winRes; 270 DWORD winRes;
271 const wchar_t *cmdLineParams; 271 const WCHAR *cmdLineParams;
272 const char *errorMessage = NULL; 272 const char *errorMessage = NULL;
273 BoolInt useShellExecute = True; 273 BoolInt useShellExecute = True;
274 DWORD exitCode = 0; 274 DWORD exitCode = 0;
@@ -306,7 +306,7 @@ int APIENTRY WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance,
306 BoolInt quoteMode = False; 306 BoolInt quoteMode = False;
307 for (;; cmdLineParams++) 307 for (;; cmdLineParams++)
308 { 308 {
309 const wchar_t c = *cmdLineParams; 309 const WCHAR c = *cmdLineParams;
310 if (c == L'\"') 310 if (c == L'\"')
311 quoteMode = !quoteMode; 311 quoteMode = !quoteMode;
312 else if (c == 0 || (c == L' ' && !quoteMode)) 312 else if (c == 0 || (c == L' ' && !quoteMode))
@@ -335,14 +335,14 @@ int APIENTRY WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance,
335 wcscpy(path + pathLen, L"7z"); 335 wcscpy(path + pathLen, L"7z");
336 336
337 { 337 {
338 wchar_t *s = path + wcslen(path); 338 WCHAR *s = path + wcslen(path);
339 UInt32 value = d; 339 UInt32 value = d;
340 unsigned k; 340 unsigned k;
341 for (k = 0; k < 8; k++) 341 for (k = 0; k < 8; k++)
342 { 342 {
343 const unsigned t = value & 0xF; 343 const unsigned t = value & 0xF;
344 value >>= 4; 344 value >>= 4;
345 s[7 - k] = (wchar_t)((t < 10) ? ('0' + t) : ('A' + (t - 10))); 345 s[7 - k] = (WCHAR)((t < 10) ? ('0' + t) : ('A' + (t - 10)));
346 } 346 }
347 s[k] = '\0'; 347 s[k] = '\0';
348 } 348 }
diff --git a/C/XzDec.c b/C/XzDec.c
index fe6b425..e4ae144 100644
--- a/C/XzDec.c
+++ b/C/XzDec.c
@@ -25,8 +25,8 @@
25#define PRF(x) 25#define PRF(x)
26#endif 26#endif
27 27
28#define PRF_STR(s) PRF(printf("\n" s "\n")) 28#define PRF_STR(s) PRF(printf("\n" s "\n");)
29#define PRF_STR_INT(s, d) PRF(printf("\n" s " %d\n", (unsigned)d)) 29#define PRF_STR_INT(s, d) PRF(printf("\n" s " %d\n", (unsigned)d);)
30 30
31#include <stdlib.h> 31#include <stdlib.h>
32#include <string.h> 32#include <string.h>
@@ -574,7 +574,7 @@ static SRes MixCoder_ResetFromMethod(CMixCoder *p, unsigned coderIndex, UInt64 m
574output (status) can be : 574output (status) can be :
575 CODER_STATUS_NOT_FINISHED 575 CODER_STATUS_NOT_FINISHED
576 CODER_STATUS_FINISHED_WITH_MARK 576 CODER_STATUS_FINISHED_WITH_MARK
577 CODER_STATUS_NEEDS_MORE_INPUT - not implemented still 577 CODER_STATUS_NEEDS_MORE_INPUT
578*/ 578*/
579 579
580static SRes MixCoder_Code(CMixCoder *p, 580static SRes MixCoder_Code(CMixCoder *p,
@@ -582,8 +582,8 @@ static SRes MixCoder_Code(CMixCoder *p,
582 const Byte *src, SizeT *srcLen, int srcWasFinished, 582 const Byte *src, SizeT *srcLen, int srcWasFinished,
583 ECoderFinishMode finishMode) 583 ECoderFinishMode finishMode)
584{ 584{
585 SizeT destLenOrig = *destLen; 585 const SizeT destLenOrig = *destLen;
586 SizeT srcLenOrig = *srcLen; 586 const SizeT srcLenOrig = *srcLen;
587 587
588 *destLen = 0; 588 *destLen = 0;
589 *srcLen = 0; 589 *srcLen = 0;
@@ -597,39 +597,26 @@ static SRes MixCoder_Code(CMixCoder *p,
597 if (p->outBuf) 597 if (p->outBuf)
598 { 598 {
599 SRes res; 599 SRes res;
600 SizeT destLen2, srcLen2; 600 SizeT destLen2;
601 int wasFinished; 601 int wasFinished;
602 602
603 PRF_STR("------- MixCoder Single ----------") 603 PRF_STR("------- MixCoder Single ----------")
604 604
605 srcLen2 = srcLenOrig;
606 destLen2 = destLenOrig; 605 destLen2 = destLenOrig;
607 606 if (p->numCoders != 1)
608 { 607 {
609 IStateCoder *coder = &p->coders[0]; 608 if (destLen2 < p->outWritten)
610 res = coder->Code2(coder->p, NULL, &destLen2, src, &srcLen2, srcWasFinished, finishMode, 609 return SZ_ERROR_FAIL;
611 // &wasFinished, 610 destLen2 -= p->outWritten;
612 &p->status);
613 wasFinished = (p->status == CODER_STATUS_FINISHED_WITH_MARK);
614 } 611 }
615 612 *srcLen = srcLenOrig;
616 p->res = res;
617
618 /*
619 if (wasFinished)
620 p->status = CODER_STATUS_FINISHED_WITH_MARK;
621 else
622 { 613 {
623 if (res == SZ_OK) 614 IStateCoder *coder = &p->coders[0];
624 if (destLen2 != destLenOrig) 615 res = coder->Code2(coder->p, NULL, &destLen2, src, srcLen, srcWasFinished, finishMode, &p->status);
625 p->status = CODER_STATUS_NEEDS_MORE_INPUT;
626 } 616 }
627 */ 617 p->res = res;
628
629
630 *srcLen = srcLen2;
631 src += srcLen2;
632 p->outWritten += destLen2; 618 p->outWritten += destLen2;
619 wasFinished = (p->status == CODER_STATUS_FINISHED_WITH_MARK);
633 620
634 if (res != SZ_OK || srcWasFinished || wasFinished) 621 if (res != SZ_OK || srcWasFinished || wasFinished)
635 p->wasFinished = True; 622 p->wasFinished = True;
@@ -1016,8 +1003,8 @@ SRes XzUnpacker_Code(CXzUnpacker *p, Byte *dest, SizeT *destLen,
1016 const Byte *src, SizeT *srcLen, int srcFinished, 1003 const Byte *src, SizeT *srcLen, int srcFinished,
1017 ECoderFinishMode finishMode, ECoderStatus *status) 1004 ECoderFinishMode finishMode, ECoderStatus *status)
1018{ 1005{
1019 SizeT destLenOrig = *destLen; 1006 const SizeT destLenOrig = *destLen;
1020 SizeT srcLenOrig = *srcLen; 1007 const SizeT srcLenOrig = *srcLen;
1021 *destLen = 0; 1008 *destLen = 0;
1022 *srcLen = 0; 1009 *srcLen = 0;
1023 *status = CODER_STATUS_NOT_SPECIFIED; 1010 *status = CODER_STATUS_NOT_SPECIFIED;