Compare commits

...

5 Commits
15.10 ... 16.00

Author SHA1 Message Date
Igor Pavlov
66ac98bb02 16.00 2016-05-28 00:16:59 +01:00
Igor Pavlov
c20d013055 15.14 2016-05-28 00:16:58 +01:00
Igor Pavlov
9608215ad8 15.13 2016-05-28 00:16:58 +01:00
Igor Pavlov
5de23c1deb 15.12 2016-05-28 00:16:58 +01:00
Igor Pavlov
e24f7fba53 15.11 2016-05-28 00:16:57 +01:00
197 changed files with 5337 additions and 2392 deletions

82
C/7z.h
View File

@@ -1,5 +1,5 @@
/* 7z.h -- 7z interface /* 7z.h -- 7z interface
2014-02-08 : Igor Pavlov : Public domain */ 2015-11-18 : Igor Pavlov : Public domain */
#ifndef __7Z_H #ifndef __7Z_H
#define __7Z_H #define __7Z_H
@@ -48,21 +48,10 @@ typedef struct
UInt32 PackStreams[SZ_NUM_PACK_STREAMS_IN_FOLDER_MAX]; UInt32 PackStreams[SZ_NUM_PACK_STREAMS_IN_FOLDER_MAX];
CSzBond Bonds[SZ_NUM_BONDS_IN_FOLDER_MAX]; CSzBond Bonds[SZ_NUM_BONDS_IN_FOLDER_MAX];
CSzCoderInfo Coders[SZ_NUM_CODERS_IN_FOLDER_MAX]; CSzCoderInfo Coders[SZ_NUM_CODERS_IN_FOLDER_MAX];
UInt64 CodersUnpackSizes[SZ_NUM_CODERS_IN_FOLDER_MAX];
} CSzFolder; } CSzFolder;
/*
typedef struct
{
size_t CodersDataOffset;
size_t UnpackSizeDataOffset;
// UInt32 StartCoderUnpackSizesIndex;
UInt32 StartPackStreamIndex;
// UInt32 IndexOfMainOutStream;
} CSzFolder2;
*/
SRes SzGetNextFolderItem(CSzFolder *f, CSzData *sd, CSzData *sdSizes); SRes SzGetNextFolderItem(CSzFolder *f, CSzData *sd);
typedef struct typedef struct
{ {
@@ -92,47 +81,25 @@ typedef struct
UInt32 NumPackStreams; UInt32 NumPackStreams;
UInt32 NumFolders; UInt32 NumFolders;
UInt64 *PackPositions; // NumPackStreams + 1 UInt64 *PackPositions; // NumPackStreams + 1
CSzBitUi32s FolderCRCs; CSzBitUi32s FolderCRCs; // NumFolders
size_t *FoCodersOffsets; size_t *FoCodersOffsets; // NumFolders + 1
size_t *FoSizesOffsets; UInt32 *FoStartPackStreamIndex; // NumFolders + 1
// UInt32 StartCoderUnpackSizesIndex; UInt32 *FoToCoderUnpackSizes; // NumFolders + 1
UInt32 *FoStartPackStreamIndex; Byte *FoToMainUnpackSizeIndex; // NumFolders
UInt64 *CoderUnpackSizes; // for all coders in all folders
// CSzFolder2 *Folders; // +1 item for sum values
Byte *CodersData; Byte *CodersData;
Byte *UnpackSizesData;
size_t UnpackSizesDataSize;
// UInt64 *CoderUnpackSizes;
} CSzAr; } CSzAr;
UInt64 SzAr_GetFolderUnpackSize(const CSzAr *p, UInt32 folderIndex);
SRes SzAr_DecodeFolder(const CSzAr *p, UInt32 folderIndex, SRes SzAr_DecodeFolder(const CSzAr *p, UInt32 folderIndex,
ILookInStream *stream, UInt64 startPos, ILookInStream *stream, UInt64 startPos,
Byte *outBuffer, size_t outSize, Byte *outBuffer, size_t outSize,
ISzAlloc *allocMain); ISzAlloc *allocMain);
/*
SzExtract extracts file from archive
*outBuffer must be 0 before first call for each new archive.
Extracting cache:
If you need to decompress more than one file, you can send
these values from previous call:
*blockIndex,
*outBuffer,
*outBufferSize
You can consider "*outBuffer" as cache of solid block. If your archive is solid,
it will increase decompression speed.
If you use external function, you can declare these 3 cache variables
(blockIndex, outBuffer, outBufferSize) as static in that external function.
Free *outBuffer and set *outBuffer to 0, if you want to flush cache.
*/
typedef struct typedef struct
{ {
CSzAr db; CSzAr db;
@@ -142,7 +109,7 @@ typedef struct
UInt32 NumFiles; UInt32 NumFiles;
UInt64 *UnpackPositions; UInt64 *UnpackPositions; // NumFiles + 1
// Byte *IsEmptyFiles; // Byte *IsEmptyFiles;
Byte *IsDirs; Byte *IsDirs;
CSzBitUi32s CRCs; CSzBitUi32s CRCs;
@@ -152,9 +119,8 @@ typedef struct
CSzBitUi64s MTime; CSzBitUi64s MTime;
CSzBitUi64s CTime; CSzBitUi64s CTime;
// UInt32 *FolderStartPackStreamIndex; UInt32 *FolderToFile; // NumFolders + 1
UInt32 *FolderStartFileIndex; // + 1 UInt32 *FileToFolder; // NumFiles
UInt32 *FileIndexToFolderIndexMap;
size_t *FileNameOffsets; /* in 2-byte steps */ size_t *FileNameOffsets; /* in 2-byte steps */
Byte *FileNames; /* UTF-16-LE */ Byte *FileNames; /* UTF-16-LE */
@@ -182,6 +148,28 @@ size_t SzArEx_GetFullNameLen(const CSzArEx *p, size_t fileIndex);
UInt16 *SzArEx_GetFullNameUtf16_Back(const CSzArEx *p, size_t fileIndex, UInt16 *dest); UInt16 *SzArEx_GetFullNameUtf16_Back(const CSzArEx *p, size_t fileIndex, UInt16 *dest);
*/ */
/*
SzArEx_Extract extracts file from archive
*outBuffer must be 0 before first call for each new archive.
Extracting cache:
If you need to decompress more than one file, you can send
these values from previous call:
*blockIndex,
*outBuffer,
*outBufferSize
You can consider "*outBuffer" as cache of solid block. If your archive is solid,
it will increase decompression speed.
If you use external function, you can declare these 3 cache variables
(blockIndex, outBuffer, outBufferSize) as static in that external function.
Free *outBuffer and set *outBuffer to 0, if you want to flush cache.
*/
SRes SzArEx_Extract( SRes SzArEx_Extract(
const CSzArEx *db, const CSzArEx *db,
ILookInStream *inStream, ILookInStream *inStream,

View File

@@ -1,5 +1,5 @@
/* 7zAlloc.c -- Allocation functions /* 7zAlloc.c -- Allocation functions
2015-02-21 : Igor Pavlov : Public domain */ 2015-11-09 : Igor Pavlov : Public domain */
#include "Precomp.h" #include "Precomp.h"
@@ -26,7 +26,7 @@ void *SzAlloc(void *p, size_t size)
if (size == 0) if (size == 0)
return 0; return 0;
#ifdef _SZ_ALLOC_DEBUG #ifdef _SZ_ALLOC_DEBUG
fprintf(stderr, "\nAlloc %10d bytes; count = %10d", size, g_allocCount); fprintf(stderr, "\nAlloc %10u bytes; count = %10d", (unsigned)size, g_allocCount);
g_allocCount++; g_allocCount++;
#endif #endif
return malloc(size); return malloc(size);
@@ -51,7 +51,7 @@ void *SzAllocTemp(void *p, size_t size)
if (size == 0) if (size == 0)
return 0; return 0;
#ifdef _SZ_ALLOC_DEBUG #ifdef _SZ_ALLOC_DEBUG
fprintf(stderr, "\nAlloc_temp %10d bytes; count = %10d", size, g_allocCountTemp); fprintf(stderr, "\nAlloc_temp %10u bytes; count = %10d", (unsigned)size, g_allocCountTemp);
g_allocCountTemp++; g_allocCountTemp++;
#ifdef _WIN32 #ifdef _WIN32
return HeapAlloc(GetProcessHeap(), 0, size); return HeapAlloc(GetProcessHeap(), 0, size);

View File

File diff suppressed because it is too large Load Diff

View File

@@ -1,5 +1,5 @@
/* 7zDec.c -- Decoding from 7z folder /* 7zDec.c -- Decoding from 7z folder
2015-08-01 : Igor Pavlov : Public domain */ 2015-11-18 : Igor Pavlov : Public domain */
#include "Precomp.h" #include "Precomp.h"
@@ -8,6 +8,7 @@
/* #define _7ZIP_PPMD_SUPPPORT */ /* #define _7ZIP_PPMD_SUPPPORT */
#include "7z.h" #include "7z.h"
#include "7zCrc.h"
#include "Bcj2.h" #include "Bcj2.h"
#include "Bra.h" #include "Bra.h"
@@ -160,14 +161,23 @@ static SRes SzDecodeLzma(const Byte *props, unsigned propsSize, UInt64 inSize, I
inSize -= inProcessed; inSize -= inProcessed;
if (res != SZ_OK) if (res != SZ_OK)
break; break;
if (state.dicPos == state.dicBufSize || (inProcessed == 0 && dicPos == state.dicPos))
if (status == LZMA_STATUS_FINISHED_WITH_MARK)
{ {
if (state.dicBufSize != outSize || lookahead != 0 || if (outSize != state.dicPos || inSize != 0)
(status != LZMA_STATUS_FINISHED_WITH_MARK &&
status != LZMA_STATUS_MAYBE_FINISHED_WITHOUT_MARK))
res = SZ_ERROR_DATA; res = SZ_ERROR_DATA;
break; break;
} }
if (outSize == state.dicPos && inSize == 0 && status == LZMA_STATUS_MAYBE_FINISHED_WITHOUT_MARK)
break;
if (inProcessed == 0 && dicPos == state.dicPos)
{
res = SZ_ERROR_DATA;
break;
}
res = inStream->Skip((void *)inStream, inProcessed); res = inStream->Skip((void *)inStream, inProcessed);
if (res != SZ_OK) if (res != SZ_OK)
break; break;
@@ -213,13 +223,20 @@ static SRes SzDecodeLzma2(const Byte *props, unsigned propsSize, UInt64 inSize,
inSize -= inProcessed; inSize -= inProcessed;
if (res != SZ_OK) if (res != SZ_OK)
break; break;
if (state.decoder.dicPos == state.decoder.dicBufSize || (inProcessed == 0 && dicPos == state.decoder.dicPos))
if (status == LZMA_STATUS_FINISHED_WITH_MARK)
{ {
if (state.decoder.dicBufSize != outSize || lookahead != 0 || if (outSize != state.decoder.dicPos || inSize != 0)
(status != LZMA_STATUS_FINISHED_WITH_MARK))
res = SZ_ERROR_DATA; res = SZ_ERROR_DATA;
break; break;
} }
if (inProcessed == 0 && dicPos == state.decoder.dicPos)
{
res = SZ_ERROR_DATA;
break;
}
res = inStream->Skip((void *)inStream, inProcessed); res = inStream->Skip((void *)inStream, inProcessed);
if (res != SZ_OK) if (res != SZ_OK)
break; break;
@@ -537,33 +554,38 @@ SRes SzAr_DecodeFolder(const CSzAr *p, UInt32 folderIndex,
SRes res; SRes res;
CSzFolder folder; CSzFolder folder;
CSzData sd; CSzData sd;
CSzData sdSizes;
const Byte *data = p->CodersData + p->FoCodersOffsets[folderIndex]; const Byte *data = p->CodersData + p->FoCodersOffsets[folderIndex];
sd.Data = data; sd.Data = data;
sd.Size = p->FoCodersOffsets[folderIndex + 1] - p->FoCodersOffsets[folderIndex]; sd.Size = p->FoCodersOffsets[folderIndex + 1] - p->FoCodersOffsets[folderIndex];
sdSizes.Data = p->UnpackSizesData + p->FoSizesOffsets[folderIndex]; res = SzGetNextFolderItem(&folder, &sd);
sdSizes.Size =
p->FoSizesOffsets[folderIndex + 1] -
p->FoSizesOffsets[folderIndex];
res = SzGetNextFolderItem(&folder, &sd, &sdSizes);
if (res != SZ_OK) if (res != SZ_OK)
return res; return res;
if (sd.Size != 0 || outSize != folder.CodersUnpackSizes[folder.UnpackStream]) if (sd.Size != 0
|| folder.UnpackStream != p->FoToMainUnpackSizeIndex[folderIndex]
|| outSize != SzAr_GetFolderUnpackSize(p, folderIndex))
return SZ_ERROR_FAIL; return SZ_ERROR_FAIL;
{ {
unsigned i; unsigned i;
Byte *tempBuf[3] = { 0, 0, 0}; Byte *tempBuf[3] = { 0, 0, 0};
res = SzFolder_Decode2(&folder, data, folder.CodersUnpackSizes,
res = SzFolder_Decode2(&folder, data,
&p->CoderUnpackSizes[p->FoToCoderUnpackSizes[folderIndex]],
p->PackPositions + p->FoStartPackStreamIndex[folderIndex], p->PackPositions + p->FoStartPackStreamIndex[folderIndex],
inStream, startPos, inStream, startPos,
outBuffer, (SizeT)outSize, allocMain, tempBuf); outBuffer, (SizeT)outSize, allocMain, tempBuf);
for (i = 0; i < 3; i++) for (i = 0; i < 3; i++)
IAlloc_Free(allocMain, tempBuf[i]); IAlloc_Free(allocMain, tempBuf[i]);
if (res == SZ_OK)
if (SzBitWithVals_Check(&p->FolderCRCs, folderIndex))
if (CrcCalc(outBuffer, outSize) != p->FolderCRCs.Vals[folderIndex])
res = SZ_ERROR_CRC;
return res; return res;
} }
} }

View File

@@ -1,14 +1,14 @@
#define MY_VER_MAJOR 15 #define MY_VER_MAJOR 16
#define MY_VER_MINOR 10 #define MY_VER_MINOR 00
#define MY_VER_BUILD 0 #define MY_VER_BUILD 0
#define MY_VERSION_NUMBERS "15.10" #define MY_VERSION_NUMBERS "16.00"
#define MY_VERSION "15.10 beta" #define MY_VERSION "16.00"
#define MY_DATE "2015-11-01" #define MY_DATE "2016-05-10"
#undef MY_COPYRIGHT #undef MY_COPYRIGHT
#undef MY_VERSION_COPYRIGHT_DATE #undef MY_VERSION_COPYRIGHT_DATE
#define MY_AUTHOR_NAME "Igor Pavlov" #define MY_AUTHOR_NAME "Igor Pavlov"
#define MY_COPYRIGHT_PD "Igor Pavlov : Public domain" #define MY_COPYRIGHT_PD "Igor Pavlov : Public domain"
#define MY_COPYRIGHT_CR "Copyright (c) 1999-2015 Igor Pavlov" #define MY_COPYRIGHT_CR "Copyright (c) 1999-2016 Igor Pavlov"
#ifdef USE_COPYRIGHT_CR #ifdef USE_COPYRIGHT_CR
#define MY_COPYRIGHT MY_COPYRIGHT_CR #define MY_COPYRIGHT MY_COPYRIGHT_CR

View File

@@ -513,4 +513,3 @@ UInt32 BlockSort(UInt32 *Indices, const Byte *data, UInt32 blockSize)
#endif #endif
return Groups[0]; return Groups[0];
} }

View File

@@ -1,5 +1,5 @@
/* CpuArch.c -- CPU specific code /* CpuArch.c -- CPU specific code
2015-03-25: Igor Pavlov : Public domain */ 2016-02-25: Igor Pavlov : Public domain */
#include "Precomp.h" #include "Precomp.h"
@@ -45,7 +45,8 @@ static UInt32 CheckFlag(UInt32 flag)
"push %%EDX\n\t" "push %%EDX\n\t"
"popf\n\t" "popf\n\t"
"andl %%EAX, %0\n\t": "andl %%EAX, %0\n\t":
"=c" (flag) : "c" (flag)); "=c" (flag) : "c" (flag) :
"%eax", "%edx");
#endif #endif
return flag; return flag;
} }
@@ -79,7 +80,13 @@ void MyCPUID(UInt32 function, UInt32 *a, UInt32 *b, UInt32 *c, UInt32 *d)
#else #else
__asm__ __volatile__ ( __asm__ __volatile__ (
#if defined(MY_CPU_X86) && defined(__PIC__) #if defined(MY_CPU_AMD64) && defined(__PIC__)
"mov %%rbx, %%rdi;"
"cpuid;"
"xchg %%rbx, %%rdi;"
: "=a" (*a) ,
"=D" (*b) ,
#elif defined(MY_CPU_X86) && defined(__PIC__)
"mov %%ebx, %%edi;" "mov %%ebx, %%edi;"
"cpuid;" "cpuid;"
"xchgl %%ebx, %%edi;" "xchgl %%ebx, %%edi;"

View File

@@ -1,5 +1,5 @@
/* CpuArch.h -- CPU specific code /* CpuArch.h -- CPU specific code
2015-10-31: Igor Pavlov : Public domain */ 2015-12-01: Igor Pavlov : Public domain */
#ifndef __CPU_ARCH_H #ifndef __CPU_ARCH_H
#define __CPU_ARCH_H #define __CPU_ARCH_H
@@ -78,7 +78,9 @@ MY_CPU_LE_UNALIGN means that CPU is LITTLE ENDIAN and CPU supports unaligned mem
|| defined(__MIPSEB) \ || defined(__MIPSEB) \
|| defined(_MIPSEB) \ || defined(_MIPSEB) \
|| defined(__m68k__) \ || defined(__m68k__) \
|| defined(__s390__) \
|| defined(__s390x__) \ || defined(__s390x__) \
|| defined(__zarch__) \
|| (defined(__BYTE_ORDER__) && (__BYTE_ORDER__ == __ORDER_BIG_ENDIAN__)) || (defined(__BYTE_ORDER__) && (__BYTE_ORDER__ == __ORDER_BIG_ENDIAN__))
#define MY_CPU_BE #define MY_CPU_BE
#endif #endif

View File

@@ -1,5 +1,5 @@
/* Lzma2Dec.c -- LZMA2 Decoder /* Lzma2Dec.c -- LZMA2 Decoder
2014-10-29 : Igor Pavlov : Public domain */ 2015-11-09 : Igor Pavlov : Public domain */
/* #define SHOW_DEBUG_INFO */ /* #define SHOW_DEBUG_INFO */
@@ -103,8 +103,8 @@ static ELzma2State Lzma2Dec_UpdateState(CLzma2Dec *p, Byte b)
{ {
case LZMA2_STATE_CONTROL: case LZMA2_STATE_CONTROL:
p->control = b; p->control = b;
PRF(printf("\n %4X ", p->decoder.dicPos)); PRF(printf("\n %4X ", (unsigned)p->decoder.dicPos));
PRF(printf(" %2X", b)); PRF(printf(" %2X", (unsigned)b));
if (p->control == 0) if (p->control == 0)
return LZMA2_STATE_FINISHED; return LZMA2_STATE_FINISHED;
if (LZMA2_IS_UNCOMPRESSED_STATE(p)) if (LZMA2_IS_UNCOMPRESSED_STATE(p))
@@ -124,7 +124,7 @@ static ELzma2State Lzma2Dec_UpdateState(CLzma2Dec *p, Byte b)
case LZMA2_STATE_UNPACK1: case LZMA2_STATE_UNPACK1:
p->unpackSize |= (UInt32)b; p->unpackSize |= (UInt32)b;
p->unpackSize++; p->unpackSize++;
PRF(printf(" %8d", p->unpackSize)); PRF(printf(" %8u", (unsigned)p->unpackSize));
return (LZMA2_IS_UNCOMPRESSED_STATE(p)) ? LZMA2_STATE_DATA : LZMA2_STATE_PACK0; return (LZMA2_IS_UNCOMPRESSED_STATE(p)) ? LZMA2_STATE_DATA : LZMA2_STATE_PACK0;
case LZMA2_STATE_PACK0: case LZMA2_STATE_PACK0:
@@ -134,7 +134,7 @@ static ELzma2State Lzma2Dec_UpdateState(CLzma2Dec *p, Byte b)
case LZMA2_STATE_PACK1: case LZMA2_STATE_PACK1:
p->packSize |= (UInt32)b; p->packSize |= (UInt32)b;
p->packSize++; p->packSize++;
PRF(printf(" %8d", p->packSize)); PRF(printf(" %8u", (unsigned)p->packSize));
return LZMA2_IS_THERE_PROP(LZMA2_GET_LZMA_MODE(p)) ? LZMA2_STATE_PROP: return LZMA2_IS_THERE_PROP(LZMA2_GET_LZMA_MODE(p)) ? LZMA2_STATE_PROP:
(p->needInitProp ? LZMA2_STATE_ERROR : LZMA2_STATE_DATA); (p->needInitProp ? LZMA2_STATE_ERROR : LZMA2_STATE_DATA);

View File

@@ -1,5 +1,7 @@
/* Lzma86Dec.c -- LZMA + x86 (BCJ) Filter Decoder /* Lzma86Dec.c -- LZMA + x86 (BCJ) Filter Decoder
2009-08-14 : Igor Pavlov : Public domain */ 2015-11-08 : Igor Pavlov : Public domain */
#include "Precomp.h"
#include "Lzma86.h" #include "Lzma86.h"
@@ -7,8 +9,8 @@
#include "Bra.h" #include "Bra.h"
#include "LzmaDec.h" #include "LzmaDec.h"
static void *SzAlloc(void *p, size_t size) { p = p; return MyAlloc(size); } static void *SzAlloc(void *p, size_t size) { UNUSED_VAR(p); return MyAlloc(size); }
static void SzFree(void *p, void *address) { p = p; MyFree(address); } static void SzFree(void *p, void *address) { UNUSED_VAR(p); MyFree(address); }
SRes Lzma86_GetUnpackSize(const Byte *src, SizeT srcLen, UInt64 *unpackSize) SRes Lzma86_GetUnpackSize(const Byte *src, SizeT srcLen, UInt64 *unpackSize)
{ {

View File

@@ -1,5 +1,7 @@
/* Lzma86Enc.c -- LZMA + x86 (BCJ) Filter Encoder /* Lzma86Enc.c -- LZMA + x86 (BCJ) Filter Encoder
2009-08-14 : Igor Pavlov : Public domain */ 2015-11-08 : Igor Pavlov : Public domain */
#include "Precomp.h"
#include <string.h> #include <string.h>
@@ -11,8 +13,8 @@
#define SZE_OUT_OVERFLOW SZE_DATA_ERROR #define SZE_OUT_OVERFLOW SZE_DATA_ERROR
static void *SzAlloc(void *p, size_t size) { p = p; return MyAlloc(size); } static void *SzAlloc(void *p, size_t size) { UNUSED_VAR(p); return MyAlloc(size); }
static void SzFree(void *p, void *address) { p = p; MyFree(address); } static void SzFree(void *p, void *address) { UNUSED_VAR(p); MyFree(address); }
int Lzma86_Encode(Byte *dest, size_t *destLen, const Byte *src, size_t srcLen, int Lzma86_Encode(Byte *dest, size_t *destLen, const Byte *src, size_t srcLen,
int level, UInt32 dictSize, int filterMode) int level, UInt32 dictSize, int filterMode)

View File

@@ -1,5 +1,5 @@
/* LzmaEnc.c -- LZMA Encoder /* LzmaEnc.c -- LZMA Encoder
2015-10-15 Igor Pavlov : Public domain */ 2015-11-08 : Igor Pavlov : Public domain */
#include "Precomp.h" #include "Precomp.h"
@@ -854,7 +854,7 @@ static void MovePos(CLzmaEnc *p, UInt32 num)
{ {
#ifdef SHOW_STAT #ifdef SHOW_STAT
g_STAT_OFFSET += num; g_STAT_OFFSET += num;
printf("\n MovePos %d", num); printf("\n MovePos %u", num);
#endif #endif
if (num != 0) if (num != 0)
@@ -871,12 +871,12 @@ static UInt32 ReadMatchDistances(CLzmaEnc *p, UInt32 *numDistancePairsRes)
numPairs = p->matchFinder.GetMatches(p->matchFinderObj, p->matches); numPairs = p->matchFinder.GetMatches(p->matchFinderObj, p->matches);
#ifdef SHOW_STAT #ifdef SHOW_STAT
printf("\n i = %d numPairs = %d ", g_STAT_OFFSET, numPairs / 2); printf("\n i = %u numPairs = %u ", g_STAT_OFFSET, numPairs / 2);
g_STAT_OFFSET++; g_STAT_OFFSET++;
{ {
UInt32 i; UInt32 i;
for (i = 0; i < numPairs; i += 2) for (i = 0; i < numPairs; i += 2)
printf("%2d %6d | ", p->matches[i], p->matches[i + 1]); printf("%2u %6u | ", p->matches[i], p->matches[i + 1]);
} }
#endif #endif
@@ -1167,12 +1167,12 @@ static UInt32 GetOptimum(CLzmaEnc *p, UInt32 position, UInt32 *backRes)
cur = 0; cur = 0;
#ifdef SHOW_STAT2 #ifdef SHOW_STAT2
if (position >= 0) /* if (position >= 0) */
{ {
unsigned i; unsigned i;
printf("\n pos = %4X", position); printf("\n pos = %4X", position);
for (i = cur; i <= lenEnd; i++) for (i = cur; i <= lenEnd; i++)
printf("\nprice[%4X] = %d", position - cur + i, p->opt[i].price); printf("\nprice[%4X] = %u", position - cur + i, p->opt[i].price);
} }
#endif #endif
@@ -1397,13 +1397,13 @@ static UInt32 GetOptimum(CLzmaEnc *p, UInt32 position, UInt32 *backRes)
{ {
UInt32 lenTest2 = lenTest + 1; UInt32 lenTest2 = lenTest + 1;
UInt32 limit = lenTest2 + p->numFastBytes; UInt32 limit = lenTest2 + p->numFastBytes;
UInt32 nextRepMatchPrice;
if (limit > numAvailFull) if (limit > numAvailFull)
limit = numAvailFull; limit = numAvailFull;
for (; lenTest2 < limit && data[lenTest2] == data2[lenTest2]; lenTest2++); for (; lenTest2 < limit && data[lenTest2] == data2[lenTest2]; lenTest2++);
lenTest2 -= lenTest + 1; lenTest2 -= lenTest + 1;
if (lenTest2 >= 2) if (lenTest2 >= 2)
{ {
UInt32 nextRepMatchPrice;
UInt32 state2 = kRepNextStates[state]; UInt32 state2 = kRepNextStates[state];
UInt32 posStateNext = (position + lenTest) & p->pbMask; UInt32 posStateNext = (position + lenTest) & p->pbMask;
UInt32 curAndLenCharPrice = UInt32 curAndLenCharPrice =
@@ -1487,13 +1487,13 @@ static UInt32 GetOptimum(CLzmaEnc *p, UInt32 position, UInt32 *backRes)
const Byte *data2 = data - curBack - 1; const Byte *data2 = data - curBack - 1;
UInt32 lenTest2 = lenTest + 1; UInt32 lenTest2 = lenTest + 1;
UInt32 limit = lenTest2 + p->numFastBytes; UInt32 limit = lenTest2 + p->numFastBytes;
UInt32 nextRepMatchPrice;
if (limit > numAvailFull) if (limit > numAvailFull)
limit = numAvailFull; limit = numAvailFull;
for (; lenTest2 < limit && data[lenTest2] == data2[lenTest2]; lenTest2++); for (; lenTest2 < limit && data[lenTest2] == data2[lenTest2]; lenTest2++);
lenTest2 -= lenTest + 1; lenTest2 -= lenTest + 1;
if (lenTest2 >= 2) if (lenTest2 >= 2)
{ {
UInt32 nextRepMatchPrice;
UInt32 state2 = kMatchNextStates[state]; UInt32 state2 = kMatchNextStates[state];
UInt32 posStateNext = (position + lenTest) & p->pbMask; UInt32 posStateNext = (position + lenTest) & p->pbMask;
UInt32 curAndLenCharPrice = curAndLenPrice + UInt32 curAndLenCharPrice = curAndLenPrice +
@@ -1829,7 +1829,7 @@ static SRes LzmaEnc_CodeOneBlock(CLzmaEnc *p, Bool useLimits, UInt32 maxPackSize
len = GetOptimum(p, nowPos32, &pos); len = GetOptimum(p, nowPos32, &pos);
#ifdef SHOW_STAT2 #ifdef SHOW_STAT2
printf("\n pos = %4X, len = %d pos = %d", nowPos32, len, pos); printf("\n pos = %4X, len = %u pos = %u", nowPos32, len, pos);
#endif #endif
posState = nowPos32 & p->pbMask; posState = nowPos32 & p->pbMask;

View File

@@ -1,5 +1,5 @@
/* Sha1.c -- SHA-1 Hash /* Sha1.c -- SHA-1 Hash
2015-05-10 : Igor Pavlov : Public domain 2016-02-09 : Igor Pavlov : Public domain
This code is based on public domain code of Steve Reid from Wei Dai's Crypto++ library. */ This code is based on public domain code of Steve Reid from Wei Dai's Crypto++ library. */
#include "Precomp.h" #include "Precomp.h"
@@ -151,18 +151,23 @@ void Sha1_Update(CSha1 *p, const Byte *data, size_t size)
if (pos2 != 0) if (pos2 != 0)
{ {
UInt32 w = ((UInt32)data[0]) << 24; UInt32 w;
if (--size && pos2 < 3) pos2 = (3 - pos2) * 8;
w = ((UInt32)*data++) << pos2;
if (--size && pos2)
{ {
w |= ((UInt32)data[1]) << 16; pos2 -= 8;
if (--size && pos2 < 2) w |= ((UInt32)*data++) << pos2;
if (--size && pos2)
{ {
w |= ((UInt32)data[2]) << 8; pos2 -= 8;
--size; w |= ((UInt32)*data++) << pos2;
size--;
} }
} }
data += 4 - pos2; p->buffer[pos] |= w;
p->buffer[pos++] |= (w >> (8 * pos2)); if (pos2 == 0)
pos++;
} }
for (;;) for (;;)

View File

@@ -1,5 +1,5 @@
/* Crypto/Sha256.c -- SHA-256 Hash /* Crypto/Sha256.c -- SHA-256 Hash
2015-03-02 : Igor Pavlov : Public domain 2015-11-14 : Igor Pavlov : Public domain
This code is based on public domain code from Wei Dai's Crypto++ library. */ This code is based on public domain code from Wei Dai's Crypto++ library. */
#include "Precomp.h" #include "Precomp.h"
@@ -113,10 +113,26 @@ static void Sha256_WriteByteBlock(CSha256 *p)
{ {
UInt32 W[16]; UInt32 W[16];
unsigned j; unsigned j;
UInt32 *state = p->state; UInt32 *state;
#ifdef _SHA256_UNROLL2 #ifdef _SHA256_UNROLL2
UInt32 a,b,c,d,e,f,g,h; UInt32 a,b,c,d,e,f,g,h;
#else
UInt32 T[8];
#endif
for (j = 0; j < 16; j += 4)
{
const Byte *ccc = p->buffer + j * 4;
W[j ] = GetBe32(ccc);
W[j + 1] = GetBe32(ccc + 4);
W[j + 2] = GetBe32(ccc + 8);
W[j + 3] = GetBe32(ccc + 12);
}
state = p->state;
#ifdef _SHA256_UNROLL2
a = state[0]; a = state[0];
b = state[1]; b = state[1];
c = state[2]; c = state[2];
@@ -126,17 +142,10 @@ static void Sha256_WriteByteBlock(CSha256 *p)
g = state[6]; g = state[6];
h = state[7]; h = state[7];
#else #else
UInt32 T[8];
for (j = 0; j < 8; j++) for (j = 0; j < 8; j++)
T[j] = state[j]; T[j] = state[j];
#endif #endif
for (j = 0; j < 16; j += 2)
{
W[j ] = GetBe32(p->buffer + j * 4);
W[j + 1] = GetBe32(p->buffer + j * 4 + 4);
}
for (j = 0; j < 64; j += 16) for (j = 0; j < 64; j += 16)
{ {
RX_16 RX_16
@@ -226,11 +235,13 @@ void Sha256_Final(CSha256 *p, Byte *digest)
Sha256_WriteByteBlock(p); Sha256_WriteByteBlock(p);
for (i = 0; i < 8; i++) for (i = 0; i < 8; i += 2)
{ {
UInt32 v = p->state[i]; UInt32 v0 = p->state[i];
SetBe32(digest, v); UInt32 v1 = p->state[i + 1];
digest += 4; SetBe32(digest , v0);
SetBe32(digest + 4, v1);
digest += 8;
} }
Sha256_Init(p); Sha256_Init(p);

View File

@@ -73,4 +73,3 @@ Ppmd7Dec.o: ../../Ppmd7Dec.c
clean: clean:
-$(RM) $(PROG) $(OBJS) -$(RM) $(PROG) $(OBJS)

View File

@@ -1,5 +1,5 @@
/* 7zipInstall.c - 7-Zip Installer /* 7zipInstall.c - 7-Zip Installer
2015-09-28 : Igor Pavlov : Public domain */ 2015-12-09 : Igor Pavlov : Public domain */
#include "Precomp.h" #include "Precomp.h"
@@ -261,7 +261,7 @@ static LONG MyRegistry_CreateKeyAndVal(HKEY parentKey, LPCWSTR keyName, LPCWSTR
if (res == ERROR_SUCCESS) if (res == ERROR_SUCCESS)
{ {
res = MyRegistry_SetString(destKey, valName, val); res = MyRegistry_SetString(destKey, valName, val);
res = RegCloseKey(destKey); /* res = */ RegCloseKey(destKey);
} }
return res; return res;
} }
@@ -284,7 +284,7 @@ static LONG MyRegistry_CreateKeyAndVal_32(HKEY parentKey, LPCWSTR keyName, LPCWS
if (res == ERROR_SUCCESS) if (res == ERROR_SUCCESS)
{ {
res = MyRegistry_SetString(destKey, valName, val); res = MyRegistry_SetString(destKey, valName, val);
res = RegCloseKey(destKey); /* res = */ RegCloseKey(destKey);
} }
return res; return res;
} }
@@ -322,7 +322,7 @@ static Bool FindSignature(CSzFile *stream, UInt64 *resPos)
processed -= k7zStartHeaderSize; processed -= k7zStartHeaderSize;
for (pos = 0; pos <= processed; pos++) for (pos = 0; pos <= processed; pos++)
{ {
for (; buf[pos] != '7' && pos <= processed; pos++); for (; pos <= processed && buf[pos] != '7'; pos++);
if (pos > processed) if (pos > processed)
break; break;
if (memcmp(buf + pos, k7zSignature, k7zSignatureSize) == 0) if (memcmp(buf + pos, k7zSignature, k7zSignatureSize) == 0)
@@ -571,6 +571,8 @@ static INT_PTR CALLBACK MyDlgProc(HWND hwnd, UINT message, WPARAM wParam, LPARAM
#endif #endif
break; break;
} }
default: return FALSE;
} }
break; break;
@@ -598,8 +600,8 @@ static LONG SetRegKey_Path2(HKEY parentKey)
if (res == ERROR_SUCCESS) if (res == ERROR_SUCCESS)
{ {
res = MyRegistry_SetString(destKey, k_Reg_Path32, path); res = MyRegistry_SetString(destKey, k_Reg_Path32, path);
res = MyRegistry_SetString(destKey, k_Reg_Path, path); /* res = */ MyRegistry_SetString(destKey, k_Reg_Path, path);
res = RegCloseKey(destKey); /* res = */ RegCloseKey(destKey);
} }
return res; return res;
} }
@@ -718,10 +720,10 @@ static void WriteCLSID()
WCHAR destPath[MAX_PATH + 10]; WCHAR destPath[MAX_PATH + 10];
wcscpy(destPath, path); wcscpy(destPath, path);
wcscat(destPath, L"7-zip32.dll"); wcscat(destPath, L"7-zip32.dll");
res = MyRegistry_SetString(destKey, NULL, destPath); /* res = */ MyRegistry_SetString(destKey, NULL, destPath);
res = MyRegistry_SetString(destKey, L"ThreadingModel", L"Apartment"); /* res = */ MyRegistry_SetString(destKey, L"ThreadingModel", L"Apartment");
// DeleteRegValue(destKey, L"InprocServer32"); // DeleteRegValue(destKey, L"InprocServer32");
res = RegCloseKey(destKey); /* res = */ RegCloseKey(destKey);
} }
#endif #endif
@@ -737,10 +739,10 @@ static void WriteCLSID()
WCHAR destPath[MAX_PATH + 10]; WCHAR destPath[MAX_PATH + 10];
wcscpy(destPath, path); wcscpy(destPath, path);
wcscat(destPath, L"7-zip.dll"); wcscat(destPath, L"7-zip.dll");
res = MyRegistry_SetString(destKey, NULL, destPath); /* res = */ MyRegistry_SetString(destKey, NULL, destPath);
res = MyRegistry_SetString(destKey, L"ThreadingModel", L"Apartment"); /* res = */ MyRegistry_SetString(destKey, L"ThreadingModel", L"Apartment");
// DeleteRegValue(destKey, L"InprocServer32"); // DeleteRegValue(destKey, L"InprocServer32");
res = RegCloseKey(destKey); /* res = */ RegCloseKey(destKey);
} }
} }
@@ -1011,7 +1013,8 @@ int APIENTRY WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance,
BOOL bRet; BOOL bRet;
MSG msg; MSG msg;
while ((bRet = GetMessage(&msg, g_HWND, 0, 0)) != 0) // we need messages for all thread windows (including EDITTEXT window in dialog)
while ((bRet = GetMessage(&msg, NULL, 0, 0)) != 0)
{ {
if (bRet == -1) if (bRet == -1)
return retCode; return retCode;
@@ -1083,7 +1086,6 @@ static int Install()
WCHAR sfxPath[MAX_PATH + 2]; WCHAR sfxPath[MAX_PATH + 2];
Bool needReboot = False; Bool needReboot = False;
size_t pathLen;
allocImp.Alloc = SzAlloc; allocImp.Alloc = SzAlloc;
allocImp.Free = SzFree; allocImp.Free = SzFree;
@@ -1116,6 +1118,7 @@ static int Install()
if (res == SZ_OK) if (res == SZ_OK)
{ {
size_t pathLen;
if (!g_SilentMode) if (!g_SilentMode)
{ {
GetDlgItemTextW(g_HWND, IDE_EXTRACT_PATH, path, MAX_PATH); GetDlgItemTextW(g_HWND, IDE_EXTRACT_PATH, path, MAX_PATH);

View File

@@ -1,5 +1,5 @@
/* 7zipUninstall.c - 7-Zip Uninstaller /* 7zipUninstall.c - 7-Zip Uninstaller
2015-08-09 : Igor Pavlov : Public domain */ 2015-12-26 : Igor Pavlov : Public domain */
#include "Precomp.h" #include "Precomp.h"
@@ -384,7 +384,7 @@ static void WriteCLSID()
if (res == ERROR_SUCCESS) if (res == ERROR_SUCCESS)
{ {
RegDeleteValueW(destKey, k_7zip_CLSID); RegDeleteValueW(destKey, k_7zip_CLSID);
res = RegCloseKey(destKey); /* res = */ RegCloseKey(destKey);
} }
} }
} }
@@ -419,7 +419,7 @@ static void WriteCLSID()
if (res == ERROR_SUCCESS) if (res == ERROR_SUCCESS)
{ {
RegDeleteValueW(destKey, k_7zip_CLSID); RegDeleteValueW(destKey, k_7zip_CLSID);
res = RegCloseKey(destKey); /* res = */ RegCloseKey(destKey);
} }
} }
} }
@@ -542,7 +542,7 @@ static BOOL RemoveDir()
#define k_Lang L"Lang" #define k_Lang L"Lang"
// NUM_LANG_TXT_FILES files are placed before en.ttt // NUM_LANG_TXT_FILES files are placed before en.ttt
#define NUM_LANG_TXT_FILES 86 #define NUM_LANG_TXT_FILES 87
#ifdef _64BIT_INSTALLER #ifdef _64BIT_INSTALLER
#define NUM_EXTRA_FILES_64BIT 1 #define NUM_EXTRA_FILES_64BIT 1
@@ -556,7 +556,7 @@ static const char *k_Names =
"af an ar ast az ba be bg bn br ca co cs cy da de el eo es et eu ext" "af an ar ast az ba be bg bn br ca co cs cy da de el eo es et eu ext"
" fa fi fr fur fy ga gl gu he hi hr hu hy id io is it ja ka kaa kk ko ku ku-ckb ky" " fa fi fr fur fy ga gl gu he hi hr hu hy id io is it ja ka kaa kk ko ku ku-ckb ky"
" lij lt lv mk mn mng mng2 mr ms nb ne nl nn pa-in pl ps pt pt-br ro ru" " lij lt lv mk mn mng mng2 mr ms nb ne nl nn pa-in pl ps pt pt-br ro ru"
" sa si sk sl sq sr-spc sr-spl sv ta th tr tt ug uk uz va vi zh-cn zh-tw" " sa si sk sl sq sr-spc sr-spl sv ta th tr tt ug uk uz va vi yo zh-cn zh-tw"
" en.ttt" " en.ttt"
" descript.ion" " descript.ion"
" History.txt" " History.txt"
@@ -771,6 +771,8 @@ static INT_PTR CALLBACK MyDlgProc(HWND hwnd, UINT message, WPARAM wParam, LPARAM
OnClose(); OnClose();
break; break;
} }
default: return FALSE;
} }
break; break;
@@ -1033,7 +1035,7 @@ int APIENTRY WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance,
BOOL bRet; BOOL bRet;
MSG msg; MSG msg;
while ((bRet = GetMessage(&msg, g_HWND, 0, 0)) != 0) while ((bRet = GetMessage(&msg, NULL, 0, 0)) != 0)
{ {
if (bRet == -1) if (bRet == -1)
return retCode; return retCode;

View File

@@ -1,5 +1,5 @@
/* LzmaUtil.c -- Test application for LZMA compression /* LzmaUtil.c -- Test application for LZMA compression
2015-06-13 : Igor Pavlov : Public domain */ 2015-11-08 : Igor Pavlov : Public domain */
#include "../../Precomp.h" #include "../../Precomp.h"
@@ -133,7 +133,7 @@ static SRes Encode(ISeqOutStream *outStream, ISeqInStream *inStream, UInt64 file
SRes res; SRes res;
CLzmaEncProps props; CLzmaEncProps props;
rs = rs; UNUSED_VAR(rs);
enc = LzmaEnc_Create(&g_Alloc); enc = LzmaEnc_Create(&g_Alloc);
if (enc == 0) if (enc == 0)

View File

@@ -1,12 +1,14 @@
/* LzmaLibExports.c -- LZMA library DLL Entry point /* LzmaLibExports.c -- LZMA library DLL Entry point
2008-10-04 : Igor Pavlov : Public domain */ 2015-11-08 : Igor Pavlov : Public domain */
#include "../../Precomp.h"
#include <windows.h> #include <windows.h>
BOOL WINAPI DllMain(HINSTANCE hInstance, DWORD dwReason, LPVOID lpReserved) BOOL WINAPI DllMain(HINSTANCE hInstance, DWORD dwReason, LPVOID lpReserved)
{ {
hInstance = hInstance; UNUSED_VAR(hInstance);
dwReason = dwReason; UNUSED_VAR(dwReason);
lpReserved = lpReserved; UNUSED_VAR(lpReserved);
return TRUE; return TRUE;
} }

View File

@@ -1,5 +1,5 @@
/* SfxSetup.c - 7z SFX Setup /* SfxSetup.c - 7z SFX Setup
2015-03-25 : Igor Pavlov : Public domain */ 2015-11-08 : Igor Pavlov : Public domain */
#include "Precomp.h" #include "Precomp.h"
@@ -88,7 +88,7 @@ static unsigned FindItem(const char * const *items, unsigned num, const wchar_t
#ifdef _CONSOLE #ifdef _CONSOLE
static BOOL WINAPI HandlerRoutine(DWORD ctrlType) static BOOL WINAPI HandlerRoutine(DWORD ctrlType)
{ {
ctrlType = ctrlType; UNUSED_VAR(ctrlType);
return TRUE; return TRUE;
} }
#endif #endif
@@ -144,7 +144,7 @@ static Bool FindSignature(CSzFile *stream, UInt64 *resPos)
processed -= k7zStartHeaderSize; processed -= k7zStartHeaderSize;
for (pos = 0; pos <= processed; pos++) for (pos = 0; pos <= processed; pos++)
{ {
for (; buf[pos] != '7' && pos <= processed; pos++); for (; pos <= processed && buf[pos] != '7'; pos++);
if (pos > processed) if (pos > processed)
break; break;
if (memcmp(buf + pos, k7zSignature, k7zSignatureSize) == 0) if (memcmp(buf + pos, k7zSignature, k7zSignatureSize) == 0)
@@ -257,10 +257,10 @@ int APIENTRY WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance,
#ifdef _CONSOLE #ifdef _CONSOLE
SetConsoleCtrlHandler(HandlerRoutine, TRUE); SetConsoleCtrlHandler(HandlerRoutine, TRUE);
#else #else
hInstance = hInstance; UNUSED_VAR(hInstance);
hPrevInstance = hPrevInstance; UNUSED_VAR(hPrevInstance);
lpCmdLine = lpCmdLine; UNUSED_VAR(lpCmdLine);
nCmdShow = nCmdShow; UNUSED_VAR(nCmdShow);
#endif #endif
CrcGenerateTable(); CrcGenerateTable();

View File

@@ -1,5 +1,5 @@
/* XzDec.c -- Xz Decode /* XzDec.c -- Xz Decode
2015-05-01 : Igor Pavlov : Public domain */ 2015-11-09 : Igor Pavlov : Public domain */
#include "Precomp.h" #include "Precomp.h"
@@ -74,7 +74,7 @@ static void BraState_Free(void *pp, ISzAlloc *alloc)
static SRes BraState_SetProps(void *pp, const Byte *props, size_t propSize, ISzAlloc *alloc) static SRes BraState_SetProps(void *pp, const Byte *props, size_t propSize, ISzAlloc *alloc)
{ {
CBraState *p = ((CBraState *)pp); CBraState *p = ((CBraState *)pp);
alloc = alloc; UNUSED_VAR(alloc);
p->ip = 0; p->ip = 0;
if (p->methodId == XZ_ID_Delta) if (p->methodId == XZ_ID_Delta)
{ {
@@ -129,9 +129,9 @@ static SRes BraState_Code(void *pp, Byte *dest, SizeT *destLen, const Byte *src,
CBraState *p = ((CBraState *)pp); CBraState *p = ((CBraState *)pp);
SizeT destLenOrig = *destLen; SizeT destLenOrig = *destLen;
SizeT srcLenOrig = *srcLen; SizeT srcLenOrig = *srcLen;
UNUSED_VAR(finishMode);
*destLen = 0; *destLen = 0;
*srcLen = 0; *srcLen = 0;
finishMode = finishMode;
*wasFinished = 0; *wasFinished = 0;
while (destLenOrig > 0) while (destLenOrig > 0)
{ {
@@ -236,8 +236,8 @@ static void SbState_Free(void *pp, ISzAlloc *alloc)
static SRes SbState_SetProps(void *pp, const Byte *props, size_t propSize, ISzAlloc *alloc) static SRes SbState_SetProps(void *pp, const Byte *props, size_t propSize, ISzAlloc *alloc)
{ {
UNUSED_VAR(pp); UNUSED_VAR(pp);
props = props; UNUSED_VAR(props);
alloc = alloc; UNUSED_VAR(alloc);
return (propSize == 0) ? SZ_OK : SZ_ERROR_UNSUPPORTED; return (propSize == 0) ? SZ_OK : SZ_ERROR_UNSUPPORTED;
} }
@@ -251,7 +251,7 @@ static SRes SbState_Code(void *pp, Byte *dest, SizeT *destLen, const Byte *src,
{ {
CSbDec *p = (CSbDec *)pp; CSbDec *p = (CSbDec *)pp;
SRes res; SRes res;
srcWasFinished = srcWasFinished; UNUSED_VAR(srcWasFinished);
p->dest = dest; p->dest = dest;
p->destLen = *destLen; p->destLen = *destLen;
p->src = src; p->src = src;
@@ -308,7 +308,7 @@ static SRes Lzma2State_Code(void *pp, Byte *dest, SizeT *destLen, const Byte *sr
ELzmaStatus status; ELzmaStatus status;
/* ELzmaFinishMode fm = (finishMode == LZMA_FINISH_ANY) ? LZMA_FINISH_ANY : LZMA_FINISH_END; */ /* ELzmaFinishMode fm = (finishMode == LZMA_FINISH_ANY) ? LZMA_FINISH_ANY : LZMA_FINISH_END; */
SRes res = Lzma2Dec_DecodeToBuf((CLzma2Dec *)pp, dest, destLen, src, srcLen, (ELzmaFinishMode)finishMode, &status); SRes res = Lzma2Dec_DecodeToBuf((CLzma2Dec *)pp, dest, destLen, src, srcLen, (ELzmaFinishMode)finishMode, &status);
srcWasFinished = srcWasFinished; UNUSED_VAR(srcWasFinished);
*wasFinished = (status == LZMA_STATUS_FINISHED_WITH_MARK); *wasFinished = (status == LZMA_STATUS_FINISHED_WITH_MARK);
return res; return res;
} }
@@ -555,7 +555,7 @@ SRes XzBlock_Parse(CXzBlock *p, const Byte *header)
pos += (unsigned)size; pos += (unsigned)size;
#ifdef XZ_DUMP #ifdef XZ_DUMP
printf("\nf[%d] = %2X: ", i, filter->id); printf("\nf[%u] = %2X: ", i, (unsigned)filter->id);
{ {
unsigned i; unsigned i;
for (i = 0; i < size; i++) for (i = 0; i < size; i++)

View File

@@ -1,5 +1,5 @@
/* XzIn.c - Xz input /* XzIn.c - Xz input
2015-04-21 : Igor Pavlov : Public domain */ 2015-11-08 : Igor Pavlov : Public domain */
#include "Precomp.h" #include "Precomp.h"
@@ -72,7 +72,7 @@ SRes XzBlock_ReadFooter(CXzBlock *p, CXzStreamFlags f, ISeqInStream *inStream)
static SRes Xz_ReadIndex2(CXzStream *p, const Byte *buf, size_t size, ISzAlloc *alloc) static SRes Xz_ReadIndex2(CXzStream *p, const Byte *buf, size_t size, ISzAlloc *alloc)
{ {
size_t i, numBlocks, pos = 1; size_t numBlocks, pos = 1;
UInt32 crc; UInt32 crc;
if (size < 5 || buf[0] != 0) if (size < 5 || buf[0] != 0)
@@ -94,6 +94,7 @@ static SRes Xz_ReadIndex2(CXzStream *p, const Byte *buf, size_t size, ISzAlloc *
Xz_Free(p, alloc); Xz_Free(p, alloc);
if (numBlocks != 0) if (numBlocks != 0)
{ {
size_t i;
p->numBlocks = numBlocks; p->numBlocks = numBlocks;
p->numBlocksAllocated = numBlocks; p->numBlocksAllocated = numBlocks;
p->blocks = alloc->Alloc(alloc, sizeof(CXzBlockSizes) * numBlocks); p->blocks = alloc->Alloc(alloc, sizeof(CXzBlockSizes) * numBlocks);

View File

@@ -93,6 +93,8 @@ void CStreamSwitch::Set(CInArchive *archive, const CObjectVector<CByteBuffer> *d
Byte external = archive->ReadByte(); Byte external = archive->ReadByte();
if (external != 0) if (external != 0)
{ {
if (!dataVector)
ThrowIncorrect();
CNum dataIndex = archive->ReadNum(); CNum dataIndex = archive->ReadNum();
if (dataIndex >= dataVector->Size()) if (dataIndex >= dataVector->Size())
ThrowIncorrect(); ThrowIncorrect();
@@ -761,6 +763,8 @@ void CInArchive::ReadUnpackInfo(
folders.FoToCoderUnpackSizes[fo] = numCodersOutStreams; folders.FoToCoderUnpackSizes[fo] = numCodersOutStreams;
numCodersOutStreams += numCoders; numCodersOutStreams += numCoders;
folders.FoStartPackStreamIndex[fo] = packStreamIndex; folders.FoStartPackStreamIndex[fo] = packStreamIndex;
if (numPackStreams > folders.NumPackStreams - packStreamIndex)
ThrowIncorrect();
packStreamIndex += numPackStreams; packStreamIndex += numPackStreams;
folders.FoToMainUnpackSizeIndex[fo] = (Byte)indexOfMainStream; folders.FoToMainUnpackSizeIndex[fo] = (Byte)indexOfMainStream;
} }
@@ -770,6 +774,8 @@ void CInArchive::ReadUnpackInfo(
folders.FoStartPackStreamIndex[fo] = packStreamIndex; folders.FoStartPackStreamIndex[fo] = packStreamIndex;
folders.FoCodersDataOffset[fo] = _inByteBack->GetPtr() - startBufPtr; folders.FoCodersDataOffset[fo] = _inByteBack->GetPtr() - startBufPtr;
folders.CodersData.CopyFrom(startBufPtr, dataSize); folders.CodersData.CopyFrom(startBufPtr, dataSize);
// if (folders.NumPackStreams != packStreamIndex) ThrowUnsupported();
} }
WaitId(NID::kCodersUnpackSize); WaitId(NID::kCodersUnpackSize);

View File

@@ -87,6 +87,8 @@ struct CFolders
return PackPositions[index + 1] - PackPositions[index]; return PackPositions[index + 1] - PackPositions[index];
} }
CFolders(): NumPackStreams(0), NumFolders(0) {}
void Clear() void Clear()
{ {
NumPackStreams = 0; NumPackStreams = 0;

View File

@@ -380,29 +380,33 @@ static inline bool IsExeFilter(CMethodId m)
return false; return false;
} }
static unsigned Get_FilterGroup_for_Folder(CRecordVector<CFilterMode2> &filters, const CFolderEx &f) static unsigned Get_FilterGroup_for_Folder(
CRecordVector<CFilterMode2> &filters, const CFolderEx &f, bool extractFilter)
{ {
CFilterMode2 m; CFilterMode2 m;
m.Id = 0; m.Id = 0;
m.Delta = 0; m.Delta = 0;
m.Encrypted = f.IsEncrypted(); m.Encrypted = f.IsEncrypted();
const CCoderInfo &coder = f.Coders[f.UnpackCoder]; if (extractFilter)
{
const CCoderInfo &coder = f.Coders[f.UnpackCoder];
if (coder.MethodID == k_Delta) if (coder.MethodID == k_Delta)
{
if (coder.Props.Size() == 1)
{ {
m.Delta = (unsigned)coder.Props[0] + 1; if (coder.Props.Size() == 1)
m.Id = k_Delta; {
m.Delta = (unsigned)coder.Props[0] + 1;
m.Id = k_Delta;
}
}
else if (IsExeFilter(coder.MethodID))
{
m.Id = (UInt32)coder.MethodID;
if (m.Id == k_BCJ2)
m.Id = k_BCJ;
m.SetDelta();
} }
}
else if (IsExeFilter(coder.MethodID))
{
m.Id = (UInt32)coder.MethodID;
if (m.Id == k_BCJ2)
m.Id = k_BCJ;
m.SetDelta();
} }
return GetGroup(filters, m); return GetGroup(filters, m);
@@ -567,14 +571,17 @@ static const char *g_Exts =
" iso bin nrg mdf img pdi tar cpio xpi" " iso bin nrg mdf img pdi tar cpio xpi"
" vfd vhd vud vmc vsv" " vfd vhd vud vmc vsv"
" vmdk dsk nvram vmem vmsd vmsn vmss vmtm" " vmdk dsk nvram vmem vmsd vmsn vmss vmtm"
" inl inc idl acf asa h hpp hxx c cpp cxx rc java cs pas bas vb cls ctl frm dlg def" " inl inc idl acf asa"
" h hpp hxx c cpp cxx m mm go swift"
" rc java cs rs pas bas vb cls ctl frm dlg def"
" f77 f f90 f95" " f77 f f90 f95"
" asm sql manifest dep" " asm s"
" sql manifest dep"
" mak clw csproj vcproj sln dsp dsw" " mak clw csproj vcproj sln dsp dsw"
" class" " class"
" bat cmd" " bat cmd bash sh"
" xml xsd xsl xslt hxk hxc htm html xhtml xht mht mhtml htw asp aspx css cgi jsp shtml" " xml xsd xsl xslt hxk hxc htm html xhtml xht mht mhtml htw asp aspx css cgi jsp shtml"
" awk sed hta js php php3 php4 php5 phptml pl pm py pyo rb sh tcl vbs" " awk sed hta js json php php3 php4 php5 phptml pl pm py pyo rb tcl ts vbs"
" text txt tex ans asc srt reg ini doc docx mcw dot rtf hlp xls xlr xlt xlw ppt pdf" " text txt tex ans asc srt reg ini doc docx mcw dot rtf hlp xls xlr xlt xlw ppt pdf"
" sxc sxd sxi sxg sxw stc sti stw stm odt ott odg otg odp otp ods ots odf" " sxc sxd sxi sxg sxw stc sti stw stm odt ott odg otg odp otp ods ots odf"
" abw afp cwk lwp wpd wps wpt wrf wri" " abw afp cwk lwp wpd wps wpt wrf wri"
@@ -1574,7 +1581,7 @@ HRESULT Update(
return E_NOTIMPL; return E_NOTIMPL;
*/ */
UInt64 startBlockSize = db != 0 ? db->ArcInfo.StartPosition: 0; UInt64 startBlockSize = db ? db->ArcInfo.StartPosition: 0;
if (startBlockSize > 0 && !options.RemoveSfxBlock) if (startBlockSize > 0 && !options.RemoveSfxBlock)
{ {
RINOK(WriteRange(inStream, seqOutStream, 0, startBlockSize, NULL)); RINOK(WriteRange(inStream, seqOutStream, 0, startBlockSize, NULL));
@@ -1588,8 +1595,21 @@ HRESULT Update(
CRecordVector<CFilterMode2> filters; CRecordVector<CFilterMode2> filters;
CObjectVector<CSolidGroup> groups; CObjectVector<CSolidGroup> groups;
bool thereAreRepacks = false; bool thereAreRepacks = false;
bool useFilters = options.UseFilters;
if (useFilters)
{
const CCompressionMethodMode &method = *options.Method;
FOR_VECTOR (i, method.Methods)
if (IsFilterMethod(method.Methods[i].Id))
{
useFilters = false;
break;
}
}
if (db != 0) if (db)
{ {
fileIndexToUpdateIndexMap.Alloc(db->Files.Size()); fileIndexToUpdateIndexMap.Alloc(db->Files.Size());
unsigned i; unsigned i;
@@ -1635,16 +1655,18 @@ HRESULT Update(
CFolderEx f; CFolderEx f;
db->ParseFolderEx(i, f); db->ParseFolderEx(i, f);
bool isEncrypted = f.IsEncrypted(); const bool isEncrypted = f.IsEncrypted();
const bool needCopy = (numCopyItems == numUnpackStreams);
unsigned groupIndex = Get_FilterGroup_for_Folder(filters, f); const bool extractFilter = (useFilters || needCopy);
unsigned groupIndex = Get_FilterGroup_for_Folder(filters, f, extractFilter);
while (groupIndex >= groups.Size()) while (groupIndex >= groups.Size())
groups.AddNew(); groups.AddNew();
groups[groupIndex].folderRefs.Add(rep); groups[groupIndex].folderRefs.Add(rep);
if (numCopyItems == numUnpackStreams) if (needCopy)
complexity += db->GetFolderFullPackSize(i); complexity += db->GetFolderFullPackSize(i);
else else
{ {
@@ -1729,22 +1751,8 @@ HRESULT Update(
// ---------- Split files to groups ---------- // ---------- Split files to groups ----------
bool useFilters = options.UseFilters;
const CCompressionMethodMode &method = *options.Method; const CCompressionMethodMode &method = *options.Method;
if (useFilters)
for (i = 0; i < method.Methods.Size(); i++)
if (IsFilterMethod(method.Methods[i].Id))
{
useFilters = false;
break;
}
/*
if (!method.Bonds.IsEmpty())
useFilters = false;
*/
for (i = 0; i < updateItems.Size(); i++) for (i = 0; i < updateItems.Size(); i++)
{ {
const CUpdateItem &ui = updateItems[i]; const CUpdateItem &ui = updateItems[i];
@@ -2153,7 +2161,13 @@ HRESULT Update(
#ifndef _7ZIP_ST #ifndef _7ZIP_ST
if (options.MultiThreadMixer) if (options.MultiThreadMixer)
{ {
// 16.00: hang was fixed : for case if decoding was not finished.
// We close CBinderInStream and it calls CStreamBinder::CloseRead()
inStreamSizeCount.Release();
sbInStream.Release();
threadDecoder.WaitExecuteFinish(); threadDecoder.WaitExecuteFinish();
HRESULT decodeRes = threadDecoder.Result; HRESULT decodeRes = threadDecoder.Result;
// if (res == k_My_HRESULT_CRC_ERROR) // if (res == k_My_HRESULT_CRC_ERROR)
if (decodeRes == S_FALSE) if (decodeRes == S_FALSE)

View File

@@ -348,15 +348,19 @@ STDMETHODIMP CHandler::Open(IInStream *inStream,
CMyComPtr<IInStream> nextStream = inStream; CMyComPtr<IInStream> nextStream = inStream;
bool prevChecked = false; bool prevChecked = false;
UString startVolName;
bool startVolName_was_Requested = false;
UInt64 numItems = 0; UInt64 numItems = 0;
unsigned numTempVolumes = 0; unsigned numTempVolumes = 0;
// try // try
{ {
while (nextStream != NULL) while (nextStream)
{ {
CDatabaseEx db; CDatabaseEx db;
db.Stream = nextStream; db.Stream = nextStream;
HRESULT res = archive.Open(db, maxCheckStartPosition); HRESULT res = archive.Open(db, maxCheckStartPosition);
_errorInHeaders |= archive.HeaderError; _errorInHeaders |= archive.HeaderError;
_errorInHeaders |= archive.ErrorInNames; _errorInHeaders |= archive.ErrorInNames;
_unexpectedEnd |= archive.UnexpectedEnd; _unexpectedEnd |= archive.UnexpectedEnd;
@@ -426,6 +430,7 @@ STDMETHODIMP CHandler::Open(IInStream *inStream,
for (;;) for (;;)
{ {
const COtherArc *otherArc = NULL; const COtherArc *otherArc = NULL;
if (!prevChecked) if (!prevChecked)
{ {
if (numTempVolumes == 0) if (numTempVolumes == 0)
@@ -449,18 +454,35 @@ STDMETHODIMP CHandler::Open(IInStream *inStream,
} }
} }
} }
if (!otherArc) if (!otherArc)
{ {
const CInArcInfo &ai = m_Database.Volumes.Back().ArcInfo; const CInArcInfo &ai = m_Database.Volumes.Back().ArcInfo;
if (ai.IsThereNext()) if (ai.IsThereNext())
otherArc = &ai.NextArc; otherArc = &ai.NextArc;
} }
if (!otherArc) if (!otherArc)
break; break;
if (!openVolumeCallback) if (!openVolumeCallback)
break; break;
// printf("\n%s", otherArc->FileName); // printf("\n%s", otherArc->FileName);
const UString fullName = MultiByteToUnicodeString(otherArc->FileName, CP_ACP); const UString fullName = MultiByteToUnicodeString(otherArc->FileName, CP_ACP);
if (!startVolName_was_Requested)
{
// some "bad" cab example can contain the link to itself.
startVolName_was_Requested = true;
{
NCOM::CPropVariant prop;
RINOK(openVolumeCallback->GetProperty(kpidName, &prop));
if (prop.vt == VT_BSTR)
startVolName = prop.bstrVal;
}
if (fullName == startVolName)
break;
}
HRESULT result = openVolumeCallback->GetStream(fullName, &nextStream); HRESULT result = openVolumeCallback->GetStream(fullName, &nextStream);
if (result == S_OK) if (result == S_OK)
break; break;
@@ -572,6 +594,7 @@ public:
HRESULT FlushCorrupted(unsigned folderIndex); HRESULT FlushCorrupted(unsigned folderIndex);
HRESULT Unsupported(); HRESULT Unsupported();
bool NeedMoreWrite() const { return (m_FolderSize > m_PosInFolder); }
UInt64 GetRemain() const { return m_FolderSize - m_PosInFolder; } UInt64 GetRemain() const { return m_FolderSize - m_PosInFolder; }
UInt64 GetPosInFolder() const { return m_PosInFolder; } UInt64 GetPosInFolder() const { return m_PosInFolder; }
}; };
@@ -781,6 +804,7 @@ HRESULT CFolderOutStream::Write2(const void *data, UInt32 size, UInt32 *processe
realProcessed += size; realProcessed += size;
if (processedSize) if (processedSize)
*processedSize = realProcessed; *processedSize = realProcessed;
m_PosInFolder += size;
return S_OK; return S_OK;
// return E_FAIL; // return E_FAIL;
} }
@@ -830,9 +854,7 @@ STDMETHODIMP CFolderOutStream::Write(const void *data, UInt32 size, UInt32 *proc
HRESULT CFolderOutStream::FlushCorrupted(unsigned folderIndex) HRESULT CFolderOutStream::FlushCorrupted(unsigned folderIndex)
{ {
UInt64 remain = GetRemain(); if (!NeedMoreWrite())
if (remain == 0)
{ {
CMyComPtr<IArchiveExtractCallbackMessage> callbackMessage; CMyComPtr<IArchiveExtractCallbackMessage> callbackMessage;
m_ExtractCallback.QueryInterface(IID_IArchiveExtractCallbackMessage, &callbackMessage); m_ExtractCallback.QueryInterface(IID_IArchiveExtractCallbackMessage, &callbackMessage);
@@ -843,16 +865,16 @@ HRESULT CFolderOutStream::FlushCorrupted(unsigned folderIndex)
return S_OK; return S_OK;
} }
const unsigned kBufSize = (1 << 10); const unsigned kBufSize = (1 << 12);
Byte buf[kBufSize]; Byte buf[kBufSize];
for (unsigned i = 0; i < kBufSize; i++) for (unsigned i = 0; i < kBufSize; i++)
buf[i] = 0; buf[i] = 0;
for (;;) for (;;)
{ {
UInt64 remain = GetRemain(); if (!NeedMoreWrite())
if (remain == 0)
return S_OK; return S_OK;
UInt64 remain = GetRemain();
UInt32 size = (remain < kBufSize ? (UInt32)remain : (UInt32)kBufSize); UInt32 size = (remain < kBufSize ? (UInt32)remain : (UInt32)kBufSize);
UInt32 processedSizeLocal = 0; UInt32 processedSizeLocal = 0;
RINOK(Write2(buf, size, &processedSizeLocal, false)); RINOK(Write2(buf, size, &processedSizeLocal, false));
@@ -937,8 +959,15 @@ STDMETHODIMP CHandler::Extract(const UInt32 *indices, UInt32 numItems,
CRecordVector<bool> extractStatuses; CRecordVector<bool> extractStatuses;
for (i = 0; i < numItems;) for (i = 0;;)
{ {
lps->OutSize = totalUnPacked;
lps->InSize = totalPacked;
RINOK(lps->SetCur());
if (i >= numItems)
break;
unsigned index = allFilesMode ? i : indices[i]; unsigned index = allFilesMode ? i : indices[i];
const CMvItem &mvItem = m_Database.Items[index]; const CMvItem &mvItem = m_Database.Items[index];
@@ -1003,10 +1032,6 @@ STDMETHODIMP CHandler::Extract(const UInt32 *indices, UInt32 numItems,
curUnpack = item.GetEndOffset(); curUnpack = item.GetEndOffset();
} }
lps->OutSize = totalUnPacked;
lps->InSize = totalPacked;
RINOK(lps->SetCur());
CFolderOutStream *cabFolderOutStream = new CFolderOutStream; CFolderOutStream *cabFolderOutStream = new CFolderOutStream;
CMyComPtr<ISequentialOutStream> outStream(cabFolderOutStream); CMyComPtr<ISequentialOutStream> outStream(cabFolderOutStream);
@@ -1071,7 +1096,7 @@ STDMETHODIMP CHandler::Extract(const UInt32 *indices, UInt32 numItems,
bool keepInputBuffer = false; bool keepInputBuffer = false;
bool thereWasNotAlignedChunk = false; bool thereWasNotAlignedChunk = false;
for (UInt32 bl = 0; cabFolderOutStream->GetRemain() != 0;) for (UInt32 bl = 0; cabFolderOutStream->NeedMoreWrite();)
{ {
if (volIndex >= m_Database.Volumes.Size()) if (volIndex >= m_Database.Volumes.Size())
{ {
@@ -1213,7 +1238,7 @@ STDMETHODIMP CHandler::Extract(const UInt32 *indices, UInt32 numItems,
} }
} }
if (res != S_OK || cabFolderOutStream->GetRemain() != 0) if (res != S_OK || cabFolderOutStream->NeedMoreWrite())
{ {
RINOK(cabFolderOutStream->FlushCorrupted(folderIndex2)); RINOK(cabFolderOutStream->FlushCorrupted(folderIndex2));
} }

View File

@@ -67,6 +67,7 @@ void CInArchive::ReadOtherArc(COtherArc &oa)
ReadName(oa.DiskName); ReadName(oa.DiskName);
} }
struct CSignatureFinder struct CSignatureFinder
{ {
Byte *Buf; Byte *Buf;
@@ -100,6 +101,7 @@ struct CSignatureFinder
HRESULT Find(); HRESULT Find();
}; };
HRESULT CSignatureFinder::Find() HRESULT CSignatureFinder::Find()
{ {
for (;;) for (;;)
@@ -156,6 +158,7 @@ HRESULT CSignatureFinder::Find()
} }
} }
bool CInArcInfo::Parse(const Byte *p) bool CInArcInfo::Parse(const Byte *p)
{ {
if (Get32(p + 0x0C) != 0 || if (Get32(p + 0x0C) != 0 ||
@@ -177,6 +180,7 @@ bool CInArcInfo::Parse(const Byte *p)
return true; return true;
} }
HRESULT CInArchive::Open2(CDatabaseEx &db, const UInt64 *searchHeaderSizeLimit) HRESULT CInArchive::Open2(CDatabaseEx &db, const UInt64 *searchHeaderSizeLimit)
{ {
IsArc = false; IsArc = false;
@@ -286,7 +290,9 @@ HRESULT CInArchive::Open2(CDatabaseEx &db, const UInt64 *searchHeaderSizeLimit)
if (ai.IsThereNext()) ReadOtherArc(ai.NextArc); if (ai.IsThereNext()) ReadOtherArc(ai.NextArc);
UInt32 i; UInt32 i;
db.Folders.ClearAndReserve(ai.NumFolders); db.Folders.ClearAndReserve(ai.NumFolders);
for (i = 0; i < ai.NumFolders; i++) for (i = 0; i < ai.NumFolders; i++)
{ {
Read(p, 8); Read(p, 8);
@@ -311,6 +317,7 @@ HRESULT CInArchive::Open2(CDatabaseEx &db, const UInt64 *searchHeaderSizeLimit)
} }
db.Items.ClearAndReserve(ai.NumFiles); db.Items.ClearAndReserve(ai.NumFiles);
for (i = 0; i < ai.NumFiles; i++) for (i = 0; i < ai.NumFiles; i++)
{ {
Read(p, 16); Read(p, 16);
@@ -324,6 +331,7 @@ HRESULT CInArchive::Open2(CDatabaseEx &db, const UInt64 *searchHeaderSizeLimit)
item.Attributes = Get16(p + 14); item.Attributes = Get16(p + 14);
ReadName(item.Name); ReadName(item.Name);
if (item.GetFolderIndex(db.Folders.Size()) >= (int)db.Folders.Size()) if (item.GetFolderIndex(db.Folders.Size()) >= (int)db.Folders.Size())
{ {
HeaderError = true; HeaderError = true;
@@ -336,6 +344,7 @@ HRESULT CInArchive::Open2(CDatabaseEx &db, const UInt64 *searchHeaderSizeLimit)
return S_OK; return S_OK;
} }
HRESULT CInArchive::Open(CDatabaseEx &db, const UInt64 *searchHeaderSizeLimit) HRESULT CInArchive::Open(CDatabaseEx &db, const UInt64 *searchHeaderSizeLimit)
{ {
try try
@@ -370,6 +379,7 @@ static int CompareMvItems(const CMvItem *p1, const CMvItem *p2, void *param)
return MyCompare(p1->ItemIndex, p2->ItemIndex); return MyCompare(p1->ItemIndex, p2->ItemIndex);
} }
bool CMvDatabaseEx::AreItemsEqual(unsigned i1, unsigned i2) bool CMvDatabaseEx::AreItemsEqual(unsigned i1, unsigned i2)
{ {
const CMvItem *p1 = &Items[i1]; const CMvItem *p1 = &Items[i1];
@@ -384,12 +394,15 @@ bool CMvDatabaseEx::AreItemsEqual(unsigned i1, unsigned i2)
&& item1.Name == item2.Name; && item1.Name == item2.Name;
} }
void CMvDatabaseEx::FillSortAndShrink() void CMvDatabaseEx::FillSortAndShrink()
{ {
Items.Clear(); Items.Clear();
StartFolderOfVol.Clear(); StartFolderOfVol.Clear();
FolderStartFileIndex.Clear(); FolderStartFileIndex.Clear();
int offset = 0; int offset = 0;
FOR_VECTOR (v, Volumes) FOR_VECTOR (v, Volumes)
{ {
const CDatabaseEx &db = Volumes[v]; const CDatabaseEx &db = Volumes[v];
@@ -422,11 +435,12 @@ void CMvDatabaseEx::FillSortAndShrink()
FOR_VECTOR (i, Items) FOR_VECTOR (i, Items)
{ {
int folderIndex = GetFolderIndex(&Items[i]); int folderIndex = GetFolderIndex(&Items[i]);
if (folderIndex >= (int)FolderStartFileIndex.Size()) while (folderIndex >= (int)FolderStartFileIndex.Size())
FolderStartFileIndex.Add(i); FolderStartFileIndex.Add(i);
} }
} }
bool CMvDatabaseEx::Check() bool CMvDatabaseEx::Check()
{ {
for (unsigned v = 1; v < Volumes.Size(); v++) for (unsigned v = 1; v < Volumes.Size(); v++)
@@ -444,9 +458,11 @@ bool CMvDatabaseEx::Check()
return false; return false;
} }
} }
UInt32 beginPos = 0; UInt32 beginPos = 0;
UInt64 endPos = 0; UInt64 endPos = 0;
int prevFolder = -2; int prevFolder = -2;
FOR_VECTOR (i, Items) FOR_VECTOR (i, Items)
{ {
const CMvItem &mvItem = Items[i]; const CMvItem &mvItem = Items[i];
@@ -456,15 +472,19 @@ bool CMvDatabaseEx::Check()
const CItem &item = Volumes[mvItem.VolumeIndex].Items[mvItem.ItemIndex]; const CItem &item = Volumes[mvItem.VolumeIndex].Items[mvItem.ItemIndex];
if (item.IsDir()) if (item.IsDir())
continue; continue;
int folderIndex = GetFolderIndex(&mvItem); int folderIndex = GetFolderIndex(&mvItem);
if (folderIndex != prevFolder) if (folderIndex != prevFolder)
prevFolder = folderIndex; prevFolder = folderIndex;
else if (item.Offset < endPos && else if (item.Offset < endPos &&
(item.Offset != beginPos || item.GetEndOffset() != endPos)) (item.Offset != beginPos || item.GetEndOffset() != endPos))
return false; return false;
beginPos = item.Offset; beginPos = item.Offset;
endPos = item.GetEndOffset(); endPos = item.GetEndOffset();
} }
return true; return true;
} }

View File

@@ -25,6 +25,7 @@ struct COtherArc
} }
}; };
struct CArchInfo struct CArchInfo
{ {
Byte VersionMinor; // cabinet file format version, minor Byte VersionMinor; // cabinet file format version, minor
@@ -65,6 +66,7 @@ struct CArchInfo
} }
}; };
struct CInArcInfo: public CArchInfo struct CInArcInfo: public CArchInfo
{ {
UInt32 Size; // size of this cabinet file in bytes UInt32 Size; // size of this cabinet file in bytes
@@ -105,17 +107,20 @@ struct CDatabase
} }
}; };
struct CDatabaseEx: public CDatabase struct CDatabaseEx: public CDatabase
{ {
CMyComPtr<IInStream> Stream; CMyComPtr<IInStream> Stream;
}; };
struct CMvItem struct CMvItem
{ {
unsigned VolumeIndex; unsigned VolumeIndex;
unsigned ItemIndex; unsigned ItemIndex;
}; };
class CMvDatabaseEx class CMvDatabaseEx
{ {
bool AreItemsEqual(unsigned i1, unsigned i2); bool AreItemsEqual(unsigned i1, unsigned i2);

View File

@@ -571,23 +571,30 @@ HRESULT CDatabase::Open(IInStream *inStream)
RINOK(AddNode(-1, root.SonDid)); RINOK(AddNode(-1, root.SonDid));
unsigned numCabs = 0; unsigned numCabs = 0;
FOR_VECTOR (i, Refs) FOR_VECTOR (i, Refs)
{ {
const CItem &item = Items[Refs[i].Did]; const CItem &item = Items[Refs[i].Did];
if (item.IsDir() || numCabs > 1) if (item.IsDir() || numCabs > 1)
continue; continue;
bool isMsiName; bool isMsiName;
UString msiName = ConvertName(item.Name, isMsiName); const UString msiName = ConvertName(item.Name, isMsiName);
if (isMsiName) if (isMsiName && !msiName.IsEmpty())
{ {
// bool isThereExt = (msiName.Find(L'.') >= 0);
bool isMsiSpec = (msiName[0] == k_Msi_SpecChar);
if (msiName.Len() >= 4 && StringsAreEqualNoCase_Ascii(msiName.RightPtr(4), ".cab") if (msiName.Len() >= 4 && StringsAreEqualNoCase_Ascii(msiName.RightPtr(4), ".cab")
|| msiName.Len() >= 3 && msiName[0] != k_Msi_SpecChar && StringsAreEqualNoCase_Ascii(msiName.RightPtr(3), "exe")) || !isMsiSpec && msiName.Len() >= 3 && StringsAreEqualNoCase_Ascii(msiName.RightPtr(3), "exe")
// || !isMsiSpec && !isThereExt
)
{ {
numCabs++; numCabs++;
MainSubfile = i; MainSubfile = i;
} }
} }
} }
if (numCabs > 1) if (numCabs > 1)
MainSubfile = -1; MainSubfile = -1;

View File

@@ -26,6 +26,7 @@ HINSTANCE g_hInstance;
#define NT_CHECK_FAIL_ACTION return FALSE; #define NT_CHECK_FAIL_ACTION return FALSE;
#ifdef _WIN32
extern "C" extern "C"
BOOL WINAPI DllMain( BOOL WINAPI DllMain(
#ifdef UNDER_CE #ifdef UNDER_CE
@@ -49,6 +50,7 @@ BOOL WINAPI DllMain(
*/ */
return TRUE; return TRUE;
} }
#endif
DEFINE_GUID(CLSID_CArchiveHandler, DEFINE_GUID(CLSID_CArchiveHandler,
k_7zip_GUID_Data1, k_7zip_GUID_Data1,

View File

@@ -34,48 +34,35 @@
static const Byte k_Base64Table[256] = static const Byte k_Base64Table[256] =
{ {
64,77,77,77,77,77,77,77,77,77,77,77,77,77,77,77,77,77,77,77,77,77,77,77,77,77,77,77,77,77,77,77, 66,77,77,77,77,77,77,77,77,65,65,77,77,65,77,77,
77,77,77,77,77,77,77,77,77,77,77,62,77,64,77,63,52,53,54,55,56,57,58,59,60,61,77,77,77,77,77,77, 77,77,77,77,77,77,77,77,77,77,77,77,77,77,77,77,
77, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,77,77,77,77,77, 65,77,77,77,77,77,77,77,77,77,77,62,77,77,77,63,
77,26,27,28,29,30,31,32,33,34,35,36,37,38,39,40,41,42,43,44,45,46,47,48,49,50,51,77,77,77,77,77, 52,53,54,55,56,57,58,59,60,61,77,77,77,64,77,77,
77,77,77,77,77,77,77,77,77,77,77,77,77,77,77,77,77,77,77,77,77,77,77,77,77,77,77,77,77,77,77,77, 77, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9,10,11,12,13,14,
77,77,77,77,77,77,77,77,77,77,77,77,77,77,77,77,77,77,77,77,77,77,77,77,77,77,77,77,77,77,77,77, 15,16,17,18,19,20,21,22,23,24,25,77,77,77,77,77,
77,77,77,77,77,77,77,77,77,77,77,77,77,77,77,77,77,77,77,77,77,77,77,77,77,77,77,77,77,77,77,77, 77,26,27,28,29,30,31,32,33,34,35,36,37,38,39,40,
77,77,77,77,77,77,77,77,77,77,77,77,77,77,77,77,77,77,77,77,77,77,77,77,77,77,77,77,77,77,77,77 41,42,43,44,45,46,47,48,49,50,51,77,77,77,77,77,
77,77,77,77,77,77,77,77,77,77,77,77,77,77,77,77,
77,77,77,77,77,77,77,77,77,77,77,77,77,77,77,77,
77,77,77,77,77,77,77,77,77,77,77,77,77,77,77,77,
77,77,77,77,77,77,77,77,77,77,77,77,77,77,77,77,
77,77,77,77,77,77,77,77,77,77,77,77,77,77,77,77,
77,77,77,77,77,77,77,77,77,77,77,77,77,77,77,77,
77,77,77,77,77,77,77,77,77,77,77,77,77,77,77,77,
77,77,77,77,77,77,77,77,77,77,77,77,77,77,77,77
}; };
static Byte *Base64ToBin(Byte *dest, const char *src) static Byte *Base64ToBin(Byte *dest, const char *src)
{ {
UInt32 val = 1; UInt32 val = 1;
UInt32 c = k_Base64Table[(Byte)(*src++)];
for (;;) for (;;)
{ {
/* UInt32 c = k_Base64Table[(Byte)(*src++)];
UInt32 c = (Byte)(*src++);
if (c >= 'A')
{
if (c <= 'Z') c -= 'A';
else if (c >= 'a' && c <= 'z') c -= 'a' - 26;
else continue;
}
else if (c >= '0')
{
if (c <= '9') c += 52 - '0';
else if (c == '=') break;
else continue;
}
else if (c == '+') c = 62;
else if (c == '/') c = 63;
else if (c == 0) break;
else continue;
*/
// UInt32 c = k_Base64Table[(Byte)(*src++)];
if (c < 64) if (c < 64)
{ {
val = (val << 6) | c; val = (val << 6) | c;
c = k_Base64Table[(Byte)(*src++)];
if ((val & ((UInt32)1 << 24)) == 0) if ((val & ((UInt32)1 << 24)) == 0)
continue; continue;
dest[0] = (Byte)(val >> 16); dest[0] = (Byte)(val >> 16);
@@ -85,19 +72,41 @@ static Byte *Base64ToBin(Byte *dest, const char *src)
val = 1; val = 1;
continue; continue;
} }
if (c == 64)
if (c == 65) // space
continue;
if (c == 64) // '='
break; break;
c = k_Base64Table[(Byte)(*src++)];
if (c == 66 && val == 1) // end of string
return dest;
return NULL;
} }
if (val >= ((UInt32)1 << 12)) if (val < (1 << 12))
return NULL;
if (val & (1 << 18))
{ {
if (val >= ((UInt32)1 << 18)) *dest++ = (Byte)(val >> 10);
*dest++ = (Byte)(val >> 16); *dest++ = (Byte)(val >> 2);
*dest++ = (Byte)(val); }
else if (k_Base64Table[(Byte)(*src++)] != 64) // '='
return NULL;
else
*dest++ = (Byte)(val >> 4);
for (;;)
{
Byte c = k_Base64Table[(Byte)(*src++)];
if (c == 65) // space
continue;
if (c == 66) // end of string
return dest;
return NULL;
} }
return dest;
} }
@@ -720,7 +729,13 @@ HRESULT CHandler::Open2(IInStream *stream)
return S_FALSE; return S_FALSE;
destLen = dataString->Len() / 4 * 3 + 4; destLen = dataString->Len() / 4 * 3 + 4;
rawBuf.Alloc(destLen); rawBuf.Alloc(destLen);
destLen = (unsigned)(Base64ToBin(rawBuf, *dataString) - rawBuf); {
const Byte *endPtr = Base64ToBin(rawBuf, *dataString);
if (!endPtr)
return S_FALSE;
destLen = (unsigned)(endPtr - rawBuf);
}
#ifdef DMG_SHOW_RAW #ifdef DMG_SHOW_RAW
CExtraFile &extra = _extras.AddNew(); CExtraFile &extra = _extras.AddNew();
{ {

View File

@@ -1118,7 +1118,7 @@ HRESULT CHandler::SeekAndRead(IInStream *inStream, UInt64 block, Byte *data, siz
{ {
if (block == 0 || block >= _h.NumBlocks) if (block == 0 || block >= _h.NumBlocks)
return S_FALSE; return S_FALSE;
if (((size + (1 << _h.BlockBits) + 1) >> _h.BlockBits) > _h.NumBlocks - block) if (((size + ((size_t)1 << _h.BlockBits) - 1) >> _h.BlockBits) > _h.NumBlocks - block)
return S_FALSE; return S_FALSE;
RINOK(inStream->Seek((UInt64)block << _h.BlockBits, STREAM_SEEK_SET, NULL)); RINOK(inStream->Seek((UInt64)block << _h.BlockBits, STREAM_SEEK_SET, NULL));
_totalRead += size; _totalRead += size;
@@ -1167,6 +1167,9 @@ HRESULT CHandler::Open2(IInStream *inStream)
RINOK(_openCallback->SetTotal(NULL, &_phySize)); RINOK(_openCallback->SetTotal(NULL, &_phySize));
} }
UInt64 fileSize = 0;
RINOK(inStream->Seek(0, STREAM_SEEK_END, &fileSize));
CRecordVector<CGroupDescriptor> groups; CRecordVector<CGroupDescriptor> groups;
{ {
@@ -1213,6 +1216,21 @@ HRESULT CHandler::Open2(IInStream *inStream)
if (_h.NumInodes < _h.NumFreeInodes) if (_h.NumInodes < _h.NumFreeInodes)
return S_FALSE; return S_FALSE;
UInt32 numNodes = _h.InodesPerGroup;
if (numNodes > _h.NumInodes)
numNodes = _h.NumInodes;
size_t nodesDataSize = (size_t)numNodes * _h.InodeSize;
if (nodesDataSize / _h.InodeSize != numNodes)
return S_FALSE;
// that code to reduce false detecting cases
if (nodesDataSize > fileSize)
{
if (numNodes > (1 << 24))
return S_FALSE;
}
UInt32 numReserveInodes = _h.NumInodes - _h.NumFreeInodes + 1; UInt32 numReserveInodes = _h.NumInodes - _h.NumFreeInodes + 1;
// numReserveInodes = _h.NumInodes + 1; // numReserveInodes = _h.NumInodes + 1;
@@ -1222,13 +1240,6 @@ HRESULT CHandler::Open2(IInStream *inStream)
_refs.Reserve(numReserveInodes); _refs.Reserve(numReserveInodes);
} }
UInt32 numNodes = _h.InodesPerGroup;
if (numNodes > _h.NumInodes)
numNodes = _h.NumInodes;
size_t nodesDataSize = numNodes * _h.InodeSize;
if (nodesDataSize / _h.InodeSize != numNodes)
return S_FALSE;
CByteBuffer nodesData; CByteBuffer nodesData;
nodesData.Alloc(nodesDataSize); nodesData.Alloc(nodesDataSize);

View File

@@ -160,10 +160,13 @@ bool CHeader::Parse(const Byte *p)
if (NumFats < 1 || NumFats > 4) if (NumFats < 1 || NumFats > 4)
return false; return false;
// we also support images that contain 0 in offset field.
bool isOkOffset = (codeOffset == 0 || (p[0] == 0xEB && p[1] == 0));
UInt16 numRootDirEntries = Get16(p + 17); UInt16 numRootDirEntries = Get16(p + 17);
if (numRootDirEntries == 0) if (numRootDirEntries == 0)
{ {
if (codeOffset < 90) if (codeOffset < 90 && !isOkOffset)
return false; return false;
NumFatBits = 32; NumFatBits = 32;
NumRootDirSectors = 0; NumRootDirSectors = 0;
@@ -171,7 +174,7 @@ bool CHeader::Parse(const Byte *p)
else else
{ {
// Some FAT12s don't contain VolFields // Some FAT12s don't contain VolFields
if (codeOffset < 62 - 24) if (codeOffset < 62 - 24 && !isOkOffset)
return false; return false;
NumFatBits = 0; NumFatBits = 0;
UInt32 mask = (1 << (SectorSizeLog - 5)) - 1; UInt32 mask = (1 << (SectorSizeLog - 5)) - 1;

View File

@@ -87,6 +87,9 @@ struct CPartType
static const CPartType kPartTypes[] = static const CPartType kPartTypes[] =
{ {
// { 0x0, 0, "Unused" }, // { 0x0, 0, "Unused" },
{ 0x21686148, 0, "BIOS Boot" },
{ 0xC12A7328, 0, "EFI System" }, { 0xC12A7328, 0, "EFI System" },
{ 0x024DEE41, 0, "MBR" }, { 0x024DEE41, 0, "MBR" },
@@ -98,10 +101,13 @@ static const CPartType kPartTypes[] =
// { 0x37AFFC90, 0, "IBM GPFS" }, // { 0x37AFFC90, 0, "IBM GPFS" },
// { 0xE75CAF8F, 0, "Windows Storage Spaces" }, // { 0xE75CAF8F, 0, "Windows Storage Spaces" },
{ 0x83BD6B9D, 0, "FreeBSD Boot" }, { 0x0FC63DAF, 0, "Linux Data" },
{ 0x0657FD6D, 0, "Linux Swap" },
{ 0x83BD6B9D, 0, "FreeBSD Boot" },
{ 0x516E7CB4, 0, "FreeBSD Data" }, { 0x516E7CB4, 0, "FreeBSD Data" },
{ 0x516E7CB5, 0, "FreeBSD Swap" }, { 0x516E7CB5, 0, "FreeBSD Swap" },
{ 0x516E7CB6, "ufs", "FreeBSD UFS" }, { 0x516E7CB6, "ufs", "FreeBSD UFS" },
{ 0x516E7CB8, 0, "FreeBSD Vinum" }, { 0x516E7CB8, 0, "FreeBSD Vinum" },
{ 0x516E7CB8, "zfs", "FreeBSD ZFS" }, { 0x516E7CB8, "zfs", "FreeBSD ZFS" },
@@ -335,6 +341,12 @@ STDMETHODIMP CHandler::GetProperty(UInt32 index, PROPID propID, PROPVARIANT *val
break; break;
s += c; s += c;
} }
if (s.IsEmpty())
{
char temp[16];
ConvertUInt32ToString(index, temp);
s.AddAscii(temp);
}
{ {
int typeIndex = FindPartType(item.Type); int typeIndex = FindPartType(item.Type);
s += L'.'; s += L'.';

View File

@@ -987,7 +987,9 @@ HRESULT CDatabase::LoadCatalog(const CFork &fork, const CObjectVector<CIdExtents
item.GroupID = Get32(r + 0x24); item.GroupID = Get32(r + 0x24);
item.AdminFlags = r[0x28]; item.AdminFlags = r[0x28];
item.OwnerFlags = r[0x29]; item.OwnerFlags = r[0x29];
*/
item.FileMode = Get16(r + 0x2A); item.FileMode = Get16(r + 0x2A);
/*
item.special.iNodeNum = Get16(r + 0x2C); // or .linkCount item.special.iNodeNum = Get16(r + 0x2C); // or .linkCount
item.FileType = Get32(r + 0x30); item.FileType = Get32(r + 0x30);
item.FileCreator = Get32(r + 0x34); item.FileCreator = Get32(r + 0x34);
@@ -1572,6 +1574,9 @@ HRESULT CHandler::ExtractZlibFile(
UInt32 size = GetUi32(tableBuf + i * 8 + 4); UInt32 size = GetUi32(tableBuf + i * 8 + 4);
if (size > buf.Size() || size > kCompressionBlockSize + 1)
return S_FALSE;
RINOK(ReadStream_FALSE(inStream, buf, size)); RINOK(ReadStream_FALSE(inStream, buf, size));
if ((buf[0] & 0xF) == 0xF) if ((buf[0] & 0xF) == 0xF)

View File

@@ -170,7 +170,7 @@ struct CBootInitialEntry
// Partition Table found in the boot image. // Partition Table found in the boot image.
UInt16 SectorCount; // This is the number of virtual/emulated sectors the system UInt16 SectorCount; // This is the number of virtual/emulated sectors the system
// will store at Load Segment during the initial boot procedure. // will store at Load Segment during the initial boot procedure.
UInt32 LoadRBA; // This is the start address of the virtual disk. CD<EFBFBD>s use UInt32 LoadRBA; // This is the start address of the virtual disk. CDs use
// Relative/Logical block addressing. // Relative/Logical block addressing.
Byte VendorSpec[20]; Byte VendorSpec[20];

View File

@@ -79,7 +79,7 @@ struct CDirRecord
while (rem >= 5) while (rem >= 5)
{ {
unsigned len = p[2]; unsigned len = p[2];
if (len > rem) if (len < 3 || len > rem)
return 0; return 0;
if (p[0] == 'N' && p[1] == 'M' && p[3] == 1) if (p[0] == 'N' && p[1] == 'M' && p[3] == 1)
{ {

View File

@@ -110,7 +110,7 @@ HRESULT CDecoder::Create(bool filteredMode, ISequentialInStream *inStream)
{ {
_filterCoder = new CFilterCoder(false); _filterCoder = new CFilterCoder(false);
CMyComPtr<ICompressCoder> coder = _filterCoder; CMyComPtr<ICompressCoder> coder = _filterCoder;
_filterCoder->Filter = new CBcjCoder(false); _filterCoder->Filter = new NCompress::NBcj::CCoder(false);
_bcjStream = _filterCoder; _bcjStream = _filterCoder;
} }
} }

View File

@@ -59,7 +59,7 @@ HRESULT CDecoder::Init(ISequentialInStream *inStream, bool &useFilter)
{ {
_filter = new CFilterCoder(false); _filter = new CFilterCoder(false);
_filterInStream = _filter; _filterInStream = _filter;
_filter->Filter = new CBcjCoder(false); _filter->Filter = new NCompress::NBcj::CCoder(false);
} }
RINOK(_filter->SetInStream(_codecInStream)); RINOK(_filter->SetInStream(_codecInStream));
_decoderInStream = _filterInStream; _decoderInStream = _filterInStream;

View File

@@ -88,7 +88,7 @@ enum
EW_SENDMESSAGE, // SendMessage EW_SENDMESSAGE, // SendMessage
EW_ISWINDOW, // IsWindow EW_ISWINDOW, // IsWindow
EW_GETDLGITEM, // GetDlgItem EW_GETDLGITEM, // GetDlgItem
EW_SETCTLCOLORS, // SerCtlColors EW_SETCTLCOLORS, // SetCtlColors
EW_SETBRANDINGIMAGE, // SetBrandingImage EW_SETBRANDINGIMAGE, // SetBrandingImage
EW_CREATEFONT, // CreateFont EW_CREATEFONT, // CreateFont
EW_SHOWWINDOW, // ShowWindow, EnableWindow, HideWindow EW_SHOWWINDOW, // ShowWindow, EnableWindow, HideWindow
@@ -1155,9 +1155,13 @@ bool CInArchive::IsGoodString(UInt32 param) const
if (param == 0) if (param == 0)
return true; return true;
const Byte *p = _data + _stringsPos; const Byte *p = _data + _stringsPos;
unsigned c;
if (IsUnicode) if (IsUnicode)
return (Get16(p + param * 2 - 2)) == 0; c = Get16(p + param * 2 - 2);
return p[param - 1] == 0; else
c = p[param - 1];
// some files have '\\' character before string?
return (c == 0 || c == '\\');
} }
bool CInArchive::AreTwoParamStringsEqual(UInt32 param1, UInt32 param2) const bool CInArchive::AreTwoParamStringsEqual(UInt32 param1, UInt32 param2) const
@@ -1509,7 +1513,7 @@ static const UInt32 CMD_REF_Pre = (1 << 2);
static const UInt32 CMD_REF_Show = (1 << 3); static const UInt32 CMD_REF_Show = (1 << 3);
static const UInt32 CMD_REF_Leave = (1 << 4); static const UInt32 CMD_REF_Leave = (1 << 4);
static const UInt32 CMD_REF_OnFunc = (1 << 5); static const UInt32 CMD_REF_OnFunc = (1 << 5);
static const UInt32 CMD_REF_Section = (1 << 6); static const UInt32 CMD_REF_Section = (1 << 6);
static const UInt32 CMD_REF_InitPluginDir = (1 << 7); static const UInt32 CMD_REF_InitPluginDir = (1 << 7);
// static const UInt32 CMD_REF_Creator = (1 << 5); // _Pre is used instead // static const UInt32 CMD_REF_Creator = (1 << 5); // _Pre is used instead
static const unsigned CMD_REF_OnFunc_NumShifts = 28; // it uses for onFunc too static const unsigned CMD_REF_OnFunc_NumShifts = 28; // it uses for onFunc too
@@ -3357,7 +3361,7 @@ HRESULT CInArchive::ReadEntries(const CBlockHeader &bh)
#ifdef NSIS_SCRIPT #ifdef NSIS_SCRIPT
s += isSetOutPath ? "SetOutPath" : "CreateDirectory"; s += isSetOutPath ? "SetOutPath" : "CreateDirectory";
AddParam(params[0]); AddParam(params[0]);
#endif #endif
break; break;
@@ -3571,15 +3575,16 @@ HRESULT CInArchive::ReadEntries(const CBlockHeader &bh)
AddParam(params[0]); AddParam(params[0]);
SmallSpaceComment();
/* /*
for (int i = 1; i < 3; i++) for (int i = 1; i < 3; i++)
AddParam_UInt(params[i]); AddParam_UInt(params[i]);
*/ */
if (params[3] != 0) if (params[3] != 0)
{
SmallSpaceComment();
AddParam(params[3]); AddParam(params[3]);
}
#endif #endif

View File

@@ -421,7 +421,11 @@ public:
const char *kRemoveStr = "$INSTDIR\\"; const char *kRemoveStr = "$INSTDIR\\";
if (s.IsPrefixedBy_Ascii_NoCase(kRemoveStr)) if (s.IsPrefixedBy_Ascii_NoCase(kRemoveStr))
{
s.Delete(0, MyStringLen(kRemoveStr)); s.Delete(0, MyStringLen(kRemoveStr));
if (s[0] == L'\\')
s.DeleteFrontal(1);
}
if (item.IsUninstaller && ExeStub.Size() == 0) if (item.IsUninstaller && ExeStub.Size() == 0)
s += L".nsis"; s += L".nsis";
return s; return s;

View File

@@ -1148,8 +1148,16 @@ bool CMftRec::Parse(Byte *p, unsigned sectorSizeLog, UInt32 numSectors, UInt32 r
return false; return false;
if (usaOffset >= 0x30) // NTFS 3.1+ if (usaOffset >= 0x30) // NTFS 3.1+
if (Get32(p + 0x2C) != recNumber) {
return false; UInt32 iii = Get32(p + 0x2C);
if (iii != recNumber)
{
// ntfs-3g probably writes 0 (that probably is incorrect value) to this field for unused records.
// so we support that "bad" case.
if (iii != 0)
return false;
}
}
UInt16 usn = Get16(p + usaOffset); UInt16 usn = Get16(p + usaOffset);
// PRF(printf("\nusn = %d", usn)); // PRF(printf("\nusn = %d", usn));

View File

@@ -347,18 +347,24 @@ struct CSection
CSection(): IsRealSect(false), IsDebug(false), IsAdditionalSection(false) {} CSection(): IsRealSect(false), IsDebug(false), IsAdditionalSection(false) {}
const UInt32 GetSizeExtract() const { return PSize; }
const UInt32 GetSizeMin() const { return MyMin(PSize, VSize); }
void UpdateTotalSize(UInt32 &totalSize) const void UpdateTotalSize(UInt32 &totalSize) const
{ {
UInt32 t = Pa + PSize; UInt32 t = Pa + PSize;
if (totalSize < t) if (totalSize < t)
totalSize = t; totalSize = t;
} }
void Parse(const Byte *p); void Parse(const Byte *p);
int Compare(const CSection &s) const int Compare(const CSection &s) const
{ {
RINOZ(MyCompare(Pa, s.Pa)); RINOZ(MyCompare(Pa, s.Pa));
return MyCompare(PSize, s.PSize); UInt32 size1 = GetSizeExtract();
UInt32 size2 = s.GetSizeExtract();
return MyCompare(size1, size2);
} }
}; };
@@ -1039,7 +1045,7 @@ STDMETHODIMP CHandler::GetProperty(UInt32 index, PROPID propID, PROPVARIANT *val
switch (propID) switch (propID)
{ {
case kpidPath: prop = MultiByteToUnicodeString(item.Name); break; case kpidPath: prop = MultiByteToUnicodeString(item.Name); break;
case kpidSize: prop = (UInt64)MyMin(item.PSize, item.VSize); break; case kpidSize: prop = (UInt64)item.PSize; break;
case kpidPackSize: prop = (UInt64)item.PSize; break; case kpidPackSize: prop = (UInt64)item.PSize; break;
case kpidVirtualSize: prop = (UInt64)item.VSize; break; case kpidVirtualSize: prop = (UInt64)item.VSize; break;
case kpidOffset: prop = item.Pa; break; case kpidOffset: prop = item.Pa; break;
@@ -1883,14 +1889,17 @@ static bool ParseVersion(const Byte *p, UInt32 size, CTextFile &f, CObjectVector
} }
f.CloseBlock(2); f.CloseBlock(2);
} }
f.CloseBlock(0); f.CloseBlock(0);
return true; return true;
} }
HRESULT CHandler::OpenResources(unsigned sectionIndex, IInStream *stream, IArchiveOpenCallback *callback) HRESULT CHandler::OpenResources(unsigned sectionIndex, IInStream *stream, IArchiveOpenCallback *callback)
{ {
const CSection &sect = _sections[sectionIndex]; const CSection &sect = _sections[sectionIndex];
size_t fileSize = sect.PSize; // Maybe we need sect.VSize here !!! const size_t fileSize = sect.GetSizeMin();
if (fileSize > kFileSizeMax) if (fileSize > kFileSizeMax)
return S_FALSE; return S_FALSE;
{ {
@@ -1917,6 +1926,7 @@ HRESULT CHandler::OpenResources(unsigned sectionIndex, IInStream *stream, IArchi
_oneLang = true; _oneLang = true;
bool stringsOk = true; bool stringsOk = true;
size_t maxOffset = 0; size_t maxOffset = 0;
FOR_VECTOR (i, specItems) FOR_VECTOR (i, specItems)
{ {
const CTableItem &item1 = specItems[i]; const CTableItem &item1 = specItems[i];
@@ -1998,6 +2008,7 @@ HRESULT CHandler::OpenResources(unsigned sectionIndex, IInStream *stream, IArchi
} }
// PrintError("ver.Parse error"); // PrintError("ver.Parse error");
} }
item.Enabled = true; item.Enabled = true;
_items.Add(item); _items.Add(item);
} }
@@ -2031,7 +2042,10 @@ HRESULT CHandler::OpenResources(unsigned sectionIndex, IInStream *stream, IArchi
{ {
UInt32 mask = (1 << numBits) - 1; UInt32 mask = (1 << numBits) - 1;
size_t end = ((maxOffset + mask) & ~mask); size_t end = ((maxOffset + mask) & ~mask);
// 9.29: we use only PSize. PSize can be larger than VSize
// PSize can be much larger than VSize in some exe installers.
// it contains archive data after PE resources.
// So we need to use PSize here!
if (/* end < sect.VSize && */ end <= sect.PSize) if (/* end < sect.VSize && */ end <= sect.PSize)
{ {
CSection sect2; CSection sect2;
@@ -2051,6 +2065,7 @@ HRESULT CHandler::OpenResources(unsigned sectionIndex, IInStream *stream, IArchi
// 9.29: we use sect.PSize instead of sect.VSize to support some CAB-SFX // 9.29: we use sect.PSize instead of sect.VSize to support some CAB-SFX
// the code for .rsrc_2 is commented. // the code for .rsrc_2 is commented.
sect2.PSize = sect.PSize - (UInt32)maxOffset; sect2.PSize = sect.PSize - (UInt32)maxOffset;
if (sect2.PSize != 0) if (sect2.PSize != 0)
{ {
sect2.VSize = sect2.PSize; sect2.VSize = sect2.PSize;
@@ -2463,7 +2478,7 @@ STDMETHODIMP CHandler::Extract(const UInt32 *indices, UInt32 numItems,
else if (mixItem.ResourceIndex >= 0) else if (mixItem.ResourceIndex >= 0)
size = _items[mixItem.ResourceIndex].GetSize(); size = _items[mixItem.ResourceIndex].GetSize();
else else
size = _sections[mixItem.SectionIndex].PSize; size = _sections[mixItem.SectionIndex].GetSizeExtract();
totalSize += size; totalSize += size;
} }
extractCallback->SetTotal(totalSize); extractCallback->SetTotal(totalSize);
@@ -2539,7 +2554,7 @@ STDMETHODIMP CHandler::Extract(const UInt32 *indices, UInt32 numItems,
} }
else else
{ {
currentItemSize = sect.PSize; currentItemSize = sect.GetSizeExtract();
if (!testMode && !outStream) if (!testMode && !outStream)
continue; continue;

View File

@@ -1,5 +1,5 @@
/* PpmdHandler.c -- PPMd format handler /* PpmdHandler.cpp -- PPMd format handler
2010-03-10 : Igor Pavlov : Public domain 2015-11-30 : Igor Pavlov : Public domain
This code is based on: This code is based on:
PPMd var.H (2001) / var.I (2002): Dmitry Shkarin : Public domain PPMd var.H (2001) / var.I (2002): Dmitry Shkarin : Public domain
Carryless rangecoder (1999): Dmitry Subbotin : Public domain */ Carryless rangecoder (1999): Dmitry Subbotin : Public domain */
@@ -349,6 +349,7 @@ struct CPpmdCpp
} }
}; };
STDMETHODIMP CHandler::Extract(const UInt32 *indices, UInt32 numItems, STDMETHODIMP CHandler::Extract(const UInt32 *indices, UInt32 numItems,
Int32 testMode, IArchiveExtractCallback *extractCallback) Int32 testMode, IArchiveExtractCallback *extractCallback)
{ {
@@ -386,13 +387,17 @@ STDMETHODIMP CHandler::Extract(const UInt32 *indices, UInt32 numItems,
CPpmdCpp ppmd(_item.Ver); CPpmdCpp ppmd(_item.Ver);
if (!ppmd.Alloc(_item.MemInMB)) if (!ppmd.Alloc(_item.MemInMB))
return E_OUTOFMEMORY; return E_OUTOFMEMORY;
Int32 opRes = NExtract::NOperationResult::kUnsupportedMethod; Int32 opRes = NExtract::NOperationResult::kUnsupportedMethod;
if (_item.IsSupported()) if (_item.IsSupported())
{ {
opRes = NExtract::NOperationResult::kDataError; opRes = NExtract::NOperationResult::kDataError;
ppmd.Init(_item.Order, _item.Restor); ppmd.Init(_item.Order, _item.Restor);
inBuf.Init(); inBuf.Init();
UInt64 outSize = 0; UInt64 outSize = 0;
if (ppmd.InitRc(&inBuf) && !inBuf.Extra && inBuf.Res == S_OK) if (ppmd.InitRc(&inBuf) && !inBuf.Extra && inBuf.Res == S_OK)
for (;;) for (;;)
{ {
@@ -431,6 +436,13 @@ STDMETHODIMP CHandler::Extract(const UInt32 *indices, UInt32 numItems,
{ {
RINOK(WriteStream(realOutStream, outBuf.Buf, i)); RINOK(WriteStream(realOutStream, outBuf.Buf, i));
} }
if (inBuf.Extra)
{
opRes = NExtract::NOperationResult::kUnexpectedEnd;
break;
}
if (sym < 0) if (sym < 0)
{ {
if (sym == -1 && ppmd.IsFinishedOK()) if (sym == -1 && ppmd.IsFinishedOK())
@@ -438,12 +450,15 @@ STDMETHODIMP CHandler::Extract(const UInt32 *indices, UInt32 numItems,
break; break;
} }
} }
RINOK(inBuf.Res); RINOK(inBuf.Res);
} }
realOutStream.Release(); realOutStream.Release();
return extractCallback->SetOperationResult(opRes); return extractCallback->SetOperationResult(opRes);
} }
static const Byte k_Signature[] = { 0x8F, 0xAF, 0xAC, 0x84 }; static const Byte k_Signature[] = { 0x8F, 0xAF, 0xAC, 0x84 };
REGISTER_ARC_I( REGISTER_ARC_I(

View File

@@ -1825,6 +1825,8 @@ HRESULT CHandler::Open2(IInStream *stream,
int prevSplitFile = -1; int prevSplitFile = -1;
int prevMainFile = -1; int prevMainFile = -1;
bool nextVol_is_Required = false;
CInArchive arch; CInArchive arch;
for (;;) for (;;)
@@ -1861,7 +1863,8 @@ HRESULT CHandler::Open2(IInStream *stream,
if (!inStream || result != S_OK) if (!inStream || result != S_OK)
{ {
_missingVolName = volName; if (nextVol_is_Required)
_missingVolName = volName;
break; break;
} }
} }
@@ -2111,11 +2114,18 @@ HRESULT CHandler::Open2(IInStream *stream,
} }
curBytes += endPos; curBytes += endPos;
nextVol_is_Required = false;
if (!arcInfo.IsVolume()) if (!arcInfo.IsVolume())
break; break;
if (arcInfo.EndOfArchive_was_Read
&& !arcInfo.AreMoreVolumes()) if (arcInfo.EndOfArchive_was_Read)
break; {
if (!arcInfo.AreMoreVolumes())
break;
nextVol_is_Required = true;
}
} }
FillLinks(); FillLinks();
@@ -2323,6 +2333,7 @@ STDMETHODIMP CHandler::Extract(const UInt32 *indices, UInt32 numItems,
{ {
UInt64 total = 0; UInt64 total = 0;
bool isThereUndefinedSize = false;
bool thereAreLinks = false; bool thereAreLinks = false;
{ {
@@ -2332,9 +2343,14 @@ STDMETHODIMP CHandler::Extract(const UInt32 *indices, UInt32 numItems,
unsigned index = allFilesMode ? t : indices[t]; unsigned index = allFilesMode ? t : indices[t];
const CRefItem &ref = _refs[index]; const CRefItem &ref = _refs[index];
const CItem &item = _items[ref.Item]; const CItem &item = _items[ref.Item];
const CItem &lastItem = _items[ref.Last];
extractStatuses[index] |= kStatus_Extract; extractStatuses[index] |= kStatus_Extract;
total += item.Size;
if (!lastItem.Is_UnknownSize())
total += lastItem.Size;
else
isThereUndefinedSize = true;
if (ref.Link >= 0) if (ref.Link >= 0)
{ {
@@ -2342,11 +2358,18 @@ STDMETHODIMP CHandler::Extract(const UInt32 *indices, UInt32 numItems,
{ {
if ((unsigned)ref.Link < index) if ((unsigned)ref.Link < index)
{ {
const CItem &linkItem = _items[_refs[(unsigned)ref.Link].Item]; const CRefItem &linkRef = _refs[(unsigned)ref.Link];
const CItem &linkItem = _items[linkRef.Item];
if (linkItem.IsSolid() && linkItem.Size <= k_CopyLinkFile_MaxSize) if (linkItem.IsSolid() && linkItem.Size <= k_CopyLinkFile_MaxSize)
{ {
if (extractStatuses[(unsigned)ref.Link] == 0) if (extractStatuses[(unsigned)ref.Link] == 0)
total += linkItem.Size; {
const CItem &lastLinkItem = _items[linkRef.Last];
if (!lastLinkItem.Is_UnknownSize())
total += lastLinkItem.Size;
else
isThereUndefinedSize = true;
}
extractStatuses[(unsigned)ref.Link] |= kStatus_Link; extractStatuses[(unsigned)ref.Link] |= kStatus_Link;
thereAreLinks = true; thereAreLinks = true;
} }
@@ -2365,11 +2388,18 @@ STDMETHODIMP CHandler::Extract(const UInt32 *indices, UInt32 numItems,
while (j > solidLimit) while (j > solidLimit)
{ {
j--; j--;
const CItem &item2 = _items[_refs[j].Item]; const CRefItem &ref2 = _refs[j];
const CItem &item2 = _items[ref2.Item];
if (!item2.IsService()) if (!item2.IsService())
{ {
if (extractStatuses[j] == 0) if (extractStatuses[j] == 0)
total += item2.Size; {
const CItem &lastItem2 = _items[ref2.Last];
if (!lastItem2.Is_UnknownSize())
total += lastItem2.Size;
else
isThereUndefinedSize = true;
}
extractStatuses[j] |= kStatus_Skip; extractStatuses[j] |= kStatus_Skip;
if (!item2.IsSolid()) if (!item2.IsSolid())
break; break;
@@ -2405,13 +2435,20 @@ STDMETHODIMP CHandler::Extract(const UInt32 *indices, UInt32 numItems,
while (j > solidLimit) while (j > solidLimit)
{ {
j--; j--;
const CItem &item2 = _items[_refs[j].Item]; const CRefItem &ref2 = _refs[j];
const CItem &item2 = _items[ref2.Item];
if (!item2.IsService()) if (!item2.IsService())
{ {
if (extractStatuses[j] != 0) if (extractStatuses[j] != 0)
break; break;
extractStatuses[j] = kStatus_Skip; extractStatuses[j] = kStatus_Skip;
total += item2.Size; {
const CItem &lastItem2 = _items[ref2.Last];
if (!lastItem2.Is_UnknownSize())
total += lastItem2.Size;
else
isThereUndefinedSize = true;
}
if (!item2.IsSolid()) if (!item2.IsSolid())
break; break;
} }
@@ -2439,7 +2476,10 @@ STDMETHODIMP CHandler::Extract(const UInt32 *indices, UInt32 numItems,
} }
} }
RINOK(extractCallback->SetTotal(total)); if (total != 0 || !isThereUndefinedSize)
{
RINOK(extractCallback->SetTotal(total));
}
} }
@@ -2492,8 +2532,12 @@ STDMETHODIMP CHandler::Extract(const UInt32 *indices, UInt32 numItems,
const CRefItem *ref = &_refs[index]; const CRefItem *ref = &_refs[index];
const CItem *item = &_items[ref->Item]; const CItem *item = &_items[ref->Item];
const CItem &lastItem = _items[ref->Last];
curUnpackSize = 0;
if (!lastItem.Is_UnknownSize())
curUnpackSize = lastItem.Size;
curUnpackSize = item->Size;
curPackSize = GetPackSize(index); curPackSize = GetPackSize(index);
RINOK(extractCallback->GetStream(index, &realOutStream, askMode)); RINOK(extractCallback->GetStream(index, &realOutStream, askMode));
@@ -2522,11 +2566,15 @@ STDMETHODIMP CHandler::Extract(const UInt32 *indices, UInt32 numItems,
{ {
const CRefItem &ref2 = _refs[index2]; const CRefItem &ref2 = _refs[index2];
const CItem &item2 = _items[ref2.Item]; const CItem &item2 = _items[ref2.Item];
const CItem &lastItem2 = _items[ref2.Last];
if (!item2.IsSolid()) if (!item2.IsSolid())
{ {
item = &item2; item = &item2;
ref = &ref2; ref = &ref2;
curUnpackSize = item->Size; if (!lastItem2.Is_UnknownSize())
curUnpackSize = lastItem2.Size;
else
curUnpackSize = 0;
curPackSize = GetPackSize(index2); curPackSize = GetPackSize(index2);
} }
else if ((unsigned)index2 < index) else if ((unsigned)index2 < index)

View File

@@ -640,6 +640,7 @@ HRESULT CInArchive::GetNextItem(CItem &item, ICryptoGetTextPassword *getTextPass
{ {
ArcInfo.EndFlags = m_BlockHeader.Flags; ArcInfo.EndFlags = m_BlockHeader.Flags;
UInt32 offset = 7; UInt32 offset = 7;
if (m_BlockHeader.Flags & NHeader::NArchive::kEndOfArc_Flags_DataCRC) if (m_BlockHeader.Flags & NHeader::NArchive::kEndOfArc_Flags_DataCRC)
{ {
if (processed < offset + 4) if (processed < offset + 4)
@@ -648,6 +649,7 @@ HRESULT CInArchive::GetNextItem(CItem &item, ICryptoGetTextPassword *getTextPass
ArcInfo.DataCRC = Get32(m_FileHeaderData + offset); ArcInfo.DataCRC = Get32(m_FileHeaderData + offset);
offset += 4; offset += 4;
} }
if (m_BlockHeader.Flags & NHeader::NArchive::kEndOfArc_Flags_VolNumber) if (m_BlockHeader.Flags & NHeader::NArchive::kEndOfArc_Flags_VolNumber)
{ {
if (processed < offset + 2) if (processed < offset + 2)
@@ -657,6 +659,7 @@ HRESULT CInArchive::GetNextItem(CItem &item, ICryptoGetTextPassword *getTextPass
ArcInfo.EndOfArchive_was_Read = true; ArcInfo.EndOfArchive_was_Read = true;
} }
m_Position += processed; m_Position += processed;
FinishCryptoBlock(); FinishCryptoBlock();
ArcInfo.EndPos = m_Position; ArcInfo.EndPos = m_Position;
@@ -699,11 +702,13 @@ HRESULT CInArchive::GetNextItem(CItem &item, ICryptoGetTextPassword *getTextPass
continue; continue;
*/ */
} }
if (m_CryptoMode && m_BlockHeader.HeadSize > (1 << 10)) if (m_CryptoMode && m_BlockHeader.HeadSize > (1 << 10))
{ {
error = k_ErrorType_DecryptionError; error = k_ErrorType_DecryptionError;
return S_OK; return S_OK;
} }
if ((m_BlockHeader.Flags & NHeader::NBlock::kLongBlock) != 0) if ((m_BlockHeader.Flags & NHeader::NBlock::kLongBlock) != 0)
{ {
if (m_FileHeaderData.Size() < 7 + 4) if (m_FileHeaderData.Size() < 7 + 4)
@@ -948,6 +953,8 @@ STDMETHODIMP CHandler::GetProperty(UInt32 index, PROPID propID, PROPVARIANT *val
NCOM::CPropVariant prop; NCOM::CPropVariant prop;
const CRefItem &refItem = _refItems[index]; const CRefItem &refItem = _refItems[index];
const CItem &item = _items[refItem.ItemIndex]; const CItem &item = _items[refItem.ItemIndex];
const CItem &lastItem = _items[refItem.ItemIndex + refItem.NumItems - 1];
/* /*
const CItem *mainItem = &item; const CItem *mainItem = &item;
if (item.BaseFileIndex >= 0) if (item.BaseFileIndex >= 0)
@@ -967,7 +974,7 @@ STDMETHODIMP CHandler::GetProperty(UInt32 index, PROPID propID, PROPVARIANT *val
break; break;
} }
case kpidIsDir: prop = item.IsDir(); break; case kpidIsDir: prop = item.IsDir(); break;
case kpidSize: prop = item.Size; break; case kpidSize: if (lastItem.Is_Size_Defined()) prop = lastItem.Size; break;
case kpidPackSize: prop = GetPackSize(index); break; case kpidPackSize: prop = GetPackSize(index); break;
case kpidMTime: RarTimeToProp(item.MTime, prop); break; case kpidMTime: RarTimeToProp(item.MTime, prop); break;
case kpidCTime: if (item.CTimeDefined) RarTimeToProp(item.CTime, prop); break; case kpidCTime: if (item.CTimeDefined) RarTimeToProp(item.CTime, prop); break;
@@ -980,7 +987,6 @@ STDMETHODIMP CHandler::GetProperty(UInt32 index, PROPID propID, PROPVARIANT *val
case kpidSplitAfter: prop = _items[refItem.ItemIndex + refItem.NumItems - 1].IsSplitAfter(); break; case kpidSplitAfter: prop = _items[refItem.ItemIndex + refItem.NumItems - 1].IsSplitAfter(); break;
case kpidCRC: case kpidCRC:
{ {
const CItem &lastItem = _items[refItem.ItemIndex + refItem.NumItems - 1];
prop = ((lastItem.IsSplitAfter()) ? item.FileCRC : lastItem.FileCRC); prop = ((lastItem.IsSplitAfter()) ? item.FileCRC : lastItem.FileCRC);
break; break;
} }
@@ -1032,7 +1038,10 @@ HRESULT CHandler::Open2(IInStream *stream,
openCallback->QueryInterface(IID_ICryptoGetTextPassword, (void **)&getTextPassword); openCallback->QueryInterface(IID_ICryptoGetTextPassword, (void **)&getTextPassword);
} }
bool nextVol_is_Required = false;
CInArchive archive; CInArchive archive;
for (;;) for (;;)
{ {
CMyComPtr<IInStream> inStream; CMyComPtr<IInStream> inStream;
@@ -1072,7 +1081,8 @@ HRESULT CHandler::Open2(IInStream *stream,
if (!inStream || result != S_OK) if (!inStream || result != S_OK)
{ {
_missingVolName = volName; if (nextVol_is_Required)
_missingVolName = volName;
break; break;
} }
} }
@@ -1191,6 +1201,18 @@ HRESULT CHandler::Open2(IInStream *stream,
arc.PhySize = archive.ArcInfo.GetPhySize(); arc.PhySize = archive.ArcInfo.GetPhySize();
arc.Stream = inStream; arc.Stream = inStream;
} }
nextVol_is_Required = false;
if (!archive.ArcInfo.IsVolume())
break;
if (archive.ArcInfo.EndOfArchive_was_Read)
{
if (!archive.ArcInfo.AreMoreVolumes())
break;
nextVol_is_Required = true;
}
} }
} }
@@ -1357,34 +1379,52 @@ STDMETHODIMP CHandler::Extract(const UInt32 *indices, UInt32 numItems,
CRecordVector<unsigned> importantIndexes; CRecordVector<unsigned> importantIndexes;
CRecordVector<bool> extractStatuses; CRecordVector<bool> extractStatuses;
bool isThereUndefinedSize = false;
for (UInt32 t = 0; t < numItems; t++) for (UInt32 t = 0; t < numItems; t++)
{ {
unsigned index = allFilesMode ? t : indices[t]; unsigned index = allFilesMode ? t : indices[t];
const CRefItem &refItem = _refItems[index];
const CItem &item = _items[refItem.ItemIndex]; {
censoredTotalUnPacked += item.Size; const CRefItem &refItem = _refItems[index];
// censoredTotalPacked += item.PackSize; const CItem &item = _items[refItem.ItemIndex + refItem.NumItems - 1];
if (item.Is_Size_Defined())
censoredTotalUnPacked += item.Size;
else
isThereUndefinedSize = true;
// censoredTotalPacked += item.PackSize;
}
unsigned j; unsigned j;
for (j = lastIndex; j <= index; j++) for (j = lastIndex; j <= index; j++)
// if (!_items[_refItems[j].ItemIndex].IsSolid()) // if (!_items[_refItems[j].ItemIndex].IsSolid())
if (!IsSolid(j)) if (!IsSolid(j))
lastIndex = j; lastIndex = j;
for (j = lastIndex; j <= index; j++) for (j = lastIndex; j <= index; j++)
{ {
const CRefItem &refItem = _refItems[j]; const CRefItem &refItem = _refItems[j];
const CItem &item = _items[refItem.ItemIndex]; const CItem &item = _items[refItem.ItemIndex + refItem.NumItems - 1];
// const CItem &item = _items[j]; if (item.Is_Size_Defined())
importantTotalUnPacked += item.Size;
importantTotalUnPacked += item.Size; else
isThereUndefinedSize = true;
// importantTotalPacked += item.PackSize; // importantTotalPacked += item.PackSize;
importantIndexes.Add(j); importantIndexes.Add(j);
extractStatuses.Add(j == index); extractStatuses.Add(j == index);
} }
lastIndex = index + 1; lastIndex = index + 1;
} }
RINOK(extractCallback->SetTotal(importantTotalUnPacked)); if (importantTotalUnPacked != 0 || !isThereUndefinedSize)
{
RINOK(extractCallback->SetTotal(importantTotalUnPacked));
}
UInt64 currentImportantTotalUnPacked = 0; UInt64 currentImportantTotalUnPacked = 0;
UInt64 currentImportantTotalPacked = 0; UInt64 currentImportantTotalPacked = 0;
UInt64 currentUnPackSize, currentPackSize; UInt64 currentUnPackSize, currentPackSize;
@@ -1410,13 +1450,19 @@ STDMETHODIMP CHandler::Extract(const UInt32 *indices, UInt32 numItems,
lps->Init(extractCallback, false); lps->Init(extractCallback, false);
bool solidStart = true; bool solidStart = true;
for (unsigned i = 0; i < importantIndexes.Size(); i++,
for (unsigned i = 0;;
i++,
currentImportantTotalUnPacked += currentUnPackSize, currentImportantTotalUnPacked += currentUnPackSize,
currentImportantTotalPacked += currentPackSize) currentImportantTotalPacked += currentPackSize)
{ {
lps->InSize = currentImportantTotalPacked; lps->InSize = currentImportantTotalPacked;
lps->OutSize = currentImportantTotalUnPacked; lps->OutSize = currentImportantTotalUnPacked;
RINOK(lps->SetCur()); RINOK(lps->SetCur());
if (i >= importantIndexes.Size())
break;
CMyComPtr<ISequentialOutStream> realOutStream; CMyComPtr<ISequentialOutStream> realOutStream;
Int32 askMode; Int32 askMode;
@@ -1431,8 +1477,15 @@ STDMETHODIMP CHandler::Extract(const UInt32 *indices, UInt32 numItems,
const CRefItem &refItem = _refItems[index]; const CRefItem &refItem = _refItems[index];
const CItem &item = _items[refItem.ItemIndex]; const CItem &item = _items[refItem.ItemIndex];
const CItem &lastItem = _items[refItem.ItemIndex + refItem.NumItems - 1];
currentUnPackSize = item.Size;
UInt64 outSize = (UInt64)(Int64)-1;
currentUnPackSize = 0;
if (lastItem.Is_Size_Defined())
{
outSize = lastItem.Size;
currentUnPackSize = outSize;
}
currentPackSize = GetPackSize(index); currentPackSize = GetPackSize(index);
@@ -1657,12 +1710,14 @@ STDMETHODIMP CHandler::Extract(const UInt32 *indices, UInt32 numItems,
continue; continue;
} }
HRESULT result = commonCoder->Code(inStream, outStream, &packSize, &item.Size, progress); HRESULT result = commonCoder->Code(inStream, outStream, &packSize, &outSize, progress);
if (item.IsEncrypted()) if (item.IsEncrypted())
filterStreamSpec->ReleaseInStream(); filterStreamSpec->ReleaseInStream();
const CItem &lastItem = _items[refItem.ItemIndex + refItem.NumItems - 1]; if (outSize == (UInt64)(Int64)-1)
currentUnPackSize = outStreamSpec->GetSize();
int opRes = (volsInStreamSpec->CrcIsOK && outStreamSpec->GetCRC() == lastItem.FileCRC) ? int opRes = (volsInStreamSpec->CrcIsOK && outStreamSpec->GetCRC() == lastItem.FileCRC) ?
NExtract::NOperationResult::kOK: NExtract::NOperationResult::kOK:
NExtract::NOperationResult::kCRCError; NExtract::NOperationResult::kCRCError;

View File

@@ -45,6 +45,7 @@ struct CInArcInfo
bool IsEncryptOld() const { return (!IsThereEncryptVer() || EncryptVersion < 36); } bool IsEncryptOld() const { return (!IsThereEncryptVer() || EncryptVersion < 36); }
bool AreMoreVolumes() const { return (EndFlags & NHeader::NArchive::kEndOfArc_Flags_NextVol) != 0; }
bool Is_VolNumber_Defined() const { return (EndFlags & NHeader::NArchive::kEndOfArc_Flags_VolNumber) != 0; } bool Is_VolNumber_Defined() const { return (EndFlags & NHeader::NArchive::kEndOfArc_Flags_VolNumber) != 0; }
bool Is_DataCRC_Defined() const { return (EndFlags & NHeader::NArchive::kEndOfArc_Flags_DataCRC) != 0; } bool Is_DataCRC_Defined() const { return (EndFlags & NHeader::NArchive::kEndOfArc_Flags_DataCRC) != 0; }
}; };

View File

@@ -42,6 +42,8 @@ struct CItem
Byte Salt[8]; Byte Salt[8];
bool Is_Size_Defined() const { return Size != (UInt64)(Int64)-1; }
bool IsEncrypted() const { return (Flags & NHeader::NFile::kEncrypted) != 0; } bool IsEncrypted() const { return (Flags & NHeader::NFile::kEncrypted) != 0; }
bool IsSolid() const { return (Flags & NHeader::NFile::kSolid) != 0; } bool IsSolid() const { return (Flags & NHeader::NFile::kSolid) != 0; }
bool IsCommented() const { return (Flags & NHeader::NFile::kComment) != 0; } bool IsCommented() const { return (Flags & NHeader::NFile::kComment) != 0; }

View File

@@ -187,11 +187,15 @@ HRESULT CHandler::Open2(IInStream *stream, IArchiveOpenCallback *callback)
UInt64 size; UInt64 size;
{ {
/*
NCOM::CPropVariant prop; NCOM::CPropVariant prop;
RINOK(volumeCallback->GetProperty(kpidSize, &prop)); RINOK(volumeCallback->GetProperty(kpidSize, &prop));
if (prop.vt != VT_UI8) if (prop.vt != VT_UI8)
return E_INVALIDARG; return E_INVALIDARG;
size = prop.uhVal.QuadPart; size = prop.uhVal.QuadPart;
*/
RINOK(stream->Seek(0, STREAM_SEEK_END, &size));
RINOK(stream->Seek(0, STREAM_SEEK_SET, NULL));
} }
_totalSize += size; _totalSize += size;
@@ -217,11 +221,15 @@ HRESULT CHandler::Open2(IInStream *stream, IArchiveOpenCallback *callback)
if (!stream) if (!stream)
break; break;
{ {
/*
NCOM::CPropVariant prop; NCOM::CPropVariant prop;
RINOK(volumeCallback->GetProperty(kpidSize, &prop)); RINOK(volumeCallback->GetProperty(kpidSize, &prop));
if (prop.vt != VT_UI8) if (prop.vt != VT_UI8)
return E_INVALIDARG; return E_INVALIDARG;
size = prop.uhVal.QuadPart; size = prop.uhVal.QuadPart;
*/
RINOK(stream->Seek(0, STREAM_SEEK_END, &size));
RINOK(stream->Seek(0, STREAM_SEEK_SET, NULL));
} }
_totalSize += size; _totalSize += size;
_sizes.Add(size); _sizes.Add(size);

View File

@@ -98,6 +98,7 @@ STDMETHODIMP CHandler::GetArchiveProperty(PROPID propID, PROPVARIANT *value)
if (!_archive.IsArc) v |= kpv_ErrorFlags_IsNotArc; if (!_archive.IsArc) v |= kpv_ErrorFlags_IsNotArc;
if (_archive.Unsupported) v |= kpv_ErrorFlags_UnsupportedFeature; if (_archive.Unsupported) v |= kpv_ErrorFlags_UnsupportedFeature;
if (_archive.UnexpectedEnd) v |= kpv_ErrorFlags_UnexpectedEnd; if (_archive.UnexpectedEnd) v |= kpv_ErrorFlags_UnexpectedEnd;
if (_archive.NoEndAnchor) v |= kpv_ErrorFlags_HeadersError;
prop = v; prop = v;
break; break;
} }

View File

@@ -389,7 +389,10 @@ HRESULT CInArchive::ReadFileItem(int volIndex, int fsIndex, const CLongAllocDesc
return S_FALSE; return S_FALSE;
CFile &file = Files.Back(); CFile &file = Files.Back();
const CLogVol &vol = LogVols[volIndex]; const CLogVol &vol = LogVols[volIndex];
CPartition &partition = Partitions[vol.PartitionMaps[lad.Location.PartitionRef].PartitionIndex]; unsigned partitionRef = lad.Location.PartitionRef;
if (partitionRef >= vol.PartitionMaps.Size())
return S_FALSE;
CPartition &partition = Partitions[vol.PartitionMaps[partitionRef].PartitionIndex];
UInt32 key = lad.Location.Pos; UInt32 key = lad.Location.Pos;
UInt32 value; UInt32 value;
@@ -610,6 +613,7 @@ API_FUNC_IsArc IsArc_Udf(const Byte *p, size_t size)
} }
} }
HRESULT CInArchive::Open2() HRESULT CInArchive::Open2()
{ {
Clear(); Clear();
@@ -644,8 +648,10 @@ HRESULT CInArchive::Open2()
CExtent extentVDS; CExtent extentVDS;
extentVDS.Parse(buf + i + 16); extentVDS.Parse(buf + i + 16);
*/ */
const size_t kBufSize = 1 << 11; const size_t kBufSize = 1 << 11;
Byte buf[kBufSize]; Byte buf[kBufSize];
for (SecLogSize = 11;; SecLogSize -= 3) for (SecLogSize = 11;; SecLogSize -= 3)
{ {
if (SecLogSize < 8) if (SecLogSize < 8)
@@ -665,6 +671,7 @@ HRESULT CInArchive::Open2()
break; break;
} }
} }
PhySize = (UInt32)(256 + 1) << SecLogSize; PhySize = (UInt32)(256 + 1) << SecLogSize;
IsArc = true; IsArc = true;
@@ -946,28 +953,63 @@ HRESULT CInArchive::Open2()
} }
{ {
UInt32 secMask = ((UInt32)1 << SecLogSize) - 1; const UInt32 secMask = ((UInt32)1 << SecLogSize) - 1;
PhySize = (PhySize + secMask) & ~(UInt64)secMask; PhySize = (PhySize + secMask) & ~(UInt64)secMask;
} }
NoEndAnchor = true;
if (PhySize < fileSize) if (PhySize < fileSize)
{ {
UInt64 rem = fileSize - PhySize;
const size_t secSize = (size_t)1 << SecLogSize;
RINOK(_stream->Seek(PhySize, STREAM_SEEK_SET, NULL)); RINOK(_stream->Seek(PhySize, STREAM_SEEK_SET, NULL));
size_t bufSize = (UInt32)1 << SecLogSize;
size_t readSize = bufSize; // some UDF images contain ZEROs before "Anchor Volume Descriptor Pointer" at the end
RINOK(ReadStream(_stream, buf, &readSize));
if (readSize == bufSize) for (unsigned sec = 0; sec < 1024; sec++)
{ {
CTag tag; if (rem == 0)
if (tag.Parse(buf, readSize) == S_OK) break;
if (tag.Id == DESC_TYPE_AnchorVolPtr)
size_t readSize = secSize;
if (readSize > rem)
readSize = (size_t)rem;
RINOK(ReadStream(_stream, buf, &readSize));
if (readSize == 0)
break;
if (readSize == secSize && NoEndAnchor)
{
CTag tag;
if (tag.Parse(buf, readSize) == S_OK &&
tag.Id == DESC_TYPE_AnchorVolPtr)
{ {
PhySize += bufSize; NoEndAnchor = false;
rem -= readSize;
PhySize = fileSize - rem;
continue;
} }
}
size_t i;
for (i = 0; i < readSize && buf[i] == 0; i++);
if (i != readSize)
break;
rem -= readSize;
} }
if (rem == 0)
PhySize = fileSize;
} }
return S_OK; return S_OK;
} }
HRESULT CInArchive::Open(IInStream *inStream, CProgressVirt *progress) HRESULT CInArchive::Open(IInStream *inStream, CProgressVirt *progress)
{ {
_progress = progress; _progress = progress;
@@ -1000,6 +1042,7 @@ void CInArchive::Clear()
IsArc = false; IsArc = false;
Unsupported = false; Unsupported = false;
UnexpectedEnd = false; UnexpectedEnd = false;
NoEndAnchor = false;
PhySize = 0; PhySize = 0;
FileSize = 0; FileSize = 0;

View File

@@ -370,6 +370,7 @@ public:
bool IsArc; bool IsArc;
bool Unsupported; bool Unsupported;
bool UnexpectedEnd; bool UnexpectedEnd;
bool NoEndAnchor;
void UpdatePhySize(UInt64 val) void UpdatePhySize(UInt64 val)
{ {

View File

@@ -475,14 +475,10 @@ STDMETHODIMP CHandler::GetProperty(UInt32 index, PROPID propID, PROPVARIANT *val
case kpidPackSize: case kpidPackSize:
{ {
UInt64 size = 0;
if (si) if (si)
{ {
if (!si->Resource.IsSolidSmall()) if (!si->Resource.IsSolidSmall())
{ prop = si->Resource.PackSize;
size = si->Resource.PackSize;
prop = size;
}
else else
{ {
if (si->Resource.SolidIndex >= 0) if (si->Resource.SolidIndex >= 0)
@@ -493,12 +489,14 @@ STDMETHODIMP CHandler::GetProperty(UInt32 index, PROPID propID, PROPVARIANT *val
} }
} }
} }
else if (!item.IsDir)
prop = (UInt64)0;
break; break;
} }
case kpidSize: case kpidSize:
{ {
UInt64 size = 0;
if (si) if (si)
{ {
if (si->Resource.IsSolid()) if (si->Resource.IsSolid())
@@ -507,22 +505,19 @@ STDMETHODIMP CHandler::GetProperty(UInt32 index, PROPID propID, PROPVARIANT *val
{ {
if (si->Resource.SolidIndex >= 0) if (si->Resource.SolidIndex >= 0)
{ {
CSolid &ss = _db.Solids[(unsigned)si->Resource.SolidIndex]; const CSolid &ss = _db.Solids[(unsigned)si->Resource.SolidIndex];
prop = ss.UnpackSize; prop = ss.UnpackSize;
} }
} }
else else
{ prop = si->Resource.PackSize;
size = si->Resource.PackSize;
prop = size;
}
} }
else else
{ prop = si->Resource.UnpackSize;
size = si->Resource.UnpackSize;
prop = size;
}
} }
else if (!item.IsDir)
prop = (UInt64)0;
break; break;
} }

View File

@@ -10,6 +10,8 @@
#include "../../Common/Defs.h" #include "../../Common/Defs.h"
#include "../../Common/IntToString.h" #include "../../Common/IntToString.h"
#include "../../Windows/PropVariant.h"
#include "../ICoder.h" #include "../ICoder.h"
#include "../Common/CWrappers.h" #include "../Common/CWrappers.h"
@@ -21,7 +23,9 @@
#include "IArchive.h" #include "IArchive.h"
#ifndef EXTRACT_ONLY
#include "Common/HandlerOut.h" #include "Common/HandlerOut.h"
#endif
#include "XzHandler.h" #include "XzHandler.h"
@@ -83,14 +87,19 @@ class CHandler:
CMyComPtr<IInStream> _stream; CMyComPtr<IInStream> _stream;
CMyComPtr<ISequentialInStream> _seqStream; CMyComPtr<ISequentialInStream> _seqStream;
UInt32 _filterId;
AString _methodsString; AString _methodsString;
#ifndef EXTRACT_ONLY
UInt32 _filterId;
void Init() void Init()
{ {
_filterId = 0; _filterId = 0;
CMultiMethodProps::Init(); CMultiMethodProps::Init();
} }
#endif
HRESULT Open2(IInStream *inStream, /* UInt32 flags, */ IArchiveOpenCallback *callback); HRESULT Open2(IInStream *inStream, /* UInt32 flags, */ IArchiveOpenCallback *callback);
@@ -126,9 +135,12 @@ public:
CHandler::CHandler() CHandler::CHandler()
{ {
#ifndef EXTRACT_ONLY
Init(); Init();
#endif
} }
static const Byte kProps[] = static const Byte kProps[] =
{ {
kpidSize, kpidSize,

View File

@@ -4,6 +4,7 @@
#include "../../../Common/ComTry.h" #include "../../../Common/ComTry.h"
#include "../../../Common/IntToString.h" #include "../../../Common/IntToString.h"
#include "../../../Common/StringConvert.h"
#include "../../../Windows/PropVariant.h" #include "../../../Windows/PropVariant.h"
#include "../../../Windows/TimeUtils.h" #include "../../../Windows/TimeUtils.h"
@@ -11,6 +12,7 @@
#include "../../IPassword.h" #include "../../IPassword.h"
#include "../../Common/FilterCoder.h" #include "../../Common/FilterCoder.h"
#include "../../Common/LimitedStreams.h"
#include "../../Common/ProgressUtils.h" #include "../../Common/ProgressUtils.h"
#include "../../Common/StreamObjects.h" #include "../../Common/StreamObjects.h"
#include "../../Common/StreamUtils.h" #include "../../Common/StreamUtils.h"
@@ -141,14 +143,19 @@ static const Byte kProps[] =
kpidCRC, kpidCRC,
kpidMethod, kpidMethod,
kpidHostOS, kpidHostOS,
kpidUnpackVer kpidUnpackVer,
kpidVolumeIndex
}; };
static const Byte kArcProps[] = static const Byte kArcProps[] =
{ {
kpidEmbeddedStubSize, kpidEmbeddedStubSize,
kpidBit64, kpidBit64,
kpidComment kpidComment,
kpidTotalPhySize,
kpidIsVolume,
kpidVolumeIndex,
kpidNumVolumes
}; };
CHandler::CHandler() CHandler::CHandler()
@@ -174,18 +181,23 @@ STDMETHODIMP CHandler::GetArchiveProperty(PROPID propID, PROPVARIANT *value)
{ {
case kpidBit64: if (m_Archive.IsZip64) prop = m_Archive.IsZip64; break; case kpidBit64: if (m_Archive.IsZip64) prop = m_Archive.IsZip64; break;
case kpidComment: if (m_Archive.ArcInfo.Comment.Size() != 0) prop = MultiByteToUnicodeString(BytesToString(m_Archive.ArcInfo.Comment), CP_ACP); break; case kpidComment: if (m_Archive.ArcInfo.Comment.Size() != 0) prop = MultiByteToUnicodeString(BytesToString(m_Archive.ArcInfo.Comment), CP_ACP); break;
case kpidPhySize: prop = m_Archive.ArcInfo.GetPhySize(); break;
case kpidOffset: /* if (m_Archive.ArcInfo.Base != 0) */ case kpidPhySize: prop = m_Archive.GetPhySize(); break;
prop = m_Archive.ArcInfo.Base; break; case kpidOffset: prop = m_Archive.GetOffset(); break;
case kpidEmbeddedStubSize: case kpidEmbeddedStubSize:
{ {
UInt64 stubSize = m_Archive.ArcInfo.GetEmbeddedStubSize(); UInt64 stubSize = m_Archive.GetEmbeddedStubSize();
if (stubSize != 0) if (stubSize != 0)
prop = stubSize; prop = stubSize;
break; break;
} }
case kpidTotalPhySize: if (m_Archive.IsMultiVol) prop = m_Archive.Vols.GetTotalSize(); break;
case kpidVolumeIndex: if (m_Archive.IsMultiVol) prop = (UInt32)m_Archive.Vols.StartVolIndex; break;
case kpidIsVolume: if (m_Archive.IsMultiVol) prop = true; break;
case kpidNumVolumes: if (m_Archive.IsMultiVol) prop = (UInt32)m_Archive.Vols.Streams.Size(); break;
case kpidWarningFlags: case kpidWarningFlags:
{ {
UInt32 v = 0; UInt32 v = 0;
@@ -196,6 +208,18 @@ STDMETHODIMP CHandler::GetArchiveProperty(PROPID propID, PROPVARIANT *value)
break; break;
} }
case kpidError:
{
if (!m_Archive.Vols.MissingName.IsEmpty())
{
UString s;
s.SetFromAscii("Missing volume : ");
s += m_Archive.Vols.MissingName;
prop = s;
}
break;
}
case kpidErrorFlags: case kpidErrorFlags:
{ {
UInt32 v = 0; UInt32 v = 0;
@@ -208,7 +232,7 @@ STDMETHODIMP CHandler::GetArchiveProperty(PROPID propID, PROPVARIANT *value)
but the stream has access only to zip part. but the stream has access only to zip part.
In that case we ignore UnavailableStart error. In that case we ignore UnavailableStart error.
maybe we must show warning in that case. */ maybe we must show warning in that case. */
UInt64 stubSize = m_Archive.ArcInfo.GetEmbeddedStubSize(); UInt64 stubSize = m_Archive.GetEmbeddedStubSize();
if (stubSize < (UInt64)-m_Archive.ArcInfo.Base) if (stubSize < (UInt64)-m_Archive.ArcInfo.Base)
v |= kpv_ErrorFlags_UnavailableStart; v |= kpv_ErrorFlags_UnavailableStart;
} }
@@ -241,12 +265,14 @@ STDMETHODIMP CHandler::GetProperty(UInt32 index, PROPID propID, PROPVARIANT *val
COM_TRY_BEGIN COM_TRY_BEGIN
NWindows::NCOM::CPropVariant prop; NWindows::NCOM::CPropVariant prop;
const CItemEx &item = m_Items[index]; const CItemEx &item = m_Items[index];
const CExtraBlock &extra = item.GetMainExtra();
switch (propID) switch (propID)
{ {
case kpidPath: case kpidPath:
{ {
UString res; UString res;
item.GetUnicodeString(item.Name, res, _forceCodePage, _specifiedCodePage); item.GetUnicodeString(res, item.Name, false, _forceCodePage, _specifiedCodePage);
NItemName::ConvertToOSName2(res); NItemName::ConvertToOSName2(res);
prop = res; prop = res;
break; break;
@@ -261,9 +287,9 @@ STDMETHODIMP CHandler::GetProperty(UInt32 index, PROPID propID, PROPVARIANT *val
FILETIME ft; FILETIME ft;
UInt32 unixTime; UInt32 unixTime;
UInt32 type; UInt32 type;
if (item.CentralExtra.GetNtfsTime(NFileHeader::NNtfsExtra::kMTime, ft)) if (extra.GetNtfsTime(NFileHeader::NNtfsExtra::kMTime, ft))
type = NFileTimeType::kWindows; type = NFileTimeType::kWindows;
else if (item.CentralExtra.GetUnixTime(true, NFileHeader::NUnixTime::kMTime, unixTime)) else if (extra.GetUnixTime(true, NFileHeader::NUnixTime::kMTime, unixTime))
type = NFileTimeType::kUnix; type = NFileTimeType::kUnix;
else else
type = NFileTimeType::kDOS; type = NFileTimeType::kDOS;
@@ -274,7 +300,7 @@ STDMETHODIMP CHandler::GetProperty(UInt32 index, PROPID propID, PROPVARIANT *val
case kpidCTime: case kpidCTime:
{ {
FILETIME ft; FILETIME ft;
if (item.CentralExtra.GetNtfsTime(NFileHeader::NNtfsExtra::kCTime, ft)) if (extra.GetNtfsTime(NFileHeader::NNtfsExtra::kCTime, ft))
prop = ft; prop = ft;
break; break;
} }
@@ -282,7 +308,7 @@ STDMETHODIMP CHandler::GetProperty(UInt32 index, PROPID propID, PROPVARIANT *val
case kpidATime: case kpidATime:
{ {
FILETIME ft; FILETIME ft;
if (item.CentralExtra.GetNtfsTime(NFileHeader::NNtfsExtra::kATime, ft)) if (extra.GetNtfsTime(NFileHeader::NNtfsExtra::kATime, ft))
prop = ft; prop = ft;
break; break;
} }
@@ -291,10 +317,10 @@ STDMETHODIMP CHandler::GetProperty(UInt32 index, PROPID propID, PROPVARIANT *val
{ {
FILETIME utc; FILETIME utc;
bool defined = true; bool defined = true;
if (!item.CentralExtra.GetNtfsTime(NFileHeader::NNtfsExtra::kMTime, utc)) if (!extra.GetNtfsTime(NFileHeader::NNtfsExtra::kMTime, utc))
{ {
UInt32 unixTime = 0; UInt32 unixTime = 0;
if (item.CentralExtra.GetUnixTime(true, NFileHeader::NUnixTime::kMTime, unixTime)) if (extra.GetUnixTime(true, NFileHeader::NUnixTime::kMTime, unixTime))
NTime::UnixTimeToFileTime(unixTime, utc); NTime::UnixTimeToFileTime(unixTime, utc);
else else
{ {
@@ -328,7 +354,7 @@ STDMETHODIMP CHandler::GetProperty(UInt32 index, PROPID propID, PROPVARIANT *val
if (item.Comment.Size() != 0) if (item.Comment.Size() != 0)
{ {
UString res; UString res;
item.GetUnicodeString(BytesToString(item.Comment), res, _forceCodePage, _specifiedCodePage); item.GetUnicodeString(res, BytesToString(item.Comment), true, _forceCodePage, _specifiedCodePage);
prop = res; prop = res;
} }
break; break;
@@ -347,7 +373,7 @@ STDMETHODIMP CHandler::GetProperty(UInt32 index, PROPID propID, PROPVARIANT *val
{ {
m += kMethod_AES; m += kMethod_AES;
CWzAesExtra aesField; CWzAesExtra aesField;
if (item.CentralExtra.GetWzAes(aesField)) if (extra.GetWzAes(aesField))
{ {
char s[16]; char s[16];
s[0] = '-'; s[0] = '-';
@@ -360,7 +386,7 @@ STDMETHODIMP CHandler::GetProperty(UInt32 index, PROPID propID, PROPVARIANT *val
{ {
CStrongCryptoExtra f; CStrongCryptoExtra f;
f.AlgId = 0; f.AlgId = 0;
if (item.CentralExtra.GetStrongCrypto(f)) if (extra.GetStrongCrypto(f))
{ {
const char *s = FindNameForId(k_StrongCryptoPairs, ARRAY_SIZE(k_StrongCryptoPairs), f.AlgId); const char *s = FindNameForId(k_StrongCryptoPairs, ARRAY_SIZE(k_StrongCryptoPairs), f.AlgId);
if (s) if (s)
@@ -373,6 +399,8 @@ STDMETHODIMP CHandler::GetProperty(UInt32 index, PROPID propID, PROPVARIANT *val
ConvertUInt32ToString(f.AlgId, temp + 1); ConvertUInt32ToString(f.AlgId, temp + 1);
m += temp; m += temp;
} }
if (f.CertificateIsUsed())
m += "-Cert";
} }
else else
m += kMethod_StrongCrypto; m += kMethod_StrongCrypto;
@@ -424,36 +452,17 @@ STDMETHODIMP CHandler::GetProperty(UInt32 index, PROPID propID, PROPVARIANT *val
case kpidUnpackVer: case kpidUnpackVer:
prop = (UInt32)item.ExtractVersion.Version; prop = (UInt32)item.ExtractVersion.Version;
break; break;
case kpidVolumeIndex:
prop = item.Disk;
break;
} }
prop.Detach(value); prop.Detach(value);
return S_OK; return S_OK;
COM_TRY_END COM_TRY_END
} }
class CProgressImp: public CProgressVirt
{
CMyComPtr<IArchiveOpenCallback> _callback;
public:
virtual HRESULT SetCompletedLocal(UInt64 numFiles, UInt64 numBytes);
virtual HRESULT SetTotalCD(UInt64 numFiles);
virtual HRESULT SetCompletedCD(UInt64 numFiles);
CProgressImp(IArchiveOpenCallback *callback): _callback(callback) {}
};
HRESULT CProgressImp::SetCompletedLocal(UInt64 numFiles, UInt64 numBytes)
{
return _callback->SetCompleted(&numFiles, &numBytes);
}
HRESULT CProgressImp::SetTotalCD(UInt64 numFiles)
{
return _callback->SetTotal(&numFiles, NULL);
}
HRESULT CProgressImp::SetCompletedCD(UInt64 numFiles)
{
return _callback->SetCompleted(&numFiles, NULL);
}
STDMETHODIMP CHandler::Open(IInStream *inStream, STDMETHODIMP CHandler::Open(IInStream *inStream,
const UInt64 *maxCheckStartPosition, IArchiveOpenCallback *callback) const UInt64 *maxCheckStartPosition, IArchiveOpenCallback *callback)
@@ -462,9 +471,13 @@ STDMETHODIMP CHandler::Open(IInStream *inStream,
try try
{ {
Close(); Close();
RINOK(m_Archive.Open(inStream, maxCheckStartPosition)); HRESULT res = m_Archive.Open(inStream, maxCheckStartPosition, callback, m_Items);
CProgressImp progressImp(callback); if (res != S_OK)
return m_Archive.ReadHeaders(m_Items, callback ? &progressImp : NULL); {
m_Items.Clear();
m_Archive.ClearRefs();
}
return res;
} }
catch(...) { Close(); throw; } catch(...) { Close(); throw; }
COM_TRY_END COM_TRY_END
@@ -477,8 +490,6 @@ STDMETHODIMP CHandler::Close()
return S_OK; return S_OK;
} }
//////////////////////////////////////
// CHandler::DecompressItems
class CLzmaDecoder: class CLzmaDecoder:
public ICompressCoder, public ICompressCoder,
@@ -544,6 +555,8 @@ struct CMethodItem
CMyComPtr<ICompressCoder> Coder; CMyComPtr<ICompressCoder> Coder;
}; };
class CZipDecoder class CZipDecoder
{ {
NCrypto::NZip::CDecoder *_zipCryptoDecoderSpec; NCrypto::NZip::CDecoder *_zipCryptoDecoderSpec;
@@ -578,6 +591,24 @@ public:
Int32 &res); Int32 &res);
}; };
static HRESULT SkipStreamData(ISequentialInStream *stream, UInt64 size)
{
const size_t kBufSize = 1 << 12;
Byte buf[kBufSize];
for (;;)
{
if (size == 0)
return S_OK;
size_t curSize = kBufSize;
if (curSize > size)
curSize = (size_t)size;
RINOK(ReadStream_FALSE(stream, buf, curSize));
size -= curSize;
}
}
HRESULT CZipDecoder::Decode( HRESULT CZipDecoder::Decode(
DECL_EXTERNAL_CODECS_LOC_VARS DECL_EXTERNAL_CODECS_LOC_VARS
CInArchive &archive, const CItemEx &item, CInArchive &archive, const CItemEx &item,
@@ -615,7 +646,7 @@ HRESULT CZipDecoder::Decode(
if (!pkAesMode && id == NFileHeader::NCompressionMethod::kWzAES) if (!pkAesMode && id == NFileHeader::NCompressionMethod::kWzAES)
{ {
CWzAesExtra aesField; CWzAesExtra aesField;
if (item.CentralExtra.GetWzAes(aesField)) if (item.GetMainExtra().GetWzAes(aesField))
{ {
wzAesMode = true; wzAesMode = true;
needCRC = aesField.NeedCrc(); needCRC = aesField.NeedCrc();
@@ -628,9 +659,11 @@ HRESULT CZipDecoder::Decode(
outStreamSpec->SetStream(realOutStream); outStreamSpec->SetStream(realOutStream);
outStreamSpec->Init(needCRC); outStreamSpec->Init(needCRC);
UInt64 authenticationPos; CMyComPtr<ISequentialInStream> packStream;
CMyComPtr<ISequentialInStream> inStream; CLimitedSequentialInStream *limitedStreamSpec = new CLimitedSequentialInStream;
CMyComPtr<ISequentialInStream> inStream(limitedStreamSpec);
{ {
UInt64 packSize = item.PackSize; UInt64 packSize = item.PackSize;
if (wzAesMode) if (wzAesMode)
@@ -639,9 +672,14 @@ HRESULT CZipDecoder::Decode(
return S_OK; return S_OK;
packSize -= NCrypto::NWzAes::kMacSize; packSize -= NCrypto::NWzAes::kMacSize;
} }
UInt64 dataPos = item.GetDataPosition(); RINOK(archive.GetItemStream(item, true, packStream));
inStream.Attach(archive.CreateLimitedStream(dataPos, packSize)); if (!packStream)
authenticationPos = dataPos + packSize; {
res = NExtract::NOperationResult::kUnavailable;
return S_OK;
}
limitedStreamSpec->SetStream(packStream);
limitedStreamSpec->Init(packSize);
} }
CMyComPtr<ICompressFilter> cryptoFilter; CMyComPtr<ICompressFilter> cryptoFilter;
@@ -651,7 +689,7 @@ HRESULT CZipDecoder::Decode(
if (wzAesMode) if (wzAesMode)
{ {
CWzAesExtra aesField; CWzAesExtra aesField;
if (!item.CentralExtra.GetWzAes(aesField)) if (!item.GetMainExtra().GetWzAes(aesField))
return S_OK; return S_OK;
id = aesField.Method; id = aesField.Method;
if (!_wzAesDecoder) if (!_wzAesDecoder)
@@ -906,9 +944,15 @@ HRESULT CZipDecoder::Decode(
bool authOk = true; bool authOk = true;
if (needCRC) if (needCRC)
crcOK = (outStreamSpec->GetCRC() == item.Crc); crcOK = (outStreamSpec->GetCRC() == item.Crc);
if (wzAesMode) if (wzAesMode)
{ {
inStream.Attach(archive.CreateLimitedStream(authenticationPos, NCrypto::NWzAes::kMacSize)); const UInt64 rem = limitedStreamSpec->GetRem();
if (rem != 0)
if (SkipStreamData(inStream, rem) != S_OK)
authOk = false;
limitedStreamSpec->Init(NCrypto::NWzAes::kMacSize);
if (_wzAesDecoderSpec->CheckMac(inStream, authOk) != S_OK) if (_wzAesDecoderSpec->CheckMac(inStream, authOk) != S_OK)
authOk = false; authOk = false;
} }
@@ -982,16 +1026,21 @@ STDMETHODIMP CHandler::Extract(const UInt32 *indices, UInt32 numItems,
RINOK(extractCallback->SetOperationResult(NExtract::NOperationResult::kUnavailable)); RINOK(extractCallback->SetOperationResult(NExtract::NOperationResult::kUnavailable));
continue; continue;
} }
if (!item.FromLocal) if (!item.FromLocal)
{ {
HRESULT res = m_Archive.ReadLocalItemAfterCdItem(item); bool isAvail = true;
HRESULT res = m_Archive.ReadLocalItemAfterCdItem(item, isAvail);
if (res == S_FALSE) if (res == S_FALSE)
{ {
if (item.IsDir() || realOutStream || testMode) if (item.IsDir() || realOutStream || testMode)
{ {
RINOK(extractCallback->PrepareOperation(askMode)); RINOK(extractCallback->PrepareOperation(askMode));
realOutStream.Release(); realOutStream.Release();
RINOK(extractCallback->SetOperationResult(NExtract::NOperationResult::kHeadersError)); RINOK(extractCallback->SetOperationResult(
isAvail ?
NExtract::NOperationResult::kHeadersError :
NExtract::NOperationResult::kUnavailable));
} }
continue; continue;
} }
@@ -1028,6 +1077,7 @@ STDMETHODIMP CHandler::Extract(const UInt32 *indices, UInt32 numItems,
RINOK(extractCallback->SetOperationResult(res)) RINOK(extractCallback->SetOperationResult(res))
} }
lps->InSize = currentTotalPacked; lps->InSize = currentTotalPacked;
lps->OutSize = currentTotalUnPacked; lps->OutSize = currentTotalUnPacked;
return lps->SetCur(); return lps->SetCur();

View File

@@ -18,9 +18,8 @@ namespace NSignature
const UInt32 kEcd = 0x06054B50; const UInt32 kEcd = 0x06054B50;
const UInt32 kEcd64 = 0x06064B50; const UInt32 kEcd64 = 0x06064B50;
const UInt32 kEcd64Locator = 0x07064B50; const UInt32 kEcd64Locator = 0x07064B50;
const UInt32 kSpan = 0x08074B50;
// const UInt32 kSpan = 0x08074B50; const UInt32 kNoSpan = 0x30304B50; // PK00, replaces kSpan, if there is only 1 segment
const UInt32 kNoSpan = 0x30304b50; // PK00, replaces kSpan, if there is only 1 segment
} }
const unsigned kLocalHeaderSize = 4 + 26; // including signature const unsigned kLocalHeaderSize = 4 + 26; // including signature
@@ -84,6 +83,8 @@ namespace NFileHeader
kNTFS = 0x0A, kNTFS = 0x0A,
kStrongEncrypt = 0x17, kStrongEncrypt = 0x17,
kUnixTime = 0x5455, kUnixTime = 0x5455,
kIzUnicodeComment = 0x6375,
kIzUnicodeName = 0x7075,
kWzAES = 0x9901 kWzAES = 0x9901
}; };
} }

View File

File diff suppressed because it is too large Load Diff

View File

@@ -28,6 +28,7 @@ public:
{ return LocalHeaderPos + LocalFullHeaderSize; } { return LocalHeaderPos + LocalFullHeaderSize; }
}; };
struct CInArchiveInfo struct CInArchiveInfo
{ {
Int64 Base; /* Base offset of start of archive in stream. Int64 Base; /* Base offset of start of archive in stream.
@@ -40,74 +41,195 @@ struct CInArchiveInfo
Base = ArcInfo.MarkerPos; */ Base = ArcInfo.MarkerPos; */
/* The following *Pos variables contain absolute offsets in Stream */ /* The following *Pos variables contain absolute offsets in Stream */
UInt64 MarkerPos; /* Pos of first signature, it can point to PK00 signature
UInt64 MarkerPos; /* Pos of first signature, it can point to kSpan/kNoSpan signature
= MarkerPos2 in most archives = MarkerPos2 in most archives
= MarkerPos2 - 4 if there is PK00 signature */ = MarkerPos2 - 4 if there is kSpan/kNoSpan signature */
UInt64 MarkerPos2; // Pos of first local item signature in stream UInt64 MarkerPos2; // Pos of first local item signature in stream
UInt64 FinishPos; // Finish pos of archive data UInt64 FinishPos; // Finish pos of archive data in starting volume
UInt64 FileEndPos; // Finish pos of stream UInt64 FileEndPos; // Finish pos of stream
UInt64 FirstItemRelatOffset; /* Relative offset of first local (read from cd) (relative to Base). UInt64 FirstItemRelatOffset; /* Relative offset of first local (read from cd) (relative to Base).
= 0 in most archives = 0 in most archives
= size of stub for some SFXs */ = size of stub for some SFXs */
bool CdWasRead; bool CdWasRead;
bool IsSpanMode;
bool ThereIsTail;
// UInt32 BaseVolIndex;
CByteBuffer Comment; CByteBuffer Comment;
CInArchiveInfo(): Base(0), MarkerPos(0), MarkerPos2(0), FinishPos(0), FileEndPos(0),
FirstItemRelatOffset(0), CdWasRead(false) {}
UInt64 GetPhySize() const { return FinishPos - Base; }
UInt64 GetEmbeddedStubSize() const
{
if (CdWasRead)
return FirstItemRelatOffset;
return MarkerPos2 - Base;
}
bool ThereIsTail() const { return FileEndPos > FinishPos; }
CInArchiveInfo():
Base(0),
MarkerPos(0),
MarkerPos2(0),
FinishPos(0),
FileEndPos(0),
FirstItemRelatOffset(0),
CdWasRead(false),
IsSpanMode(false),
ThereIsTail(false)
// BaseVolIndex(0)
{}
void Clear() void Clear()
{ {
// BaseVolIndex = 0;
Base = 0; Base = 0;
MarkerPos = 0; MarkerPos = 0;
MarkerPos2 = 0; MarkerPos2 = 0;
FinishPos = 0; FinishPos = 0;
FileEndPos = 0; FileEndPos = 0;
ThereIsTail = false;
FirstItemRelatOffset = 0; FirstItemRelatOffset = 0;
CdWasRead = false; CdWasRead = false;
IsSpanMode = false;
Comment.Free(); Comment.Free();
} }
}; };
struct CProgressVirt
{
virtual HRESULT SetCompletedLocal(UInt64 numFiles, UInt64 numBytes) = 0;
virtual HRESULT SetTotalCD(UInt64 numFiles) = 0;
virtual HRESULT SetCompletedCD(UInt64 numFiles) = 0;
};
struct CCdInfo struct CCdInfo
{ {
// 64
UInt16 VersionMade;
UInt16 VersionNeedExtract;
// old zip
UInt32 ThisDisk;
UInt32 CdDisk;
UInt64 NumEntries_in_ThisDisk;
UInt64 NumEntries; UInt64 NumEntries;
UInt64 Size; UInt64 Size;
UInt64 Offset; UInt64 Offset;
void ParseEcd(const Byte *p); UInt16 CommentSize;
void ParseEcd64(const Byte *p);
CCdInfo() { memset(this, 0, sizeof(*this)); }
void ParseEcd32(const Byte *p); // (p) includes signature
void ParseEcd64e(const Byte *p); // (p) exclude signature
}; };
class CVols
{
public:
struct CSubStreamInfo
{
CMyComPtr<IInStream> Stream;
UInt64 Size;
CSubStreamInfo(): Size(0) {}
};
CObjectVector<CSubStreamInfo> Streams;
int StreamIndex;
bool NeedSeek;
CMyComPtr<IInStream> ZipStream;
bool StartIsExe; // is .exe
bool StartIsZ; // is .zip or .zNN
bool StartIsZip; // is .zip
bool IsUpperCase;
Int32 StartVolIndex; // = (NN - 1), if StartStream is .zNN
Int32 StartParsingVol; // if we need local parsing, we must use that stream
unsigned NumVols;
int EndVolIndex; // index of last volume (ecd volume),
// -1, if is not multivol
UString BaseName; // including '.'
UString MissingName;
CCdInfo ecd;
bool ecd_wasRead;
void Clear()
{
StreamIndex = -1;
NeedSeek = false;
StartIsExe = false;
StartIsZ = false;
StartIsZip = false;
IsUpperCase = false;
StartVolIndex = -1;
StartParsingVol = 0;
NumVols = 0;
EndVolIndex = -1;
BaseName.Empty();
MissingName.Empty();
ecd_wasRead = false;
Streams.Clear();
ZipStream.Release();
}
HRESULT ParseArcName(IArchiveOpenVolumeCallback *volCallback);
HRESULT Read(void *data, UInt32 size, UInt32 *processedSize);
UInt64 GetTotalSize() const
{
UInt64 total = 0;
FOR_VECTOR (i, Streams)
total += Streams[i].Size;
return total;
}
};
class CVolStream:
public ISequentialInStream,
public CMyUnknownImp
{
public:
CVols *Vols;
MY_UNKNOWN_IMP1(ISequentialInStream)
STDMETHOD(Read)(void *data, UInt32 size, UInt32 *processedSize);
};
class CInArchive class CInArchive
{ {
CInBuffer _inBuffer; CInBuffer _inBuffer;
bool _inBufMode; bool _inBufMode;
UInt32 m_Signature; UInt32 m_Signature;
UInt64 m_Position; UInt64 m_Position;
UInt64 _processedCnt;
bool CanStartNewVol;
CMyComPtr<IInStream> StreamRef;
IInStream *Stream;
IInStream *StartStream;
bool IsArcOpen;
HRESULT ReadVols2(IArchiveOpenVolumeCallback *volCallback,
unsigned start, int lastDisk, int zipDisk, unsigned numMissingVolsMax, unsigned &numMissingVols);
HRESULT ReadVols();
HRESULT Seek(UInt64 offset); HRESULT Seek(UInt64 offset);
HRESULT FindAndReadMarker(IInStream *stream, const UInt64 *searchHeaderSizeLimit); HRESULT FindMarker(IInStream *stream, const UInt64 *searchLimit);
HRESULT IncreaseRealPosition(Int64 addValue); HRESULT IncreaseRealPosition(Int64 addValue, bool &isFinished);
HRESULT ReadBytes(void *data, UInt32 size, UInt32 *processedSize); HRESULT ReadBytes(void *data, UInt32 size, UInt32 *processedSize);
void SafeReadBytes(void *data, unsigned size); void SafeReadBytes(void *data, unsigned size);
@@ -126,12 +248,14 @@ class CInArchive
HRESULT ReadLocalItemDescriptor(CItemEx &item); HRESULT ReadLocalItemDescriptor(CItemEx &item);
HRESULT ReadCdItem(CItemEx &item); HRESULT ReadCdItem(CItemEx &item);
HRESULT TryEcd64(UInt64 offset, CCdInfo &cdInfo); HRESULT TryEcd64(UInt64 offset, CCdInfo &cdInfo);
HRESULT FindCd(CCdInfo &cdInfo); HRESULT FindCd(bool checkOffsetMode);
HRESULT TryReadCd(CObjectVector<CItemEx> &items, UInt64 cdOffset, UInt64 cdSize, CProgressVirt *progress); HRESULT TryReadCd(CObjectVector<CItemEx> &items, const CCdInfo &cdInfo, UInt64 cdOffset, UInt64 cdSize);
HRESULT ReadCd(CObjectVector<CItemEx> &items, UInt64 &cdOffset, UInt64 &cdSize, CProgressVirt *progress); HRESULT ReadCd(CObjectVector<CItemEx> &items, UInt32 &cdDisk, UInt64 &cdOffset, UInt64 &cdSize);
HRESULT ReadLocals(CObjectVector<CItemEx> &localItems, CProgressVirt *progress); HRESULT ReadLocals(CObjectVector<CItemEx> &localItems);
HRESULT ReadHeaders2(CObjectVector<CItemEx> &items, CProgressVirt *progress); HRESULT ReadHeaders2(CObjectVector<CItemEx> &items);
HRESULT GetVolStream(unsigned vol, UInt64 pos, CMyComPtr<ISequentialInStream> &stream);
public: public:
CInArchiveInfo ArcInfo; CInArchiveInfo ArcInfo;
@@ -142,46 +266,87 @@ public:
bool ExtraMinorError; bool ExtraMinorError;
bool UnexpectedEnd; bool UnexpectedEnd;
bool NoCentralDir; bool NoCentralDir;
CMyComPtr<IInStream> Stream;
void Close();
HRESULT Open(IInStream *stream, const UInt64 *searchHeaderSizeLimit);
HRESULT ReadHeaders(CObjectVector<CItemEx> &items, CProgressVirt *progress);
bool IsOpen() const { return Stream != NULL; } bool MarkerIsFound;
bool AreThereErrors() const { return HeadersError || UnexpectedEnd; }
bool IsMultiVol;
bool UseDisk_in_SingleVol;
UInt32 EcdVolIndex;
CVols Vols;
IArchiveOpenCallback *Callback;
CInArchive(): Stream(NULL), Callback(NULL), IsArcOpen(false) {}
UInt64 GetPhySize() const
{
if (IsMultiVol)
return ArcInfo.FinishPos;
else
return ArcInfo.FinishPos - ArcInfo.Base;
}
UInt64 GetOffset() const
{
if (IsMultiVol)
return 0;
else
return ArcInfo.Base;
}
void ClearRefs();
void Close();
HRESULT Open(IInStream *stream, const UInt64 *searchLimit, IArchiveOpenCallback *callback, CObjectVector<CItemEx> &items);
HRESULT ReadHeaders(CObjectVector<CItemEx> &items);
bool IsOpen() const { return IsArcOpen; }
bool AreThereErrors() const
{
return HeadersError
|| UnexpectedEnd
|| !Vols.MissingName.IsEmpty();
}
bool IsLocalOffsetOK(const CItemEx &item) const bool IsLocalOffsetOK(const CItemEx &item) const
{ {
if (item.FromLocal) if (item.FromLocal)
return true; return true;
return /* ArcInfo.Base >= 0 || */ ArcInfo.Base + (Int64)item.LocalHeaderPos >= 0; return (Int64)GetOffset() + (Int64)item.LocalHeaderPos >= 0;
} }
HRESULT ReadLocalItemAfterCdItem(CItemEx &item); UInt64 GetEmbeddedStubSize() const
{
if (ArcInfo.CdWasRead)
return ArcInfo.FirstItemRelatOffset;
if (IsMultiVol)
return 0;
return ArcInfo.MarkerPos2 - ArcInfo.Base;
}
HRESULT ReadLocalItemAfterCdItem(CItemEx &item, bool &isAvail);
HRESULT ReadLocalItemAfterCdItemFull(CItemEx &item); HRESULT ReadLocalItemAfterCdItemFull(CItemEx &item);
ISequentialInStream *CreateLimitedStream(UInt64 position, UInt64 size); HRESULT GetItemStream(const CItemEx &item, bool seekPackData, CMyComPtr<ISequentialInStream> &stream);
UInt64 GetOffsetInStream(UInt64 offsetFromArc) const { return ArcInfo.Base + offsetFromArc; } IInStream *GetBaseStream() { return StreamRef; }
bool CanUpdate() const bool CanUpdate() const
{ {
if (AreThereErrors()) if (AreThereErrors()
return false; || IsMultiVol
if (ArcInfo.Base < 0) || ArcInfo.Base < 0
return false; || (Int64)ArcInfo.MarkerPos2 < ArcInfo.Base
if ((Int64)ArcInfo.MarkerPos2 < ArcInfo.Base) || ArcInfo.ThereIsTail
|| GetEmbeddedStubSize() != 0)
return false; return false;
// 7-zip probably can update archives with embedded stubs. // 7-zip probably can update archives with embedded stubs.
// we just disable that feature for more safety. // we just disable that feature for more safety.
if (ArcInfo.GetEmbeddedStubSize() != 0)
return false;
if (ArcInfo.ThereIsTail())
return false;
return true; return true;
} }
}; };

View File

@@ -3,8 +3,10 @@
#include "StdAfx.h" #include "StdAfx.h"
#include "../../../../C/CpuArch.h" #include "../../../../C/CpuArch.h"
#include "../../../../C/7zCrc.h"
#include "../../../Common/MyLinux.h" #include "../../../Common/MyLinux.h"
#include "../../../Common/StringConvert.h"
#include "../Common/ItemNameUtils.h" #include "../Common/ItemNameUtils.h"
@@ -80,6 +82,30 @@ bool CExtraSubBlock::ExtractUnixTime(bool isCentral, unsigned index, UInt32 &res
return false; return false;
} }
bool CExtraBlock::GetNtfsTime(unsigned index, FILETIME &ft) const
{
FOR_VECTOR (i, SubBlocks)
{
const CExtraSubBlock &sb = SubBlocks[i];
if (sb.ID == NFileHeader::NExtraID::kNTFS)
return sb.ExtractNtfsTime(index, ft);
}
return false;
}
bool CExtraBlock::GetUnixTime(bool isCentral, unsigned index, UInt32 &res) const
{
FOR_VECTOR (i, SubBlocks)
{
const CExtraSubBlock &sb = SubBlocks[i];
if (sb.ID == NFileHeader::NExtraID::kUnixTime)
return sb.ExtractUnixTime(isCentral, index, res);
}
return false;
}
bool CLocalItem::IsDir() const bool CLocalItem::IsDir() const
{ {
return NItemName::HasTailSlash(Name, GetCodePage()); return NItemName::HasTailSlash(Name, GetCodePage());
@@ -89,12 +115,29 @@ bool CItem::IsDir() const
{ {
if (NItemName::HasTailSlash(Name, GetCodePage())) if (NItemName::HasTailSlash(Name, GetCodePage()))
return true; return true;
Byte hostOS = GetHostOS();
if (Size == 0 && PackSize == 0 && !Name.IsEmpty() && Name.Back() == '\\')
{
// do we need to use CharPrevExA?
// .NET Framework 4.5 : System.IO.Compression::CreateFromDirectory() probably writes backslashes to headers?
// so we support that case
switch (hostOS)
{
case NHostOS::kFAT:
case NHostOS::kNTFS:
case NHostOS::kHPFS:
case NHostOS::kVFAT:
return true;
}
}
if (!FromCentral) if (!FromCentral)
return false; return false;
UInt16 highAttrib = (UInt16)((ExternalAttrib >> 16 ) & 0xFFFF); UInt16 highAttrib = (UInt16)((ExternalAttrib >> 16 ) & 0xFFFF);
Byte hostOS = GetHostOS();
switch (hostOS) switch (hostOS)
{ {
case NHostOS::kAMIGA: case NHostOS::kAMIGA:
@@ -158,4 +201,53 @@ bool CItem::GetPosixAttrib(UInt32 &attrib) const
return false; return false;
} }
void CItem::GetUnicodeString(UString &res, const AString &s, bool isComment, bool useSpecifiedCodePage, UINT codePage) const
{
bool isUtf8 = IsUtf8();
bool ignore_Utf8_Errors = true;
if (!isUtf8)
{
{
const unsigned id = isComment ?
NFileHeader::NExtraID::kIzUnicodeComment:
NFileHeader::NExtraID::kIzUnicodeName;
const CObjectVector<CExtraSubBlock> &subBlocks = GetMainExtra().SubBlocks;
FOR_VECTOR (i, subBlocks)
{
const CExtraSubBlock &sb = subBlocks[i];
if (sb.ID == id)
{
AString utf;
if (sb.ExtractIzUnicode(CrcCalc(s, s.Len()), utf))
if (ConvertUTF8ToUnicode(utf, res))
return;
break;
}
}
}
if (useSpecifiedCodePage)
isUtf8 = (codePage == CP_UTF8);
#ifdef _WIN32
else if (GetHostOS() == NFileHeader::NHostOS::kUnix)
{
/* Some ZIP archives in Unix use UTF-8 encoding without Utf8 flag in header.
We try to get name as UTF-8.
Do we need to do it in POSIX version also? */
isUtf8 = true;
ignore_Utf8_Errors = false;
}
#endif
}
if (isUtf8)
if (ConvertUTF8ToUnicode(s, res) || ignore_Utf8_Errors)
return;
MultiByteToUnicodeString2(res, s, useSpecifiedCodePage ? codePage : GetCodePage());
}
}} }}

View File

@@ -7,7 +7,6 @@
#include "../../../Common/MyBuffer.h" #include "../../../Common/MyBuffer.h"
#include "../../../Common/MyString.h" #include "../../../Common/MyString.h"
#include "../../../Common/StringConvert.h"
#include "../../../Common/UTFConvert.h" #include "../../../Common/UTFConvert.h"
#include "ZipHeader.h" #include "ZipHeader.h"
@@ -28,6 +27,23 @@ struct CExtraSubBlock
bool ExtractNtfsTime(unsigned index, FILETIME &ft) const; bool ExtractNtfsTime(unsigned index, FILETIME &ft) const;
bool ExtractUnixTime(bool isCentral, unsigned index, UInt32 &res) const; bool ExtractUnixTime(bool isCentral, unsigned index, UInt32 &res) const;
bool ExtractIzUnicode(UInt32 crc, AString &name) const
{
unsigned size = (unsigned)Data.Size();
if (size < 1 + 4)
return false;
const Byte *p = (const Byte *)Data;
if (p[0] > 1)
return false;
if (crc != GetUi32(p + 1))
return false;
size -= 5;
name.SetFrom_CalcLen((const char *)p + 5, size);
if (size != name.Len())
return false;
return CheckUTF8(name, false);
}
}; };
const unsigned k_WzAesExtra_Size = 7; const unsigned k_WzAesExtra_Size = 7;
@@ -109,6 +125,8 @@ struct CStrongCryptoExtra
Flags = GetUi16(p + 6); Flags = GetUi16(p + 6);
return (Format == 2); return (Format == 2);
} }
bool CertificateIsUsed() const { return (Flags > 0x0001); }
}; };
struct CExtraBlock struct CExtraBlock
@@ -155,27 +173,8 @@ struct CExtraBlock
} }
*/ */
bool GetNtfsTime(unsigned index, FILETIME &ft) const bool GetNtfsTime(unsigned index, FILETIME &ft) const;
{ bool GetUnixTime(bool isCentral, unsigned index, UInt32 &res) const;
FOR_VECTOR (i, SubBlocks)
{
const CExtraSubBlock &sb = SubBlocks[i];
if (sb.ID == NFileHeader::NExtraID::kNTFS)
return sb.ExtractNtfsTime(index, ft);
}
return false;
}
bool GetUnixTime(bool isCentral, unsigned index, UInt32 &res) const
{
FOR_VECTOR (i, SubBlocks)
{
const CExtraSubBlock &sb = SubBlocks[i];
if (sb.ID == NFileHeader::NExtraID::kUnixTime)
return sb.ExtractUnixTime(isCentral, index, res);
}
return false;
}
void RemoveUnknownSubBlocks() void RemoveUnknownSubBlocks()
{ {
@@ -200,6 +199,8 @@ public:
UInt64 PackSize; UInt64 PackSize;
UInt32 Time; UInt32 Time;
UInt32 Crc; UInt32 Crc;
UInt32 Disk;
AString Name; AString Name;
@@ -272,45 +273,22 @@ public:
MadeByVersion.HostOS = 0; MadeByVersion.HostOS = 0;
} }
const CExtraBlock &GetMainExtra() const { return *(FromCentral ? &CentralExtra : &LocalExtra); }
bool IsDir() const; bool IsDir() const;
UInt32 GetWinAttrib() const; UInt32 GetWinAttrib() const;
bool GetPosixAttrib(UInt32 &attrib) const; bool GetPosixAttrib(UInt32 &attrib) const;
Byte GetHostOS() const { return FromCentral ? MadeByVersion.HostOS : ExtractVersion.HostOS; } Byte GetHostOS() const { return FromCentral ? MadeByVersion.HostOS : ExtractVersion.HostOS; }
void GetUnicodeString(const AString &s, UString &res, bool useSpecifiedCodePage, UINT codePage) const void GetUnicodeString(UString &res, const AString &s, bool isComment, bool useSpecifiedCodePage, UINT codePage) const;
{
bool isUtf8 = IsUtf8();
bool ignore_Utf8_Errors = true;
#ifdef _WIN32
if (!isUtf8)
{
if (useSpecifiedCodePage)
isUtf8 = (codePage == CP_UTF8);
else if (GetHostOS() == NFileHeader::NHostOS::kUnix)
{
/* Some ZIP archives in Unix use UTF-8 encoding without Utf8 flag in header.
We try to get name as UTF-8.
Do we need to do it in POSIX version also? */
isUtf8 = true;
ignore_Utf8_Errors = false;
}
}
#endif
if (isUtf8)
if (ConvertUTF8ToUnicode(s, res) || ignore_Utf8_Errors)
return;
MultiByteToUnicodeString2(res, s, useSpecifiedCodePage ? codePage : GetCodePage());
}
bool IsThereCrc() const bool IsThereCrc() const
{ {
if (Method == NFileHeader::NCompressionMethod::kWzAES) if (Method == NFileHeader::NCompressionMethod::kWzAES)
{ {
CWzAesExtra aesField; CWzAesExtra aesField;
if (CentralExtra.GetWzAes(aesField)) if (GetMainExtra().GetWzAes(aesField))
return aesField.NeedCrc(); return aesField.NeedCrc();
} }
return (Crc != 0 || !IsDir()); return (Crc != 0 || !IsDir());
@@ -320,8 +298,10 @@ public:
{ {
Byte hostOS = GetHostOS(); Byte hostOS = GetHostOS();
return (UINT)(( return (UINT)((
hostOS == NFileHeader::NHostOS::kFAT || hostOS == NFileHeader::NHostOS::kFAT
hostOS == NFileHeader::NHostOS::kNTFS) ? CP_OEMCP : CP_ACP); || hostOS == NFileHeader::NHostOS::kNTFS
|| hostOS == NFileHeader::NHostOS::kUnix // do we need it?
) ? CP_OEMCP : CP_ACP);
} }
}; };

View File

@@ -12,10 +12,11 @@ namespace NZip {
static const Byte k_Signature[] = { static const Byte k_Signature[] = {
4, 0x50, 0x4B, 0x03, 0x04, 4, 0x50, 0x4B, 0x03, 0x04,
4, 0x50, 0x4B, 0x05, 0x06, 4, 0x50, 0x4B, 0x05, 0x06,
6, 0x50, 0x4B, 0x07, 0x08, 0x50, 0x4B,
6, 0x50, 0x4B, 0x30, 0x30, 0x50, 0x4B }; 6, 0x50, 0x4B, 0x30, 0x30, 0x50, 0x4B };
REGISTER_ARC_IO( REGISTER_ARC_IO(
"zip", "zip zipx jar xpi odt ods docx xlsx epub", 0, 1, "zip", "zip z01 zipx jar xpi odt ods docx xlsx epub", 0, 1,
k_Signature, k_Signature,
0, 0,
NArcInfoFlags::kFindSignature | NArcInfoFlags::kFindSignature |

View File

@@ -52,16 +52,6 @@ static HRESULT CopyBlockToArchive(ISequentialInStream *inStream, UInt64 size,
return NCompress::CopyStream_ExactSize(inStream, outStream, size, progress); return NCompress::CopyStream_ExactSize(inStream, outStream, size, progress);
} }
static HRESULT WriteRange(IInStream *inStream, COutArchive &outArchive,
const CUpdateRange &range, ICompressProgressInfo *progress)
{
UInt64 position;
RINOK(inStream->Seek(range.Position, STREAM_SEEK_SET, &position));
RINOK(CopyBlockToArchive(inStream, range.Size, outArchive, progress));
return progress->SetRatioInfo(&range.Size, &range.Size);
}
static void SetFileHeader( static void SetFileHeader(
COutArchive &archive, COutArchive &archive,
const CCompressionMethodMode &options, const CCompressionMethodMode &options,
@@ -358,9 +348,12 @@ static HRESULT UpdateItemOldData(
return E_NOTIMPL; return E_NOTIMPL;
// use old name size. // use old name size.
// CUpdateRange range(item.GetLocalExtraPosition(), item.LocalExtraSize + item.PackSize);
CUpdateRange range(inArchive->GetOffsetInStream(itemEx.GetDataPosition()), itemEx.PackSize);
CMyComPtr<ISequentialInStream> packStream;
RINOK(inArchive->GetItemStream(itemEx, true, packStream));
if (!packStream)
return E_NOTIMPL;
// we keep ExternalAttrib and some another properties from old archive // we keep ExternalAttrib and some another properties from old archive
// item.ExternalAttrib = ui.Attrib; // item.ExternalAttrib = ui.Attrib;
@@ -378,19 +371,27 @@ static HRESULT UpdateItemOldData(
archive.PrepareWriteCompressedData2(item.Name.Len(), item.Size, item.PackSize, item.LocalExtra.HasWzAes()); archive.PrepareWriteCompressedData2(item.Name.Len(), item.Size, item.PackSize, item.LocalExtra.HasWzAes());
archive.WriteLocalHeader(item); archive.WriteLocalHeader(item);
RINOK(WriteRange(inArchive->Stream, archive, range, progress));
complexity += range.Size; RINOK(CopyBlockToArchive(packStream, itemEx.PackSize, archive, progress));
complexity += itemEx.PackSize;
} }
else else
{ {
CUpdateRange range(inArchive->GetOffsetInStream(itemEx.LocalHeaderPos), itemEx.GetLocalFullSize()); CMyComPtr<ISequentialInStream> packStream;
RINOK(inArchive->GetItemStream(itemEx, false, packStream));
if (!packStream)
return E_NOTIMPL;
// set new header position // set new header position
item.LocalHeaderPos = archive.GetCurPos(); item.LocalHeaderPos = archive.GetCurPos();
RINOK(WriteRange(inArchive->Stream, archive, range, progress)); const UInt64 rangeSize = itemEx.GetLocalFullSize();
complexity += range.Size;
archive.MoveCurPos(range.Size); RINOK(CopyBlockToArchive(packStream, rangeSize, archive, progress));
complexity += rangeSize;
archive.MoveCurPos(rangeSize);
} }
return S_OK; return S_OK;
@@ -1191,10 +1192,11 @@ HRESULT Update(
if (inArchive) if (inArchive)
{ {
if (inArchive->ArcInfo.Base > 0 && !removeSfx) if (!inArchive->IsMultiVol && inArchive->ArcInfo.Base > 0 && !removeSfx)
{ {
RINOK(inArchive->Stream->Seek(0, STREAM_SEEK_SET, NULL)); IInStream *baseStream = inArchive->GetBaseStream();
RINOK(NCompress::CopyStream_ExactSize(inArchive->Stream, outStreamReal, inArchive->ArcInfo.Base, NULL)); RINOK(baseStream->Seek(0, STREAM_SEEK_SET, NULL));
RINOK(NCompress::CopyStream_ExactSize(baseStream, outStreamReal, inArchive->ArcInfo.Base, NULL));
} }
} }
@@ -1210,11 +1212,12 @@ HRESULT Update(
if (inArchive) if (inArchive)
{ {
if ((Int64)inArchive->ArcInfo.MarkerPos2 > inArchive->ArcInfo.Base) if (!inArchive->IsMultiVol && (Int64)inArchive->ArcInfo.MarkerPos2 > inArchive->ArcInfo.Base)
{ {
RINOK(inArchive->Stream->Seek(inArchive->ArcInfo.Base, STREAM_SEEK_SET, NULL)); IInStream *baseStream = inArchive->GetBaseStream();
RINOK(baseStream->Seek(inArchive->ArcInfo.Base, STREAM_SEEK_SET, NULL));
UInt64 embStubSize = inArchive->ArcInfo.MarkerPos2 - inArchive->ArcInfo.Base; UInt64 embStubSize = inArchive->ArcInfo.MarkerPos2 - inArchive->ArcInfo.Base;
RINOK(NCompress::CopyStream_ExactSize(inArchive->Stream, outStream, embStubSize, NULL)); RINOK(NCompress::CopyStream_ExactSize(baseStream, outStream, embStubSize, NULL));
outArchive.MoveCurPos(embStubSize); outArchive.MoveCurPos(embStubSize);
} }
} }

View File

@@ -107,4 +107,4 @@ C_OBJS = \
!include "../../Aes.mak" !include "../../Aes.mak"
!include "../../Crc.mak" !include "../../Crc.mak"
!include "../../7zip.mak" !include "../../7zip.mak"

View File

@@ -18,7 +18,6 @@ FILE_IO =FileIO
FILE_IO_2 =Windows/$(FILE_IO) FILE_IO_2 =Windows/$(FILE_IO)
MT_FILES = \ MT_FILES = \
System.o \
LzFindMt.o \ LzFindMt.o \
Threads.o \ Threads.o \
@@ -60,6 +59,7 @@ OBJS = \
StringConvert.o \ StringConvert.o \
StringToInt.o \ StringToInt.o \
PropVariant.o \ PropVariant.o \
System.o \
7zCrc.o \ 7zCrc.o \
7zCrcOpt.o \ 7zCrcOpt.o \
Alloc.o \ Alloc.o \
@@ -150,10 +150,8 @@ StringToInt.o: ../../../Common/StringToInt.cpp
PropVariant.o: ../../../Windows/PropVariant.cpp PropVariant.o: ../../../Windows/PropVariant.cpp
$(CXX) $(CFLAGS) ../../../Windows/PropVariant.cpp $(CXX) $(CFLAGS) ../../../Windows/PropVariant.cpp
ifdef MT_FILES
System.o: ../../../Windows/System.cpp System.o: ../../../Windows/System.cpp
$(CXX) $(CFLAGS) ../../../Windows/System.cpp $(CXX) $(CFLAGS) ../../../Windows/System.cpp
endif
7zCrc.o: ../../../../C/7zCrc.c 7zCrc.o: ../../../../C/7zCrc.c
$(CXX_C) $(CFLAGS) ../../../../C/7zCrc.c $(CXX_C) $(CFLAGS) ../../../../C/7zCrc.c
@@ -195,4 +193,3 @@ Lzma86Enc.o: ../../../../C/Lzma86Enc.c
clean: clean:
-$(RM) $(PROG) $(OBJS) -$(RM) $(PROG) $(OBJS)

View File

@@ -325,14 +325,6 @@ SOURCE=..\..\UI\FileManager\ComboDialog.h
# End Source File # End Source File
# Begin Source File # Begin Source File
SOURCE=..\..\UI\FileManager\MessagesDialog.cpp
# End Source File
# Begin Source File
SOURCE=..\..\UI\FileManager\MessagesDialog.h
# End Source File
# Begin Source File
SOURCE=..\..\UI\FileManager\OverwriteDialog.cpp SOURCE=..\..\UI\FileManager\OverwriteDialog.cpp
# End Source File # End Source File
# Begin Source File # Begin Source File

View File

@@ -5,16 +5,19 @@
#include <string.h> #include <string.h>
#include "LimitedStreams.h" #include "LimitedStreams.h"
#include "../../Common/Defs.h"
STDMETHODIMP CLimitedSequentialInStream::Read(void *data, UInt32 size, UInt32 *processedSize) STDMETHODIMP CLimitedSequentialInStream::Read(void *data, UInt32 size, UInt32 *processedSize)
{ {
UInt32 realProcessedSize = 0; UInt32 realProcessedSize = 0;
UInt32 sizeToRead = (UInt32)MyMin((_size - _pos), (UInt64)size);
HRESULT result = S_OK;
if (sizeToRead > 0)
{ {
result = _stream->Read(data, sizeToRead, &realProcessedSize); const UInt64 rem = _size - _pos;
if (size > rem)
size = (UInt32)rem;
}
HRESULT result = S_OK;
if (size != 0)
{
result = _stream->Read(data, size, &realProcessedSize);
_pos += realProcessedSize; _pos += realProcessedSize;
if (realProcessedSize == 0) if (realProcessedSize == 0)
_wasFinished = true; _wasFinished = true;
@@ -34,9 +37,11 @@ STDMETHODIMP CLimitedInStream::Read(void *data, UInt32 size, UInt32 *processedSi
return S_OK; return S_OK;
// return (_virtPos == _size) ? S_OK: E_FAIL; // ERROR_HANDLE_EOF // return (_virtPos == _size) ? S_OK: E_FAIL; // ERROR_HANDLE_EOF
} }
UInt64 rem = _size - _virtPos; {
if (rem < size) const UInt64 rem = _size - _virtPos;
size = (UInt32)rem; if (size > rem)
size = (UInt32)rem;
}
UInt64 newPos = _startOffset + _virtPos; UInt64 newPos = _startOffset + _virtPos;
if (newPos != _physPos) if (newPos != _physPos)
{ {

View File

@@ -30,6 +30,7 @@ public:
STDMETHOD(Read)(void *data, UInt32 size, UInt32 *processedSize); STDMETHOD(Read)(void *data, UInt32 size, UInt32 *processedSize);
UInt64 GetSize() const { return _pos; } UInt64 GetSize() const { return _pos; }
UInt64 GetRem() const { return _size - _pos; }
bool WasFinished() const { return _wasFinished; } bool WasFinished() const { return _wasFinished; }
}; };

View File

@@ -783,7 +783,7 @@ void CState::ThreadFunc()
} }
packSize = Decoder->Base.BitDecoder.GetProcessedSize(); packSize = Decoder->Base.BitDecoder.GetProcessedSize();
} }
catch(const CInBufferException &e) { res = e.ErrorCode; if (res != S_OK) res = E_FAIL; } catch(const CInBufferException &e) { res = e.ErrorCode; if (res == S_OK) res = E_FAIL; }
catch(...) { res = E_FAIL; } catch(...) { res = E_FAIL; }
if (res != S_OK) if (res != S_OK)
{ {
@@ -809,7 +809,7 @@ void CState::ThreadFunc()
res = S_FALSE; res = S_FALSE;
} }
} }
catch(const COutBufferException &e) { res = e.ErrorCode; if (res != S_OK) res = E_FAIL; } catch(const COutBufferException &e) { res = e.ErrorCode; if (res == S_OK) res = E_FAIL; }
catch(...) { res = E_FAIL; } catch(...) { res = E_FAIL; }
if (res != S_OK) if (res != S_OK)
{ {

View File

@@ -214,11 +214,13 @@ public:
HRESULT Flush() { return m_OutStream.Flush(); } HRESULT Flush() { return m_OutStream.Flush(); }
MY_QUERYINTERFACE_BEGIN2(ICompressCoder)
#ifndef _7ZIP_ST #ifndef _7ZIP_ST
MY_UNKNOWN_IMP2(ICompressSetCoderMt, ICompressSetCoderProperties) MY_QUERYINTERFACE_ENTRY(ICompressSetCoderMt)
#else
MY_UNKNOWN_IMP1(ICompressSetCoderProperties)
#endif #endif
MY_QUERYINTERFACE_ENTRY(ICompressSetCoderProperties)
MY_QUERYINTERFACE_END
MY_ADDREF_RELEASE
HRESULT CodeReal(ISequentialInStream *inStream, ISequentialOutStream *outStream, HRESULT CodeReal(ISequentialInStream *inStream, ISequentialOutStream *outStream,
const UInt64 *inSize, const UInt64 *outSize, ICompressProgressInfo *progress); const UInt64 *inSize, const UInt64 *outSize, ICompressProgressInfo *progress);

View File

@@ -5,14 +5,21 @@
#include "../Common/RegisterCodec.h" #include "../Common/RegisterCodec.h"
#include "BZip2Decoder.h" #include "BZip2Decoder.h"
REGISTER_CODEC_CREATE(CreateDec, NCompress::NBZip2::CDecoder)
#if !defined(EXTRACT_ONLY) && !defined(BZIP2_EXTRACT_ONLY) #if !defined(EXTRACT_ONLY) && !defined(BZIP2_EXTRACT_ONLY)
#include "BZip2Encoder.h" #include "BZip2Encoder.h"
REGISTER_CODEC_CREATE(CreateEnc, NCompress::NBZip2::CEncoder) #endif
namespace NCompress {
namespace NBZip2 {
REGISTER_CODEC_CREATE(CreateDec, CDecoder)
#if !defined(EXTRACT_ONLY) && !defined(BZIP2_EXTRACT_ONLY)
REGISTER_CODEC_CREATE(CreateEnc, CEncoder)
#else #else
#define CreateEnc NULL #define CreateEnc NULL
#endif #endif
REGISTER_CODEC_2(BZip2, CreateDec, CreateEnc, 0x40202, "BZip2") REGISTER_CODEC_2(BZip2, CreateDec, CreateEnc, 0x40202, "BZip2")
}}

View File

@@ -6,9 +6,12 @@
#include "Bcj2Coder.h" #include "Bcj2Coder.h"
REGISTER_CODEC_CREATE_2(CreateCodec, NCompress::NBcj2::CDecoder(), ICompressCoder2) namespace NCompress {
namespace NBcj2 {
REGISTER_CODEC_CREATE_2(CreateCodec, CDecoder(), ICompressCoder2)
#ifndef EXTRACT_ONLY #ifndef EXTRACT_ONLY
REGISTER_CODEC_CREATE_2(CreateCodecOut, NCompress::NBcj2::CEncoder(), ICompressCoder2) REGISTER_CODEC_CREATE_2(CreateCodecOut, CEncoder(), ICompressCoder2)
#else #else
#define CreateCodecOut NULL #define CreateCodecOut NULL
#endif #endif
@@ -17,3 +20,5 @@ REGISTER_CODEC_VAR
{ CreateCodec, CreateCodecOut, 0x303011B, "BCJ2", 4, false }; { CreateCodec, CreateCodecOut, 0x303011B, "BCJ2", 4, false };
REGISTER_CODEC(BCJ2) REGISTER_CODEC(BCJ2)
}}

View File

@@ -4,16 +4,21 @@
#include "BcjCoder.h" #include "BcjCoder.h"
STDMETHODIMP CBcjCoder::Init() namespace NCompress {
namespace NBcj {
STDMETHODIMP CCoder::Init()
{ {
_bufferPos = 0; _bufferPos = 0;
x86_Convert_Init(_prevMask); x86_Convert_Init(_prevMask);
return S_OK; return S_OK;
} }
STDMETHODIMP_(UInt32) CBcjCoder::Filter(Byte *data, UInt32 size) STDMETHODIMP_(UInt32) CCoder::Filter(Byte *data, UInt32 size)
{ {
UInt32 processed = (UInt32)::x86_Convert(data, size, _bufferPos, &_prevMask, _encode); UInt32 processed = (UInt32)::x86_Convert(data, size, _bufferPos, &_prevMask, _encode);
_bufferPos += processed; _bufferPos += processed;
return processed; return processed;
} }
}}

View File

@@ -9,7 +9,10 @@
#include "../ICoder.h" #include "../ICoder.h"
class CBcjCoder: namespace NCompress {
namespace NBcj {
class CCoder:
public ICompressFilter, public ICompressFilter,
public CMyUnknownImp public CMyUnknownImp
{ {
@@ -17,10 +20,12 @@ class CBcjCoder:
UInt32 _prevMask; UInt32 _prevMask;
int _encode; int _encode;
public: public:
MY_UNKNOWN_IMP; MY_UNKNOWN_IMP1(ICompressFilter);
INTERFACE_ICompressFilter(;) INTERFACE_ICompressFilter(;)
CBcjCoder(int encode): _bufferPos(0), _encode(encode) { x86_Convert_Init(_prevMask); } CCoder(int encode): _bufferPos(0), _encode(encode) { x86_Convert_Init(_prevMask); }
}; };
}}
#endif #endif

View File

@@ -6,7 +6,12 @@
#include "BcjCoder.h" #include "BcjCoder.h"
namespace NCompress {
namespace NBcj {
REGISTER_FILTER_E(BCJ, REGISTER_FILTER_E(BCJ,
CBcjCoder(false), CCoder(false),
CBcjCoder(true), CCoder(true),
0x3030103, "BCJ") 0x3030103, "BCJ")
}}

View File

@@ -4,15 +4,20 @@
#include "BranchMisc.h" #include "BranchMisc.h"
STDMETHODIMP CBranchCoder::Init() namespace NCompress {
namespace NBranch {
STDMETHODIMP CCoder::Init()
{ {
_bufferPos = 0; _bufferPos = 0;
return S_OK; return S_OK;
} }
STDMETHODIMP_(UInt32) CBranchCoder::Filter(Byte *data, UInt32 size) STDMETHODIMP_(UInt32) CCoder::Filter(Byte *data, UInt32 size)
{ {
UInt32 processed = (UInt32)BraFunc(data, size, _bufferPos, _encode); UInt32 processed = (UInt32)BraFunc(data, size, _bufferPos, _encode);
_bufferPos += processed; _bufferPos += processed;
return processed; return processed;
} }
}}

View File

@@ -13,7 +13,10 @@ typedef SizeT (*Func_Bra)(Byte *data, SizeT size, UInt32 ip, int encoding);
EXTERN_C_END EXTERN_C_END
class CBranchCoder: namespace NCompress {
namespace NBranch {
class CCoder:
public ICompressFilter, public ICompressFilter,
public CMyUnknownImp public CMyUnknownImp
{ {
@@ -21,10 +24,12 @@ class CBranchCoder:
int _encode; int _encode;
Func_Bra BraFunc; Func_Bra BraFunc;
public: public:
MY_UNKNOWN_IMP; MY_UNKNOWN_IMP1(ICompressFilter);
INTERFACE_ICompressFilter(;) INTERFACE_ICompressFilter(;)
CBranchCoder(Func_Bra bra, int encode): _bufferPos(0), _encode(encode), BraFunc(bra) {} CCoder(Func_Bra bra, int encode): _bufferPos(0), _encode(encode), BraFunc(bra) {}
}; };
}}
#endif #endif

View File

@@ -8,9 +8,12 @@
#include "BranchMisc.h" #include "BranchMisc.h"
namespace NCompress {
namespace NBranch {
#define CREATE_BRA(n) \ #define CREATE_BRA(n) \
REGISTER_FILTER_CREATE(CreateBra_Decoder_ ## n, CBranchCoder(n ## _Convert, false)) \ REGISTER_FILTER_CREATE(CreateBra_Decoder_ ## n, CCoder(n ## _Convert, false)) \
REGISTER_FILTER_CREATE(CreateBra_Encoder_ ## n, CBranchCoder(n ## _Convert, true)) \ REGISTER_FILTER_CREATE(CreateBra_Encoder_ ## n, CCoder(n ## _Convert, true)) \
CREATE_BRA(PPC) CREATE_BRA(PPC)
CREATE_BRA(IA64) CREATE_BRA(IA64)
@@ -34,3 +37,5 @@ REGISTER_CODECS_VAR
}; };
REGISTER_CODECS(Branch) REGISTER_CODECS(Branch)
}}

View File

@@ -8,12 +8,15 @@
#include "../Common/RegisterCodec.h" #include "../Common/RegisterCodec.h"
namespace NCompress {
namespace NByteSwap {
class CByteSwap2: class CByteSwap2:
public ICompressFilter, public ICompressFilter,
public CMyUnknownImp public CMyUnknownImp
{ {
public: public:
MY_UNKNOWN_IMP MY_UNKNOWN_IMP1(ICompressFilter);
INTERFACE_ICompressFilter(;) INTERFACE_ICompressFilter(;)
}; };
@@ -22,7 +25,7 @@ class CByteSwap4:
public CMyUnknownImp public CMyUnknownImp
{ {
public: public:
MY_UNKNOWN_IMP MY_UNKNOWN_IMP1(ICompressFilter);
INTERFACE_ICompressFilter(;) INTERFACE_ICompressFilter(;)
}; };
@@ -85,3 +88,5 @@ REGISTER_CODECS_VAR
}; };
REGISTER_CODECS(ByteSwap) REGISTER_CODECS(ByteSwap)
}}

View File

@@ -6,6 +6,10 @@
#include "CopyCoder.h" #include "CopyCoder.h"
REGISTER_CODEC_CREATE(CreateCodec, NCompress::CCopyCoder()) namespace NCompress {
REGISTER_CODEC_CREATE(CreateCodec, CCopyCoder())
REGISTER_CODEC_2(Copy, CreateCodec, CreateCodec, 0, "Copy") REGISTER_CODEC_2(Copy, CreateCodec, CreateCodec, 0, "Copy")
}

View File

@@ -6,13 +6,21 @@
#include "DeflateDecoder.h" #include "DeflateDecoder.h"
REGISTER_CODEC_CREATE(CreateDec, NCompress::NDeflate::NDecoder::CCOMCoder64())
#if !defined(EXTRACT_ONLY) && !defined(DEFLATE_EXTRACT_ONLY) #if !defined(EXTRACT_ONLY) && !defined(DEFLATE_EXTRACT_ONLY)
#include "DeflateEncoder.h" #include "DeflateEncoder.h"
REGISTER_CODEC_CREATE(CreateEnc, NCompress::NDeflate::NEncoder::CCOMCoder64()) #endif
namespace NCompress {
namespace NDeflate {
REGISTER_CODEC_CREATE(CreateDec, NDecoder::CCOMCoder64())
#if !defined(EXTRACT_ONLY) && !defined(DEFLATE_EXTRACT_ONLY)
REGISTER_CODEC_CREATE(CreateEnc, NEncoder::CCOMCoder64())
#else #else
#define CreateEnc NULL #define CreateEnc NULL
#endif #endif
REGISTER_CODEC_2(Deflate64, CreateDec, CreateEnc, 0x40109, "Deflate64") REGISTER_CODEC_2(Deflate64, CreateDec, CreateEnc, 0x40109, "Deflate64")
}}

View File

@@ -92,14 +92,16 @@ public:
const UInt64 *outSize, ICompressProgressInfo *progress); const UInt64 *outSize, ICompressProgressInfo *progress);
#ifndef NO_READ_FROM_CODER #ifndef NO_READ_FROM_CODER
MY_UNKNOWN_IMP4( MY_UNKNOWN_IMP5(
ICompressCoder,
ICompressGetInStreamProcessedSize, ICompressGetInStreamProcessedSize,
ICompressSetInStream, ICompressSetInStream,
ICompressSetOutStreamSize, ICompressSetOutStreamSize,
ISequentialInStream ISequentialInStream
) )
#else #else
MY_UNKNOWN_IMP1( MY_UNKNOWN_IMP2(
ICompressCoder,
ICompressGetInStreamProcessedSize) ICompressGetInStreamProcessedSize)
#endif #endif

View File

@@ -190,7 +190,7 @@ class CCOMCoder :
public CCoder public CCoder
{ {
public: public:
MY_UNKNOWN_IMP1(ICompressSetCoderProperties) MY_UNKNOWN_IMP2(ICompressCoder, ICompressSetCoderProperties)
CCOMCoder(): CCoder(false) {}; CCOMCoder(): CCoder(false) {};
STDMETHOD(Code)(ISequentialInStream *inStream, ISequentialOutStream *outStream, STDMETHOD(Code)(ISequentialInStream *inStream, ISequentialOutStream *outStream,
const UInt64 *inSize, const UInt64 *outSize, ICompressProgressInfo *progress); const UInt64 *inSize, const UInt64 *outSize, ICompressProgressInfo *progress);
@@ -204,7 +204,7 @@ class CCOMCoder64 :
public CCoder public CCoder
{ {
public: public:
MY_UNKNOWN_IMP1(ICompressSetCoderProperties) MY_UNKNOWN_IMP2(ICompressCoder, ICompressSetCoderProperties)
CCOMCoder64(): CCoder(true) {}; CCOMCoder64(): CCoder(true) {};
STDMETHOD(Code)(ISequentialInStream *inStream, ISequentialOutStream *outStream, STDMETHOD(Code)(ISequentialInStream *inStream, ISequentialOutStream *outStream,
const UInt64 *inSize, const UInt64 *outSize, ICompressProgressInfo *progress); const UInt64 *inSize, const UInt64 *outSize, ICompressProgressInfo *progress);

View File

@@ -5,14 +5,21 @@
#include "../Common/RegisterCodec.h" #include "../Common/RegisterCodec.h"
#include "DeflateDecoder.h" #include "DeflateDecoder.h"
REGISTER_CODEC_CREATE(CreateDec, NCompress::NDeflate::NDecoder::CCOMCoder)
#if !defined(EXTRACT_ONLY) && !defined(DEFLATE_EXTRACT_ONLY) #if !defined(EXTRACT_ONLY) && !defined(DEFLATE_EXTRACT_ONLY)
#include "DeflateEncoder.h" #include "DeflateEncoder.h"
REGISTER_CODEC_CREATE(CreateEnc, NCompress::NDeflate::NEncoder::CCOMCoder) #endif
namespace NCompress {
namespace NDeflate {
REGISTER_CODEC_CREATE(CreateDec, NDecoder::CCOMCoder)
#if !defined(EXTRACT_ONLY) && !defined(DEFLATE_EXTRACT_ONLY)
REGISTER_CODEC_CREATE(CreateEnc, NEncoder::CCOMCoder)
#else #else
#define CreateEnc NULL #define CreateEnc NULL
#endif #endif
REGISTER_CODEC_2(Deflate, CreateDec, CreateEnc, 0x40108, "Deflate") REGISTER_CODEC_2(Deflate, CreateDec, CreateEnc, 0x40108, "Deflate")
}}

View File

@@ -10,6 +10,9 @@
#include "../Common/RegisterCodec.h" #include "../Common/RegisterCodec.h"
namespace NCompress {
namespace NDelta {
struct CDelta struct CDelta
{ {
unsigned _delta; unsigned _delta;
@@ -22,7 +25,7 @@ struct CDelta
#ifndef EXTRACT_ONLY #ifndef EXTRACT_ONLY
class CDeltaEncoder: class CEncoder:
public ICompressFilter, public ICompressFilter,
public ICompressSetCoderProperties, public ICompressSetCoderProperties,
public ICompressWriteCoderProperties, public ICompressWriteCoderProperties,
@@ -30,25 +33,25 @@ class CDeltaEncoder:
public CMyUnknownImp public CMyUnknownImp
{ {
public: public:
MY_UNKNOWN_IMP2(ICompressSetCoderProperties, ICompressWriteCoderProperties) MY_UNKNOWN_IMP3(ICompressFilter, ICompressSetCoderProperties, ICompressWriteCoderProperties)
INTERFACE_ICompressFilter(;) INTERFACE_ICompressFilter(;)
STDMETHOD(SetCoderProperties)(const PROPID *propIDs, const PROPVARIANT *props, UInt32 numProps); STDMETHOD(SetCoderProperties)(const PROPID *propIDs, const PROPVARIANT *props, UInt32 numProps);
STDMETHOD(WriteCoderProperties)(ISequentialOutStream *outStream); STDMETHOD(WriteCoderProperties)(ISequentialOutStream *outStream);
}; };
STDMETHODIMP CDeltaEncoder::Init() STDMETHODIMP CEncoder::Init()
{ {
DeltaInit(); DeltaInit();
return S_OK; return S_OK;
} }
STDMETHODIMP_(UInt32) CDeltaEncoder::Filter(Byte *data, UInt32 size) STDMETHODIMP_(UInt32) CEncoder::Filter(Byte *data, UInt32 size)
{ {
Delta_Encode(_state, _delta, data, size); Delta_Encode(_state, _delta, data, size);
return size; return size;
} }
STDMETHODIMP CDeltaEncoder::SetCoderProperties(const PROPID *propIDs, const PROPVARIANT *props, UInt32 numProps) STDMETHODIMP CEncoder::SetCoderProperties(const PROPID *propIDs, const PROPVARIANT *props, UInt32 numProps)
{ {
UInt32 delta = _delta; UInt32 delta = _delta;
for (UInt32 i = 0; i < numProps; i++) for (UInt32 i = 0; i < numProps; i++)
@@ -75,7 +78,7 @@ STDMETHODIMP CDeltaEncoder::SetCoderProperties(const PROPID *propIDs, const PROP
return S_OK; return S_OK;
} }
STDMETHODIMP CDeltaEncoder::WriteCoderProperties(ISequentialOutStream *outStream) STDMETHODIMP CEncoder::WriteCoderProperties(ISequentialOutStream *outStream)
{ {
Byte prop = (Byte)(_delta - 1); Byte prop = (Byte)(_delta - 1);
return outStream->Write(&prop, 1, NULL); return outStream->Write(&prop, 1, NULL);
@@ -84,31 +87,31 @@ STDMETHODIMP CDeltaEncoder::WriteCoderProperties(ISequentialOutStream *outStream
#endif #endif
class CDeltaDecoder: class CDecoder:
public ICompressFilter, public ICompressFilter,
public ICompressSetDecoderProperties2, public ICompressSetDecoderProperties2,
CDelta, CDelta,
public CMyUnknownImp public CMyUnknownImp
{ {
public: public:
MY_UNKNOWN_IMP1(ICompressSetDecoderProperties2) MY_UNKNOWN_IMP2(ICompressFilter, ICompressSetDecoderProperties2)
INTERFACE_ICompressFilter(;) INTERFACE_ICompressFilter(;)
STDMETHOD(SetDecoderProperties2)(const Byte *data, UInt32 size); STDMETHOD(SetDecoderProperties2)(const Byte *data, UInt32 size);
}; };
STDMETHODIMP CDeltaDecoder::Init() STDMETHODIMP CDecoder::Init()
{ {
DeltaInit(); DeltaInit();
return S_OK; return S_OK;
} }
STDMETHODIMP_(UInt32) CDeltaDecoder::Filter(Byte *data, UInt32 size) STDMETHODIMP_(UInt32) CDecoder::Filter(Byte *data, UInt32 size)
{ {
Delta_Decode(_state, _delta, data, size); Delta_Decode(_state, _delta, data, size);
return size; return size;
} }
STDMETHODIMP CDeltaDecoder::SetDecoderProperties2(const Byte *props, UInt32 size) STDMETHODIMP CDecoder::SetDecoderProperties2(const Byte *props, UInt32 size)
{ {
if (size != 1) if (size != 1)
return E_INVALIDARG; return E_INVALIDARG;
@@ -118,6 +121,8 @@ STDMETHODIMP CDeltaDecoder::SetDecoderProperties2(const Byte *props, UInt32 size
REGISTER_FILTER_E(Delta, REGISTER_FILTER_E(Delta,
CDeltaDecoder(), CDecoder(),
CDeltaEncoder(), CEncoder(),
3, "Delta") 3, "Delta")
}}

View File

@@ -20,7 +20,7 @@ class CEncoder:
{ {
CLzma2EncHandle _encoder; CLzma2EncHandle _encoder;
public: public:
MY_UNKNOWN_IMP2(ICompressSetCoderProperties, ICompressWriteCoderProperties) MY_UNKNOWN_IMP3(ICompressCoder, ICompressSetCoderProperties, ICompressWriteCoderProperties)
STDMETHOD(Code)(ISequentialInStream *inStream, ISequentialOutStream *outStream, STDMETHOD(Code)(ISequentialInStream *inStream, ISequentialOutStream *outStream,
const UInt64 *inSize, const UInt64 *outSize, ICompressProgressInfo *progress); const UInt64 *inSize, const UInt64 *outSize, ICompressProgressInfo *progress);

View File

@@ -10,8 +10,13 @@
#include "Lzma2Encoder.h" #include "Lzma2Encoder.h"
#endif #endif
namespace NCompress {
namespace NLzma2 {
REGISTER_CODEC_E(LZMA2, REGISTER_CODEC_E(LZMA2,
NCompress::NLzma2::CDecoder(), CDecoder(),
NCompress::NLzma2::CEncoder(), CEncoder(),
0x21, 0x21,
"LZMA2") "LZMA2")
}}

View File

@@ -21,7 +21,7 @@ class CEncoder:
CLzmaEncHandle _encoder; CLzmaEncHandle _encoder;
UInt64 _inputProcessed; UInt64 _inputProcessed;
public: public:
MY_UNKNOWN_IMP2(ICompressSetCoderProperties, ICompressWriteCoderProperties) MY_UNKNOWN_IMP3(ICompressCoder, ICompressSetCoderProperties, ICompressWriteCoderProperties)
STDMETHOD(Code)(ISequentialInStream *inStream, ISequentialOutStream *outStream, STDMETHOD(Code)(ISequentialInStream *inStream, ISequentialOutStream *outStream,
const UInt64 *inSize, const UInt64 *outSize, ICompressProgressInfo *progress); const UInt64 *inSize, const UInt64 *outSize, ICompressProgressInfo *progress);

View File

@@ -10,8 +10,13 @@
#include "LzmaEncoder.h" #include "LzmaEncoder.h"
#endif #endif
namespace NCompress {
namespace NLzma {
REGISTER_CODEC_E(LZMA, REGISTER_CODEC_E(LZMA,
NCompress::NLzma::CDecoder(), CDecoder(),
NCompress::NLzma::CEncoder(), CEncoder(),
0x30101, 0x30101,
"LZMA") "LZMA")
}}

View File

@@ -41,7 +41,8 @@ class CEncoder :
CPpmd7 _ppmd; CPpmd7 _ppmd;
CEncProps _props; CEncProps _props;
public: public:
MY_UNKNOWN_IMP2( MY_UNKNOWN_IMP3(
ICompressCoder,
ICompressSetCoderProperties, ICompressSetCoderProperties,
ICompressWriteCoderProperties) ICompressWriteCoderProperties)
STDMETHOD(Code)(ISequentialInStream *inStream, ISequentialOutStream *outStream, STDMETHOD(Code)(ISequentialInStream *inStream, ISequentialOutStream *outStream,

View File

@@ -10,8 +10,13 @@
#include "PpmdEncoder.h" #include "PpmdEncoder.h"
#endif #endif
namespace NCompress {
namespace NPpmd {
REGISTER_CODEC_E(PPMD, REGISTER_CODEC_E(PPMD,
NCompress::NPpmd::CDecoder(), CDecoder(),
NCompress::NPpmd::CEncoder(), CEncoder(),
0x30401, 0x30401,
"PPMD") "PPMD")
}}

View File

@@ -154,7 +154,7 @@ HRESULT CDecoder::WriteBuf()
FOR_VECTOR (i, _tempFilters) FOR_VECTOR (i, _tempFilters)
{ {
CTempFilter *filter = _tempFilters[i]; CTempFilter *filter = _tempFilters[i];
if (filter == NULL) if (!filter)
continue; continue;
if (filter->NextWindow) if (filter->NextWindow)
{ {
@@ -187,8 +187,10 @@ HRESULT CDecoder::WriteBuf()
while (i + 1 < _tempFilters.Size()) while (i + 1 < _tempFilters.Size())
{ {
CTempFilter *nextFilter = _tempFilters[i + 1]; CTempFilter *nextFilter = _tempFilters[i + 1];
if (nextFilter == NULL || nextFilter->BlockStart != blockStart || if (!nextFilter
nextFilter->BlockSize != outBlockRef.Size || nextFilter->NextWindow) || nextFilter->BlockStart != blockStart
|| nextFilter->BlockSize != outBlockRef.Size
|| nextFilter->NextWindow)
break; break;
_vm.SetMemory(0, _vm.GetDataPointer(outBlockRef.Offset), outBlockRef.Size); _vm.SetMemory(0, _vm.GetDataPointer(outBlockRef.Offset), outBlockRef.Size);
ExecuteFilter(++i, outBlockRef); ExecuteFilter(++i, outBlockRef);
@@ -203,7 +205,7 @@ HRESULT CDecoder::WriteBuf()
for (unsigned j = i; j < _tempFilters.Size(); j++) for (unsigned j = i; j < _tempFilters.Size(); j++)
{ {
CTempFilter *filter = _tempFilters[j]; CTempFilter *filter = _tempFilters[j];
if (filter != NULL && filter->NextWindow) if (filter && filter->NextWindow)
filter->NextWindow = false; filter->NextWindow = false;
} }
_wrPtr = writtenBorder; _wrPtr = writtenBorder;
@@ -273,7 +275,7 @@ bool CDecoder::AddVmCode(UInt32 firstByte, UInt32 codeSize)
for (i = 0; i < _tempFilters.Size(); i++) for (i = 0; i < _tempFilters.Size(); i++)
{ {
_tempFilters[i - numEmptyItems] = _tempFilters[i]; _tempFilters[i - numEmptyItems] = _tempFilters[i];
if (_tempFilters[i] == NULL) if (!_tempFilters[i])
numEmptyItems++; numEmptyItems++;
if (numEmptyItems > 0) if (numEmptyItems > 0)
_tempFilters[i] = NULL; _tempFilters[i] = NULL;
@@ -865,21 +867,21 @@ STDMETHODIMP CDecoder::Code(ISequentialInStream *inStream, ISequentialOutStream
{ {
try try
{ {
if (inSize == NULL || outSize == NULL) if (!inSize)
return E_INVALIDARG; return E_INVALIDARG;
if (_vmData == 0) if (!_vmData)
{ {
_vmData = (Byte *)::MidAlloc(kVmDataSizeMax + kVmCodeSizeMax); _vmData = (Byte *)::MidAlloc(kVmDataSizeMax + kVmCodeSizeMax);
if (_vmData == 0) if (!_vmData)
return E_OUTOFMEMORY; return E_OUTOFMEMORY;
_vmCode = _vmData + kVmDataSizeMax; _vmCode = _vmData + kVmDataSizeMax;
} }
if (_window == 0) if (!_window)
{ {
_window = (Byte *)::MidAlloc(kWindowSize); _window = (Byte *)::MidAlloc(kWindowSize);
if (_window == 0) if (!_window)
return E_OUTOFMEMORY; return E_OUTOFMEMORY;
} }
if (!m_InBitStream.BitDecoder.Create(1 << 20)) if (!m_InBitStream.BitDecoder.Create(1 << 20))
@@ -893,7 +895,7 @@ STDMETHODIMP CDecoder::Code(ISequentialInStream *inStream, ISequentialOutStream
_outStream = outStream; _outStream = outStream;
// CCoderReleaser coderReleaser(this); // CCoderReleaser coderReleaser(this);
_unpackSize = *outSize; _unpackSize = outSize ? *outSize : (UInt64)(Int64)-1;
return CodeReal(progress); return CodeReal(progress);
} }
catch(const CInBufferException &e) { return e.ErrorCode; } catch(const CInBufferException &e) { return e.ErrorCode; }

View File

@@ -9,7 +9,9 @@
#include "Rar3Decoder.h" #include "Rar3Decoder.h"
#include "Rar5Decoder.h" #include "Rar5Decoder.h"
#define CREATE_CODEC(x) REGISTER_CODEC_CREATE(CreateCodec ## x, NCompress::NRar ## x::CDecoder()) namespace NCompress {
#define CREATE_CODEC(x) REGISTER_CODEC_CREATE(CreateCodec ## x, NRar ## x::CDecoder())
CREATE_CODEC(1) CREATE_CODEC(1)
CREATE_CODEC(2) CREATE_CODEC(2)
@@ -27,3 +29,5 @@ REGISTER_CODECS_VAR
}; };
REGISTER_CODECS(Rar) REGISTER_CODECS(Rar)
}

View File

@@ -1,7 +1,10 @@
// ShrinkDecoder.cpp // ShrinkDecoder.cpp
#include "StdAfx.h" #include "StdAfx.h"
#include <stdio.h>
#include "../../../C/Alloc.h" #include "../../../C/Alloc.h"
#include "../Common/InBuffer.h" #include "../Common/InBuffer.h"
@@ -13,8 +16,8 @@
namespace NCompress { namespace NCompress {
namespace NShrink { namespace NShrink {
static const UInt32 kBufferSize = (1 << 20); static const UInt32 kBufferSize = (1 << 18);
static const int kNumMinBits = 9; static const unsigned kNumMinBits = 9;
HRESULT CDecoder::CodeReal(ISequentialInStream *inStream, ISequentialOutStream *outStream, HRESULT CDecoder::CodeReal(ISequentialInStream *inStream, ISequentialOutStream *outStream,
const UInt64 * /* inSize */, const UInt64 * /* outSize */, ICompressProgressInfo *progress) const UInt64 * /* inSize */, const UInt64 * /* outSize */, ICompressProgressInfo *progress)
@@ -32,109 +35,121 @@ HRESULT CDecoder::CodeReal(ISequentialInStream *inStream, ISequentialOutStream *
outBuffer.SetStream(outStream); outBuffer.SetStream(outStream);
outBuffer.Init(); outBuffer.Init();
UInt64 prevPos = 0; {
int numBits = kNumMinBits; unsigned i;
UInt32 head = 257; for (i = 0; i < 257; i++)
bool needPrev = false; _parents[i] = (UInt16)i;
UInt32 lastSymbol = 0; for (; i < kNumItems; i++)
_parents[i] = kNumItems;
for (i = 0; i < kNumItems; i++)
_suffixes[i] = 0;
}
int i; UInt64 prevPos = 0;
for (i = 0; i < kNumItems; i++) unsigned numBits = kNumMinBits;
_parents[i] = 0; unsigned head = 257;
for (i = 0; i < kNumItems; i++) int lastSym = -1;
_suffixes[i] = 0; Byte lastChar2 = 0;
for (i = 0; i < 257; i++)
_isFree[i] = false;
for (; i < kNumItems; i++)
_isFree[i] = true;
for (;;) for (;;)
{ {
UInt32 symbol = inBuffer.ReadBits(numBits); UInt32 sym = inBuffer.ReadBits(numBits);
if (inBuffer.ExtraBitsWereRead()) if (inBuffer.ExtraBitsWereRead())
break; break;
if (_isFree[symbol])
return S_FALSE; if (sym == 256)
if (symbol == 256)
{ {
UInt32 symbol = inBuffer.ReadBits(numBits); sym = inBuffer.ReadBits(numBits);
if (symbol == 1) if (sym == 1)
{ {
if (numBits < kNumMaxBits) if (numBits >= kNumMaxBits)
numBits++; return S_FALSE;
numBits++;
continue;
} }
else if (symbol == 2) if (sym != 2)
{
if (needPrev)
_isFree[head - 1] = true;
for (i = 257; i < kNumItems; i++)
_isParent[i] = false;
for (i = 257; i < kNumItems; i++)
if (!_isFree[i])
_isParent[_parents[i]] = true;
for (i = 257; i < kNumItems; i++)
if (!_isParent[i])
_isFree[i] = true;
head = 257;
while (head < kNumItems && !_isFree[head])
head++;
if (head < kNumItems)
{
needPrev = true;
_isFree[head] = false;
_parents[head] = (UInt16)lastSymbol;
head++;
}
}
else
return S_FALSE; return S_FALSE;
continue; {
unsigned i;
for (i = 257; i < kNumItems; i++)
_stack[i] = 0;
for (i = 257; i < kNumItems; i++)
{
unsigned par = _parents[i];
if (par != kNumItems)
_stack[par] = 1;
}
for (i = 257; i < kNumItems; i++)
if (_stack[i] == 0)
_parents[i] = kNumItems;
head = 257;
continue;
}
} }
UInt32 cur = symbol;
i = 0; bool needPrev = false;
int corectionIndex = -1; if (head < kNumItems && lastSym >= 0)
{
while (head < kNumItems && _parents[head] != kNumItems)
head++;
if (head < kNumItems)
{
if (head == (unsigned)lastSym)
{
// we need to fix the code for that case
// _parents[head] is not allowed to link to itself
return E_NOTIMPL;
}
needPrev = true;
_parents[head] = (UInt16)lastSym;
_suffixes[head] = (Byte)lastChar2;
head++;
}
}
if (_parents[sym] == kNumItems)
return S_FALSE;
lastSym = sym;
unsigned cur = sym;
unsigned i = 0;
while (cur >= 256) while (cur >= 256)
{ {
if (cur == head - 1)
corectionIndex = i;
_stack[i++] = _suffixes[cur]; _stack[i++] = _suffixes[cur];
cur = _parents[cur]; cur = _parents[cur];
} }
_stack[i++] = (Byte)cur; _stack[i++] = (Byte)cur;
if (needPrev) lastChar2 = (Byte)cur;
{
_suffixes[head - 1] = (Byte)cur;
if (corectionIndex >= 0)
_stack[corectionIndex] = (Byte)cur;
}
while (i > 0)
outBuffer.WriteByte((_stack[--i]));
while (head < kNumItems && !_isFree[head])
head++;
if (head < kNumItems)
{
needPrev = true;
_isFree[head] = false;
_parents[head] = (UInt16)symbol;
head++;
}
else
needPrev = false;
lastSymbol = symbol;
UInt64 nowPos = outBuffer.GetProcessedSize(); if (needPrev)
if (progress != NULL && nowPos - prevPos > (1 << 18)) _suffixes[head - 1] = (Byte)cur;
do
outBuffer.WriteByte(_stack[--i]);
while (i);
if (progress)
{ {
prevPos = nowPos; const UInt64 nowPos = outBuffer.GetProcessedSize();
UInt64 packSize = inBuffer.GetProcessedSize(); if (nowPos - prevPos >= (1 << 18))
RINOK(progress->SetRatioInfo(&packSize, &nowPos)); {
prevPos = nowPos;
const UInt64 packSize = inBuffer.GetProcessedSize();
RINOK(progress->SetRatioInfo(&packSize, &nowPos));
}
} }
} }
return outBuffer.Flush(); return outBuffer.Flush();
} }
STDMETHODIMP CDecoder ::Code(ISequentialInStream *inStream, ISequentialOutStream *outStream, STDMETHODIMP CDecoder ::Code(ISequentialInStream *inStream, ISequentialOutStream *outStream,
const UInt64 *inSize, const UInt64 *outSize, ICompressProgressInfo *progress) const UInt64 *inSize, const UInt64 *outSize, ICompressProgressInfo *progress)
{ {
try { return CodeReal(inStream, outStream, inSize, outSize, progress); } try { return CodeReal(inStream, outStream, inSize, outSize, progress); }
catch(const CInBufferException &e) { return e.ErrorCode; } catch(const CInBufferException &e) { return e.ErrorCode; }

View File

@@ -10,8 +10,8 @@
namespace NCompress { namespace NCompress {
namespace NShrink { namespace NShrink {
const int kNumMaxBits = 13; const unsigned kNumMaxBits = 13;
const UInt32 kNumItems = 1 << kNumMaxBits; const unsigned kNumItems = 1 << kNumMaxBits;
class CDecoder : class CDecoder :
public ICompressCoder, public ICompressCoder,
@@ -20,8 +20,6 @@ class CDecoder :
UInt16 _parents[kNumItems]; UInt16 _parents[kNumItems];
Byte _suffixes[kNumItems]; Byte _suffixes[kNumItems];
Byte _stack[kNumItems]; Byte _stack[kNumItems];
bool _isFree[kNumItems];
bool _isParent[kNumItems];
public: public:
MY_UNKNOWN_IMP MY_UNKNOWN_IMP

View File

@@ -86,7 +86,8 @@ class CEncoder:
public ICryptoResetInitVector public ICryptoResetInitVector
{ {
public: public:
MY_UNKNOWN_IMP3( MY_UNKNOWN_IMP4(
ICompressFilter,
ICryptoSetPassword, ICryptoSetPassword,
ICompressWriteCoderProperties, ICompressWriteCoderProperties,
// ICryptoResetSalt, // ICryptoResetSalt,
@@ -104,7 +105,8 @@ class CDecoder:
public ICompressSetDecoderProperties2 public ICompressSetDecoderProperties2
{ {
public: public:
MY_UNKNOWN_IMP2( MY_UNKNOWN_IMP3(
ICompressFilter,
ICryptoSetPassword, ICryptoSetPassword,
ICompressSetDecoderProperties2) ICompressSetDecoderProperties2)
STDMETHOD(SetDecoderProperties2)(const Byte *data, UInt32 size); STDMETHOD(SetDecoderProperties2)(const Byte *data, UInt32 size);

View File

@@ -6,7 +6,12 @@
#include "7zAes.h" #include "7zAes.h"
namespace NCrypto {
namespace N7z {
REGISTER_FILTER_E(7zAES, REGISTER_FILTER_E(7zAES,
NCrypto::N7z::CDecoder(), CDecoder(),
NCrypto::N7z::CEncoder(), CEncoder(),
0x6F10701, "7zAES") 0x6F10701, "7zAES")
}}

View File

@@ -30,7 +30,7 @@ class CAesCbcCoder:
public: public:
CAesCbcCoder(bool encodeMode, unsigned keySize); CAesCbcCoder(bool encodeMode, unsigned keySize);
MY_UNKNOWN_IMP2(ICryptoProperties, ICompressSetCoderProperties) MY_UNKNOWN_IMP3(ICompressFilter, ICryptoProperties, ICompressSetCoderProperties)
INTERFACE_ICompressFilter(;) INTERFACE_ICompressFilter(;)

View File

@@ -6,7 +6,11 @@
#include "MyAes.h" #include "MyAes.h"
namespace NCrypto {
REGISTER_FILTER_E(AES256CBC, REGISTER_FILTER_E(AES256CBC,
NCrypto::CAesCbcDecoder(32), CAesCbcDecoder(32),
NCrypto::CAesCbcEncoder(32), CAesCbcEncoder(32),
0x6F00181, "AES256CBC") 0x6F00181, "AES256CBC")
}

View File

@@ -73,8 +73,10 @@ void CRandomGenerator::Init()
HASH_UPD(v2); HASH_UPD(v2);
#endif #endif
#ifdef _WIN32
DWORD tickCount = ::GetTickCount(); DWORD tickCount = ::GetTickCount();
HASH_UPD(tickCount); HASH_UPD(tickCount);
#endif
for (unsigned j = 0; j < 100; j++) for (unsigned j = 0; j < 100; j++)
{ {

View File

@@ -112,25 +112,87 @@ HRESULT CDecoder::Init_and_CheckPassword(bool &passwOK)
if (algId * 64 + 128 != bitLen) if (algId * 64 + 128 != bitLen)
return E_NOTIMPL; return E_NOTIMPL;
_key.KeySize = 16 + algId * 8; _key.KeySize = 16 + algId * 8;
if ((flags & 1) == 0) bool cert = ((flags & 2) != 0);
return E_NOTIMPL;
if ((flags & 0x4000) != 0) if ((flags & 0x4000) != 0)
{ {
// Use 3DES // Use 3DES
return E_NOTIMPL; return E_NOTIMPL;
} }
if (cert)
{
return E_NOTIMPL;
}
else
{
if ((flags & 1) == 0)
return E_NOTIMPL;
}
UInt32 rdSize = GetUi16(p + 8); UInt32 rdSize = GetUi16(p + 8);
if ((rdSize & 0xF) != 0 || rdSize + 16 > _remSize)
return E_NOTIMPL; if (rdSize + 16 > _remSize)
memmove(p, p + 10, rdSize);
Byte *validData = p + rdSize + 16;
if (GetUi32(validData - 6) != 0) // reserved
return E_NOTIMPL;
UInt32 validSize = GetUi16(validData - 2);
if ((validSize & 0xF) != 0 || 16 + rdSize + validSize != _remSize)
return E_NOTIMPL; return E_NOTIMPL;
/*
if (cert)
{
// how to filter rd, if ((rdSize & 0xF) != 0) ?
/*
if ((rdSize & 0x7) != 0)
return E_NOTIMPL;
}
else
*/
{
if ((rdSize & 0xF) != 0)
return E_NOTIMPL;
}
memmove(p, p + 10, rdSize);
const Byte *p2 = p + rdSize + 10;
UInt32 reserved = GetUi32(p2);
p2 += 4;
/*
if (cert)
{
UInt32 numRecipients = reserved;
if (numRecipients == 0)
return E_NOTIMPL;
{
UInt32 hashAlg = GetUi16(p2);
hashAlg = hashAlg;
UInt32 hashSize = GetUi16(p2 + 2);
hashSize = hashSize;
p2 += 4;
reserved = reserved;
// return E_NOTIMPL;
for (unsigned r = 0; r < numRecipients; r++)
{
UInt32 specSize = GetUi16(p2);
p2 += 2;
p2 += specSize;
}
}
}
else
*/
{
if (reserved != 0)
return E_NOTIMPL;
}
UInt32 validSize = GetUi16(p2);
p2 += 2;
const size_t validOffset = p2 - p;
if ((validSize & 0xF) != 0 || validOffset + validSize != _remSize)
return E_NOTIMPL;
{ {
RINOK(SetKey(_key.MasterKey, _key.KeySize)); RINOK(SetKey(_key.MasterKey, _key.KeySize));
@@ -149,12 +211,14 @@ HRESULT CDecoder::Init_and_CheckPassword(bool &passwOK)
RINOK(SetKey(fileKey, _key.KeySize)); RINOK(SetKey(fileKey, _key.KeySize));
RINOK(SetInitVector(_iv, 16)); RINOK(SetInitVector(_iv, 16));
Init(); Init();
Filter(validData, validSize);
memmove(p, p + validOffset, validSize);
Filter(p, validSize);
if (validSize < 4) if (validSize < 4)
return E_NOTIMPL; return E_NOTIMPL;
validSize -= 4; validSize -= 4;
if (GetUi32(validData + validSize) != CrcCalc(validData, validSize)) if (GetUi32(p + validSize) != CrcCalc(p, validSize))
return S_OK; return S_OK;
passwOK = true; passwOK = true;
return S_OK; return S_OK;

Some files were not shown because too many files have changed in this diff Show More