Welcome to mirror list, hosted at ThFree Co, Russian Federation.

github.com/kornelski/7z.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorIgor Pavlov <ipavlov@users.sourceforge.net>2021-07-23 01:00:14 +0300
committerKornel <kornel@geekhood.net>2021-07-23 01:00:14 +0300
commit585698650f7257d2cefa6a3a2a49d5bbe84fd9b2 (patch)
tree8900be42e892a440bbd1063804b0557288c2f97f /CPP/7zip/Archive
parent4a960640a340a848a2d2c27f19b339c2c3d3f734 (diff)
21.0221.02
Diffstat (limited to 'CPP/7zip/Archive')
-rw-r--r--CPP/7zip/Archive/7z/7zCompressionMode.h10
-rw-r--r--CPP/7zip/Archive/7z/7zDecode.cpp50
-rw-r--r--CPP/7zip/Archive/7z/7zEncode.cpp17
-rw-r--r--CPP/7zip/Archive/7z/7zEncode.h2
-rw-r--r--CPP/7zip/Archive/7z/7zExtract.cpp9
-rw-r--r--CPP/7zip/Archive/7z/7zHandler.cpp91
-rw-r--r--CPP/7zip/Archive/7z/7zHandler.h6
-rw-r--r--CPP/7zip/Archive/7z/7zHandlerOut.cpp66
-rw-r--r--CPP/7zip/Archive/7z/7zHeader.h5
-rw-r--r--CPP/7zip/Archive/7z/7zIn.cpp84
-rw-r--r--CPP/7zip/Archive/7z/7zIn.h14
-rw-r--r--CPP/7zip/Archive/7z/7zItem.h4
-rw-r--r--CPP/7zip/Archive/7z/7zOut.cpp86
-rw-r--r--CPP/7zip/Archive/7z/7zUpdate.cpp78
-rw-r--r--CPP/7zip/Archive/7z/7zUpdate.h2
-rw-r--r--CPP/7zip/Archive/ApmHandler.cpp2
-rw-r--r--CPP/7zip/Archive/ArHandler.cpp6
-rw-r--r--CPP/7zip/Archive/ArchiveExports.cpp7
-rw-r--r--CPP/7zip/Archive/ArjHandler.cpp114
-rw-r--r--CPP/7zip/Archive/Base64Handler.cpp511
-rw-r--r--CPP/7zip/Archive/Cab/CabHandler.cpp37
-rw-r--r--CPP/7zip/Archive/Cab/CabIn.cpp6
-rw-r--r--CPP/7zip/Archive/Cab/CabIn.h2
-rw-r--r--CPP/7zip/Archive/Cab/CabItem.h4
-rw-r--r--CPP/7zip/Archive/Chm/ChmHandler.cpp2
-rw-r--r--CPP/7zip/Archive/Chm/ChmIn.cpp3
-rw-r--r--CPP/7zip/Archive/ComHandler.cpp23
-rw-r--r--CPP/7zip/Archive/Common/CoderMixer2.cpp97
-rw-r--r--CPP/7zip/Archive/Common/CoderMixer2.h20
-rw-r--r--CPP/7zip/Archive/Common/HandlerOut.cpp4
-rw-r--r--CPP/7zip/Archive/Common/ItemNameUtils.cpp48
-rw-r--r--CPP/7zip/Archive/Common/ItemNameUtils.h2
-rw-r--r--CPP/7zip/Archive/Common/MultiStream.cpp6
-rw-r--r--CPP/7zip/Archive/Common/OutStreamWithSha1.cpp2
-rw-r--r--CPP/7zip/Archive/Common/OutStreamWithSha1.h15
-rw-r--r--CPP/7zip/Archive/CpioHandler.cpp50
-rw-r--r--CPP/7zip/Archive/DllExports2.cpp41
-rw-r--r--CPP/7zip/Archive/DmgHandler.cpp117
-rw-r--r--CPP/7zip/Archive/ElfHandler.cpp11
-rw-r--r--CPP/7zip/Archive/ExtHandler.cpp27
-rw-r--r--CPP/7zip/Archive/FatHandler.cpp2
-rw-r--r--CPP/7zip/Archive/FlvHandler.cpp4
-rw-r--r--CPP/7zip/Archive/GptHandler.cpp23
-rw-r--r--CPP/7zip/Archive/GzHandler.cpp13
-rw-r--r--CPP/7zip/Archive/HandlerCont.cpp2
-rw-r--r--CPP/7zip/Archive/HfsHandler.cpp140
-rw-r--r--CPP/7zip/Archive/IArchive.h35
-rw-r--r--CPP/7zip/Archive/IhexHandler.cpp4
-rw-r--r--CPP/7zip/Archive/Iso/IsoHandler.cpp6
-rw-r--r--CPP/7zip/Archive/Iso/IsoIn.cpp2
-rw-r--r--CPP/7zip/Archive/Iso/IsoItem.h8
-rw-r--r--CPP/7zip/Archive/LzhHandler.cpp26
-rw-r--r--CPP/7zip/Archive/LzmaHandler.cpp21
-rw-r--r--CPP/7zip/Archive/MachoHandler.cpp4
-rw-r--r--CPP/7zip/Archive/MbrHandler.cpp2
-rw-r--r--CPP/7zip/Archive/MubHandler.cpp13
-rw-r--r--CPP/7zip/Archive/Nsis/NsisHandler.cpp2
-rw-r--r--CPP/7zip/Archive/Nsis/NsisIn.cpp249
-rw-r--r--CPP/7zip/Archive/Nsis/NsisIn.h13
-rw-r--r--CPP/7zip/Archive/NtfsHandler.cpp22
-rw-r--r--CPP/7zip/Archive/PeHandler.cpp26
-rw-r--r--CPP/7zip/Archive/PpmdHandler.cpp99
-rw-r--r--CPP/7zip/Archive/QcowHandler.cpp215
-rw-r--r--CPP/7zip/Archive/Rar/Rar5Handler.cpp50
-rw-r--r--CPP/7zip/Archive/Rar/RarHandler.cpp62
-rw-r--r--CPP/7zip/Archive/Rar/RarHandler.h2
-rw-r--r--CPP/7zip/Archive/SplitHandler.cpp4
-rw-r--r--CPP/7zip/Archive/SquashfsHandler.cpp45
-rw-r--r--CPP/7zip/Archive/SwfHandler.cpp12
-rw-r--r--CPP/7zip/Archive/Tar/TarHandler.cpp118
-rw-r--r--CPP/7zip/Archive/Tar/TarHandler.h2
-rw-r--r--CPP/7zip/Archive/Tar/TarHandlerOut.cpp31
-rw-r--r--CPP/7zip/Archive/Tar/TarHeader.h1
-rw-r--r--CPP/7zip/Archive/Tar/TarIn.cpp38
-rw-r--r--CPP/7zip/Archive/Tar/TarItem.h47
-rw-r--r--CPP/7zip/Archive/Tar/TarOut.cpp2
-rw-r--r--CPP/7zip/Archive/Tar/TarUpdate.cpp21
-rw-r--r--CPP/7zip/Archive/Tar/TarUpdate.h7
-rw-r--r--CPP/7zip/Archive/Udf/UdfIn.cpp8
-rw-r--r--CPP/7zip/Archive/Udf/UdfIn.h2
-rw-r--r--CPP/7zip/Archive/UefiHandler.cpp30
-rw-r--r--CPP/7zip/Archive/VdiHandler.cpp7
-rw-r--r--CPP/7zip/Archive/VhdHandler.cpp8
-rw-r--r--CPP/7zip/Archive/VmdkHandler.cpp6
-rw-r--r--CPP/7zip/Archive/Wim/WimHandler.cpp2
-rw-r--r--CPP/7zip/Archive/Wim/WimHandlerOut.cpp58
-rw-r--r--CPP/7zip/Archive/Wim/WimIn.cpp21
-rw-r--r--CPP/7zip/Archive/XarHandler.cpp14
-rw-r--r--CPP/7zip/Archive/XzHandler.cpp149
-rw-r--r--CPP/7zip/Archive/Zip/ZipAddCommon.cpp62
-rw-r--r--CPP/7zip/Archive/Zip/ZipAddCommon.h12
-rw-r--r--CPP/7zip/Archive/Zip/ZipCompressionMode.h4
-rw-r--r--CPP/7zip/Archive/Zip/ZipHandler.cpp377
-rw-r--r--CPP/7zip/Archive/Zip/ZipHandler.h4
-rw-r--r--CPP/7zip/Archive/Zip/ZipHandlerOut.cpp60
-rw-r--r--CPP/7zip/Archive/Zip/ZipHeader.h8
-rw-r--r--CPP/7zip/Archive/Zip/ZipIn.cpp351
-rw-r--r--CPP/7zip/Archive/Zip/ZipIn.h28
-rw-r--r--CPP/7zip/Archive/Zip/ZipItem.cpp66
-rw-r--r--CPP/7zip/Archive/Zip/ZipItem.h49
-rw-r--r--CPP/7zip/Archive/Zip/ZipOut.cpp41
-rw-r--r--CPP/7zip/Archive/Zip/ZipOut.h11
-rw-r--r--CPP/7zip/Archive/Zip/ZipUpdate.cpp233
-rw-r--r--CPP/7zip/Archive/Zip/ZipUpdate.h4
104 files changed, 3214 insertions, 1455 deletions
diff --git a/CPP/7zip/Archive/7z/7zCompressionMode.h b/CPP/7zip/Archive/7z/7zCompressionMode.h
index 608293d6..44c90226 100644
--- a/CPP/7zip/Archive/7z/7zCompressionMode.h
+++ b/CPP/7zip/Archive/7z/7zCompressionMode.h
@@ -57,18 +57,20 @@ struct CCompressionMethodMode
#endif
bool PasswordIsDefined;
- UString Password;
+ UString Password; // _Wipe
bool IsEmpty() const { return (Methods.IsEmpty() && !PasswordIsDefined); }
CCompressionMethodMode():
- DefaultMethod_was_Inserted(false),
- Filter_was_Inserted(false),
- PasswordIsDefined(false)
+ DefaultMethod_was_Inserted(false)
+ , Filter_was_Inserted(false)
#ifndef _7ZIP_ST
, NumThreads(1)
, MultiThreadMixer(true)
#endif
+ , PasswordIsDefined(false)
{}
+
+ ~CCompressionMethodMode() { Password.Wipe_and_Empty(); }
};
}}
diff --git a/CPP/7zip/Archive/7z/7zDecode.cpp b/CPP/7zip/Archive/7z/7zDecode.cpp
index 9df531e0..c27c8fbc 100644
--- a/CPP/7zip/Archive/7z/7zDecode.cpp
+++ b/CPP/7zip/Archive/7z/7zDecode.cpp
@@ -158,7 +158,7 @@ STDMETHODIMP CLockedSequentialInStreamMT::Read(void *data, UInt32 size, UInt32 *
if (_pos != _glob->Pos)
{
- RINOK(_glob->Stream->Seek(_pos, STREAM_SEEK_SET, NULL));
+ RINOK(_glob->Stream->Seek((Int64)_pos, STREAM_SEEK_SET, NULL));
_glob->Pos = _pos;
}
@@ -200,7 +200,7 @@ STDMETHODIMP CLockedSequentialInStreamST::Read(void *data, UInt32 size, UInt32 *
{
if (_pos != _glob->Pos)
{
- RINOK(_glob->Stream->Seek(_pos, STREAM_SEEK_SET, NULL));
+ RINOK(_glob->Stream->Seek((Int64)_pos, STREAM_SEEK_SET, NULL));
_glob->Pos = _pos;
}
@@ -276,6 +276,7 @@ HRESULT CDecoder::Decode(
if (!_bindInfoPrev_Defined || !AreBindInfoExEqual(bindInfo, _bindInfoPrev))
{
+ _bindInfoPrev_Defined = false;
_mixerRef.Release();
#ifdef USE_MIXER_MT
@@ -348,7 +349,7 @@ HRESULT CDecoder::Decode(
_bindInfoPrev_Defined = true;
}
- _mixer->ReInit();
+ RINOK(_mixer->ReInit2());
UInt32 packStreamIndex = 0;
UInt32 unpackStreamIndexStart = folders.FoToCoderUnpackSizes[folderIndex];
@@ -396,10 +397,10 @@ HRESULT CDecoder::Decode(
if (setDecoderProperties)
{
const CByteBuffer &props = coderInfo.Props;
- size_t size = props.Size();
- if (size > 0xFFFFFFFF)
+ const UInt32 size32 = (UInt32)props.Size();
+ if (props.Size() != size32)
return E_NOTIMPL;
- HRESULT res = setDecoderProperties->SetDecoderProperties2((const Byte *)props, (UInt32)size);
+ HRESULT res = setDecoderProperties->SetDecoderProperties2((const Byte *)props, size32);
if (res == E_INVALIDARG)
res = E_NOTIMPL;
RINOK(res);
@@ -415,17 +416,17 @@ HRESULT CDecoder::Decode(
isEncrypted = true;
if (!getTextPassword)
return E_NOTIMPL;
- CMyComBSTR passwordBSTR;
+ CMyComBSTR_Wipe passwordBSTR;
RINOK(getTextPassword->CryptoGetTextPassword(&passwordBSTR));
passwordIsDefined = true;
- password.Empty();
+ password.Wipe_and_Empty();
size_t len = 0;
if (passwordBSTR)
{
password = passwordBSTR;
len = password.Len();
}
- CByteBuffer buffer(len * 2);
+ CByteBuffer_Wipe buffer(len * 2);
for (size_t k = 0; k < len; k++)
{
wchar_t c = passwordBSTR[k];
@@ -444,7 +445,7 @@ HRESULT CDecoder::Decode(
if (setFinishMode)
{
finishMode = fullUnpack;
- RINOK(setFinishMode->SetFinishMode(BoolToInt(finishMode)));
+ RINOK(setFinishMode->SetFinishMode(BoolToUInt(finishMode)));
}
}
@@ -487,36 +488,49 @@ HRESULT CDecoder::Decode(
CLockedInStream *lockedInStreamSpec = new CLockedInStream;
CMyComPtr<IUnknown> lockedInStream = lockedInStreamSpec;
- bool needMtLock = false;
+ #ifdef USE_MIXER_MT
+ #ifdef USE_MIXER_ST
+ bool needMtLock = _useMixerMT;
+ #endif
+ #endif
if (folderInfo.PackStreams.Size() > 1)
{
// lockedInStream.Pos = (UInt64)(Int64)-1;
// RINOK(inStream->Seek(0, STREAM_SEEK_CUR, &lockedInStream.Pos));
- RINOK(inStream->Seek(startPos + packPositions[0], STREAM_SEEK_SET, &lockedInStreamSpec->Pos));
+ RINOK(inStream->Seek((Int64)(startPos + packPositions[0]), STREAM_SEEK_SET, &lockedInStreamSpec->Pos));
lockedInStreamSpec->Stream = inStream;
+ #ifdef USE_MIXER_MT
#ifdef USE_MIXER_ST
- if (_mixer->IsThere_ExternalCoder_in_PackTree(_mixer->MainCoderIndex))
- #endif
+ /*
+ For ST-mixer mode:
+ If parallel input stream reading from pack streams is possible,
+ we must use MT-lock for packed streams.
+ Internal decoders in 7-Zip will not read pack streams in parallel in ST-mixer mode.
+ So we force to needMtLock mode only if there is unknown (external) decoder.
+ */
+ if (!needMtLock && _mixer->IsThere_ExternalCoder_in_PackTree(_mixer->MainCoderIndex))
needMtLock = true;
+ #endif
+ #endif
}
for (unsigned j = 0; j < folderInfo.PackStreams.Size(); j++)
{
CMyComPtr<ISequentialInStream> packStream;
- UInt64 packPos = startPos + packPositions[j];
+ const UInt64 packPos = startPos + packPositions[j];
if (folderInfo.PackStreams.Size() == 1)
{
- RINOK(inStream->Seek(packPos, STREAM_SEEK_SET, NULL));
+ RINOK(inStream->Seek((Int64)packPos, STREAM_SEEK_SET, NULL));
packStream = inStream;
}
else
{
#ifdef USE_MIXER_MT
#ifdef USE_MIXER_ST
- if (_useMixerMT || needMtLock)
+ if (needMtLock)
#endif
{
CLockedSequentialInStreamMT *lockedStreamImpSpec = new CLockedSequentialInStreamMT;
@@ -542,7 +556,7 @@ HRESULT CDecoder::Decode(
streamSpec->Init(packPositions[j + 1] - packPositions[j]);
}
- unsigned num = inStreams.Size();
+ const unsigned num = inStreams.Size();
CObjArray<ISequentialInStream *> inStreamPointers(num);
for (i = 0; i < num; i++)
inStreamPointers[i] = inStreams[i];
diff --git a/CPP/7zip/Archive/7z/7zEncode.cpp b/CPP/7zip/Archive/7z/7zEncode.cpp
index 7d8270f9..49963241 100644
--- a/CPP/7zip/Archive/7z/7zEncode.cpp
+++ b/CPP/7zip/Archive/7z/7zEncode.cpp
@@ -158,7 +158,7 @@ HRESULT CEncoder::CreateMixerCoder(
{
RINOK(CreateCoder_Index(
EXTERNAL_CODECS_LOC_VARS
- methodFull.CodecIndex, true, cod));
+ (unsigned)methodFull.CodecIndex, true, cod));
}
else
{
@@ -215,7 +215,7 @@ HRESULT CEncoder::CreateMixerCoder(
if (cryptoSetPassword)
{
const unsigned sizeInBytes = _options.Password.Len() * 2;
- CByteBuffer buffer(sizeInBytes);
+ CByteBuffer_Wipe buffer(sizeInBytes);
for (unsigned i = 0; i < _options.Password.Len(); i++)
{
wchar_t c = _options.Password[i];
@@ -249,11 +249,12 @@ public:
STDMETHODIMP CSequentialOutTempBufferImp2::Write(const void *data, UInt32 size, UInt32 *processed)
{
- if (!_buf->Write(data, size))
+ HRESULT res = _buf->Write_HRESULT(data, size);
+ if (res != S_OK)
{
if (processed)
*processed = 0;
- return E_FAIL;
+ return res;
}
if (processed)
*processed = size;
@@ -309,7 +310,7 @@ HRESULT CEncoder::Encode(
RINOK(CreateMixerCoder(EXTERNAL_CODECS_LOC_VARS inSizeForReduce));
}
- _mixer->ReInit();
+ RINOK(_mixer->ReInit2());
CMtEncMultiProgress *mtProgressSpec = NULL;
CMyComPtr<ICompressProgressInfo> mtProgress;
@@ -478,7 +479,7 @@ HRESULT CEncoder::Encode(
unpackSize = streamSize;
}
else
- streamSize = _mixer->GetBondStreamSize(bond);
+ streamSize = _mixer->GetBondStreamSize((unsigned)bond);
coderUnpackSizes.Add(streamSize);
}
@@ -609,13 +610,13 @@ HRESULT CEncoder::EncoderConstr()
int bond = _bindInfo.FindBond_for_PackStream(outIndex);
if (bond >= 0)
{
- ci = _bindInfo.Bonds[bond].UnpackIndex;
+ ci = _bindInfo.Bonds[(unsigned)bond].UnpackIndex;
continue;
}
int si = _bindInfo.FindStream_in_PackStreams(outIndex);
if (si >= 0)
- _bindInfo.PackStreams.MoveToFront(si);
+ _bindInfo.PackStreams.MoveToFront((unsigned)si);
break;
}
}
diff --git a/CPP/7zip/Archive/7z/7zEncode.h b/CPP/7zip/Archive/7z/7zEncode.h
index f1a9b5ad..6ea7f276 100644
--- a/CPP/7zip/Archive/7z/7zEncode.h
+++ b/CPP/7zip/Archive/7z/7zEncode.h
@@ -41,7 +41,7 @@ public:
STDMETHOD(SetRatioInfo)(const UInt64 *inSize, const UInt64 *outSize);
};
-class CEncoder
+class CEncoder MY_UNCOPYABLE
{
#ifdef USE_MIXER_ST
NCoderMixer2::CMixerST *_mixerST;
diff --git a/CPP/7zip/Archive/7z/7zExtract.cpp b/CPP/7zip/Archive/7z/7zExtract.cpp
index 9ffe2fdc..95eba9af 100644
--- a/CPP/7zip/Archive/7z/7zExtract.cpp
+++ b/CPP/7zip/Archive/7z/7zExtract.cpp
@@ -217,6 +217,10 @@ HRESULT CFolderOutStream::FlushCorrupted(Int32 callbackOperationResult)
STDMETHODIMP CHandler::Extract(const UInt32 *indices, UInt32 numItems,
Int32 testModeSpec, IArchiveExtractCallback *extractCallbackSpec)
{
+ // for GCC
+ // CFolderOutStream *folderOutStream = new CFolderOutStream;
+ // CMyComPtr<ISequentialOutStream> outStream(folderOutStream);
+
COM_TRY_BEGIN
CMyComPtr<IArchiveExtractCallback> extractCallback = extractCallbackSpec;
@@ -350,7 +354,7 @@ STDMETHODIMP CHandler::Extract(const UInt32 *indices, UInt32 numItems,
#ifndef _NO_CRYPTO
bool isEncrypted = false;
bool passwordIsDefined = false;
- UString password;
+ UString_Wipe password;
#endif
@@ -411,7 +415,8 @@ STDMETHODIMP CHandler::Extract(const UInt32 *indices, UInt32 numItems,
{
RINOK(folderOutStream->FlushCorrupted(NExtract::NOperationResult::kDataError));
// continue;
- return E_FAIL;
+ // return E_FAIL;
+ throw;
}
}
diff --git a/CPP/7zip/Archive/7z/7zHandler.cpp b/CPP/7zip/Archive/7z/7zHandler.cpp
index bbb892e7..9e344c34 100644
--- a/CPP/7zip/Archive/7z/7zHandler.cpp
+++ b/CPP/7zip/Archive/7z/7zHandler.cpp
@@ -107,34 +107,62 @@ static void ConvertMethodIdToString(AString &res, UInt64 id)
res += s + len - ConvertMethodIdToString_Back(s + len, id);
}
-static unsigned GetStringForSizeValue(char *s, UInt32 val)
+
+static char *GetStringForSizeValue(char *s, UInt32 val)
{
unsigned i;
for (i = 0; i <= 31; i++)
if (((UInt32)1 << i) == val)
{
- if (i < 10)
+ if (i >= 10)
{
- s[0] = (char)('0' + i);
- s[1] = 0;
- return 1;
+ *s++= (char)('0' + i / 10);
+ i %= 10;
}
- if (i < 20) { s[0] = '1'; s[1] = (char)('0' + i - 10); }
- else if (i < 30) { s[0] = '2'; s[1] = (char)('0' + i - 20); }
- else { s[0] = '3'; s[1] = (char)('0' + i - 30); }
- s[2] = 0;
- return 2;
+ *s++ = (char)('0' + i);
+ *s = 0;
+ return s;
}
+
char c = 'b';
if ((val & ((1 << 20) - 1)) == 0) { val >>= 20; c = 'm'; }
else if ((val & ((1 << 10) - 1)) == 0) { val >>= 10; c = 'k'; }
- ::ConvertUInt32ToString(val, s);
- unsigned pos = MyStringLen(s);
- s[pos++] = c;
- s[pos] = 0;
- return pos;
+ s = ConvertUInt32ToString(val, s);
+ *s++ = c;
+ *s = 0;
+ return s;
}
+
+static void GetLzma2String(char *s, unsigned d)
+{
+ if (d > 40)
+ {
+ *s = 0;
+ return;
+ // s = MyStpCpy(s, "unsup");
+ }
+ else if ((d & 1) == 0)
+ d = (d >> 1) + 12;
+ else
+ {
+ // s = GetStringForSizeValue(s, (UInt32)3 << ((d >> 1) + 11));
+ d = (d >> 1) + 1;
+ char c = 'k';
+ if (d >= 10)
+ {
+ c = 'm';
+ d -= 10;
+ }
+ s = ConvertUInt32ToString((UInt32)3 << d, s);
+ *s++ = c;
+ *s = 0;
+ return;
+ }
+ ConvertUInt32ToString(d, s);
+}
+
+
/*
static inline void AddHexToString(UString &res, Byte value)
{
@@ -147,8 +175,7 @@ static char *AddProp32(char *s, const char *name, UInt32 v)
{
*s++ = ':';
s = MyStpCpy(s, name);
- ::ConvertUInt32ToString(v, s);
- return s + MyStringLen(s);
+ return ConvertUInt32ToString(v, s);
}
void CHandler::AddMethodName(AString &s, UInt64 id)
@@ -184,10 +211,7 @@ STDMETHODIMP CHandler::GetArchiveProperty(PROPID propID, PROPVARIANT *value)
if (id == k_LZMA2)
{
s += "LZMA2:";
- if ((pm.Lzma2Prop & 1) == 0)
- ConvertUInt32ToString((pm.Lzma2Prop >> 1) + 12, temp);
- else
- GetStringForSizeValue(temp, 3 << ((pm.Lzma2Prop >> 1) + 11));
+ GetLzma2String(temp, pm.Lzma2Prop);
s += temp;
}
else if (id == k_LZMA)
@@ -244,14 +268,13 @@ STDMETHODIMP CHandler::GetArchiveProperty(PROPID propID, PROPVARIANT *value)
break;
}
}
- prop.Detach(value);
- return S_OK;
+ return prop.Detach(value);
#ifndef _SFX
COM_TRY_END
#endif
}
-static void SetFileTimeProp_From_UInt64Def(PROPVARIANT *prop, const CUInt64DefVector &v, int index)
+static void SetFileTimeProp_From_UInt64Def(PROPVARIANT *prop, const CUInt64DefVector &v, unsigned index)
{
UInt64 value;
if (v.GetItem(index, value))
@@ -416,7 +439,7 @@ HRESULT CHandler::SetMethodToProp(CNum folderIndex, PROPVARIANT *prop) const
if (propsSize == 5)
{
UInt32 dicSize = GetUi32((const Byte *)props + 1);
- char *dest = s + GetStringForSizeValue(s, dicSize);
+ char *dest = GetStringForSizeValue(s, dicSize);
UInt32 d = props[0];
if (d != 0x5D)
{
@@ -434,24 +457,16 @@ HRESULT CHandler::SetMethodToProp(CNum folderIndex, PROPVARIANT *prop) const
{
name = "LZMA2";
if (propsSize == 1)
- {
- Byte d = props[0];
- if ((d & 1) == 0)
- ConvertUInt32ToString((UInt32)((d >> 1) + 12), s);
- else
- GetStringForSizeValue(s, 3 << ((d >> 1) + 11));
- }
+ GetLzma2String(s, props[0]);
}
else if (id == k_PPMD)
{
name = "PPMD";
if (propsSize == 5)
{
- Byte order = *props;
char *dest = s;
*dest++ = 'o';
- ConvertUInt32ToString(order, dest);
- dest += MyStringLen(dest);
+ dest = ConvertUInt32ToString(*props, dest);
dest = MyStpCpy(dest, ":mem");
GetStringForSizeValue(dest, GetUi32(props + 1));
}
@@ -534,7 +549,7 @@ HRESULT CHandler::SetMethodToProp(CNum folderIndex, PROPVARIANT *prop) const
STDMETHODIMP CHandler::GetProperty(UInt32 index, PROPID propID, PROPVARIANT *value)
{
- PropVariant_Clear(value);
+ RINOK(PropVariant_Clear(value));
// COM_TRY_BEGIN
// NCOM::CPropVariant prop;
@@ -637,7 +652,7 @@ STDMETHODIMP CHandler::GetProperty(UInt32 index, PROPID propID, PROPVARIANT *val
#endif
}
- // prop.Detach(value);
+ // return prop.Detach(value);
return S_OK;
// COM_TRY_END
}
@@ -708,7 +723,7 @@ STDMETHODIMP CHandler::Close()
#ifndef _NO_CRYPTO
_isEncrypted = false;
_passwordIsDefined = false;
- _password.Empty();
+ _password.Wipe_and_Empty();
#endif
return S_OK;
COM_TRY_END
diff --git a/CPP/7zip/Archive/7z/7zHandler.h b/CPP/7zip/Archive/7z/7zHandler.h
index 99942eb0..cad1ae61 100644
--- a/CPP/7zip/Archive/7z/7zHandler.h
+++ b/CPP/7zip/Archive/7z/7zHandler.h
@@ -129,6 +129,10 @@ public:
DECL_ISetCompressCodecsInfo
CHandler();
+ ~CHandler()
+ {
+ Close();
+ }
private:
CMyComPtr<IInStream> _inStream;
@@ -137,7 +141,7 @@ private:
#ifndef _NO_CRYPTO
bool _isEncrypted;
bool _passwordIsDefined;
- UString _password;
+ UString _password; // _Wipe
#endif
#ifdef EXTRACT_ONLY
diff --git a/CPP/7zip/Archive/7z/7zHandlerOut.cpp b/CPP/7zip/Archive/7z/7zHandlerOut.cpp
index b6be06a8..b549d94a 100644
--- a/CPP/7zip/Archive/7z/7zHandlerOut.cpp
+++ b/CPP/7zip/Archive/7z/7zHandlerOut.cpp
@@ -111,7 +111,7 @@ HRESULT CHandler::SetMainMethod(
}
const UInt64 kSolidBytes_Min = (1 << 24);
- const UInt64 kSolidBytes_Max = ((UInt64)1 << 32) - 1;
+ const UInt64 kSolidBytes_Max = ((UInt64)1 << 32);
bool needSolid = false;
@@ -140,26 +140,52 @@ HRESULT CHandler::SetMainMethod(
case k_LZMA2: dicSize = oneMethodInfo.Get_Lzma_DicSize(); break;
case k_PPMD: dicSize = oneMethodInfo.Get_Ppmd_MemSize(); break;
case k_Deflate: dicSize = (UInt32)1 << 15; break;
+ case k_Deflate64: dicSize = (UInt32)1 << 16; break;
case k_BZip2: dicSize = oneMethodInfo.Get_BZip2_BlockSize(); break;
default: continue;
}
-
- _numSolidBytes = (UInt64)dicSize << 7;
- if (_numSolidBytes < kSolidBytes_Min) _numSolidBytes = kSolidBytes_Min;
- if (_numSolidBytes > kSolidBytes_Max) _numSolidBytes = kSolidBytes_Max;
+
+ if (methodFull.Id == k_LZMA2)
+ {
+ // he we calculate default chunk Size for LZMA2 as defined in LZMA2 encoder code
+ UInt64 cs = (UInt64)dicSize << 2;
+ const UInt32 kMinSize = (UInt32)1 << 20;
+ const UInt32 kMaxSize = (UInt32)1 << 28;
+ if (cs < kMinSize) cs = kMinSize;
+ if (cs > kMaxSize) cs = kMaxSize;
+ if (cs < dicSize) cs = dicSize;
+ cs += (kMinSize - 1);
+ cs &= ~(UInt64)(kMinSize - 1);
+ // we want to use at least 64 chunks (threads) per one solid block.
+ _numSolidBytes = cs << 6;
+ const UInt64 kSolidBytes_Lzma2_Max = ((UInt64)1 << 34);
+ if (_numSolidBytes > kSolidBytes_Lzma2_Max)
+ _numSolidBytes = kSolidBytes_Lzma2_Max;
+ }
+ else
+ {
+ _numSolidBytes = (UInt64)dicSize << 7;
+ if (_numSolidBytes > kSolidBytes_Max)
+ _numSolidBytes = kSolidBytes_Max;
+ }
+
+ if (_numSolidBytes < kSolidBytes_Min)
+ _numSolidBytes = kSolidBytes_Min;
_numSolidBytesDefined = true;
}
if (!_numSolidBytesDefined)
+ {
if (needSolid)
_numSolidBytes = kSolidBytes_Max;
else
_numSolidBytes = 0;
+ }
_numSolidBytesDefined = true;
return S_OK;
}
-static HRESULT GetTime(IArchiveUpdateCallback *updateCallback, int index, PROPID propID, UInt64 &ft, bool &ftDefined)
+static HRESULT GetTime(IArchiveUpdateCallback *updateCallback, unsigned index, PROPID propID, UInt64 &ft, bool &ftDefined)
{
// ft = 0;
// ftDefined = false;
@@ -289,8 +315,8 @@ STDMETHODIMP CHandler::UpdateItems(ISequentialOutStream *outStream, UInt32 numIt
bool need_CTime = (Write_CTime.Def && Write_CTime.Val);
bool need_ATime = (Write_ATime.Def && Write_ATime.Val);
- bool need_MTime = (Write_MTime.Def && Write_MTime.Val || !Write_MTime.Def);
- bool need_Attrib = (Write_Attrib.Def && Write_Attrib.Val || !Write_Attrib.Def);
+ bool need_MTime = (Write_MTime.Def ? Write_MTime.Val : true);
+ bool need_Attrib = (Write_Attrib.Def ? Write_Attrib.Val : true);
if (db && !db->Files.IsEmpty())
{
@@ -313,7 +339,7 @@ STDMETHODIMP CHandler::UpdateItems(ISequentialOutStream *outStream, UInt32 numIt
CUpdateItem ui;
ui.NewProps = IntToBool(newProps);
ui.NewData = IntToBool(newData);
- ui.IndexInArchive = indexInArchive;
+ ui.IndexInArchive = (int)indexInArchive;
ui.IndexInClient = i;
ui.IsAnti = false;
ui.Size = 0;
@@ -322,23 +348,23 @@ STDMETHODIMP CHandler::UpdateItems(ISequentialOutStream *outStream, UInt32 numIt
// bool isAltStream = false;
if (ui.IndexInArchive != -1)
{
- if (db == 0 || (unsigned)ui.IndexInArchive >= db->Files.Size())
+ if (!db || (unsigned)ui.IndexInArchive >= db->Files.Size())
return E_INVALIDARG;
- const CFileItem &fi = db->Files[ui.IndexInArchive];
+ const CFileItem &fi = db->Files[(unsigned)ui.IndexInArchive];
if (!ui.NewProps)
{
- _db.GetPath(ui.IndexInArchive, name);
+ _db.GetPath((unsigned)ui.IndexInArchive, name);
}
ui.IsDir = fi.IsDir;
ui.Size = fi.Size;
// isAltStream = fi.IsAltStream;
- ui.IsAnti = db->IsItemAnti(ui.IndexInArchive);
+ ui.IsAnti = db->IsItemAnti((unsigned)ui.IndexInArchive);
if (!ui.NewProps)
{
- ui.CTimeDefined = db->CTime.GetItem(ui.IndexInArchive, ui.CTime);
- ui.ATimeDefined = db->ATime.GetItem(ui.IndexInArchive, ui.ATime);
- ui.MTimeDefined = db->MTime.GetItem(ui.IndexInArchive, ui.MTime);
+ ui.CTimeDefined = db->CTime.GetItem((unsigned)ui.IndexInArchive, ui.CTime);
+ ui.ATimeDefined = db->ATime.GetItem((unsigned)ui.IndexInArchive, ui.ATime);
+ ui.MTimeDefined = db->MTime.GetItem((unsigned)ui.IndexInArchive, ui.MTime);
}
}
@@ -570,10 +596,10 @@ STDMETHODIMP CHandler::UpdateItems(ISequentialOutStream *outStream, UInt32 numIt
updateCallback->QueryInterface(IID_ICryptoGetTextPassword2, (void **)&getPassword2);
methodMode.PasswordIsDefined = false;
- methodMode.Password.Empty();
+ methodMode.Password.Wipe_and_Empty();
if (getPassword2)
{
- CMyComBSTR password;
+ CMyComBSTR_Wipe password;
Int32 passwordIsDefined;
RINOK(getPassword2->CryptoGetTextPassword2(&passwordIsDefined, &password));
methodMode.PasswordIsDefined = IntToBool(passwordIsDefined);
@@ -751,7 +777,7 @@ HRESULT COutHandler::SetSolidFromString(const UString &s)
_solidExtension = true;
continue;
}
- i += (int)(end - start);
+ i += (unsigned)(end - start);
if (i == s2.Len())
return E_INVALIDARG;
wchar_t c = s2[i++];
@@ -829,7 +855,7 @@ HRESULT COutHandler::SetProperty(const wchar_t *nameSpec, const PROPVARIANT &val
}
UInt32 number;
- int index = ParseStringToUInt32(name, number);
+ unsigned index = ParseStringToUInt32(name, number);
// UString realName = name.Ptr(index);
if (index == 0)
{
diff --git a/CPP/7zip/Archive/7z/7zHeader.h b/CPP/7zip/Archive/7z/7zHeader.h
index d7f0ae36..e1bbc0aa 100644
--- a/CPP/7zip/Archive/7z/7zHeader.h
+++ b/CPP/7zip/Archive/7z/7zHeader.h
@@ -108,8 +108,9 @@ const UInt32 k_SWAP4 = 0x20304;
const UInt32 k_LZMA = 0x30101;
const UInt32 k_PPMD = 0x30401;
-const UInt32 k_Deflate = 0x40108;
-const UInt32 k_BZip2 = 0x40202;
+const UInt32 k_Deflate = 0x40108;
+const UInt32 k_Deflate64 = 0x40109;
+const UInt32 k_BZip2 = 0x40202;
const UInt32 k_BCJ = 0x3030103;
const UInt32 k_BCJ2 = 0x303011B;
diff --git a/CPP/7zip/Archive/7z/7zIn.cpp b/CPP/7zip/Archive/7z/7zIn.cpp
index ab5b5de4..7134595c 100644
--- a/CPP/7zip/Archive/7z/7zIn.cpp
+++ b/CPP/7zip/Archive/7z/7zIn.cpp
@@ -11,6 +11,8 @@
#include "../../../../C/7zCrc.h"
#include "../../../../C/CpuArch.h"
+// #include "../../../Common/UTFConvert.h"
+
#include "../../Common/StreamObjects.h"
#include "../../Common/StreamUtils.h"
@@ -32,6 +34,7 @@ using namespace NCOM;
namespace NArchive {
namespace N7z {
+unsigned BoolVector_CountSum(const CBoolVector &v);
unsigned BoolVector_CountSum(const CBoolVector &v)
{
unsigned sum = 0;
@@ -59,9 +62,13 @@ static void BoolVector_Fill_False(CBoolVector &v, unsigned size)
class CInArchiveException {};
class CUnsupportedFeatureException: public CInArchiveException {};
+MY_ATTR_NORETURN
static void ThrowException() { throw CInArchiveException(); }
+MY_ATTR_NORETURN
static inline void ThrowEndOfData() { ThrowException(); }
+MY_ATTR_NORETURN
static inline void ThrowUnsupported() { throw CUnsupportedFeatureException(); }
+MY_ATTR_NORETURN
static inline void ThrowIncorrect() { ThrowException(); }
class CStreamSwitch
@@ -328,7 +335,7 @@ HRESULT CInArchive::FindAndReadSignature(IInStream *stream, const UInt64 *search
{
memcpy(_header, p, kHeaderSize);
_arhiveBeginStreamPosition += offset + pos;
- return stream->Seek(_arhiveBeginStreamPosition + kHeaderSize, STREAM_SEEK_SET, NULL);
+ return stream->Seek((Int64)(_arhiveBeginStreamPosition + kHeaderSize), STREAM_SEEK_SET, NULL);
}
}
@@ -344,7 +351,7 @@ HRESULT CInArchive::Open(IInStream *stream, const UInt64 *searchHeaderSizeLimit)
Close();
RINOK(stream->Seek(0, STREAM_SEEK_CUR, &_arhiveBeginStreamPosition))
RINOK(stream->Seek(0, STREAM_SEEK_END, &_fileEndPosition))
- RINOK(stream->Seek(_arhiveBeginStreamPosition, STREAM_SEEK_SET, NULL))
+ RINOK(stream->Seek((Int64)_arhiveBeginStreamPosition, STREAM_SEEK_SET, NULL))
RINOK(FindAndReadSignature(stream, searchHeaderSizeLimit));
_stream = stream;
return S_OK;
@@ -478,7 +485,7 @@ void CDatabase::GetPath(unsigned index, UString &path) const
#if defined(_WIN32) && defined(MY_CPU_LE)
- wmemcpy(s, (const wchar_t *)p, size);
+ wmemcpy(s, (const wchar_t *)(const void *)p, size);
#else
@@ -506,10 +513,27 @@ HRESULT CDatabase::GetPath_Prop(unsigned index, PROPVARIANT *path) const throw()
if (size >= (1 << 14))
return S_OK;
- RINOK(PropVarEm_Alloc_Bstr(path, (unsigned)size - 1));
+ // (size) includes null terminator
+
+ /*
+ #if WCHAR_MAX > 0xffff
+
+ const Byte *p = ((const Byte *)NamesBuf + offset * 2);
+ size = Utf16LE__Get_Num_WCHARs(p, size - 1);
+ // (size) doesn't include null terminator
+ RINOK(PropVarEm_Alloc_Bstr(path, (unsigned)size));
wchar_t *s = path->bstrVal;
+ wchar_t *sEnd = Utf16LE__To_WCHARs_Sep(p, size, s);
+ *sEnd = 0;
+ if (s + size != sEnd) return E_FAIL;
+ #else
+ */
+
+ RINOK(PropVarEm_Alloc_Bstr(path, (unsigned)size - 1));
+ wchar_t *s = path->bstrVal;
const Byte *p = ((const Byte *)NamesBuf + offset * 2);
+ // Utf16LE__To_WCHARs_Sep(p, size, s);
for (size_t i = 0; i < size; i++)
{
@@ -518,10 +542,14 @@ HRESULT CDatabase::GetPath_Prop(unsigned index, PROPVARIANT *path) const throw()
#if WCHAR_PATH_SEPARATOR != L'/'
if (c == L'/')
c = WCHAR_PATH_SEPARATOR;
+ else if (c == L'\\')
+ c = WCHAR_IN_FILE_NAME_BACKSLASH_REPLACEMENT; // WSL scheme
#endif
*s++ = c;
}
+ // #endif
+
return S_OK;
/*
@@ -673,7 +701,7 @@ void CInArchive::ReadUnpackInfo(
{
UInt32 indexOfMainStream = 0;
UInt32 numPackStreams = 0;
- folders.FoCodersDataOffset[fo] = _inByteBack->GetPtr() - startBufPtr;
+ folders.FoCodersDataOffset[fo] = (size_t)(_inByteBack->GetPtr() - startBufPtr);
CNum numInStreams = 0;
CNum numCoders = inByte->ReadNum();
@@ -794,10 +822,10 @@ void CInArchive::ReadUnpackInfo(
folders.FoToMainUnpackSizeIndex[fo] = (Byte)indexOfMainStream;
}
- size_t dataSize = _inByteBack->GetPtr() - startBufPtr;
+ const size_t dataSize = (size_t)(_inByteBack->GetPtr() - startBufPtr);
folders.FoToCoderUnpackSizes[fo] = numCodersOutStreams;
folders.FoStartPackStreamIndex[fo] = packStreamIndex;
- folders.FoCodersDataOffset[fo] = _inByteBack->GetPtr() - startBufPtr;
+ folders.FoCodersDataOffset[fo] = (size_t)(_inByteBack->GetPtr() - startBufPtr);
folders.CodersData.CopyFrom(startBufPtr, dataSize);
// if (folders.NumPackStreams != packStreamIndex) ThrowUnsupported();
@@ -962,6 +990,8 @@ void CInArchive::ReadSubStreamsInfo(
}
}
+
+
void CInArchive::ReadStreamsInfo(
const CObjectVector<CByteBuffer> *dataVector,
UInt64 &dataOffset,
@@ -974,7 +1004,11 @@ void CInArchive::ReadStreamsInfo(
if (type == NID::kPackInfo)
{
dataOffset = ReadNumber();
+ if (dataOffset > _rangeLimit)
+ ThrowIncorrect();
ReadPackInfo(folders);
+ if (folders.PackPositions[folders.NumPackStreams] > _rangeLimit - dataOffset)
+ ThrowIncorrect();
type = ReadID();
}
@@ -1029,7 +1063,7 @@ void CInArchive::ReadBoolVector(unsigned numItems, CBoolVector &v)
mask = 0x80;
}
p[i] = ((b & mask) != 0);
- mask >>= 1;
+ mask = (Byte)(mask >> 1);
}
}
@@ -1090,8 +1124,8 @@ HRESULT CInArchive::ReadAndDecodePackedStreams(
for (CNum i = 0; i < folders.NumFolders; i++)
{
CByteBuffer &data = dataVector.AddNew();
- UInt64 unpackSize64 = folders.GetFolderUnpackSize(i);
- size_t unpackSize = (size_t)unpackSize64;
+ const UInt64 unpackSize64 = folders.GetFolderUnpackSize(i);
+ const size_t unpackSize = (size_t)unpackSize64;
if (unpackSize != unpackSize64)
ThrowUnsupported();
data.Alloc(unpackSize);
@@ -1106,7 +1140,7 @@ HRESULT CInArchive::ReadAndDecodePackedStreams(
EXTERNAL_CODECS_LOC_VARS
_stream, baseOffset + dataOffset,
folders, i,
- NULL, // *unpackSize
+ NULL, // &unpackSize64
outStream,
NULL, // *compressProgress
@@ -1127,6 +1161,9 @@ HRESULT CInArchive::ReadAndDecodePackedStreams(
if (dataAfterEnd_Error)
ThereIsHeaderError = true;
+ if (unpackSize != outStreamSpec->GetPos())
+ ThrowIncorrect();
+
if (folders.FolderCRCs.ValidAndDefined(i))
if (CrcCalc(data, unpackSize) != folders.FolderCRCs.Vals[i])
ThrowIncorrect();
@@ -1226,8 +1263,8 @@ HRESULT CInArchive::ReadHeader(
unsigned i;
for (i = 0; i < numFiles; i++)
{
- size_t curRem = (rem - pos) / 2;
- const UInt16 *buf = (const UInt16 *)(db.NamesBuf + pos);
+ const size_t curRem = (rem - pos) / 2;
+ const UInt16 *buf = (const UInt16 *)(const void *)(db.NamesBuf + pos);
size_t j;
for (j = 0; j < curRem && buf[j] != 0; j++);
if (j == curRem)
@@ -1519,13 +1556,13 @@ HRESULT CInArchive::ReadDatabase2(
const unsigned kCheckSize = 512;
Byte buf[kCheckSize];
RINOK(_stream->Seek(0, STREAM_SEEK_END, &fileSize));
- UInt64 rem = fileSize - cur;
+ const UInt64 rem = fileSize - cur;
unsigned checkSize = kCheckSize;
if (rem < kCheckSize)
checkSize = (unsigned)(rem);
if (checkSize < 3)
return S_FALSE;
- RINOK(_stream->Seek(fileSize - checkSize, STREAM_SEEK_SET, NULL));
+ RINOK(_stream->Seek((Int64)(fileSize - checkSize), STREAM_SEEK_SET, NULL));
RINOK(ReadStream_FALSE(_stream, buf, (size_t)checkSize));
if (buf[checkSize - 1] != 0)
@@ -1534,8 +1571,8 @@ HRESULT CInArchive::ReadDatabase2(
unsigned i;
for (i = checkSize - 2;; i--)
{
- if (buf[i] == NID::kEncodedHeader && buf[i + 1] == NID::kPackInfo ||
- buf[i] == NID::kHeader && buf[i + 1] == NID::kMainStreamsInfo)
+ if ((buf[i] == NID::kEncodedHeader && buf[i + 1] == NID::kPackInfo) ||
+ (buf[i] == NID::kHeader && buf[i + 1] == NID::kMainStreamsInfo))
break;
if (i == 0)
return S_FALSE;
@@ -1543,7 +1580,7 @@ HRESULT CInArchive::ReadDatabase2(
nextHeaderSize = checkSize - i;
nextHeaderOffset = rem - nextHeaderSize;
nextHeaderCRC = CrcCalc(buf + i, (size_t)nextHeaderSize);
- RINOK(_stream->Seek(cur, STREAM_SEEK_SET, NULL));
+ RINOK(_stream->Seek((Int64)cur, STREAM_SEEK_SET, NULL));
db.StartHeaderWasRecovered = true;
}
else
@@ -1560,25 +1597,32 @@ HRESULT CInArchive::ReadDatabase2(
if ((Int64)nextHeaderOffset < 0 ||
nextHeaderSize > ((UInt64)1 << 62))
return S_FALSE;
+
+ HeadersSize = kHeaderSize;
+
if (nextHeaderSize == 0)
{
if (nextHeaderOffset != 0)
return S_FALSE;
db.IsArc = true;
+ db.HeadersSize = HeadersSize;
return S_OK;
}
if (!db.StartHeaderWasRecovered)
db.IsArc = true;
- HeadersSize += kHeaderSize + nextHeaderSize;
+ HeadersSize += nextHeaderSize;
+ // db.EndHeaderOffset = nextHeaderOffset;
+ _rangeLimit = nextHeaderOffset;
+
db.PhySize = kHeaderSize + nextHeaderOffset + nextHeaderSize;
if (_fileEndPosition - db.ArcInfo.StartPositionAfterHeader < nextHeaderOffset + nextHeaderSize)
{
db.UnexpectedEnd = true;
return S_FALSE;
}
- RINOK(_stream->Seek(nextHeaderOffset, STREAM_SEEK_CUR, NULL));
+ RINOK(_stream->Seek((Int64)nextHeaderOffset, STREAM_SEEK_CUR, NULL));
size_t nextHeaderSize_t = (size_t)nextHeaderSize;
if (nextHeaderSize_t != nextHeaderSize)
diff --git a/CPP/7zip/Archive/7z/7zIn.h b/CPP/7zip/Archive/7z/7zIn.h
index 6a61d314..ffa1e4bc 100644
--- a/CPP/7zip/Archive/7z/7zIn.h
+++ b/CPP/7zip/Archive/7z/7zIn.h
@@ -174,13 +174,14 @@ struct CDatabase: public CFolders
HRESULT GetPath_Prop(unsigned index, PROPVARIANT *path) const throw();
};
+
struct CInArchiveInfo
{
CArchiveVersion Version;
- UInt64 StartPosition;
- UInt64 StartPositionAfterHeader;
- UInt64 DataStartPosition;
- UInt64 DataStartPosition2;
+ UInt64 StartPosition; // in stream
+ UInt64 StartPositionAfterHeader; // in stream
+ UInt64 DataStartPosition; // in stream
+ UInt64 DataStartPosition2; // in stream. it's for headers
CRecordVector<UInt64> FileInfoPopIDs;
void Clear()
@@ -193,6 +194,7 @@ struct CInArchiveInfo
}
};
+
struct CDbEx: public CDatabase
{
CInArchiveInfo ArcInfo;
@@ -202,6 +204,7 @@ struct CDbEx: public CDatabase
UInt64 HeadersSize;
UInt64 PhySize;
+ // UInt64 EndHeaderOffset; // relative to position after StartHeader (32 bytes)
/*
CRecordVector<size_t> SecureOffsets;
@@ -255,6 +258,7 @@ struct CDbEx: public CDatabase
HeadersSize = 0;
PhySize = 0;
+ // EndHeaderOffset = 0;
}
bool CanUpdate() const
@@ -349,6 +353,8 @@ class CInArchive
UInt64 _arhiveBeginStreamPosition;
UInt64 _fileEndPosition;
+ UInt64 _rangeLimit; // relative to position after StartHeader (32 bytes)
+
Byte _header[kHeaderSize];
UInt64 HeadersSize;
diff --git a/CPP/7zip/Archive/7z/7zItem.h b/CPP/7zip/Archive/7z/7zItem.h
index ee4aed3f..0f9fdada 100644
--- a/CPP/7zip/Archive/7z/7zItem.h
+++ b/CPP/7zip/Archive/7z/7zItem.h
@@ -50,7 +50,7 @@ public:
{
FOR_VECTOR(i, PackStreams)
if (PackStreams[i] == packStream)
- return i;
+ return (int)i;
return -1;
}
@@ -58,7 +58,7 @@ public:
{
FOR_VECTOR(i, Bonds)
if (Bonds[i].PackIndex == packStream)
- return i;
+ return (int)i;
return -1;
}
diff --git a/CPP/7zip/Archive/7z/7zOut.cpp b/CPP/7zip/Archive/7z/7zOut.cpp
index aa977292..2786bf28 100644
--- a/CPP/7zip/Archive/7z/7zOut.cpp
+++ b/CPP/7zip/Archive/7z/7zOut.cpp
@@ -5,6 +5,7 @@
#include "../../../../C/7zCrc.h"
#include "../../../Common/AutoPtr.h"
+// #include "../../../Common/UTFConvert.h"
#include "../../Common/StreamObjects.h"
@@ -196,7 +197,7 @@ void COutArchive::WriteNumber(UInt64 value)
break;
}
firstByte |= mask;
- mask >>= 1;
+ mask = (Byte)(mask >> 1);
}
WriteByte(firstByte);
for (; i > 0; i--)
@@ -206,9 +207,9 @@ void COutArchive::WriteNumber(UInt64 value)
}
}
-static UInt32 GetBigNumberSize(UInt64 value)
+static unsigned GetBigNumberSize(UInt64 value)
{
- int i;
+ unsigned i;
for (i = 1; i < 9; i++)
if (value < (((UInt64)1 << (i * 7))))
break;
@@ -264,18 +265,18 @@ void COutArchive::WriteFolder(const CFolder &folder)
for (idSize = 1; idSize < sizeof(id); idSize++)
if ((id >> (8 * idSize)) == 0)
break;
- idSize &= 0xF;
+ // idSize &= 0xF; // idSize is smaller than 16 already
Byte temp[16];
for (unsigned t = idSize; t != 0; t--, id >>= 8)
temp[t] = (Byte)(id & 0xFF);
- Byte b = (Byte)(idSize);
- bool isComplex = !coder.IsSimpleCoder();
+ unsigned b = idSize;
+ const bool isComplex = !coder.IsSimpleCoder();
b |= (isComplex ? 0x10 : 0);
- size_t propsSize = coder.Props.Size();
+ const size_t propsSize = coder.Props.Size();
b |= ((propsSize != 0) ? 0x20 : 0);
- temp[0] = b;
+ temp[0] = (Byte)b;
WriteBytes(temp, idSize + 1);
if (isComplex)
{
@@ -309,7 +310,7 @@ void COutArchive::WriteBoolVector(const CBoolVector &boolVector)
{
if (boolVector[i])
b |= mask;
- mask >>= 1;
+ mask = (Byte)(mask >> 1);
if (mask == 0)
{
WriteByte(b);
@@ -476,7 +477,7 @@ void COutArchive::WriteAlignedBools(const CBoolVector &v, unsigned numDefined, B
{
const unsigned bvSize = (numDefined == v.Size()) ? 0 : Bv_GetSizeInBytes(v);
const UInt64 dataSize = ((UInt64)numDefined << itemSizeShifts) + bvSize + 2;
- SkipToAligned(3 + (unsigned)bvSize + (unsigned)GetBigNumberSize(dataSize), itemSizeShifts);
+ SkipToAligned(3 + bvSize + GetBigNumberSize(dataSize), itemSizeShifts);
WriteByte(type);
WriteNumber(dataSize);
@@ -545,7 +546,39 @@ void COutArchive::WriteHeader(
WriteByte(NID::kHeader);
- // Archive Properties
+ /*
+ {
+ // It's example for per archive properies writing
+
+ WriteByte(NID::kArchiveProperties);
+
+ // you must use random 40-bit number that will identify you
+ // then you can use same kDeveloperID for any properties and methods
+ const UInt64 kDeveloperID = 0x123456789A; // change that value to real random 40-bit number
+
+ #define GENERATE_7Z_ID(developerID, subID) (((UInt64)0x3F << 56) | ((UInt64)developerID << 16) | subID)
+
+ {
+ const UInt64 kSubID = 0x1; // you can use small number for subID
+ const UInt64 kID = GENERATE_7Z_ID(kDeveloperID, kSubID);
+ WriteNumber(kID);
+ const unsigned kPropsSize = 3; // it's example size
+ WriteNumber(kPropsSize);
+ for (unsigned i = 0; i < kPropsSize; i++)
+ WriteByte((Byte)(i & 0xFF));
+ }
+ {
+ const UInt64 kSubID = 0x2; // you can use small number for subID
+ const UInt64 kID = GENERATE_7Z_ID(kDeveloperID, kSubID);
+ WriteNumber(kID);
+ const unsigned kPropsSize = 5; // it's example size
+ WriteNumber(kPropsSize);
+ for (unsigned i = 0; i < kPropsSize; i++)
+ WriteByte((Byte)(i + 16));
+ }
+ WriteByte(NID::kEnd);
+ }
+ */
if (db.Folders.Size() > 0)
{
@@ -637,7 +670,15 @@ void COutArchive::WriteHeader(
const UString &name = db.Names[i];
if (!name.IsEmpty())
numDefined++;
- namesDataSize += (name.Len() + 1) * 2;
+ const size_t numUtfChars =
+ /*
+ #if WCHAR_MAX > 0xffff
+ Get_Num_Utf16_chars_from_wchar_string(name.Ptr());
+ #else
+ */
+ name.Len();
+ // #endif
+ namesDataSize += (numUtfChars + 1) * 2;
}
if (numDefined > 0)
@@ -654,6 +695,25 @@ void COutArchive::WriteHeader(
for (unsigned t = 0; t <= name.Len(); t++)
{
wchar_t c = name[t];
+
+ /*
+ #if WCHAR_MAX > 0xffff
+ if (c >= 0x10000)
+ {
+ c -= 0x10000;
+ if (c < (1 << 20))
+ {
+ unsigned c0 = 0xd800 + ((c >> 10) & 0x3FF);
+ WriteByte((Byte)c0);
+ WriteByte((Byte)(c0 >> 8));
+ c = 0xdc00 + (c & 0x3FF);
+ }
+ else
+ c = '_'; // we change character unsupported by UTF16
+ }
+ #endif
+ */
+
WriteByte((Byte)c);
WriteByte((Byte)(c >> 8));
}
@@ -855,7 +915,7 @@ HRESULT COutArchive::WriteDatabase(
h.NextHeaderSize = headerSize;
h.NextHeaderCRC = headerCRC;
h.NextHeaderOffset = headerOffset;
- RINOK(Stream->Seek(_prefixHeaderPos, STREAM_SEEK_SET, NULL));
+ RINOK(Stream->Seek((Int64)_prefixHeaderPos, STREAM_SEEK_SET, NULL));
return WriteStartHeader(h);
}
}
diff --git a/CPP/7zip/Archive/7z/7zUpdate.cpp b/CPP/7zip/Archive/7z/7zUpdate.cpp
index 6705fc00..b641d93f 100644
--- a/CPP/7zip/Archive/7z/7zUpdate.cpp
+++ b/CPP/7zip/Archive/7z/7zUpdate.cpp
@@ -55,8 +55,8 @@ struct CFilterMode
#define PE_SIG 0x00004550
#define PE_OptHeader_Magic_32 0x10B
#define PE_OptHeader_Magic_64 0x20B
-#define PE_SectHeaderSize 40
-#define PE_SECT_EXECUTE 0x20000000
+// #define PE_SectHeaderSize 40
+// #define PE_SECT_EXECUTE 0x20000000
static int Parse_EXE(const Byte *buf, size_t size, CFilterMode *filterMode)
{
@@ -254,10 +254,12 @@ static BoolInt Parse_WAV(const Byte *buf, size_t size, CFilterMode *filterMode)
if (subChunkSize < 0x10 || subChunkSize > 0x12 || GetUi16(buf + 0x14) != 1)
return False;
- unsigned numChannels = GetUi16(buf + 0x16);
- unsigned bitsPerSample = GetUi16(buf + 0x22);
-
- if ((bitsPerSample & 0x7) != 0 || bitsPerSample >= 256 || numChannels >= 256)
+ const unsigned numChannels = GetUi16(buf + 0x16);
+ const unsigned bitsPerSample = GetUi16(buf + 0x22);
+ if ((bitsPerSample & 0x7) != 0)
+ return False;
+ const UInt32 delta = (UInt32)numChannels * (bitsPerSample >> 3);
+ if (delta == 0 || delta > 256)
return False;
pos = 0x14 + subChunkSize;
@@ -271,9 +273,6 @@ static BoolInt Parse_WAV(const Byte *buf, size_t size, CFilterMode *filterMode)
subChunkSize = GetUi32(buf + pos + 4);
if (GetUi32(buf + pos) == WAV_SUBCHUNK_data)
{
- unsigned delta = numChannels * (bitsPerSample >> 3);
- if (delta >= 256)
- return False;
filterMode->Id = k_Delta;
filterMode->Delta = delta;
return True;
@@ -418,7 +417,7 @@ static unsigned Get_FilterGroup_for_Folder(
static HRESULT WriteRange(IInStream *inStream, ISequentialOutStream *outStream,
UInt64 position, UInt64 size, ICompressProgressInfo *progress)
{
- RINOK(inStream->Seek(position, STREAM_SEEK_SET, 0));
+ RINOK(inStream->Seek((Int64)position, STREAM_SEEK_SET, 0));
CLimitedSequentialInStream *streamSpec = new CLimitedSequentialInStream;
CMyComPtr<CLimitedSequentialInStream> inStreamLimited(streamSpec);
streamSpec->SetStream(inStream);
@@ -642,13 +641,13 @@ struct CRefItem
if (sortByType)
{
int slashPos = ui.Name.ReverseFind_PathSepar();
- NamePos = slashPos + 1;
+ NamePos = (unsigned)(slashPos + 1);
int dotPos = ui.Name.ReverseFind_Dot();
if (dotPos <= slashPos)
ExtensionPos = ui.Name.Len();
else
{
- ExtensionPos = dotPos + 1;
+ ExtensionPos = (unsigned)(dotPos + 1);
if (ExtensionPos != ui.Name.Len())
{
AString s;
@@ -836,7 +835,7 @@ HRESULT CAnalysis::GetFilterGroup(UInt32 index, const CUpdateItem &ui, CFilterMo
{
const wchar_t *ext;
if (dotPos > slashPos)
- ext = ui.Name.Ptr(dotPos + 1);
+ ext = ui.Name.Ptr((unsigned)(dotPos + 1));
else
ext = ui.Name.RightPtr(0);
@@ -1071,12 +1070,12 @@ static HRESULT MakeExeMethod(CCompressionMethodMode &mode,
if (alignBits != 0)
{
if (alignBits > 2 || filterMode.Id == k_Delta)
- nextMethod.AddProp32(NCoderPropID::kPosStateBits, alignBits);
+ nextMethod.AddProp32(NCoderPropID::kPosStateBits, (unsigned)alignBits);
unsigned lc = 0;
if (alignBits < 3)
- lc = 3 - alignBits;
+ lc = (unsigned)(3 - alignBits);
nextMethod.AddProp32(NCoderPropID::kLitContextBits, lc);
- nextMethod.AddProp32(NCoderPropID::kLitPosBits, alignBits);
+ nextMethod.AddProp32(NCoderPropID::kLitPosBits, (unsigned)alignBits);
}
}
}
@@ -1453,7 +1452,7 @@ public:
UInt64 StartPos;
const CFolders *Folders;
- int FolderIndex;
+ unsigned FolderIndex;
// bool send_UnpackSize;
// UInt64 UnpackSize;
@@ -1609,7 +1608,10 @@ HRESULT Update(
CRecordVector<CFilterMode2> filters;
CObjectVector<CSolidGroup> groups;
+
+ #ifndef _7ZIP_ST
bool thereAreRepacks = false;
+ #endif
bool useFilters = options.UseFilters;
if (useFilters)
@@ -1636,7 +1638,7 @@ HRESULT Update(
{
int index = updateItems[i].IndexInArchive;
if (index != -1)
- fileIndexToUpdateIndexMap[(unsigned)index] = i;
+ fileIndexToUpdateIndexMap[(unsigned)index] = (int)i;
}
for (i = 0; i < db->NumFolders; i++)
@@ -1656,7 +1658,7 @@ HRESULT Update(
{
indexInFolder++;
int updateIndex = fileIndexToUpdateIndexMap[fi];
- if (updateIndex >= 0 && !updateItems[updateIndex].NewData)
+ if (updateIndex >= 0 && !updateItems[(unsigned)updateIndex].NewData)
{
numCopyItems++;
repackSize += file.Size;
@@ -1688,7 +1690,9 @@ HRESULT Update(
complexity += db->GetFolderFullPackSize(i);
else
{
+ #ifndef _7ZIP_ST
thereAreRepacks = true;
+ #endif
complexity += repackSize;
if (inSizeForReduce2 < repackSize)
inSizeForReduce2 = repackSize;
@@ -1727,10 +1731,12 @@ HRESULT Update(
#ifndef _7ZIP_ST
CStreamBinder sb;
+ /*
if (options.MultiThreadMixer)
{
RINOK(sb.CreateEvents());
}
+ */
#endif
@@ -1742,7 +1748,9 @@ HRESULT Update(
#ifdef EXTERNAL_CODECS
threadDecoder.__externalCodecs = __externalCodecs;
#endif
- RINOK(threadDecoder.Create());
+ WRes wres = threadDecoder.Create();
+ if (wres != 0)
+ return HRESULT_FROM_WIN32(wres);
}
#endif
@@ -1887,7 +1895,7 @@ HRESULT Update(
if (ui.HasStream())
continue;
}
- else if (ui.IndexInArchive != -1 && db->Files[ui.IndexInArchive].HasStream)
+ else if (ui.IndexInArchive != -1 && db->Files[(unsigned)ui.IndexInArchive].HasStream)
continue;
/*
if (ui.TreeFolderIndex >= 0)
@@ -1912,8 +1920,8 @@ HRESULT Update(
}
else
{
- GetFile(*db, ui.IndexInArchive, file, file2);
- db->GetPath(ui.IndexInArchive, name);
+ GetFile(*db, (unsigned)ui.IndexInArchive, file, file2);
+ db->GetPath((unsigned)ui.IndexInArchive, name);
}
/*
@@ -2065,7 +2073,7 @@ HRESULT Update(
{
indexInFolder++;
int updateIndex = fileIndexToUpdateIndexMap[fi];
- if (updateIndex >= 0 && !updateItems[updateIndex].NewData)
+ if (updateIndex >= 0 && !updateItems[(unsigned)updateIndex].NewData)
needExtract = true;
// decodeSize += file.Size;
}
@@ -2099,8 +2107,8 @@ HRESULT Update(
{
repackBase = threadDecoder.FosSpec;
CMyComPtr<ISequentialOutStream> sbOutStream;
- sb.CreateStreams(&sbInStream, &sbOutStream);
- sb.ReInit();
+ sb.CreateStreams2(sbInStream, sbOutStream);
+ RINOK(sb.Create_ReInit());
threadDecoder.FosSpec->_stream = sbOutStream;
@@ -2171,7 +2179,9 @@ HRESULT Update(
#ifndef _7ZIP_ST
if (options.MultiThreadMixer)
{
- threadDecoder.Start();
+ WRes wres = threadDecoder.Start();
+ if (wres != 0)
+ return HRESULT_FROM_WIN32(wres);
}
#endif
}
@@ -2197,7 +2207,11 @@ HRESULT Update(
inStreamSizeCount.Release();
sbInStream.Release();
- threadDecoder.WaitExecuteFinish();
+ {
+ WRes wres = threadDecoder.WaitExecuteFinish();
+ if (wres != 0)
+ return HRESULT_FROM_WIN32(wres);
+ }
HRESULT decodeRes = threadDecoder.Result;
// if (res == k_My_HRESULT_CRC_ERROR)
@@ -2259,7 +2273,7 @@ HRESULT Update(
int updateIndex = fileIndexToUpdateIndexMap[fi];
if (updateIndex >= 0)
{
- const CUpdateItem &ui = updateItems[updateIndex];
+ const CUpdateItem &ui = updateItems[(unsigned)updateIndex];
if (ui.NewData)
continue;
@@ -2347,7 +2361,7 @@ HRESULT Update(
{
int slashPos = ui.Name.ReverseFind_PathSepar();
int dotPos = ui.Name.ReverseFind_Dot();
- const wchar_t *ext = ui.Name.Ptr(dotPos <= slashPos ? ui.Name.Len() : dotPos + 1);
+ const wchar_t *ext = ui.Name.Ptr(dotPos <= slashPos ? ui.Name.Len() : (unsigned)(dotPos + 1));
if (numSubFiles == 0)
prevExtension = ext;
else if (!StringsAreEqualNoCase(ext, prevExtension))
@@ -2403,8 +2417,8 @@ HRESULT Update(
}
else
{
- GetFile(*db, ui.IndexInArchive, file, file2);
- db->GetPath(ui.IndexInArchive, name);
+ GetFile(*db, (unsigned)ui.IndexInArchive, file, file2);
+ db->GetPath((unsigned)ui.IndexInArchive, name);
}
if (file2.IsAnti || file.IsDir)
return E_FAIL;
diff --git a/CPP/7zip/Archive/7z/7zUpdate.h b/CPP/7zip/Archive/7z/7zUpdate.h
index a7abf779..7c0f78a8 100644
--- a/CPP/7zip/Archive/7z/7zUpdate.h
+++ b/CPP/7zip/Archive/7z/7zUpdate.h
@@ -31,7 +31,7 @@ struct CTreeFolder
struct CUpdateItem
{
int IndexInArchive;
- int IndexInClient;
+ unsigned IndexInClient;
UInt64 CTime;
UInt64 ATime;
diff --git a/CPP/7zip/Archive/ApmHandler.cpp b/CPP/7zip/Archive/ApmHandler.cpp
index 4d3f2728..73e5fcb6 100644
--- a/CPP/7zip/Archive/ApmHandler.cpp
+++ b/CPP/7zip/Archive/ApmHandler.cpp
@@ -240,7 +240,7 @@ STDMETHODIMP CHandler::GetArchiveProperty(PROPID propID, PROPVARIANT *value)
mainIndex = -1;
break;
}
- mainIndex = i;
+ mainIndex = (int)i;
}
}
if (mainIndex >= 0)
diff --git a/CPP/7zip/Archive/ArHandler.cpp b/CPP/7zip/Archive/ArHandler.cpp
index 09a62201..0bea8b4e 100644
--- a/CPP/7zip/Archive/ArHandler.cpp
+++ b/CPP/7zip/Archive/ArHandler.cpp
@@ -618,13 +618,15 @@ STDMETHODIMP CHandler::Open(IInStream *stream,
_items.DeleteFrontal(1);
for (unsigned i = 0; i < _items.Size(); i++)
if (_items[i].Name.IsPrefixedBy("data.tar."))
+ {
if (_mainSubfile < 0)
- _mainSubfile = i;
+ _mainSubfile = (int)i;
else
{
_mainSubfile = -1;
break;
}
+ }
}
else
{
@@ -845,7 +847,7 @@ STDMETHODIMP CHandler::GetStream(UInt32 index, ISequentialInStream **stream)
}
REGISTER_ARC_I(
- "Ar", "ar a deb lib", 0, 0xEC,
+ "Ar", "ar a deb udeb lib", 0, 0xEC,
kSignature,
0,
0,
diff --git a/CPP/7zip/Archive/ArchiveExports.cpp b/CPP/7zip/Archive/ArchiveExports.cpp
index 28e9946d..6549b3d2 100644
--- a/CPP/7zip/Archive/ArchiveExports.cpp
+++ b/CPP/7zip/Archive/ArchiveExports.cpp
@@ -46,7 +46,7 @@ static inline HRESULT SetPropGUID(const GUID &guid, PROPVARIANT *value)
return SetPropStrFromBin((const char *)&guid, sizeof(guid), value);
}
-int FindFormatCalssId(const GUID *clsid)
+static int FindFormatCalssId(const GUID *clsid)
{
GUID cls = *clsid;
CLS_ARC_ID_ITEM(cls) = 0;
@@ -59,6 +59,7 @@ int FindFormatCalssId(const GUID *clsid)
return -1;
}
+STDAPI CreateArchiver(const GUID *clsid, const GUID *iid, void **outObject);
STDAPI CreateArchiver(const GUID *clsid, const GUID *iid, void **outObject)
{
COM_TRY_BEGIN
@@ -89,6 +90,7 @@ STDAPI CreateArchiver(const GUID *clsid, const GUID *iid, void **outObject)
return S_OK;
}
+STDAPI GetHandlerProperty2(UInt32 formatIndex, PROPID propID, PROPVARIANT *value);
STDAPI GetHandlerProperty2(UInt32 formatIndex, PROPID propID, PROPVARIANT *value)
{
COM_TRY_BEGIN
@@ -130,17 +132,20 @@ STDAPI GetHandlerProperty2(UInt32 formatIndex, PROPID propID, PROPVARIANT *value
COM_TRY_END
}
+STDAPI GetHandlerProperty(PROPID propID, PROPVARIANT *value);
STDAPI GetHandlerProperty(PROPID propID, PROPVARIANT *value)
{
return GetHandlerProperty2(g_DefaultArcIndex, propID, value);
}
+STDAPI GetNumberOfFormats(UINT32 *numFormats);
STDAPI GetNumberOfFormats(UINT32 *numFormats)
{
*numFormats = g_NumArcs;
return S_OK;
}
+STDAPI GetIsArc(UInt32 formatIndex, Func_IsArc *isArc);
STDAPI GetIsArc(UInt32 formatIndex, Func_IsArc *isArc)
{
*isArc = NULL;
diff --git a/CPP/7zip/Archive/ArjHandler.cpp b/CPP/7zip/Archive/ArjHandler.cpp
index fb9e3e7a..0e353dca 100644
--- a/CPP/7zip/Archive/ArjHandler.cpp
+++ b/CPP/7zip/Archive/ArjHandler.cpp
@@ -235,13 +235,13 @@ namespace NFileType
namespace NFlags
{
const Byte kGarbled = 1 << 0;
- const Byte kAnsiPage = 1 << 1; // or (OLD_SECURED_FLAG) obsolete
+ // const Byte kAnsiPage = 1 << 1; // or (OLD_SECURED_FLAG) obsolete
const Byte kVolume = 1 << 2;
const Byte kExtFile = 1 << 3;
- const Byte kPathSym = 1 << 4;
- const Byte kBackup = 1 << 5; // obsolete
- const Byte kSecured = 1 << 6;
- const Byte kDualName = 1 << 7;
+ // const Byte kPathSym = 1 << 4;
+ // const Byte kBackup = 1 << 5; // obsolete
+ // const Byte kSecured = 1 << 6;
+ // const Byte kDualName = 1 << 7;
}
namespace NHostOS
@@ -375,6 +375,32 @@ HRESULT CArcHeader::Parse(const Byte *p, unsigned size)
return S_OK;
}
+
+struct CExtendedInfo
+{
+ UInt64 Size;
+ bool CrcError;
+
+ void Clear()
+ {
+ Size = 0;
+ CrcError = false;
+ }
+ void ParseToPropVar(NCOM::CPropVariant &prop) const
+ {
+ if (Size != 0)
+ {
+ AString s;
+ s += "Extended:";
+ s.Add_UInt32((UInt32)Size);
+ if (CrcError)
+ s += ":CRC_ERROR";
+ prop = s;
+ }
+ }
+};
+
+
struct CItem
{
AString Name;
@@ -399,6 +425,8 @@ struct CItem
// Byte LastChapter;
UInt64 DataPosition;
+
+ CExtendedInfo ExtendedInfo;
bool IsEncrypted() const { return (Flags & NFlags::kGarbled) != 0; }
bool IsDir() const { return (FileType == NFileType::kDirectory); }
@@ -462,7 +490,7 @@ enum EErrorType
{
k_ErrorType_OK,
k_ErrorType_Corrupted,
- k_ErrorType_UnexpectedEnd,
+ k_ErrorType_UnexpectedEnd
};
class CArc
@@ -476,19 +504,22 @@ public:
UInt64 NumFiles;
CArcHeader Header;
+ CExtendedInfo ExtendedInfo;
+
HRESULT Open();
HRESULT GetNextItem(CItem &item, bool &filled);
void Close()
{
IsArc = false;
Error = k_ErrorType_OK;
+ ExtendedInfo.Clear();
}
private:
- UInt32 _blockSize;
- Byte _block[kBlockSizeMax + 4];
+ unsigned _blockSize;
+ CByteBuffer _block;
- HRESULT ReadBlock(bool &filled, bool readSignature);
- HRESULT SkipExtendedHeaders();
+ HRESULT ReadBlock(bool &filled, CExtendedInfo *extendedInfo);
+ HRESULT SkipExtendedHeaders(CExtendedInfo &extendedInfo);
HRESULT Read(void *data, size_t *size);
};
@@ -503,14 +534,14 @@ HRESULT CArc::Read(void *data, size_t *size)
{ size_t _processed_ = (_size_); RINOK(Read(_dest_, &_processed_)); \
if (_processed_ != (_size_)) { Error = k_ErrorType_UnexpectedEnd; return S_OK; } }
-HRESULT CArc::ReadBlock(bool &filled, bool readSignature)
+HRESULT CArc::ReadBlock(bool &filled, CExtendedInfo *extendedInfo)
{
Error = k_ErrorType_OK;
filled = false;
Byte buf[4];
- unsigned signSize = readSignature ? 2 : 0;
+ const unsigned signSize = extendedInfo ? 0 : 2;
READ_STREAM(buf, signSize + 2)
- if (readSignature)
+ if (!extendedInfo)
if (buf[0] != kSig0 || buf[1] != kSig1)
{
Error = k_ErrorType_Corrupted;
@@ -519,28 +550,48 @@ HRESULT CArc::ReadBlock(bool &filled, bool readSignature)
_blockSize = Get16(buf + signSize);
if (_blockSize == 0) // end of archive
return S_OK;
- if (_blockSize < kBlockSizeMin ||
- _blockSize > kBlockSizeMax)
+
+ if (!extendedInfo)
+ if (_blockSize < kBlockSizeMin || _blockSize > kBlockSizeMax)
+ {
+ Error = k_ErrorType_Corrupted;
+ return S_OK;
+ }
+
+ const size_t readSize = _blockSize + 4;
+ if (readSize > _block.Size())
{
- Error = k_ErrorType_Corrupted;
- return S_OK;
+ // extended data size is limited by (64 KB)
+ // _blockSize is less than 64 KB
+ const size_t upSize = (_blockSize > kBlockSizeMax ? (1 << 16) : kBlockSizeMax);
+ _block.Alloc(upSize + 4);
}
- READ_STREAM(_block, _blockSize + 4);
+
+ if (extendedInfo)
+ extendedInfo->Size += _blockSize;
+
+ READ_STREAM(_block, readSize);
if (Get32(_block + _blockSize) != CrcCalc(_block, _blockSize))
{
- Error = k_ErrorType_Corrupted;
- return S_OK;
+ if (extendedInfo)
+ extendedInfo->CrcError = true;
+ else
+ {
+ Error = k_ErrorType_Corrupted;
+ return S_OK;
+ }
}
filled = true;
return S_OK;
}
-HRESULT CArc::SkipExtendedHeaders()
+HRESULT CArc::SkipExtendedHeaders(CExtendedInfo &extendedInfo)
{
+ extendedInfo.Clear();
for (UInt32 i = 0;; i++)
{
bool filled;
- RINOK(ReadBlock(filled, false));
+ RINOK(ReadBlock(filled, &extendedInfo));
if (!filled)
return S_OK;
if (Callback && (i & 0xFF) == 0)
@@ -551,17 +602,17 @@ HRESULT CArc::SkipExtendedHeaders()
HRESULT CArc::Open()
{
bool filled;
- RINOK(ReadBlock(filled, true));
+ RINOK(ReadBlock(filled, NULL)); // (extendedInfo = NULL)
if (!filled)
return S_FALSE;
RINOK(Header.Parse(_block, _blockSize));
IsArc = true;
- return SkipExtendedHeaders();
+ return SkipExtendedHeaders(ExtendedInfo);
}
HRESULT CArc::GetNextItem(CItem &item, bool &filled)
{
- RINOK(ReadBlock(filled, true));
+ RINOK(ReadBlock(filled, NULL)); // (extendedInfo = NULL)
if (!filled)
return S_OK;
filled = false;
@@ -576,7 +627,7 @@ HRESULT CArc::GetNextItem(CItem &item, bool &filled)
extraData = GetUi32(_block + pos);
*/
- RINOK(SkipExtendedHeaders());
+ RINOK(SkipExtendedHeaders(item.ExtendedInfo));
filled = true;
return S_OK;
}
@@ -603,7 +654,8 @@ static const Byte kArcProps[] =
kpidCTime,
kpidMTime,
kpidHostOS,
- kpidComment
+ kpidComment,
+ kpidCharacts
};
static const Byte kProps[] =
@@ -619,7 +671,8 @@ static const Byte kProps[] =
kpidCRC,
kpidMethod,
kpidHostOS,
- kpidComment
+ kpidComment,
+ kpidCharacts
};
IMP_IInArchive_Props
@@ -671,10 +724,14 @@ STDMETHODIMP CHandler::GetArchiveProperty(PROPID propID, PROPVARIANT *value)
{
case k_ErrorType_UnexpectedEnd: v |= kpv_ErrorFlags_UnexpectedEnd; break;
case k_ErrorType_Corrupted: v |= kpv_ErrorFlags_HeadersError; break;
+ case k_ErrorType_OK:
+ default:
+ break;
}
prop = v;
break;
}
+ case kpidCharacts: _arc.ExtendedInfo.ParseToPropVar(prop); break;
}
prop.Detach(value);
return S_OK;
@@ -706,6 +763,7 @@ STDMETHODIMP CHandler::GetProperty(UInt32 index, PROPID propID, PROPVARIANT *val
case kpidHostOS: SetHostOS(item.HostOS, prop); break;
case kpidMTime: SetTime(item.MTime, prop); break;
case kpidComment: SetUnicodeString(item.Comment, prop); break;
+ case kpidCharacts: item.ExtendedInfo.ParseToPropVar(prop); break;
}
prop.Detach(value);
return S_OK;
diff --git a/CPP/7zip/Archive/Base64Handler.cpp b/CPP/7zip/Archive/Base64Handler.cpp
new file mode 100644
index 00000000..63b4552e
--- /dev/null
+++ b/CPP/7zip/Archive/Base64Handler.cpp
@@ -0,0 +1,511 @@
+// Base64Handler.cpp
+
+#include "StdAfx.h"
+
+#include "../../../C/CpuArch.h"
+
+#include "../../Common/ComTry.h"
+#include "../../Common/MyBuffer.h"
+#include "../../Common/IntToString.h"
+#include "../../Common/MyVector.h"
+
+#include "../../Windows/PropVariant.h"
+
+#include "../Common/ProgressUtils.h"
+#include "../Common/RegisterArc.h"
+#include "../Common/StreamUtils.h"
+#include "../Common/InBuffer.h"
+
+/*
+spaces:
+ 9(TAB),10(LF),13(CR),32(SPACE)
+ Non-breaking space:
+ 0xa0 : Unicode, Windows code pages 1250-1258
+ 0xff (unused): DOS code pages
+
+end of stream markers: '=' (0x3d):
+ "=" , if numBytes (% 3 == 2)
+ "==" , if numBytes (% 3 == 1)
+*/
+
+
+static const Byte k_Base64Table[256] =
+{
+ 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,77,77,77,77,77,
+ 65,77,77,77,77,77,77,77,77,77,77,62,77,77,77,63,
+ 52,53,54,55,56,57,58,59,60,61,77,77,77,64,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,
+ 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,
+ 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,
+ 65,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 const unsigned k_Code_Equals = 64;
+static const unsigned k_Code_Space = 65;
+static const unsigned k_Code_Zero = 66;
+
+API_FUNC_static_IsArc IsArc_Base64(const Byte *p, size_t size)
+{
+ size_t num = 0;
+ size_t firstSpace = 0;
+
+ for (;;)
+ {
+ if (size == 0)
+ return k_IsArc_Res_NEED_MORE;
+ UInt32 c = k_Base64Table[(Byte)(*p++)];
+ size--;
+ if (c < 64)
+ {
+ num++;
+ continue;
+ }
+
+ if (c == k_Code_Space)
+ {
+ if (p[-1] == ' ' && firstSpace == 0)
+ firstSpace = num;
+ continue;
+ }
+
+ if (c != k_Code_Equals)
+ return k_IsArc_Res_NO;
+ break;
+ }
+
+ {
+ // we try to redece false positive detection here.
+ // we don't expect space character in starting base64 line
+ const unsigned kNumExpectedNonSpaceSyms = 20;
+ if (firstSpace != 0 && firstSpace < num && firstSpace < kNumExpectedNonSpaceSyms)
+ return k_IsArc_Res_NO;
+ }
+
+ num &= 3;
+
+ if (num <= 1)
+ return k_IsArc_Res_NO;
+ if (num != 3)
+ {
+ if (size == 0)
+ return k_IsArc_Res_NEED_MORE;
+ UInt32 c = k_Base64Table[(Byte)(*p++)];
+ size--;
+ if (c != k_Code_Equals)
+ return k_IsArc_Res_NO;
+ }
+
+ for (;;)
+ {
+ if (size == 0)
+ return k_IsArc_Res_YES;
+ UInt32 c = k_Base64Table[(Byte)(*p++)];
+ size--;
+ if (c == k_Code_Space)
+ continue;
+ return k_IsArc_Res_NO;
+ }
+}
+}
+
+
+enum EBase64Res
+{
+ k_Base64_RES_MaybeFinished,
+ k_Base64_RES_Finished,
+ k_Base64_RES_NeedMoreInput,
+ k_Base64_RES_UnexpectedChar
+};
+
+
+static EBase64Res Base64ToBin(Byte *p, size_t size, const Byte **srcEnd, Byte **destEnd)
+{
+ Byte *dest = p;
+ UInt32 val = 1;
+ EBase64Res res = k_Base64_RES_NeedMoreInput;
+
+ for (;;)
+ {
+ if (size == 0)
+ {
+ if (val == 1)
+ res = k_Base64_RES_MaybeFinished;
+ break;
+ }
+ UInt32 c = k_Base64Table[(Byte)(*p++)];
+ size--;
+ if (c < 64)
+ {
+ val = (val << 6) | c;
+ if ((val & ((UInt32)1 << 24)) == 0)
+ continue;
+ dest[0] = (Byte)(val >> 16);
+ dest[1] = (Byte)(val >> 8);
+ dest[2] = (Byte)(val);
+ dest += 3;
+ val = 1;
+ continue;
+ }
+
+ if (c == k_Code_Space)
+ continue;
+
+ if (c == k_Code_Equals)
+ {
+ if (val >= (1 << 12))
+ {
+ if (val & (1 << 18))
+ {
+ res = k_Base64_RES_Finished;
+ break;
+ }
+ if (size == 0)
+ break;
+ c = k_Base64Table[(Byte)(*p++)];
+ size--;
+ if (c == k_Code_Equals)
+ {
+ res = k_Base64_RES_Finished;
+ break;
+ }
+ }
+ }
+
+ p--;
+ res = k_Base64_RES_UnexpectedChar;
+ break;
+ }
+
+ if (val >= ((UInt32)1 << 12))
+ {
+ if (val & (1 << 18))
+ {
+ *dest++ = (Byte)(val >> 10);
+ val <<= 2;
+ }
+ *dest++ = (Byte)(val >> 4);
+ }
+
+ *srcEnd = p;
+ *destEnd = dest;
+ return res;
+}
+
+
+static const Byte *Base64_SkipSpaces(const Byte *p, size_t size)
+{
+ for (;;)
+ {
+ if (size == 0)
+ return p;
+ UInt32 c = k_Base64Table[(Byte)(*p++)];
+ size--;
+ if (c == k_Code_Space)
+ continue;
+ return p - 1;
+ }
+}
+
+
+// the following function is used by DmgHandler.cpp
+
+Byte *Base64ToBin(Byte *dest, const char *src);
+Byte *Base64ToBin(Byte *dest, const char *src)
+{
+ UInt32 val = 1;
+
+ for (;;)
+ {
+ UInt32 c = k_Base64Table[(Byte)(*src++)];
+
+ if (c < 64)
+ {
+ val = (val << 6) | c;
+ if ((val & ((UInt32)1 << 24)) == 0)
+ continue;
+ dest[0] = (Byte)(val >> 16);
+ dest[1] = (Byte)(val >> 8);
+ dest[2] = (Byte)(val);
+ dest += 3;
+ val = 1;
+ continue;
+ }
+
+ if (c == k_Code_Space)
+ continue;
+
+ if (c == k_Code_Equals)
+ break;
+
+ if (c == k_Code_Zero && val == 1) // end of string
+ return dest;
+
+ return NULL;
+ }
+
+ if (val < (1 << 12))
+ return NULL;
+
+ if (val & (1 << 18))
+ {
+ *dest++ = (Byte)(val >> 10);
+ val <<= 2;
+ }
+ else if (k_Base64Table[(Byte)(*src++)] != k_Code_Equals)
+ return NULL;
+ *dest++ = (Byte)(val >> 4);
+
+ for (;;)
+ {
+ Byte c = k_Base64Table[(Byte)(*src++)];
+ if (c == k_Code_Space)
+ continue;
+ if (c == k_Code_Zero)
+ return dest;
+ return NULL;
+ }
+}
+
+
+namespace NArchive {
+namespace NBase64 {
+
+class CHandler:
+ public IInArchive,
+ public CMyUnknownImp
+{
+ bool _isArc;
+ UInt64 _phySize;
+ size_t _size;
+ EBase64Res _sres;
+ CByteBuffer _data;
+public:
+ MY_UNKNOWN_IMP1(IInArchive)
+ INTERFACE_IInArchive(;)
+};
+
+static const Byte kProps[] =
+{
+ kpidSize,
+ kpidPackSize,
+};
+
+IMP_IInArchive_Props
+IMP_IInArchive_ArcProps_NO_Table
+
+STDMETHODIMP CHandler::GetNumberOfItems(UInt32 *numItems)
+{
+ *numItems = 1;
+ return S_OK;
+}
+
+STDMETHODIMP CHandler::GetArchiveProperty(PROPID propID, PROPVARIANT *value)
+{
+ NWindows::NCOM::CPropVariant prop;
+ switch (propID)
+ {
+ case kpidPhySize: if (_phySize != 0) prop = _phySize; break;
+ case kpidErrorFlags:
+ {
+ UInt32 v = 0;
+ if (!_isArc) v |= kpv_ErrorFlags_IsNotArc;
+ if (_sres == k_Base64_RES_NeedMoreInput) v |= kpv_ErrorFlags_UnexpectedEnd;
+ if (v != 0)
+ prop = v;
+ break;
+ }
+ }
+ prop.Detach(value);
+ return S_OK;
+}
+
+STDMETHODIMP CHandler::GetProperty(UInt32 /* index */, PROPID propID, PROPVARIANT *value)
+{
+ // COM_TRY_BEGIN
+ NWindows::NCOM::CPropVariant prop;
+ switch (propID)
+ {
+ case kpidSize: prop = (UInt64)_size; break;
+ case kpidPackSize: prop = _phySize; break;
+ }
+ prop.Detach(value);
+ return S_OK;
+ // COM_TRY_END
+}
+
+
+static HRESULT ReadStream_OpenProgress(ISequentialInStream *stream, void *data, size_t size, IArchiveOpenCallback *openCallback) throw()
+{
+ UInt64 bytes = 0;
+ while (size != 0)
+ {
+ const UInt32 kBlockSize = ((UInt32)1 << 24);
+ UInt32 curSize = (size < kBlockSize) ? (UInt32)size : kBlockSize;
+ UInt32 processedSizeLoc;
+ RINOK(stream->Read(data, curSize, &processedSizeLoc));
+ if (processedSizeLoc == 0)
+ return E_FAIL;
+ data = (void *)((Byte *)data + processedSizeLoc);
+ size -= processedSizeLoc;
+ bytes += processedSizeLoc;
+ const UInt64 files = 1;
+ RINOK(openCallback->SetCompleted(&files, &bytes));
+ }
+ return S_OK;
+}
+
+
+STDMETHODIMP CHandler::Open(IInStream *stream, const UInt64 *, IArchiveOpenCallback *openCallback)
+{
+ COM_TRY_BEGIN
+ {
+ Close();
+ {
+ const unsigned kStartSize = 1 << 12;
+ _data.Alloc(kStartSize);
+ size_t size = kStartSize;
+ RINOK(ReadStream(stream, _data, &size));
+ UInt32 isArcRes = IsArc_Base64(_data, size);
+ if (isArcRes == k_IsArc_Res_NO)
+ return S_FALSE;
+ }
+ _isArc = true;
+
+ UInt64 packSize64;
+ RINOK(stream->Seek(0, STREAM_SEEK_END, &packSize64));
+
+ if (packSize64 == 0)
+ return S_FALSE;
+
+ size_t curSize = 1 << 16;
+ if (curSize > packSize64)
+ curSize = (size_t)packSize64;
+ const unsigned kLogStep = 4;
+
+ for (;;)
+ {
+ RINOK(stream->Seek(0, STREAM_SEEK_SET, NULL));
+
+ _data.Alloc(curSize);
+ RINOK(ReadStream_OpenProgress(stream, _data, curSize, openCallback));
+
+ const Byte *srcEnd;
+ Byte *dest;
+ _sres = Base64ToBin(_data, curSize, &srcEnd, &dest);
+ _size = dest - _data;
+ size_t mainSize = srcEnd - _data;
+ _phySize = mainSize;
+ if (_sres == k_Base64_RES_UnexpectedChar)
+ break;
+ if (curSize != mainSize)
+ {
+ const Byte *end2 = Base64_SkipSpaces(srcEnd, curSize - mainSize);
+ if ((size_t)(end2 - _data) != curSize)
+ break;
+ _phySize = curSize;
+ }
+
+ if (curSize == packSize64)
+ break;
+
+ UInt64 curSize64 = packSize64;
+ if (curSize < (packSize64 >> kLogStep))
+ curSize64 = (UInt64)curSize << kLogStep;
+ curSize = (size_t)curSize64;
+ if (curSize != curSize64)
+ return E_OUTOFMEMORY;
+ }
+ if (_size == 0)
+ return S_FALSE;
+ return S_OK;
+ }
+ COM_TRY_END
+}
+
+STDMETHODIMP CHandler::Close()
+{
+ _phySize = 0;
+ _size = 0;
+ _isArc = false;
+ _sres = k_Base64_RES_MaybeFinished;
+ _data.Free();
+ return S_OK;
+}
+
+
+STDMETHODIMP CHandler::Extract(const UInt32 *indices, UInt32 numItems,
+ Int32 testMode, IArchiveExtractCallback *extractCallback)
+{
+ COM_TRY_BEGIN
+ bool allFilesMode = (numItems == (UInt32)(Int32)-1);
+ if (allFilesMode)
+ numItems = 1;
+ if (numItems == 0)
+ return S_OK;
+ if (numItems != 1 || *indices != 0)
+ return E_INVALIDARG;
+
+ RINOK(extractCallback->SetTotal(_size));
+
+ CLocalProgress *lps = new CLocalProgress;
+ CMyComPtr<ICompressProgressInfo> progress = lps;
+ lps->Init(extractCallback, false);
+
+ {
+ lps->InSize = lps->OutSize = 0;
+ RINOK(lps->SetCur());
+
+ CMyComPtr<ISequentialOutStream> realOutStream;
+ Int32 askMode = testMode ?
+ NExtract::NAskMode::kTest :
+ NExtract::NAskMode::kExtract;
+
+ RINOK(extractCallback->GetStream(0, &realOutStream, askMode));
+
+ if (!testMode && !realOutStream)
+ return S_OK;
+
+ extractCallback->PrepareOperation(askMode);
+
+ if (realOutStream)
+ {
+ RINOK(WriteStream(realOutStream, (const Byte *)_data, _size));
+ realOutStream.Release();
+ }
+
+ Int32 opRes = NExtract::NOperationResult::kOK;
+
+ if (_sres != k_Base64_RES_Finished)
+ {
+ if (_sres == k_Base64_RES_NeedMoreInput)
+ opRes = NExtract::NOperationResult::kUnexpectedEnd;
+ else if (_sres == k_Base64_RES_UnexpectedChar)
+ opRes = NExtract::NOperationResult::kDataError;
+ }
+
+ RINOK(extractCallback->SetOperationResult(opRes));
+ }
+
+ lps->InSize = _phySize;
+ lps->OutSize = _size;
+ return lps->SetCur();
+
+ COM_TRY_END
+}
+
+REGISTER_ARC_I_NO_SIG(
+ "Base64", "b64", 0, 0xC5,
+ 0,
+ NArcInfoFlags::kKeepName | NArcInfoFlags::kStartOpen | NArcInfoFlags::kByExtOnlyOpen,
+ IsArc_Base64)
+
+}}
diff --git a/CPP/7zip/Archive/Cab/CabHandler.cpp b/CPP/7zip/Archive/Cab/CabHandler.cpp
index 4395ae1a..9f50d3aa 100644
--- a/CPP/7zip/Archive/Cab/CabHandler.cpp
+++ b/CPP/7zip/Archive/Cab/CabHandler.cpp
@@ -309,11 +309,14 @@ STDMETHODIMP CHandler::GetProperty(UInt32 index, PROPID propID, PROPVARIANT *val
case kpidMethod:
{
- UInt32 realFolderIndex = item.GetFolderIndex(db.Folders.Size());
- const CFolder &folder = db.Folders[realFolderIndex];
- char s[kMethodNameBufSize];;
- SetMethodName(s, folder.GetMethod(), folder.MethodMinor);
- prop = s;
+ const int realFolderIndex = item.GetFolderIndex(db.Folders.Size());
+ if (realFolderIndex >= 0)
+ {
+ const CFolder &folder = db.Folders[(unsigned)realFolderIndex];
+ char s[kMethodNameBufSize];;
+ SetMethodName(s, folder.GetMethod(), folder.MethodMinor);
+ prop = s;
+ }
break;
}
@@ -341,7 +344,8 @@ STDMETHODIMP CHandler::Open(IInStream *inStream,
CInArchive archive;
CMyComPtr<IArchiveOpenVolumeCallback> openVolumeCallback;
- callback->QueryInterface(IID_IArchiveOpenVolumeCallback, (void **)&openVolumeCallback);
+ if (callback)
+ callback->QueryInterface(IID_IArchiveOpenVolumeCallback, (void **)&openVolumeCallback);
CMyComPtr<IInStream> nextStream = inStream;
bool prevChecked = false;
@@ -420,7 +424,10 @@ STDMETHODIMP CHandler::Open(IInStream *inStream,
}
}
- RINOK(callback->SetCompleted(&numItems, NULL));
+ if (callback)
+ {
+ RINOK(callback->SetCompleted(&numItems, NULL));
+ }
nextStream = NULL;
@@ -1007,7 +1014,7 @@ STDMETHODIMP CHandler::Extract(const UInt32 *indices, UInt32 numItems,
continue;
}
- unsigned startIndex2 = m_Database.FolderStartFileIndex[folderIndex];
+ const unsigned startIndex2 = m_Database.FolderStartFileIndex[(unsigned)folderIndex];
unsigned startIndex = startIndex2;
extractStatuses.Clear();
for (; startIndex < index; startIndex++)
@@ -1037,8 +1044,10 @@ STDMETHODIMP CHandler::Extract(const UInt32 *indices, UInt32 numItems,
CFolderOutStream *cabFolderOutStream = new CFolderOutStream;
CMyComPtr<ISequentialOutStream> outStream(cabFolderOutStream);
- unsigned folderIndex2 = item.GetFolderIndex(db.Folders.Size());
- const CFolder &folder = db.Folders[folderIndex2];
+ const int folderIndex2 = item.GetFolderIndex(db.Folders.Size());
+ if (folderIndex2 < 0)
+ return E_FAIL;
+ const CFolder &folder = db.Folders[(unsigned)folderIndex2];
cabFolderOutStream->Init(&m_Database, &extractStatuses, startIndex2,
curUnpack, extractCallback, testMode);
@@ -1107,12 +1116,14 @@ STDMETHODIMP CHandler::Extract(const UInt32 *indices, UInt32 numItems,
}
const CDatabaseEx &db2 = m_Database.Volumes[volIndex];
- const CFolder &folder2 = db2.Folders[locFolderIndex];
+ if (locFolderIndex < 0)
+ return E_FAIL;
+ const CFolder &folder2 = db2.Folders[(unsigned)locFolderIndex];
if (bl == 0)
{
cabBlockInStreamSpec->ReservedSize = db2.ArcInfo.GetDataBlockReserveSize();
- RINOK(db2.Stream->Seek(db2.StartPosition + folder2.DataStart, STREAM_SEEK_SET, NULL));
+ RINOK(db2.Stream->Seek((Int64)(db2.StartPosition + folder2.DataStart), STREAM_SEEK_SET, NULL));
}
if (bl == folder2.NumDataBlocks)
@@ -1242,7 +1253,7 @@ STDMETHODIMP CHandler::Extract(const UInt32 *indices, UInt32 numItems,
if (res != S_OK || cabFolderOutStream->NeedMoreWrite())
{
- RINOK(cabFolderOutStream->FlushCorrupted(folderIndex2));
+ RINOK(cabFolderOutStream->FlushCorrupted((unsigned)folderIndex2));
}
totalUnPacked += curUnpack;
diff --git a/CPP/7zip/Archive/Cab/CabIn.cpp b/CPP/7zip/Archive/Cab/CabIn.cpp
index ca0052bf..e11ce9d0 100644
--- a/CPP/7zip/Archive/Cab/CabIn.cpp
+++ b/CPP/7zip/Archive/Cab/CabIn.cpp
@@ -114,8 +114,8 @@ HRESULT CSignatureFinder::Find()
Byte b = Signature[0];
for (;;)
{
- if (*p == b) break; p++;
- if (*p == b) break; p++;
+ if (*p == b) { break; } p++;
+ if (*p == b) { break; } p++;
}
Pos = (UInt32)(p - Buf);
if (End - Pos < _HeaderSize)
@@ -311,7 +311,7 @@ HRESULT CInArchive::Open2(CDatabaseEx &db, const UInt64 *searchHeaderSizeLimit)
{
// printf("\n!!! Seek Error !!!!\n");
// fflush(stdout);
- RINOK(db.Stream->Seek(db.StartPosition + ai.FileHeadersOffset, STREAM_SEEK_SET, NULL));
+ RINOK(db.Stream->Seek((Int64)(db.StartPosition + ai.FileHeadersOffset), STREAM_SEEK_SET, NULL));
limitedStreamSpec->Init(ai.Size - ai.FileHeadersOffset);
_inBuffer.Init();
}
diff --git a/CPP/7zip/Archive/Cab/CabIn.h b/CPP/7zip/Archive/Cab/CabIn.h
index a1fc6bdc..39586d12 100644
--- a/CPP/7zip/Archive/Cab/CabIn.h
+++ b/CPP/7zip/Archive/Cab/CabIn.h
@@ -100,7 +100,7 @@ struct CDatabase
int GetNumberOfNewFolders() const
{
- int res = Folders.Size();
+ int res = (int)Folders.Size();
if (IsTherePrevFolder())
res--;
return res;
diff --git a/CPP/7zip/Archive/Cab/CabItem.h b/CPP/7zip/Archive/Cab/CabItem.h
index 9b513202..9a912d5e 100644
--- a/CPP/7zip/Archive/Cab/CabItem.h
+++ b/CPP/7zip/Archive/Cab/CabItem.h
@@ -56,8 +56,8 @@ struct CItem
if (ContinuedFromPrev())
return 0;
if (ContinuedToNext())
- return numFolders - 1;
- return FolderIndex;
+ return (int)numFolders - 1;
+ return (int)FolderIndex;
}
};
diff --git a/CPP/7zip/Archive/Chm/ChmHandler.cpp b/CPP/7zip/Archive/Chm/ChmHandler.cpp
index 7ffdafe0..03e7ddd2 100644
--- a/CPP/7zip/Archive/Chm/ChmHandler.cpp
+++ b/CPP/7zip/Archive/Chm/ChmHandler.cpp
@@ -145,10 +145,12 @@ STDMETHODIMP CHandler::GetProperty(UInt32 index, PROPID propID, PROPVARIANT *val
case kpidMethod:
{
if (!item.IsDir())
+ {
if (item.Section == 0)
prop = "Copy";
else if (item.Section < m_Database.Sections.Size())
prop = m_Database.Sections[(unsigned)item.Section].GetMethodName();
+ }
break;
}
case kpidBlock:
diff --git a/CPP/7zip/Archive/Chm/ChmIn.cpp b/CPP/7zip/Archive/Chm/ChmIn.cpp
index 7e3f155b..f4916b68 100644
--- a/CPP/7zip/Archive/Chm/ChmIn.cpp
+++ b/CPP/7zip/Archive/Chm/ChmIn.cpp
@@ -13,7 +13,6 @@
#include "ChmIn.h"
-#define Get16(p) GetUi16(p)
#define Get32(p) GetUi32(p)
#define Get64(p) GetUi64(p)
@@ -117,7 +116,7 @@ UString CSectionInfo::GetMethodName() const
if (!IsLzx())
{
UString temp;
- if (ConvertUTF8ToUnicode(Name, temp))
+ ConvertUTF8ToUnicode(Name, temp);
s += temp;
s += ": ";
}
diff --git a/CPP/7zip/Archive/ComHandler.cpp b/CPP/7zip/Archive/ComHandler.cpp
index d2dc6c5f..a1f643b7 100644
--- a/CPP/7zip/Archive/ComHandler.cpp
+++ b/CPP/7zip/Archive/ComHandler.cpp
@@ -36,7 +36,7 @@ enum EType
k_Type_Msp,
k_Type_Doc,
k_Type_Ppt,
- k_Type_Xls,
+ k_Type_Xls
};
static const char * const kExtensions[] =
@@ -51,10 +51,10 @@ static const char * const kExtensions[] =
namespace NFatID
{
- static const UInt32 kFree = 0xFFFFFFFF;
+ // static const UInt32 kFree = 0xFFFFFFFF;
static const UInt32 kEndOfChain = 0xFFFFFFFE;
- static const UInt32 kFatSector = 0xFFFFFFFD;
- static const UInt32 kMatSector = 0xFFFFFFFC;
+ // static const UInt32 kFatSector = 0xFFFFFFFD;
+ // static const UInt32 kMatSector = 0xFFFFFFFC;
static const UInt32 kMaxValue = 0xFFFFFFFA;
}
@@ -62,9 +62,9 @@ namespace NItemType
{
static const Byte kEmpty = 0;
static const Byte kStorage = 1;
- static const Byte kStream = 2;
- static const Byte kLockBytes = 3;
- static const Byte kProperty = 4;
+ // static const Byte kStream = 2;
+ // static const Byte kLockBytes = 3;
+ // static const Byte kProperty = 4;
static const Byte kRootStorage = 5;
}
@@ -298,7 +298,7 @@ static bool CompoundMsiNameToFileName(const UString &name, UString &res)
for (unsigned i = 0; i < name.Len(); i++)
{
wchar_t c = name[i];
- if (c < k_Msi_StartUnicodeChar || c > k_Msi_StartUnicodeChar + k_Msi_UnicodeRange)
+ if (c < (wchar_t)k_Msi_StartUnicodeChar || c > (wchar_t)(k_Msi_StartUnicodeChar + k_Msi_UnicodeRange))
return false;
/*
if (i == 0)
@@ -578,11 +578,10 @@ HRESULT CDatabase::Open(IInStream *inStream)
{
// bool isThereExt = (msiName.Find(L'.') >= 0);
bool isMsiSpec = (msiName[0] == k_Msi_SpecChar);
- if (msiName.Len() >= 4 && StringsAreEqualNoCase_Ascii(msiName.RightPtr(4), ".cab")
- || !isMsiSpec && msiName.Len() >= 3 && StringsAreEqualNoCase_Ascii(msiName.RightPtr(3), "exe")
- // || !isMsiSpec && !isThereExt
+ if ((msiName.Len() >= 4 && StringsAreEqualNoCase_Ascii(msiName.RightPtr(4), ".cab"))
+ || (!isMsiSpec && msiName.Len() >= 3 && StringsAreEqualNoCase_Ascii(msiName.RightPtr(3), "exe"))
+ // || (!isMsiSpec && !isThereExt)
)
-
{
numCabs++;
MainSubfile = i;
diff --git a/CPP/7zip/Archive/Common/CoderMixer2.cpp b/CPP/7zip/Archive/Common/CoderMixer2.cpp
index c7002121..c8b67bd4 100644
--- a/CPP/7zip/Archive/Common/CoderMixer2.cpp
+++ b/CPP/7zip/Archive/Common/CoderMixer2.cpp
@@ -137,7 +137,7 @@ bool CBondsChecks::CheckCoder(unsigned coderIndex)
return false;
_coderUsed[coderIndex] = true;
- UInt32 start = BindInfo->Coder_to_Stream[coderIndex];
+ const UInt32 start = BindInfo->Coder_to_Stream[coderIndex];
for (unsigned i = 0; i < coder.NumStreams; i++)
{
@@ -146,10 +146,10 @@ bool CBondsChecks::CheckCoder(unsigned coderIndex)
if (BindInfo->IsStream_in_PackStreams(ind))
continue;
- int bond = BindInfo->FindBond_for_PackStream(ind);
+ const int bond = BindInfo->FindBond_for_PackStream(ind);
if (bond < 0)
return false;
- if (!CheckCoder(BindInfo->Bonds[bond].UnpackIndex))
+ if (!CheckCoder(BindInfo->Bonds[(unsigned)bond].UnpackIndex))
return false;
}
@@ -246,15 +246,15 @@ bool CMixer::Is_UnpackSize_Correct_for_Coder(UInt32 coderIndex)
if (coderIndex == _bi.UnpackCoder)
return true;
- int bond = _bi.FindBond_for_UnpackStream(coderIndex);
+ const int bond = _bi.FindBond_for_UnpackStream(coderIndex);
if (bond < 0)
throw 20150213;
/*
UInt32 coderIndex, coderStreamIndex;
- _bi.GetCoder_for_Stream(_bi.Bonds[bond].PackIndex, coderIndex, coderStreamIndex);
+ _bi.GetCoder_for_Stream(_bi.Bonds[(unsigned)bond].PackIndex, coderIndex, coderStreamIndex);
*/
- UInt32 nextCoder = _bi.Stream_to_Coder[_bi.Bonds[bond].PackIndex];
+ const UInt32 nextCoder = _bi.Stream_to_Coder[_bi.Bonds[(unsigned)bond].PackIndex];
if (!IsFilter_Vector[nextCoder])
return false;
@@ -267,11 +267,11 @@ bool CMixer::Is_PackSize_Correct_for_Stream(UInt32 streamIndex)
if (_bi.IsStream_in_PackStreams(streamIndex))
return true;
- int bond = _bi.FindBond_for_PackStream(streamIndex);
+ const int bond = _bi.FindBond_for_PackStream(streamIndex);
if (bond < 0)
throw 20150213;
- UInt32 nextCoder = _bi.Bonds[bond].UnpackIndex;
+ const UInt32 nextCoder = _bi.Bonds[(unsigned)bond].UnpackIndex;
if (!IsFilter_Vector[nextCoder])
return false;
@@ -281,8 +281,8 @@ bool CMixer::Is_PackSize_Correct_for_Stream(UInt32 streamIndex)
bool CMixer::Is_PackSize_Correct_for_Coder(UInt32 coderIndex)
{
- UInt32 startIndex = _bi.Coder_to_Stream[coderIndex];
- UInt32 numStreams = _bi.Coders[coderIndex].NumStreams;
+ const UInt32 startIndex = _bi.Coder_to_Stream[coderIndex];
+ const UInt32 numStreams = _bi.Coders[coderIndex].NumStreams;
for (UInt32 i = 0; i < numStreams; i++)
if (!Is_PackSize_Correct_for_Stream(startIndex + i))
return false;
@@ -293,19 +293,19 @@ bool CMixer::IsThere_ExternalCoder_in_PackTree(UInt32 coderIndex)
{
if (IsExternal_Vector[coderIndex])
return true;
- UInt32 startIndex = _bi.Coder_to_Stream[coderIndex];
- UInt32 numStreams = _bi.Coders[coderIndex].NumStreams;
+ const UInt32 startIndex = _bi.Coder_to_Stream[coderIndex];
+ const UInt32 numStreams = _bi.Coders[coderIndex].NumStreams;
for (UInt32 i = 0; i < numStreams; i++)
{
- UInt32 si = startIndex + i;
+ const UInt32 si = startIndex + i;
if (_bi.IsStream_in_PackStreams(si))
continue;
- int bond = _bi.FindBond_for_PackStream(si);
+ const int bond = _bi.FindBond_for_PackStream(si);
if (bond < 0)
throw 20150213;
- if (IsThere_ExternalCoder_in_PackTree(_bi.Bonds[bond].UnpackIndex))
+ if (IsThere_ExternalCoder_in_PackTree(_bi.Bonds[(unsigned)bond].UnpackIndex))
return true;
}
return false;
@@ -360,7 +360,7 @@ CCoder &CMixerST::GetCoder(unsigned index)
return _coders[index];
}
-void CMixerST::ReInit() {}
+HRESULT CMixerST::ReInit2() { return S_OK; }
HRESULT CMixerST::GetInStream2(
ISequentialInStream * const *inStreams, /* const UInt64 * const *inSizes, */
@@ -444,18 +444,18 @@ HRESULT CMixerST::GetInStream(
}
}
- int bond = FindBond_for_Stream(
+ const int bond = FindBond_for_Stream(
true, // forInputStream
inStreamIndex);
if (bond < 0)
return E_INVALIDARG;
RINOK(GetInStream2(inStreams, /* inSizes, */
- _bi.Bonds[bond].Get_OutIndex(EncodeMode), &seqInStream));
+ _bi.Bonds[(unsigned)bond].Get_OutIndex(EncodeMode), &seqInStream));
while (_binderStreams.Size() <= (unsigned)bond)
_binderStreams.AddNew();
- CStBinderStream &bs = _binderStreams[bond];
+ CStBinderStream &bs = _binderStreams[(unsigned)bond];
if (bs.StreamRef || bs.InStreamSpec)
return E_NOTIMPL;
@@ -498,13 +498,13 @@ HRESULT CMixerST::GetOutStream(
}
}
- int bond = FindBond_for_Stream(
+ const int bond = FindBond_for_Stream(
false, // forInputStream
outStreamIndex);
if (bond < 0)
return E_INVALIDARG;
- UInt32 inStreamIndex = _bi.Bonds[bond].Get_InIndex(EncodeMode);
+ UInt32 inStreamIndex = _bi.Bonds[(unsigned)bond].Get_InIndex(EncodeMode);
UInt32 coderIndex = inStreamIndex;
UInt32 coderStreamIndex = 0;
@@ -560,7 +560,7 @@ HRESULT CMixerST::GetOutStream(
while (_binderStreams.Size() <= (unsigned)bond)
_binderStreams.AddNew();
- CStBinderStream &bs = _binderStreams[bond];
+ CStBinderStream &bs = _binderStreams[(unsigned)bond];
if (bs.StreamRef || bs.OutStreamSpec)
return E_NOTIMPL;
@@ -610,13 +610,13 @@ HRESULT CMixerST::FinishStream(UInt32 streamIndex)
return S_OK;
}
- int bond = FindBond_for_Stream(
+ const int bond = FindBond_for_Stream(
false, // forInputStream
streamIndex);
if (bond < 0)
return E_INVALIDARG;
- UInt32 inStreamIndex = _bi.Bonds[bond].Get_InIndex(EncodeMode);
+ UInt32 inStreamIndex = _bi.Bonds[(unsigned)bond].Get_InIndex(EncodeMode);
UInt32 coderIndex = inStreamIndex;
UInt32 coderStreamIndex = 0;
@@ -654,7 +654,7 @@ void CMixerST::SelectMainCoder(bool useFirst)
unsigned ci = _bi.UnpackCoder;
int firstNonFilter = -1;
- int firstAllowed = ci;
+ unsigned firstAllowed = ci;
for (;;)
{
@@ -674,7 +674,7 @@ void CMixerST::SelectMainCoder(bool useFirst)
UInt32 st = _bi.Coder_to_Stream[ci];
if (_bi.IsStream_in_PackStreams(st))
break;
- int bond = _bi.FindBond_for_PackStream(st);
+ const int bond = _bi.FindBond_for_PackStream(st);
if (bond < 0)
throw 20150213;
@@ -682,15 +682,15 @@ void CMixerST::SelectMainCoder(bool useFirst)
break;
if (firstNonFilter == -1 && !IsFilter_Vector[ci])
- firstNonFilter = ci;
+ firstNonFilter = (int)ci;
- ci = _bi.Bonds[bond].UnpackIndex;
+ ci = _bi.Bonds[(unsigned)bond].UnpackIndex;
}
if (useFirst)
ci = firstAllowed;
else if (firstNonFilter >= 0)
- ci = firstNonFilter;
+ ci = (unsigned)firstNonFilter;
MainCoderIndex = ci;
}
@@ -919,7 +919,8 @@ HRESULT CMixerMT::SetBindInfo(const CBindInfo &bindInfo)
_streamBinders.Clear();
FOR_VECTOR (i, _bi.Bonds)
{
- RINOK(_streamBinders.AddNew().CreateEvents());
+ // RINOK(_streamBinders.AddNew().CreateEvents());
+ _streamBinders.AddNew();
}
return S_OK;
}
@@ -941,10 +942,13 @@ CCoder &CMixerMT::GetCoder(unsigned index)
return _coders[index];
}
-void CMixerMT::ReInit()
+HRESULT CMixerMT::ReInit2()
{
FOR_VECTOR (i, _streamBinders)
- _streamBinders[i].ReInit();
+ {
+ RINOK(_streamBinders[i].Create_ReInit());
+ }
+ return S_OK;
}
void CMixerMT::SelectMainCoder(bool useFirst)
@@ -962,10 +966,10 @@ void CMixerMT::SelectMainCoder(bool useFirst)
UInt32 st = _bi.Coder_to_Stream[ci];
if (_bi.IsStream_in_PackStreams(st))
break;
- int bond = _bi.FindBond_for_PackStream(st);
+ const int bond = _bi.FindBond_for_PackStream(st);
if (bond < 0)
throw 20150213;
- ci = _bi.Bonds[bond].UnpackIndex;
+ ci = _bi.Bonds[(unsigned)bond].UnpackIndex;
}
MainCoderIndex = ci;
@@ -1012,9 +1016,9 @@ HRESULT CMixerMT::Init(ISequentialInStream * const *inStreams, ISequentialOutStr
outCoderStreamIndex = EncodeMode ? coderStreamIndex : 0;
}
- _streamBinders[i].CreateStreams(
- &_coders[inCoderIndex].InStreams[inCoderStreamIndex],
- &_coders[outCoderIndex].OutStreams[outCoderStreamIndex]);
+ _streamBinders[i].CreateStreams2(
+ _coders[inCoderIndex].InStreams[inCoderStreamIndex],
+ _coders[outCoderIndex].OutStreams[outCoderStreamIndex]);
CMyComPtr<ICompressSetBufSize> inSetSize, outSetSize;
_coders[inCoderIndex].QueryInterface(IID_ICompressSetBufSize, (void **)&inSetSize);
@@ -1072,18 +1076,31 @@ HRESULT CMixerMT::Code(
for (i = 0; i < _coders.Size(); i++)
if (i != MainCoderIndex)
{
- RINOK(_coders[i].Create());
+ const WRes wres = _coders[i].Create();
+ if (wres != 0)
+ return HRESULT_FROM_WIN32(wres);
}
for (i = 0; i < _coders.Size(); i++)
if (i != MainCoderIndex)
- _coders[i].Start();
+ {
+ const WRes wres = _coders[i].Start();
+ if (wres != 0)
+ return HRESULT_FROM_WIN32(wres);
+ }
_coders[MainCoderIndex].Code(progress);
+ WRes wres = 0;
for (i = 0; i < _coders.Size(); i++)
if (i != MainCoderIndex)
- _coders[i].WaitExecuteFinish();
+ {
+ WRes wres2 = _coders[i].WaitExecuteFinish();
+ if (wres == 0)
+ wres = wres2;
+ }
+ if (wres != 0)
+ return HRESULT_FROM_WIN32(wres);
RINOK(ReturnIfError(E_ABORT));
RINOK(ReturnIfError(E_OUTOFMEMORY));
diff --git a/CPP/7zip/Archive/Common/CoderMixer2.h b/CPP/7zip/Archive/Common/CoderMixer2.h
index 798411ab..f099ac3e 100644
--- a/CPP/7zip/Archive/Common/CoderMixer2.h
+++ b/CPP/7zip/Archive/Common/CoderMixer2.h
@@ -107,7 +107,7 @@ struct CBindInfo
{
FOR_VECTOR (i, Bonds)
if (Bonds[i].PackIndex == packStream)
- return i;
+ return (int)i;
return -1;
}
@@ -115,7 +115,7 @@ struct CBindInfo
{
FOR_VECTOR (i, Bonds)
if (Bonds[i].UnpackIndex == unpackStream)
- return i;
+ return (int)i;
return -1;
}
@@ -144,7 +144,7 @@ struct CBindInfo
{
FOR_VECTOR(i, PackStreams)
if (PackStreams[i] == streamIndex)
- return i;
+ return (int)i;
return -1;
}
@@ -251,6 +251,7 @@ public:
// , InternalPackSizeError(false)
{}
+ virtual ~CMixer() {};
/*
Sequence of calling:
@@ -279,7 +280,7 @@ public:
virtual void AddCoder(const CCreatedCoder &cod) = 0;
virtual CCoder &GetCoder(unsigned index) = 0;
virtual void SelectMainCoder(bool useFirst) = 0;
- virtual void ReInit() = 0;
+ virtual HRESULT ReInit2() = 0;
virtual void SetCoderInfo(unsigned coderIndex, const UInt64 *unpackSize, const UInt64 * const *packSizes, bool finish) = 0;
virtual HRESULT Code(
ISequentialInStream * const *inStreams,
@@ -322,6 +323,8 @@ class CMixerST:
public CMixer,
public CMyUnknownImp
{
+ CLASS_NO_COPY(CMixerST)
+
HRESULT GetInStream2(ISequentialInStream * const *inStreams, /* const UInt64 * const *inSizes, */
UInt32 outStreamIndex, ISequentialInStream **inStreamRes);
HRESULT GetInStream(ISequentialInStream * const *inStreams, /* const UInt64 * const *inSizes, */
@@ -345,7 +348,7 @@ public:
virtual void AddCoder(const CCreatedCoder &cod);
virtual CCoder &GetCoder(unsigned index);
virtual void SelectMainCoder(bool useFirst);
- virtual void ReInit();
+ virtual HRESULT ReInit2();
virtual void SetCoderInfo(unsigned coderIndex, const UInt64 *unpackSize, const UInt64 * const *packSizes, bool finish)
{ _coders[coderIndex].SetCoderInfo(unpackSize, packSizes, finish); }
virtual HRESULT Code(
@@ -402,7 +405,7 @@ public:
};
CCoderMT(): EncodeMode(false) {}
- ~CCoderMT() { CVirtThread::WaitThreadFinish(); }
+ virtual ~CCoderMT() { CVirtThread::WaitThreadFinish(); }
void Code(ICompressProgressInfo *progress);
};
@@ -413,11 +416,14 @@ class CMixerMT:
public CMixer,
public CMyUnknownImp
{
+ CLASS_NO_COPY(CMixerMT)
+
CObjectVector<CStreamBinder> _streamBinders;
HRESULT Init(ISequentialInStream * const *inStreams, ISequentialOutStream * const *outStreams);
HRESULT ReturnIfError(HRESULT code);
+ // virtual ~CMixerMT() {};
public:
CObjectVector<CCoderMT> _coders;
@@ -427,7 +433,7 @@ public:
virtual void AddCoder(const CCreatedCoder &cod);
virtual CCoder &GetCoder(unsigned index);
virtual void SelectMainCoder(bool useFirst);
- virtual void ReInit();
+ virtual HRESULT ReInit2();
virtual void SetCoderInfo(unsigned coderIndex, const UInt64 *unpackSize, const UInt64 * const *packSizes, bool finish)
{ _coders[coderIndex].SetCoderInfo(unpackSize, packSizes, finish); }
virtual HRESULT Code(
diff --git a/CPP/7zip/Archive/Common/HandlerOut.cpp b/CPP/7zip/Archive/Common/HandlerOut.cpp
index 77a35c74..972a766a 100644
--- a/CPP/7zip/Archive/Common/HandlerOut.cpp
+++ b/CPP/7zip/Archive/Common/HandlerOut.cpp
@@ -179,8 +179,8 @@ HRESULT CMultiMethodProps::SetProperty(const wchar_t *nameSpec, const PROPVARIAN
}
if (number > 64)
return E_FAIL;
- for (int j = _methods.Size(); j <= (int)number; j++)
- _methods.Add(COneMethodInfo());
+ for (unsigned j = _methods.Size(); j <= number; j++)
+ _methods.AddNew();
return _methods[number].ParseMethodFromPROPVARIANT(realName, value);
}
diff --git a/CPP/7zip/Archive/Common/ItemNameUtils.cpp b/CPP/7zip/Archive/Common/ItemNameUtils.cpp
index d5093a24..905a863d 100644
--- a/CPP/7zip/Archive/Common/ItemNameUtils.cpp
+++ b/CPP/7zip/Archive/Common/ItemNameUtils.cpp
@@ -8,7 +8,10 @@ namespace NArchive {
namespace NItemName {
static const wchar_t kOsPathSepar = WCHAR_PATH_SEPARATOR;
+
+#if WCHAR_PATH_SEPARATOR != L'/'
static const wchar_t kUnixPathSepar = L'/';
+#endif
void ReplaceSlashes_OsToUnix
#if WCHAR_PATH_SEPARATOR != L'/'
@@ -44,17 +47,35 @@ UString GetOsPath_Remove_TailSlash(const UString &name)
}
-void ReplaceToOsSlashes_Remove_TailSlash(UString &name)
-{
- if (!name.IsEmpty())
- {
+void ReplaceToOsSlashes_Remove_TailSlash(UString &name, bool
#if WCHAR_PATH_SEPARATOR != L'/'
- name.Replace(kUnixPathSepar, kOsPathSepar);
+ useBackslashReplacement
#endif
-
- if (name.Back() == kOsPathSepar)
- name.DeleteBack();
+ )
+{
+ if (name.IsEmpty())
+ return;
+
+ #if WCHAR_PATH_SEPARATOR != L'/'
+ {
+ // name.Replace(kUnixPathSepar, kOsPathSepar);
+ const unsigned len = name.Len();
+ for (unsigned i = 0; i < len; i++)
+ {
+ wchar_t c = name[i];
+ if (c == L'/')
+ c = WCHAR_PATH_SEPARATOR;
+ else if (useBackslashReplacement && c == L'\\')
+ c = WCHAR_IN_FILE_NAME_BACKSLASH_REPLACEMENT; // WSL scheme
+ else
+ continue;
+ name.ReplaceOneCharAtPos(i, c);
+ }
}
+ #endif
+
+ if (name.Back() == kOsPathSepar)
+ name.DeleteBack();
}
@@ -66,12 +87,15 @@ bool HasTailSlash(const AString &name, UINT
{
if (name.IsEmpty())
return false;
- char c =
+ char c;
#if defined(_WIN32) && !defined(UNDER_CE)
- *CharPrevExA((WORD)codePage, name, name.Ptr(name.Len()), 0);
- #else
- name.Back();
+ if (codePage != CP_UTF8)
+ c = *CharPrevExA((WORD)codePage, name, name.Ptr(name.Len()), 0);
+ else
#endif
+ {
+ c = name.Back();
+ }
return (c == '/');
}
diff --git a/CPP/7zip/Archive/Common/ItemNameUtils.h b/CPP/7zip/Archive/Common/ItemNameUtils.h
index 31150864..6a4d6c71 100644
--- a/CPP/7zip/Archive/Common/ItemNameUtils.h
+++ b/CPP/7zip/Archive/Common/ItemNameUtils.h
@@ -13,7 +13,7 @@ void ReplaceSlashes_OsToUnix(UString &name);
UString GetOsPath(const UString &name);
UString GetOsPath_Remove_TailSlash(const UString &name);
-void ReplaceToOsSlashes_Remove_TailSlash(UString &name);
+void ReplaceToOsSlashes_Remove_TailSlash(UString &name, bool useBackslashReplacement = false);
bool HasTailSlash(const AString &name, UINT codePage);
diff --git a/CPP/7zip/Archive/Common/MultiStream.cpp b/CPP/7zip/Archive/Common/MultiStream.cpp
index 1de74afe..162fc928 100644
--- a/CPP/7zip/Archive/Common/MultiStream.cpp
+++ b/CPP/7zip/Archive/Common/MultiStream.cpp
@@ -36,7 +36,7 @@ STDMETHODIMP CMultiStream::Read(void *data, UInt32 size, UInt32 *processedSize)
UInt64 localPos = _pos - s.GlobalOffset;
if (localPos != s.LocalPos)
{
- RINOK(s.Stream->Seek(localPos, STREAM_SEEK_SET, &s.LocalPos));
+ RINOK(s.Stream->Seek((Int64)localPos, STREAM_SEEK_SET, &s.LocalPos));
}
UInt64 rem = s.Size - localPos;
if (size > rem)
@@ -60,9 +60,9 @@ STDMETHODIMP CMultiStream::Seek(Int64 offset, UInt32 seekOrigin, UInt64 *newPosi
}
if (offset < 0)
return HRESULT_WIN32_ERROR_NEGATIVE_SEEK;
- _pos = offset;
+ _pos = (UInt64)offset;
if (newPosition)
- *newPosition = offset;
+ *newPosition = (UInt64)offset;
return S_OK;
}
diff --git a/CPP/7zip/Archive/Common/OutStreamWithSha1.cpp b/CPP/7zip/Archive/Common/OutStreamWithSha1.cpp
index 77252938..ac26edf7 100644
--- a/CPP/7zip/Archive/Common/OutStreamWithSha1.cpp
+++ b/CPP/7zip/Archive/Common/OutStreamWithSha1.cpp
@@ -10,7 +10,7 @@ STDMETHODIMP COutStreamWithSha1::Write(const void *data, UInt32 size, UInt32 *pr
if (_stream)
result = _stream->Write(data, size, &size);
if (_calculate)
- Sha1_Update(&_sha, (const Byte *)data, size);
+ Sha1_Update(Sha(), (const Byte *)data, size);
_size += size;
if (processedSize)
*processedSize = size;
diff --git a/CPP/7zip/Archive/Common/OutStreamWithSha1.h b/CPP/7zip/Archive/Common/OutStreamWithSha1.h
index 41a84cd6..5a7bfef3 100644
--- a/CPP/7zip/Archive/Common/OutStreamWithSha1.h
+++ b/CPP/7zip/Archive/Common/OutStreamWithSha1.h
@@ -5,6 +5,7 @@
#include "../../../../C/Sha1.h"
+#include "../../../Common/MyBuffer2.h"
#include "../../../Common/MyCom.h"
#include "../../IStream.h"
@@ -15,10 +16,16 @@ class COutStreamWithSha1:
{
CMyComPtr<ISequentialOutStream> _stream;
UInt64 _size;
- CSha1 _sha;
+ // CSha1 _sha;
bool _calculate;
+ CAlignedBuffer _sha;
+
+ CSha1 *Sha() { return (CSha1 *)(void *)(Byte *)_sha; }
public:
MY_UNKNOWN_IMP
+
+ COutStreamWithSha1(): _sha(sizeof(CSha1)) {}
+
STDMETHOD(Write)(const void *data, UInt32 size, UInt32 *processedSize);
void SetStream(ISequentialOutStream *stream) { _stream = stream; }
void ReleaseStream() { _stream.Release(); }
@@ -26,11 +33,11 @@ public:
{
_size = 0;
_calculate = calculate;
- Sha1_Init(&_sha);
+ Sha1_Init(Sha());
}
- void InitSha1() { Sha1_Init(&_sha); }
+ void InitSha1() { Sha1_Init(Sha()); }
UInt64 GetSize() const { return _size; }
- void Final(Byte *digest) { Sha1_Final(&_sha, digest); }
+ void Final(Byte *digest) { Sha1_Final(Sha(), digest); }
};
#endif
diff --git a/CPP/7zip/Archive/CpioHandler.cpp b/CPP/7zip/Archive/CpioHandler.cpp
index b8fb530f..ffdab16c 100644
--- a/CPP/7zip/Archive/CpioHandler.cpp
+++ b/CPP/7zip/Archive/CpioHandler.cpp
@@ -131,7 +131,7 @@ enum EErrorType
{
k_ErrorType_OK,
k_ErrorType_Corrupted,
- k_ErrorType_UnexpectedEnd,
+ k_ErrorType_UnexpectedEnd
};
struct CInArchive
@@ -218,7 +218,7 @@ API_FUNC_static_IsArc IsArc_Cpio(const Byte *p, size_t size)
{
if (size < k_OctRecord_Size)
return k_IsArc_Res_NEED_MORE;
- for (int i = 6; i < k_OctRecord_Size; i++)
+ for (unsigned i = 6; i < k_OctRecord_Size; i++)
{
char c = p[i];
if (c < '0' || c > '7')
@@ -231,7 +231,7 @@ API_FUNC_static_IsArc IsArc_Cpio(const Byte *p, size_t size)
{
if (size < k_HexRecord_Size)
return k_IsArc_Res_NEED_MORE;
- for (int i = 6; i < k_HexRecord_Size; i++)
+ for (unsigned i = 6; i < k_HexRecord_Size; i++)
{
char c = p[i];
if ((c < '0' || c > '9') &&
@@ -268,7 +268,9 @@ API_FUNC_static_IsArc IsArc_Cpio(const Byte *p, size_t size)
if (nameSize > (1 << 8))
return k_IsArc_Res_NO;
}
- if (numLinks == 0 || numLinks >= (1 << 10))
+ // 20.03: some cpio files have (numLinks == 0).
+ // if (numLinks == 0) return k_IsArc_Res_NO;
+ if (numLinks >= (1 << 10))
return k_IsArc_Res_NO;
if (nameSize == 0 || nameSize > kNameSizeMax)
return k_IsArc_Res_NO;
@@ -462,6 +464,9 @@ STDMETHODIMP CHandler::GetArchiveProperty(PROPID propID, PROPVARIANT *value)
{
case k_ErrorType_UnexpectedEnd: v |= kpv_ErrorFlags_UnexpectedEnd; break;
case k_ErrorType_Corrupted: v |= kpv_ErrorFlags_HeadersError; break;
+ case k_ErrorType_OK:
+ default:
+ break;
}
prop = v;
break;
@@ -565,23 +570,30 @@ STDMETHODIMP CHandler::Open(IInStream *stream, const UInt64 *, IArchiveOpenCallb
{
// Read tailing zeros.
// Most of cpio files use 512-bytes aligned zeros
- UInt64 pos = arc.Processed;
- const UInt32 kTailSize_MAX = 1 << 9;
+ // rare case: 4K/8K aligment is possible also
+ const unsigned kTailSize_MAX = 1 << 9;
Byte buf[kTailSize_MAX];
- UInt32 rem = (kTailSize_MAX - (UInt32)pos) & (kTailSize_MAX - 1);
- if (rem != 0)
+ unsigned pos = (unsigned)arc.Processed & (kTailSize_MAX - 1);
+ if (pos != 0) // use this check to support 512 bytes alignment only
+ for (;;)
{
- rem++; // we need to see that it's end of file
+ unsigned rem = kTailSize_MAX - pos;
size_t processed = rem;
- RINOK(ReadStream(stream, buf, &processed));
- if (processed < rem)
- {
- unsigned i;
- for (i = 0; i < processed && buf[i] == 0; i++);
- if (i == processed)
- _phySize += processed;
- }
+ RINOK(ReadStream(stream, buf + pos, &processed));
+ if (processed != rem)
+ break;
+
+ for (; pos < kTailSize_MAX && buf[pos] == 0; pos++)
+ {}
+ if (pos != kTailSize_MAX)
+ break;
+ _phySize += processed;
+ pos = 0;
+
+ // use break to support 512 bytes alignment zero tail
+ // don't use break to support 512*n bytes alignment zero tail
+ break;
}
}
@@ -622,7 +634,9 @@ STDMETHODIMP CHandler::GetProperty(UInt32 index, PROPID propID, PROPVARIANT *val
UString res;
bool needConvert = true;
#ifdef _WIN32
- if (ConvertUTF8ToUnicode(item.Name, res))
+ // if (
+ ConvertUTF8ToUnicode(item.Name, res);
+ // )
needConvert = false;
#endif
if (needConvert)
diff --git a/CPP/7zip/Archive/DllExports2.cpp b/CPP/7zip/Archive/DllExports2.cpp
index 10889e75..967a7cbf 100644
--- a/CPP/7zip/Archive/DllExports2.cpp
+++ b/CPP/7zip/Archive/DllExports2.cpp
@@ -22,11 +22,24 @@
#include "IArchive.h"
-HINSTANCE g_hInstance;
+#ifdef _WIN32
+
+#if defined(_UNICODE) && !defined(_WIN64) && !defined(UNDER_CE)
#define NT_CHECK_FAIL_ACTION return FALSE;
+#endif
+
+HINSTANCE g_hInstance;
+
+extern "C"
+BOOL WINAPI DllMain(
+ #ifdef UNDER_CE
+ HANDLE
+ #else
+ HINSTANCE
+ #endif
+ hInstance, DWORD dwReason, LPVOID /*lpReserved*/);
-#ifdef _WIN32
extern "C"
BOOL WINAPI DllMain(
#ifdef UNDER_CE
@@ -50,7 +63,22 @@ BOOL WINAPI DllMain(
*/
return TRUE;
}
-#endif
+
+#else // _WIN32
+
+#include "../../Common/StringConvert.h"
+// #include <stdio.h>
+
+// STDAPI LibStartup();
+static __attribute__((constructor)) void Init_ForceToUTF8();
+static __attribute__((constructor)) void Init_ForceToUTF8()
+{
+ g_ForceToUTF8 = IsNativeUTF8();
+ // printf("\nDLLExports2.cpp::Init_ForceToUTF8 =%d\n", g_ForceToUTF8 ? 1 : 0);
+}
+
+#endif // _WIN32
+
DEFINE_GUID(CLSID_CArchiveHandler,
k_7zip_GUID_Data1,
@@ -62,6 +90,7 @@ STDAPI CreateCoder(const GUID *clsid, const GUID *iid, void **outObject);
STDAPI CreateHasher(const GUID *clsid, IHasher **hasher);
STDAPI CreateArchiver(const GUID *clsid, const GUID *iid, void **outObject);
+STDAPI CreateObject(const GUID *clsid, const GUID *iid, void **outObject);
STDAPI CreateObject(const GUID *clsid, const GUID *iid, void **outObject)
{
// COM_TRY_BEGIN
@@ -76,16 +105,20 @@ STDAPI CreateObject(const GUID *clsid, const GUID *iid, void **outObject)
// COM_TRY_END
}
+STDAPI SetLargePageMode();
STDAPI SetLargePageMode()
{
#if defined(_7ZIP_LARGE_PAGES)
+ #ifdef _WIN32
SetLargePageSize();
#endif
+ #endif
return S_OK;
}
extern bool g_CaseSensitive;
+STDAPI SetCaseSensitive(Int32 caseSensitive);
STDAPI SetCaseSensitive(Int32 caseSensitive)
{
g_CaseSensitive = (caseSensitive != 0);
@@ -96,6 +129,7 @@ STDAPI SetCaseSensitive(Int32 caseSensitive)
CExternalCodecs g_ExternalCodecs;
+STDAPI SetCodecs(ICompressCodecsInfo *compressCodecsInfo);
STDAPI SetCodecs(ICompressCodecsInfo *compressCodecsInfo)
{
COM_TRY_BEGIN
@@ -114,6 +148,7 @@ STDAPI SetCodecs(ICompressCodecsInfo *compressCodecsInfo)
#else
+STDAPI SetCodecs(ICompressCodecsInfo *);
STDAPI SetCodecs(ICompressCodecsInfo *)
{
return S_OK;
diff --git a/CPP/7zip/Archive/DmgHandler.cpp b/CPP/7zip/Archive/DmgHandler.cpp
index d9fe6016..a08dcac1 100644
--- a/CPP/7zip/Archive/DmgHandler.cpp
+++ b/CPP/7zip/Archive/DmgHandler.cpp
@@ -33,99 +33,22 @@
#define Get32(p) GetBe32(p)
#define Get64(p) GetBe64(p)
-static const Byte k_Base64Table[256] =
-{
- 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,77,77,77,77,77,
- 65,77,77,77,77,77,77,77,77,77,77,62,77,77,77,63,
- 52,53,54,55,56,57,58,59,60,61,77,77,77,64,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,
- 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,
- 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)
-{
- UInt32 val = 1;
-
- for (;;)
- {
- UInt32 c = k_Base64Table[(Byte)(*src++)];
-
- if (c < 64)
- {
- val = (val << 6) | c;
- if ((val & ((UInt32)1 << 24)) == 0)
- continue;
- dest[0] = (Byte)(val >> 16);
- dest[1] = (Byte)(val >> 8);
- dest[2] = (Byte)(val);
- dest += 3;
- val = 1;
- continue;
- }
-
- if (c == 65) // space
- continue;
-
- if (c == 64) // '='
- break;
-
- if (c == 66 && val == 1) // end of string
- return dest;
-
- return NULL;
- }
-
- if (val < (1 << 12))
- return NULL;
-
- if (val & (1 << 18))
- {
- *dest++ = (Byte)(val >> 10);
- *dest++ = (Byte)(val >> 2);
- }
- 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;
- }
-}
-
+Byte *Base64ToBin(Byte *dest, const char *src);
namespace NArchive {
namespace NDmg {
-enum
-{
- METHOD_ZERO_0 = 0,
- METHOD_COPY = 1,
- METHOD_ZERO_2 = 2, // without file CRC calculation
- METHOD_ADC = 0x80000004,
- METHOD_ZLIB = 0x80000005,
- METHOD_BZIP2 = 0x80000006,
- METHOD_LZFSE = 0x80000007,
- METHOD_COMMENT = 0x7FFFFFFE, // is used to comment "+beg" and "+end" in extra field.
- METHOD_END = 0xFFFFFFFF
-};
+
+static const UInt32 METHOD_ZERO_0 = 0;
+static const UInt32 METHOD_COPY = 1;
+static const UInt32 METHOD_ZERO_2 = 2; // without file CRC calculation
+static const UInt32 METHOD_ADC = 0x80000004;
+static const UInt32 METHOD_ZLIB = 0x80000005;
+static const UInt32 METHOD_BZIP2 = 0x80000006;
+static const UInt32 METHOD_LZFSE = 0x80000007;
+static const UInt32 METHOD_COMMENT = 0x7FFFFFFE; // is used to comment "+beg" and "+end" in extra field.
+static const UInt32 METHOD_END = 0xFFFFFFFF;
+
struct CBlock
{
@@ -266,7 +189,7 @@ void CMethods::GetString(AString &res) const
for (i = 0; i < Types.Size(); i++)
{
- UInt32 type = Types[i];
+ const UInt32 type = Types[i];
if (type == METHOD_COMMENT || type == METHOD_END)
continue;
char buf[16];
@@ -407,6 +330,7 @@ STDMETHODIMP CHandler::GetArchiveProperty(PROPID propID, PROPVARIANT *value)
case kpidWarning:
if (_masterCrcError)
prop = "Master CRC error";
+ break;
case kpidWarningFlags:
{
@@ -727,7 +651,8 @@ HRESULT CHandler::Open2(IInStream *stream)
if (xmlPair2.Len > len)
xmlPair2.Len = len;
CByteBuffer buf2;
- if (ReadData(stream, xmlPair2, buf2) != S_OK
+ if (xmlPair2.Len < len
+ || ReadData(stream, xmlPair2, buf2) != S_OK
|| memcmp(buf2, sz, len) != 0)
{
// if absolute offset is not OK, probably it's archive with offset
@@ -1054,7 +979,9 @@ STDMETHODIMP CHandler::GetNumberOfItems(UInt32 *numItems)
return S_OK;
}
+#ifdef DMG_SHOW_RAW
#define RAW_PREFIX "raw" STRING_PATH_SEPARATOR
+#endif
STDMETHODIMP CHandler::GetProperty(UInt32 index, PROPID propID, PROPVARIANT *value)
{
@@ -1608,7 +1535,7 @@ public:
};
-unsigned FindBlock(const CRecordVector<CBlock> &blocks, UInt64 pos)
+static unsigned FindBlock(const CRecordVector<CBlock> &blocks, UInt64 pos)
{
unsigned left = 0, right = blocks.Size();
for (;;)
@@ -1762,8 +1689,8 @@ STDMETHODIMP CInStream::Read(void *data, UInt32 size, UInt32 *processedSize)
}
const CBlock &block = File->Blocks[_latestBlock];
- UInt64 offset = _virtPos - block.UnpPos;
- UInt64 rem = block.UnpSize - offset;
+ const UInt64 offset = _virtPos - block.UnpPos;
+ const UInt64 rem = block.UnpSize - offset;
if (size > rem)
size = (UInt32)rem;
@@ -1777,7 +1704,7 @@ STDMETHODIMP CInStream::Read(void *data, UInt32 size, UInt32 *processedSize)
else if (block.IsZeroMethod())
memset(data, 0, size);
else if (size != 0)
- memcpy(data, _chunks[_latestChunk].Buf + offset, size);
+ memcpy(data, _chunks[_latestChunk].Buf + (size_t)offset, size);
_virtPos += size;
if (processedSize)
diff --git a/CPP/7zip/Archive/ElfHandler.cpp b/CPP/7zip/Archive/ElfHandler.cpp
index c5ce279e..efcde95d 100644
--- a/CPP/7zip/Archive/ElfHandler.cpp
+++ b/CPP/7zip/Archive/ElfHandler.cpp
@@ -226,6 +226,7 @@ void CSegment::Parse(const Byte *p, bool mode64, bool be)
// Section types
+/*
#define SHT_NULL 0
#define SHT_PROGBITS 1
#define SHT_SYMTAB 2
@@ -234,7 +235,9 @@ void CSegment::Parse(const Byte *p, bool mode64, bool be)
#define SHT_HASH 5
#define SHT_DYNAMIC 6
#define SHT_NOTE 7
+*/
#define SHT_NOBITS 8
+/*
#define SHT_REL 9
#define SHT_SHLIB 10
#define SHT_DYNSYM 11
@@ -245,7 +248,7 @@ void CSegment::Parse(const Byte *p, bool mode64, bool be)
#define SHT_PREINIT_ARRAY 16
#define SHT_GROUP 17
#define SHT_SYMTAB_SHNDX 18
-
+*/
static const CUInt32PCharPair g_SectTypes[] =
{
@@ -633,11 +636,11 @@ static const CUInt32PCharPair g_MIPS_Flags[] =
};
-#define ET_NONE 0
+// #define ET_NONE 0
#define ET_REL 1
-#define ET_EXEC 2
+// #define ET_EXEC 2
#define ET_DYN 3
-#define ET_CORE 4
+// #define ET_CORE 4
static const char * const g_Types[] =
{
diff --git a/CPP/7zip/Archive/ExtHandler.cpp b/CPP/7zip/Archive/ExtHandler.cpp
index db65fbea..e9808aac 100644
--- a/CPP/7zip/Archive/ExtHandler.cpp
+++ b/CPP/7zip/Archive/ExtHandler.cpp
@@ -99,6 +99,8 @@ static UInt32 Crc16Calc(Byte const *data, size_t size)
#define EXT4_GOOD_OLD_INODE_SIZE 128
+#define EXT_NODE_SIZE_MIN 128
+
// inodes numbers
@@ -436,9 +438,9 @@ bool CHeader::Parse(const Byte *p)
LE_16 (0x58, InodeSize);
if (FirstInode < k_INODE_GOOD_OLD_FIRST)
return false;
- if (InodeSize > (UInt32)1 << BlockBits)
- return false;
- if (GetLog(InodeSize) < 0)
+ if (InodeSize > ((UInt32)1 << BlockBits)
+ || InodeSize < EXT_NODE_SIZE_MIN
+ || GetLog(InodeSize) < 0)
return false;
}
@@ -603,7 +605,7 @@ struct CExtent
if (Len > (UInt32)0x8000)
{
IsInited = false;
- Len -= (UInt32)0x8000;
+ Len = (UInt16)(Len - (UInt32)0x8000);
}
LE_32 (0x08, PhyStart);
UInt16 hi;
@@ -628,8 +630,8 @@ struct CNode
int DirIndex; // in _dirs[]
UInt16 Mode;
- UInt16 Uid;
- UInt16 Gid;
+ UInt32 Uid; // fixed 21.02
+ UInt32 Gid; // fixed 21.02
// UInt16 Checksum;
UInt64 FileSize;
@@ -730,6 +732,8 @@ bool CNode::Parse(const Byte *p, const CHeader &_h)
if (_h.InodeSize > 128)
{
+ // InodeSize is power of 2, so the following check is not required:
+ // if (_h.InodeSize < 128 + 2) return false;
UInt16 extra_isize;
LE_16 (0x80, extra_isize);
if (128 + extra_isize > _h.InodeSize)
@@ -842,7 +846,7 @@ class CHandler:
}
- const int GetParentAux(const CItem &item) const
+ int GetParentAux(const CItem &item) const
{
if (item.Node < _h.FirstInode && _auxSysIndex >= 0)
return _auxSysIndex;
@@ -931,7 +935,7 @@ HRESULT CHandler::ParseDir(const Byte *p, size_t size, unsigned iNodeDir)
return S_FALSE;
if (_isUTF)
- _isUTF = CheckUTF8(item.Name);
+ _isUTF = CheckUTF8_AString(item.Name);
if (iNode == 0)
{
@@ -1201,7 +1205,7 @@ HRESULT CHandler::Open2(IInStream *inStream)
UInt32 numNodes = _h.InodesPerGroup;
if (numNodes > _h.NumInodes)
numNodes = _h.NumInodes;
- size_t nodesDataSize = (size_t)numNodes * _h.InodeSize;
+ const size_t nodesDataSize = (size_t)numNodes * _h.InodeSize;
if (nodesDataSize / _h.InodeSize != numNodes)
return S_FALSE;
@@ -1213,7 +1217,7 @@ HRESULT CHandler::Open2(IInStream *inStream)
return S_FALSE;
}
- UInt32 numReserveInodes = _h.NumInodes - _h.NumFreeInodes + 1;
+ const UInt32 numReserveInodes = _h.NumInodes - _h.NumFreeInodes + 1;
// numReserveInodes = _h.NumInodes + 1;
if (numReserveInodes != 0)
{
@@ -1348,7 +1352,8 @@ HRESULT CHandler::Open2(IInStream *inStream)
RINOK(CheckProgress());
}
- if (_nodes[_refs[k_INODE_ROOT]].ParentNode != k_INODE_ROOT)
+ int ref = _refs[k_INODE_ROOT];
+ if (ref < 0 || _nodes[ref].ParentNode != k_INODE_ROOT)
return S_FALSE;
}
diff --git a/CPP/7zip/Archive/FatHandler.cpp b/CPP/7zip/Archive/FatHandler.cpp
index bf6053e0..1cbc8508 100644
--- a/CPP/7zip/Archive/FatHandler.cpp
+++ b/CPP/7zip/Archive/FatHandler.cpp
@@ -682,7 +682,7 @@ HRESULT CDatabase::Open()
RINOK(ReadStream_FALSE(InStream, byteBuf, readSize));
NumCurUsedBytes += readSize;
- const UInt32 *src = (const UInt32 *)(const Byte *)byteBuf;
+ const UInt32 *src = (const UInt32 *)(const void *)(const Byte *)byteBuf;
UInt32 *dest = Fat + i;
if (numFreeClustersDefined)
for (UInt32 j = 0; j < size; j++)
diff --git a/CPP/7zip/Archive/FlvHandler.cpp b/CPP/7zip/Archive/FlvHandler.cpp
index 1f52f60b..97a7c268 100644
--- a/CPP/7zip/Archive/FlvHandler.cpp
+++ b/CPP/7zip/Archive/FlvHandler.cpp
@@ -23,14 +23,14 @@
((UInt32)((const Byte *)(p))[1] << 8) | \
((const Byte *)(p))[2] )
-#define Get16(p) GetBe16(p)
+// #define Get16(p) GetBe16(p)
#define Get24(p) GetBe24(p)
#define Get32(p) GetBe32(p)
namespace NArchive {
namespace NFlv {
-static const UInt32 kFileSizeMax = (UInt32)1 << 30;
+// static const UInt32 kFileSizeMax = (UInt32)1 << 30;
static const UInt32 kNumChunksMax = (UInt32)1 << 23;
static const UInt32 kTagHeaderSize = 11;
diff --git a/CPP/7zip/Archive/GptHandler.cpp b/CPP/7zip/Archive/GptHandler.cpp
index a86ad37c..7b3d23bb 100644
--- a/CPP/7zip/Archive/GptHandler.cpp
+++ b/CPP/7zip/Archive/GptHandler.cpp
@@ -333,16 +333,25 @@ STDMETHODIMP CHandler::GetProperty(UInt32 index, PROPID propID, PROPVARIANT *val
{
case kpidPath:
{
+ // Windows BDP partitions can have identical names.
+ // So we add the partition number at front
UString s;
- for (unsigned i = 0; i < kNameLen; i++)
+ s.Add_UInt32(index);
{
- wchar_t c = (wchar_t)Get16(item.Name + i * 2);
- if (c == 0)
- break;
- s += c;
+ UString s2;
+ for (unsigned i = 0; i < kNameLen; i++)
+ {
+ wchar_t c = (wchar_t)Get16(item.Name + i * 2);
+ if (c == 0)
+ break;
+ s2 += c;
+ }
+ if (!s2.IsEmpty())
+ {
+ s += '.';
+ s += s2;
+ }
}
- if (s.IsEmpty())
- s.Add_UInt32(index);
{
s += '.';
const char *ext = NULL;
diff --git a/CPP/7zip/Archive/GzHandler.cpp b/CPP/7zip/Archive/GzHandler.cpp
index 130f8b35..0054840d 100644
--- a/CPP/7zip/Archive/GzHandler.cpp
+++ b/CPP/7zip/Archive/GzHandler.cpp
@@ -45,7 +45,7 @@ namespace NGz {
namespace NFlags
{
- const Byte kIsText = 1 << 0;
+ // const Byte kIsText = 1 << 0;
const Byte kCrc = 1 << 1;
const Byte kExtra = 1 << 2;
const Byte kName = 1 << 3;
@@ -234,7 +234,8 @@ static UInt32 Is_Deflate(const Byte *p, size_t size)
return k_IsArc_Res_NO;
if (size < 4)
return k_IsArc_Res_NEED_MORE;
- if (GetUi16(p) != (UInt16)~GetUi16(p + 2))
+ UInt16 r = (UInt16)~GetUi16(p + 2);
+ if (GetUi16(p) != r)
return k_IsArc_Res_NO;
}
else if (type == 2)
@@ -248,8 +249,8 @@ static UInt32 Is_Deflate(const Byte *p, size_t size)
return k_IsArc_Res_YES;
}
-static unsigned kNameMaxLen = 1 << 12;
-static unsigned kCommentMaxLen = 1 << 16;
+static const unsigned kNameMaxLen = 1 << 12;
+static const unsigned kCommentMaxLen = 1 << 16;
API_FUNC_static_IsArc IsArc_Gz(const Byte *p, size_t size)
{
@@ -962,7 +963,7 @@ STDMETHODIMP CHandler::UpdateItems(ISequentialOutStream *outStream, UInt32 numIt
UString name = prop.bstrVal;
int slashPos = name.ReverseFind_PathSepar();
if (slashPos >= 0)
- name.DeleteFrontal(slashPos + 1);
+ name.DeleteFrontal((unsigned)(slashPos + 1));
newItem.Name = UnicodeStringToMultiByte(name, CP_ACP);
if (!newItem.Name.IsEmpty())
newItem.Flags |= NFlags::kName;
@@ -1019,7 +1020,7 @@ STDMETHODIMP CHandler::UpdateItems(ISequentialOutStream *outStream, UInt32 numIt
newItem.WriteHeader(outStream);
offset += _headerSize;
}
- RINOK(_stream->Seek(offset, STREAM_SEEK_SET, NULL));
+ RINOK(_stream->Seek((Int64)offset, STREAM_SEEK_SET, NULL));
return NCompress::CopyStream(_stream, outStream, progress);
diff --git a/CPP/7zip/Archive/HandlerCont.cpp b/CPP/7zip/Archive/HandlerCont.cpp
index c2d5c70c..22a8c4a9 100644
--- a/CPP/7zip/Archive/HandlerCont.cpp
+++ b/CPP/7zip/Archive/HandlerCont.cpp
@@ -269,7 +269,7 @@ HRESULT ReadZeroTail(ISequentialInStream *stream, bool &areThereNonZeros, UInt64
for (;;)
{
UInt32 size = 0;
- HRESULT(stream->Read(buf, kBufSize, &size));
+ RINOK(stream->Read(buf, kBufSize, &size));
if (size == 0)
return S_OK;
for (UInt32 i = 0; i < size; i++)
diff --git a/CPP/7zip/Archive/HfsHandler.cpp b/CPP/7zip/Archive/HfsHandler.cpp
index ca1d7bda..57313280 100644
--- a/CPP/7zip/Archive/HfsHandler.cpp
+++ b/CPP/7zip/Archive/HfsHandler.cpp
@@ -275,7 +275,7 @@ struct CItem
CItem(): UseAttr(false), UseInlineData(false) {}
bool IsDir() const { return Type == RECORD_TYPE_FOLDER; }
- const CFork &GetFork(bool isResource) const { return (CFork & )*(isResource ? &ResourceFork: &DataFork ); }
+ const CFork &GetFork(bool isResource) const { return (const CFork & )*(isResource ? &ResourceFork: &DataFork ); }
};
struct CAttr
@@ -320,12 +320,14 @@ public:
UInt64 SpecOffset;
UInt64 PhySize;
UInt64 PhySize2;
+ UInt64 ArcFileSize;
void Clear()
{
SpecOffset = 0;
PhySize = 0;
PhySize2 = 0;
+ ArcFileSize = 0;
HeadersError = false;
ThereAreAltStreams = false;
// CaseSensetive = false;
@@ -440,7 +442,10 @@ HRESULT CDatabase::ReadFile(const CFork &fork, CByteBuffer &buf, IInStream *inSt
{
if (fork.NumBlocks >= Header.NumBlocks)
return S_FALSE;
- size_t totalSize = (size_t)fork.NumBlocks << Header.BlockSizeLog;
+ if ((ArcFileSize >> Header.BlockSizeLog) + 1 < fork.NumBlocks)
+ return S_FALSE;
+
+ const size_t totalSize = (size_t)fork.NumBlocks << Header.BlockSizeLog;
if ((totalSize >> Header.BlockSizeLog) != fork.NumBlocks)
return S_FALSE;
buf.Alloc(totalSize);
@@ -473,20 +478,36 @@ struct CNodeDescriptor
// Byte Height;
unsigned NumRecords;
- bool CheckNumRecords(unsigned nodeSizeLog)
- {
- return (kNodeDescriptor_Size + ((UInt32)NumRecords + 1) * 2 <= ((UInt32)1 << nodeSizeLog));
- }
- void Parse(const Byte *p);
+ bool Parse(const Byte *p, unsigned nodeSizeLog);
};
-void CNodeDescriptor::Parse(const Byte *p)
+
+bool CNodeDescriptor::Parse(const Byte *p, unsigned nodeSizeLog)
{
fLink = Get32(p);
// bLink = Get32(p + 4);
Kind = p[8];
// Height = p[9];
NumRecords = Get16(p + 10);
+
+ const size_t nodeSize = (size_t)1 << nodeSizeLog;
+ if (kNodeDescriptor_Size + ((UInt32)NumRecords + 1) * 2 > nodeSize)
+ return false;
+ const size_t limit = nodeSize - ((UInt32)NumRecords + 1) * 2;
+
+ p += nodeSize - 2;
+
+ for (unsigned i = 0; i < NumRecords; i++)
+ {
+ const UInt32 offs = Get16(p);
+ p -= 2;
+ const UInt32 offsNext = Get16(p);
+ if (offs < kNodeDescriptor_Size
+ || offs >= offsNext
+ || offsNext > limit)
+ return false;
+ }
+ return true;
}
struct CHeaderRec
@@ -576,7 +597,7 @@ HRESULT CDatabase::LoadExtentFile(const CFork &fork, IInStream *inStream, CObjec
if (node == 0)
return S_OK;
- CByteBuffer usedBuf(hr.TotalNodes);
+ CByteArr usedBuf(hr.TotalNodes);
memset(usedBuf, 0, hr.TotalNodes);
while (node != 0)
@@ -585,10 +606,9 @@ HRESULT CDatabase::LoadExtentFile(const CFork &fork, IInStream *inStream, CObjec
return S_FALSE;
usedBuf[node] = 1;
- size_t nodeOffset = (size_t)node << hr.NodeSizeLog;
+ const size_t nodeOffset = (size_t)node << hr.NodeSizeLog;
CNodeDescriptor desc;
- desc.Parse(p + nodeOffset);
- if (!desc.CheckNumRecords(hr.NodeSizeLog))
+ if (!desc.Parse(p + nodeOffset, hr.NodeSizeLog))
return S_FALSE;
if (desc.Kind != kNodeType_Leaf)
return S_FALSE;
@@ -597,18 +617,16 @@ HRESULT CDatabase::LoadExtentFile(const CFork &fork, IInStream *inStream, CObjec
for (unsigned i = 0; i < desc.NumRecords; i++)
{
- const UInt32 nodeSize = (UInt32)1 << hr.NodeSizeLog;
- const UInt32 offs = Get16(p + nodeOffset + nodeSize - (i + 1) * 2);
- const UInt32 offsNext = Get16(p + nodeOffset + nodeSize - (i + 2) * 2);
- if (offs > nodeSize || offsNext > nodeSize)
- return S_FALSE;
- UInt32 recSize = offsNext - offs;
+ const UInt32 nodeSize = (1 << hr.NodeSizeLog);
+ const Byte *r = p + nodeOffset + nodeSize - i * 2;
+ const UInt32 offs = Get16(r - 2);
+ UInt32 recSize = Get16(r - 4) - offs;
const unsigned kKeyLen = 10;
if (recSize != 2 + kKeyLen + kNumFixedExtents * 8)
return S_FALSE;
- const Byte *r = p + nodeOffset + offs;
+ r = p + nodeOffset + offs;
if (Get16(r) != kKeyLen)
return S_FALSE;
@@ -717,7 +735,7 @@ HRESULT CDatabase::LoadAttrs(const CFork &fork, IInStream *inStream, IArchiveOpe
if (node == 0)
return S_OK;
- CByteBuffer usedBuf(hr.TotalNodes);
+ CByteArr usedBuf(hr.TotalNodes);
memset(usedBuf, 0, hr.TotalNodes);
CFork resFork;
@@ -728,10 +746,9 @@ HRESULT CDatabase::LoadAttrs(const CFork &fork, IInStream *inStream, IArchiveOpe
return S_FALSE;
usedBuf[node] = 1;
- size_t nodeOffset = (size_t)node << hr.NodeSizeLog;
+ const size_t nodeOffset = (size_t)node << hr.NodeSizeLog;
CNodeDescriptor desc;
- desc.Parse(p + nodeOffset);
- if (!desc.CheckNumRecords(hr.NodeSizeLog))
+ if (!desc.Parse(p + nodeOffset, hr.NodeSizeLog))
return S_FALSE;
if (desc.Kind != kNodeType_Leaf)
return S_FALSE;
@@ -739,19 +756,14 @@ HRESULT CDatabase::LoadAttrs(const CFork &fork, IInStream *inStream, IArchiveOpe
for (unsigned i = 0; i < desc.NumRecords; i++)
{
const UInt32 nodeSize = (1 << hr.NodeSizeLog);
- const UInt32 offs = Get16(p + nodeOffset + nodeSize - (i + 1) * 2);
- const UInt32 offsNext = Get16(p + nodeOffset + nodeSize - (i + 2) * 2);
- UInt32 recSize = offsNext - offs;
- if (offs >= nodeSize
- || offsNext > nodeSize
- || offsNext < offs)
- return S_FALSE;
-
+ const Byte *r = p + nodeOffset + nodeSize - i * 2;
+ const UInt32 offs = Get16(r - 2);
+ UInt32 recSize = Get16(r - 4) - offs;
const unsigned kHeadSize = 14;
if (recSize < kHeadSize)
return S_FALSE;
- const Byte *r = p + nodeOffset + offs;
+ r = p + nodeOffset + offs;
UInt32 keyLen = Get16(r);
// UInt16 pad = Get16(r + 2);
@@ -805,7 +817,7 @@ HRESULT CDatabase::LoadAttrs(const CFork &fork, IInStream *inStream, IArchiveOpe
if (progress && (i & 0xFFF) == 0)
{
- UInt64 numFiles = 0;
+ const UInt64 numFiles = 0;
RINOK(progress->SetCompleted(&numFiles, NULL));
}
}
@@ -873,13 +885,6 @@ bool CDatabase::Parse_decmpgfs(const CAttr &attr, CItem &item, bool &skip)
HRESULT CDatabase::LoadCatalog(const CFork &fork, const CObjectVector<CIdExtents> *overflowExtentsArray, IInStream *inStream, IArchiveOpenCallback *progress)
{
- unsigned reserveSize = (unsigned)(Header.NumFolders + 1 + Header.NumFiles);
- Items.ClearAndReserve(reserveSize);
- Refs.ClearAndReserve(reserveSize);
-
- CRecordVector<CIdIndexPair> IdToIndexMap;
- IdToIndexMap.ClearAndReserve(reserveSize);
-
CByteBuffer buf;
RINOK(ReadFile(fork, buf, inStream));
const Byte *p = (const Byte *)buf;
@@ -888,10 +893,24 @@ HRESULT CDatabase::LoadCatalog(const CFork &fork, const CObjectVector<CIdExtents
// nodeDesc.Parse(p);
CHeaderRec hr;
RINOK(hr.Parse2(buf));
-
+
+ CRecordVector<CIdIndexPair> IdToIndexMap;
+
+ const unsigned reserveSize = (unsigned)(Header.NumFolders + 1 + Header.NumFiles);
+
+ const unsigned kBasicRecSize = 0x58;
+ const unsigned kMinRecSize = kBasicRecSize + 10;
+
+ if ((UInt64)reserveSize * kMinRecSize < buf.Size())
+ {
+ Items.ClearAndReserve(reserveSize);
+ Refs.ClearAndReserve(reserveSize);
+ IdToIndexMap.ClearAndReserve(reserveSize);
+ }
+
// CaseSensetive = (Header.IsHfsX() && hr.KeyCompareType == 0xBC);
- CByteBuffer usedBuf(hr.TotalNodes);
+ CByteArr usedBuf(hr.TotalNodes);
memset(usedBuf, 0, hr.TotalNodes);
CFork resFork;
@@ -908,8 +927,7 @@ HRESULT CDatabase::LoadCatalog(const CFork &fork, const CObjectVector<CIdExtents
const size_t nodeOffset = (size_t)node << hr.NodeSizeLog;
CNodeDescriptor desc;
- desc.Parse(p + nodeOffset);
- if (!desc.CheckNumRecords(hr.NodeSizeLog))
+ if (!desc.Parse(p + nodeOffset, hr.NodeSizeLog))
return S_FALSE;
if (desc.Kind != kNodeType_Leaf)
return S_FALSE;
@@ -917,16 +935,13 @@ HRESULT CDatabase::LoadCatalog(const CFork &fork, const CObjectVector<CIdExtents
for (unsigned i = 0; i < desc.NumRecords; i++)
{
const UInt32 nodeSize = (1 << hr.NodeSizeLog);
- const UInt32 offs = Get16(p + nodeOffset + nodeSize - (i + 1) * 2);
- const UInt32 offsNext = Get16(p + nodeOffset + nodeSize - (i + 2) * 2);
- UInt32 recSize = offsNext - offs;
- if (offs >= nodeSize
- || offsNext > nodeSize
- || offsNext < offs
- || recSize < 6)
+ const Byte *r = p + nodeOffset + nodeSize - i * 2;
+ const UInt32 offs = Get16(r - 2);
+ UInt32 recSize = Get16(r - 4) - offs;
+ if (recSize < 6)
return S_FALSE;
- const Byte *r = p + nodeOffset + offs;
+ r = p + nodeOffset + offs;
UInt32 keyLen = Get16(r);
UInt32 parentID = Get32(r + 2);
if (keyLen < 6 || (keyLen & 1) != 0 || keyLen + 2 > recSize)
@@ -952,7 +967,6 @@ HRESULT CDatabase::LoadCatalog(const CFork &fork, const CObjectVector<CIdExtents
type != RECORD_TYPE_FILE)
continue;
- const unsigned kBasicRecSize = 0x58;
if (recSize < kBasicRecSize)
return S_FALSE;
@@ -1042,7 +1056,7 @@ HRESULT CDatabase::LoadCatalog(const CFork &fork, const CObjectVector<CIdExtents
}
if (progress && (Items.Size() & 0xFFF) == 0)
{
- UInt64 numItems = Items.Size();
+ const UInt64 numItems = Items.Size();
RINOK(progress->SetCompleted(&numItems, NULL));
}
}
@@ -1286,9 +1300,12 @@ HRESULT CDatabase::Open2(IInStream *inStream, IArchiveOpenCallback *progress)
if (h.NumFolders > ((UInt32)1 << 29) ||
h.NumFiles > ((UInt32)1 << 30))
return S_FALSE;
+
+ RINOK(inStream->Seek(0, STREAM_SEEK_END, &ArcFileSize));
+
if (progress)
{
- UInt64 numFiles = (UInt64)h.NumFiles + h.NumFolders + 1;
+ const UInt64 numFiles = (UInt64)h.NumFiles + h.NumFolders + 1;
RINOK(progress->SetTotal(&numFiles, NULL));
}
@@ -1313,13 +1330,6 @@ HRESULT CDatabase::Open2(IInStream *inStream, IArchiveOpenCallback *progress)
h.VolID = Get64(p + 0x68);
*/
- /*
- UInt64 endPos;
- RINOK(inStream->Seek(0, STREAM_SEEK_END, &endPos));
- if ((endPos >> h.BlockSizeLog) < h.NumBlocks)
- return S_FALSE;
- */
-
ResFileName = kResFileName;
CFork extentsFork, catalogFork, attrFork;
@@ -1499,7 +1509,7 @@ STDMETHODIMP CHandler::GetRawProp(UInt32 index, PROPID propID, const void **data
else
s = &Items[ref.ItemIndex].Name;
*data = (const wchar_t *)(*s);
- *dataSize = (s->Len() + 1) * sizeof(wchar_t);
+ *dataSize = (s->Len() + 1) * (UInt32)sizeof(wchar_t);
*propType = PROP_DATA_TYPE_wchar_t_PTR_Z_LE;
return S_OK;
}
@@ -1700,7 +1710,7 @@ HRESULT CHandler::ExtractZlibFile(
}
outPos += blockSize;
- UInt64 progressPos = progressStart + outPos;
+ const UInt64 progressPos = progressStart + outPos;
RINOK(extractCallback->SetCompleted(&progressPos));
}
@@ -1884,7 +1894,7 @@ STDMETHODIMP CHandler::Extract(const UInt32 *indices, UInt32 numItems,
}
pos += cur;
extentRem -= cur;
- UInt64 processed = currentTotalSize + pos;
+ const UInt64 processed = currentTotalSize + pos;
RINOK(extractCallback->SetCompleted(&processed));
}
}
diff --git a/CPP/7zip/Archive/IArchive.h b/CPP/7zip/Archive/IArchive.h
index 7d7256c9..8290c735 100644
--- a/CPP/7zip/Archive/IArchive.h
+++ b/CPP/7zip/Archive/IArchive.h
@@ -10,6 +10,30 @@
#define ARCHIVE_INTERFACE_SUB(i, base, x) DECL_INTERFACE_SUB(i, base, 6, x)
#define ARCHIVE_INTERFACE(i, x) ARCHIVE_INTERFACE_SUB(i, IUnknown, x)
+/*
+How the function in 7-Zip returns object for output parameter via pointer
+
+1) The caller sets the value of variable before function call:
+ PROPVARIANT : vt = VT_EMPTY
+ BSTR : NULL
+ IUnknown* and derived interfaces : NULL
+ another scalar types : any non-initialized value is allowed
+
+2) The callee in current 7-Zip code now can free input object for output parameter:
+ PROPVARIANT : the callee calls VariantClear(propvaiant_ptr) for input
+ value stored in variable
+ another types : the callee ignores stored value.
+
+3) The callee writes new value to variable for output parameter and
+ returns execution to caller.
+
+4) The caller must free or release object returned by the callee:
+ PROPVARIANT : VariantClear(&propvaiant)
+ BSTR : SysFreeString(bstr)
+ IUnknown* and derived interfaces : if (ptr) ptr->Relase()
+*/
+
+
namespace NFileTimeType
{
enum EEnum
@@ -34,6 +58,7 @@ namespace NArcInfoFlags
const UInt32 kPreArc = 1 << 9; // such archive can be stored before real archive (like SFX stub)
const UInt32 kSymLinks = 1 << 10; // the handler supports symbolic links
const UInt32 kHardLinks = 1 << 11; // the handler supports hard links
+ const UInt32 kByExtOnlyOpen = 1 << 12; // call handler only if file extension matches
}
namespace NArchive
@@ -106,7 +131,7 @@ namespace NArchive
enum
{
kOK = 0
- , // kError
+ // , kError
};
}
}
@@ -137,13 +162,13 @@ IArchiveExtractCallback::GetStream()
Int32 askExtractMode (Extract::NAskMode)
if (askMode != NExtract::NAskMode::kExtract)
{
- then the callee can not real stream: (*inStream == NULL)
+ then the callee doesn't write data to stream: (*outStream == NULL)
}
Out:
- (*inStream == NULL) - for directories
- (*inStream == NULL) - if link (hard link or symbolic link) was created
- if (*inStream == NULL && askMode == NExtract::NAskMode::kExtract)
+ (*outStream == NULL) - for directories
+ (*outStream == NULL) - if link (hard link or symbolic link) was created
+ if (*outStream == NULL && askMode == NExtract::NAskMode::kExtract)
{
then the caller must skip extracting of that file.
}
diff --git a/CPP/7zip/Archive/IhexHandler.cpp b/CPP/7zip/Archive/IhexHandler.cpp
index 00ff80a7..05453ee6 100644
--- a/CPP/7zip/Archive/IhexHandler.cpp
+++ b/CPP/7zip/Archive/IhexHandler.cpp
@@ -121,9 +121,9 @@ static int Parse(const Byte *p)
#define kType_Data 0
#define kType_Eof 1
#define kType_Seg 2
-#define kType_CsIp 3
+// #define kType_CsIp 3
#define kType_High 4
-#define kType_Ip32 5
+// #define kType_Ip32 5
#define kType_MAX 5
diff --git a/CPP/7zip/Archive/Iso/IsoHandler.cpp b/CPP/7zip/Archive/Iso/IsoHandler.cpp
index 2230cd23..87f4aa3b 100644
--- a/CPP/7zip/Archive/Iso/IsoHandler.cpp
+++ b/CPP/7zip/Archive/Iso/IsoHandler.cpp
@@ -3,6 +3,7 @@
#include "StdAfx.h"
#include "../../../Common/ComTry.h"
+#include "../../../Common/MyLinux.h"
#include "../../../Common/StringConvert.h"
#include "../../../Windows/PropVariant.h"
@@ -221,16 +222,15 @@ STDMETHODIMP CHandler::GetProperty(UInt32 index, PROPID propID, PROPVARIANT *val
case kpidSymLink:
if (_archive.IsSusp)
{
- UString s;
UInt32 mode;
if (item.GetPx(_archive.SuspSkipSize, k_Px_Mode, mode))
{
- if (((mode >> 12) & 0xF) == 10)
+ if (MY_LIN_S_ISLNK(mode))
{
AString s8;
if (item.GetSymLink(_archive.SuspSkipSize, s8))
{
- s = MultiByteToUnicodeString(s8, CP_OEMCP);
+ UString s = MultiByteToUnicodeString(s8, CP_OEMCP);
prop = s;
}
}
diff --git a/CPP/7zip/Archive/Iso/IsoIn.cpp b/CPP/7zip/Archive/Iso/IsoIn.cpp
index b0bfb164..211b3eea 100644
--- a/CPP/7zip/Archive/Iso/IsoIn.cpp
+++ b/CPP/7zip/Archive/Iso/IsoIn.cpp
@@ -299,10 +299,12 @@ void CInArchive::ReadVolumeDescriptor(CVolumeDescriptor &d)
static const Byte kSig_CD001[5] = { 'C', 'D', '0', '0', '1' };
+/*
static const Byte kSig_NSR02[5] = { 'N', 'S', 'R', '0', '2' };
static const Byte kSig_NSR03[5] = { 'N', 'S', 'R', '0', '3' };
static const Byte kSig_BEA01[5] = { 'B', 'E', 'A', '0', '1' };
static const Byte kSig_TEA01[5] = { 'T', 'E', 'A', '0', '1' };
+*/
static inline bool CheckSignature(const Byte *sig, const Byte *data)
{
diff --git a/CPP/7zip/Archive/Iso/IsoItem.h b/CPP/7zip/Archive/Iso/IsoItem.h
index 5ae13a60..a42ae039 100644
--- a/CPP/7zip/Archive/Iso/IsoItem.h
+++ b/CPP/7zip/Archive/Iso/IsoItem.h
@@ -149,7 +149,7 @@ struct CDirRecord
}
- const bool GetSymLink(int skipSize, AString &link) const
+ bool GetSymLink(int skipSize, AString &link) const
{
link.Empty();
const Byte *p = NULL;
@@ -208,7 +208,7 @@ struct CDirRecord
return true;
}
- static const bool GetLe32Be32(const Byte *p, UInt32 &dest)
+ static bool GetLe32Be32(const Byte *p, UInt32 &dest)
{
UInt32 v1 = GetUi32(p);
UInt32 v2 = GetBe32(p + 4);
@@ -221,7 +221,7 @@ struct CDirRecord
}
- const bool GetPx(int skipSize, unsigned pxType, UInt32 &val) const
+ bool GetPx(int skipSize, unsigned pxType, UInt32 &val) const
{
val = 0;
const Byte *p = NULL;
@@ -237,7 +237,7 @@ struct CDirRecord
}
/*
- const bool GetTf(int skipSize, unsigned pxType, CRecordingDateTime &t) const
+ bool GetTf(int skipSize, unsigned pxType, CRecordingDateTime &t) const
{
const Byte *p = NULL;
unsigned len = 0;
diff --git a/CPP/7zip/Archive/LzhHandler.cpp b/CPP/7zip/Archive/LzhHandler.cpp
index 53d69db7..e1984d28 100644
--- a/CPP/7zip/Archive/LzhHandler.cpp
+++ b/CPP/7zip/Archive/LzhHandler.cpp
@@ -41,6 +41,7 @@ static UInt16 g_LzhCrc16Table[256];
#define CRC16_UPDATE_BYTE(crc, b) (g_LzhCrc16Table[((crc) ^ (b)) & 0xFF] ^ ((crc) >> 8))
+UInt32 LzhCrc16Update(UInt32 crc, const void *data, size_t size);
UInt32 LzhCrc16Update(UInt32 crc, const void *data, size_t size)
{
const Byte *p = (const Byte *)data;
@@ -83,13 +84,7 @@ struct CExtension
AString GetString() const
{
AString s;
- for (size_t i = 0; i < Data.Size(); i++)
- {
- char c = (char)Data[i];
- if (c == 0)
- break;
- s += c;
- }
+ s.SetFrom_CalcLen((const char *)(const Byte *)Data, (unsigned)Data.Size());
return s;
}
};
@@ -184,11 +179,13 @@ struct CItem
return i;
return -1;
}
+
bool GetUnixTime(UInt32 &value) const
{
value = 0;
int index = FindExt(kExtIdUnixTime);
- if (index < 0)
+ if (index < 0
+ || Extensions[index].Data.Size() < 4)
{
if (Level == 2)
{
@@ -220,13 +217,14 @@ struct CItem
AString GetName() const
{
- AString dirName (GetDirName());
+ AString s (GetDirName());
const char kDirSeparator = '\\';
// check kDirSeparator in Linux
- dirName.Replace((char)(unsigned char)0xFF, kDirSeparator);
- if (!dirName.IsEmpty() && dirName.Back() != kDirSeparator)
- dirName += kDirSeparator;
- return dirName + GetFileName();
+ s.Replace((char)(unsigned char)0xFF, kDirSeparator);
+ if (!s.IsEmpty() && s.Back() != kDirSeparator)
+ s += kDirSeparator;
+ s += GetFileName();
+ return s;
}
};
@@ -332,7 +330,7 @@ static HRESULT GetNextItem(ISequentialInStream *stream, bool &filled, CItem &ite
return S_FALSE;
CExtension ext;
RINOK(ReadStream_FALSE(stream, &ext.Type, 1))
- nextSize -= 3;
+ nextSize = (UInt16)(nextSize - 3);
ext.Data.Alloc(nextSize);
RINOK(ReadStream_FALSE(stream, (Byte *)ext.Data, nextSize))
item.Extensions.Add(ext);
diff --git a/CPP/7zip/Archive/LzmaHandler.cpp b/CPP/7zip/Archive/LzmaHandler.cpp
index 9eac3ca1..ba547c83 100644
--- a/CPP/7zip/Archive/LzmaHandler.cpp
+++ b/CPP/7zip/Archive/LzmaHandler.cpp
@@ -242,29 +242,25 @@ STDMETHODIMP CHandler::GetNumberOfItems(UInt32 *numItems)
}
-static void DictSizeToString(UInt32 val, char *s)
+static char * DictSizeToString(UInt32 val, char *s)
{
for (unsigned i = 0; i <= 31; i++)
if (((UInt32)1 << i) == val)
- {
- ::ConvertUInt32ToString(i, s);
- return;
- }
+ return ::ConvertUInt32ToString(i, s);
char c = 'b';
if ((val & ((1 << 20) - 1)) == 0) { val >>= 20; c = 'm'; }
else if ((val & ((1 << 10) - 1)) == 0) { val >>= 10; c = 'k'; }
- ::ConvertUInt32ToString(val, s);
- s += MyStringLen(s);
+ s = ::ConvertUInt32ToString(val, s);
*s++ = c;
*s = 0;
+ return s;
}
static char *AddProp32(char *s, const char *name, UInt32 v)
{
*s++ = ':';
s = MyStpCpy(s, name);
- ::ConvertUInt32ToString(v, s);
- return s + MyStringLen(s);
+ return ::ConvertUInt32ToString(v, s);
}
void CHandler::GetMethod(NCOM::CPropVariant &prop)
@@ -277,8 +273,7 @@ void CHandler::GetMethod(NCOM::CPropVariant &prop)
if (_header.FilterID != 0)
s = MyStpCpy(s, "BCJ ");
s = MyStpCpy(s, "LZMA:");
- DictSizeToString(_header.GetDicSize(), s);
- s += strlen(s);
+ s = DictSizeToString(_header.GetDicSize(), s);
UInt32 d = _header.GetProp();
// if (d != 0x5D)
@@ -315,10 +310,10 @@ API_FUNC_static_IsArc IsArc_Lzma(const Byte *p, size_t size)
return k_IsArc_Res_NEED_MORE;
if (p[0] >= 5 * 5 * 9)
return k_IsArc_Res_NO;
- UInt64 unpackSize = GetUi64(p + 1 + 4);
+ const UInt64 unpackSize = GetUi64(p + 1 + 4);
if (unpackSize != (UInt64)(Int64)-1)
{
- if (size >= ((UInt64)1 << 56))
+ if (unpackSize >= ((UInt64)1 << 56))
return k_IsArc_Res_NO;
}
if (unpackSize != 0)
diff --git a/CPP/7zip/Archive/MachoHandler.cpp b/CPP/7zip/Archive/MachoHandler.cpp
index 1f65574d..bc8ba223 100644
--- a/CPP/7zip/Archive/MachoHandler.cpp
+++ b/CPP/7zip/Archive/MachoHandler.cpp
@@ -35,11 +35,11 @@ namespace NMacho {
#define CPU_SUBTYPE_I386_ALL 3
-#define CPU_TYPE_PPC64 (CPU_ARCH_ABI64 | CPU_TYPE_PPC)
+// #define CPU_TYPE_PPC64 (CPU_ARCH_ABI64 | CPU_TYPE_PPC)
#define CPU_TYPE_AMD64 (CPU_ARCH_ABI64 | CPU_TYPE_386)
#define CPU_TYPE_ARM64 (CPU_ARCH_ABI64 | CPU_TYPE_ARM)
-#define CPU_SUBTYPE_LIB64 (1 << 31)
+#define CPU_SUBTYPE_LIB64 ((UInt32)1 << 31)
#define CPU_SUBTYPE_POWERPC_970 100
diff --git a/CPP/7zip/Archive/MbrHandler.cpp b/CPP/7zip/Archive/MbrHandler.cpp
index 14a1224c..026696f3 100644
--- a/CPP/7zip/Archive/MbrHandler.cpp
+++ b/CPP/7zip/Archive/MbrHandler.cpp
@@ -51,10 +51,10 @@ struct CChs
bool Check() const { return GetSector() > 0; }
};
-#define RINOZ(x) { int __tt = (x); if (__tt != 0) return __tt; }
// Chs in some MBRs contains only low bits of "Cyl number". So we disable check.
/*
+#define RINOZ(x) { int __tt = (x); if (__tt != 0) return __tt; }
static int CompareChs(const CChs &c1, const CChs &c2)
{
RINOZ(MyCompare(c1.GetCyl(), c2.GetCyl()));
diff --git a/CPP/7zip/Archive/MubHandler.cpp b/CPP/7zip/Archive/MubHandler.cpp
index 6d054356..c790265d 100644
--- a/CPP/7zip/Archive/MubHandler.cpp
+++ b/CPP/7zip/Archive/MubHandler.cpp
@@ -33,7 +33,7 @@ namespace NMub {
#define MACH_CPU_TYPE_AMD64 (MACH_CPU_ARCH_ABI64 | MACH_CPU_TYPE_386)
#define MACH_CPU_TYPE_ARM64 (MACH_CPU_ARCH_ABI64 | MACH_CPU_TYPE_ARM)
-#define MACH_CPU_SUBTYPE_LIB64 (1 << 31)
+#define MACH_CPU_SUBTYPE_LIB64 ((UInt32)1 << 31)
#define MACH_CPU_SUBTYPE_I386_ALL 3
@@ -124,14 +124,15 @@ STDMETHODIMP CHandler::GetProperty(UInt32 index, PROPID propID, PROPVARIANT *val
}
if (ext)
strcpy(temp, ext);
- if (item.SubType != 0 && (
- item.Type != MACH_CPU_TYPE_386 &&
- item.Type != MACH_CPU_TYPE_AMD64 ||
- (item.SubType & ~(UInt32)MACH_CPU_SUBTYPE_LIB64) != MACH_CPU_SUBTYPE_I386_ALL))
+ if (item.SubType != 0)
+ if ((item.Type != MACH_CPU_TYPE_386 &&
+ item.Type != MACH_CPU_TYPE_AMD64)
+ || (item.SubType & ~(UInt32)MACH_CPU_SUBTYPE_LIB64) != MACH_CPU_SUBTYPE_I386_ALL
+ )
{
unsigned pos = MyStringLen(temp);
temp[pos++] = '-';
- ConvertUInt32ToString(item.SubType, temp + pos);
+ ConvertUInt32ToString(item.SubType, temp + pos);
}
return PropVarEm_Set_Str(value, temp);
}
diff --git a/CPP/7zip/Archive/Nsis/NsisHandler.cpp b/CPP/7zip/Archive/Nsis/NsisHandler.cpp
index 095105fe..aa0a9175 100644
--- a/CPP/7zip/Archive/Nsis/NsisHandler.cpp
+++ b/CPP/7zip/Archive/Nsis/NsisHandler.cpp
@@ -50,6 +50,7 @@ static const Byte kArcProps[] =
{
kpidMethod,
kpidSolid,
+ kpidBit64,
kpidHeadersSize,
kpidEmbeddedStubSize,
kpidSubType
@@ -134,6 +135,7 @@ STDMETHODIMP CHandler::GetArchiveProperty(PROPID propID, PROPVARIANT *value)
break;
}
+ case kpidBit64: if (_archive.Is64Bit) prop = true; break;
case kpidMethod: prop = _methodString; break;
case kpidSolid: prop = _archive.IsSolid; break;
case kpidOffset: prop = _archive.StartOffset; break;
diff --git a/CPP/7zip/Archive/Nsis/NsisIn.cpp b/CPP/7zip/Archive/Nsis/NsisIn.cpp
index f4f9ab04..3c1a0f17 100644
--- a/CPP/7zip/Archive/Nsis/NsisIn.cpp
+++ b/CPP/7zip/Archive/Nsis/NsisIn.cpp
@@ -155,7 +155,7 @@ enum
kNumCmds
};
-static const unsigned kNumAdditionalParkCmds = 3;
+
struct CCommandInfo
{
@@ -506,18 +506,20 @@ void CInArchive::AddLicense(UInt32 param, Int32 langID)
#endif
-#define kVar_CMDLINE 20
+// #define kVar_CMDLINE 20
#define kVar_INSTDIR 21
#define kVar_OUTDIR 22
#define kVar_EXEDIR 23
-#define kVar_LANGUAGE 24
+// #define kVar_LANGUAGE 24
#define kVar_TEMP 25
#define kVar_PLUGINSDIR 26
#define kVar_EXEPATH 27 // NSIS 2.26+
-#define kVar_EXEFILE 28 // NSIS 2.26+
+// #define kVar_EXEFILE 28 // NSIS 2.26+
#define kVar_HWNDPARENT_225 27
+#ifdef NSIS_SCRIPT
#define kVar_HWNDPARENT 29
+#endif
// #define kVar__CLICK 30
#define kVar_Spec_OUTDIR_225 29 // NSIS 2.04 - 2.25
@@ -606,9 +608,9 @@ void CInArchive::AddParam_UInt(UInt32 value)
#define NS_CODE_SKIP 252
#define NS_CODE_VAR 253
#define NS_CODE_SHELL 254
-#define NS_CODE_LANG 255
+// #define NS_CODE_LANG 255
-#define NS_3_CODE_LANG 1
+// #define NS_3_CODE_LANG 1
#define NS_3_CODE_SHELL 2
#define NS_3_CODE_VAR 3
#define NS_3_CODE_SKIP 4
@@ -1364,7 +1366,7 @@ void CInArchive::ReadString2(AString &s, UInt32 pos)
#ifdef NSIS_SCRIPT
-#define DEL_DIR 1
+// #define DEL_DIR 1
#define DEL_RECURSE 2
#define DEL_REBOOT 4
// #define DEL_SIMPLE 8
@@ -1445,9 +1447,11 @@ static void FlagsToString2(CDynLimBuf &s, const char * const *table, unsigned nu
static bool DoesNeedQuotes(const char *s)
{
- char c = s[0];
- if (c == 0 || c == '#' || c == ';' || (c == '/' && s[1] == '*'))
- return true;
+ {
+ char c = s[0];
+ if (c == 0 || c == '#' || c == ';' || (c == '/' && s[1] == '*'))
+ return true;
+ }
for (;;)
{
char c = *s++;
@@ -1737,12 +1741,12 @@ void CNsis_CtlColors::Parse(const Byte *p)
// Win32 constants
#define MY__TRANSPARENT 1
-#define MY__OPAQUE 2
+// #define MY__OPAQUE 2
-#define MY__GENERIC_READ (1 << 31)
-#define MY__GENERIC_WRITE (1 << 30)
-#define MY__GENERIC_EXECUTE (1 << 29)
-#define MY__GENERIC_ALL (1 << 28)
+#define MY__GENERIC_READ ((UInt32)1 << 31)
+#define MY__GENERIC_WRITE ((UInt32)1 << 30)
+#define MY__GENERIC_EXECUTE ((UInt32)1 << 29)
+#define MY__GENERIC_ALL ((UInt32)1 << 28)
#define MY__CREATE_NEW 1
#define MY__CREATE_ALWAYS 2
@@ -2068,9 +2072,11 @@ void CSection::Parse(const Byte *p)
#define SF_BOLD (1 << 3)
#define SF_RO (1 << 4)
#define SF_EXPAND (1 << 5)
+/*
#define SF_PSELECTED (1 << 6)
#define SF_TOGGLED (1 << 7)
#define SF_NAMECHG (1 << 8)
+*/
bool CInArchive::PrintSectionBegin(const CSection &sect, unsigned index)
{
@@ -2115,7 +2121,7 @@ bool CInArchive::PrintSectionBegin(const CSection &sect, unsigned index)
Script += ' ';
else
*/
- SmallSpaceComment();
+ SmallSpaceComment();
Script += "Section_";
Add_UInt(index);
@@ -2290,14 +2296,15 @@ bool CInArchive::CompareCommands(const Byte *rawCmds, const Byte *sequence, size
return true;
}
-#endif
static const UInt32 kSectionSize_base = 6 * 4;
-static const UInt32 kSectionSize_8bit = kSectionSize_base + 1024;
-static const UInt32 kSectionSize_16bit = kSectionSize_base + 1024 * 2;
-static const UInt32 kSectionSize_16bit_Big = kSectionSize_base + 8196 * 2;
+// static const UInt32 kSectionSize_8bit = kSectionSize_base + 1024;
+// static const UInt32 kSectionSize_16bit = kSectionSize_base + 1024 * 2;
+// static const UInt32 kSectionSize_16bit_Big = kSectionSize_base + 8196 * 2;
// 8196 is default string length in NSIS-Unicode since 2.37.3
+#endif
+
static void AddString(AString &dest, const char *src)
{
@@ -2330,8 +2337,13 @@ AString CInArchive::GetFormatDescription() const
if (IsUnicode)
AddString(s, "Unicode");
+
+ if (Is64Bit)
+ AddString(s, "64-bit");
+
if (LogCmdIsEnabled)
AddString(s, "log");
+
if (BadCmd >= 0)
{
AddString(s, "BadCmd=");
@@ -2342,9 +2354,11 @@ AString CInArchive::GetFormatDescription() const
#ifdef NSIS_SCRIPT
+static const unsigned kNumAdditionalParkCmds = 3;
+
unsigned CInArchive::GetNumSupportedCommands() const
{
- unsigned numCmds = IsPark() ? kNumCmds : kNumCmds - kNumAdditionalParkCmds;
+ unsigned numCmds = IsPark() ? (unsigned)kNumCmds : (unsigned)(kNumCmds) - kNumAdditionalParkCmds;
if (!LogCmdIsEnabled)
numCmds--;
if (!IsUnicode)
@@ -2792,26 +2806,20 @@ bool CInArchive::IsAbsolutePathVar(UInt32 strPos) const
return false;
}
-#define IS_LETTER_CHAR(c) ((c) >= 'a' && (c) <= 'z' || (c) >= 'A' && (c) <= 'Z')
+#define IS_LETTER_CHAR(c) (((c) >= 'a' && (c) <= 'z') || ((c) >= 'A' && (c) <= 'Z'))
// We use same check as in NSIS decoder
-bool IsDrivePath(const wchar_t *s) { return IS_LETTER_CHAR(s[0]) && s[1] == ':' /* && s[2] == '\\' */ ; }
-bool IsDrivePath(const char *s) { return IS_LETTER_CHAR(s[0]) && s[1] == ':' /* && s[2] == '\\' */ ; }
+static bool IsDrivePath(const wchar_t *s) { return IS_LETTER_CHAR(s[0]) && s[1] == ':' /* && s[2] == '\\' */ ; }
+static bool IsDrivePath(const char *s) { return IS_LETTER_CHAR(s[0]) && s[1] == ':' /* && s[2] == '\\' */ ; }
static bool IsAbsolutePath(const wchar_t *s)
{
- return
- s[0] == WCHAR_PATH_SEPARATOR &&
- s[1] == WCHAR_PATH_SEPARATOR ||
- IsDrivePath(s);
+ return (s[0] == WCHAR_PATH_SEPARATOR && s[1] == WCHAR_PATH_SEPARATOR) || IsDrivePath(s);
}
static bool IsAbsolutePath(const char *s)
{
- return
- s[0] == CHAR_PATH_SEPARATOR &&
- s[1] == CHAR_PATH_SEPARATOR ||
- IsDrivePath(s);
+ return (s[0] == CHAR_PATH_SEPARATOR && s[1] == CHAR_PATH_SEPARATOR) || IsDrivePath(s);
}
void CInArchive::SetItemName(CItem &item, UInt32 strPos)
@@ -3748,8 +3756,8 @@ HRESULT CInArchive::ReadEntries(const CBlockHeader &bh)
for (UInt32 j = i - 1; j >= kkk + 3; j--)
{
- const Byte *pCmd = p + kCmdSize * (j - kkk);
- AddParam(GET_CMD_PARAM(pCmd, 0));
+ const Byte *pCmd2 = p + kCmdSize * (j - kkk);
+ AddParam(GET_CMD_PARAM(pCmd2, 0));
}
NewLine();
Tab(true);
@@ -3850,13 +3858,13 @@ HRESULT CInArchive::ReadEntries(const CBlockHeader &bh)
{
case k_ExecFlags_AutoClose:
case k_ExecFlags_RebootFlag:
- if (v < 2) s2 = (v == 0) ? "false" : "true"; break;
+ if (v < 2) { s2 = (v == 0) ? "false" : "true"; } break;
case k_ExecFlags_ShellVarContext:
- if (v < 2) s2 = (v == 0) ? "current" : "all"; break;
+ if (v < 2) { s2 = (v == 0) ? "current" : "all"; } break;
case k_ExecFlags_Silent:
- if (v < 2) s2 = (v == 0) ? "normal" : "silent"; break;
+ if (v < 2) { s2 = (v == 0) ? "normal" : "silent"; } break;
case k_ExecFlags_RegView:
- if (v == 0) s2 = "32";
+ if (v == 0) s2 = "32";
else if (v == 256) s2 = "64";
break;
case k_ExecFlags_DetailsPrint:
@@ -3864,6 +3872,7 @@ HRESULT CInArchive::ReadEntries(const CBlockHeader &bh)
else if (v == 2) s2 = "textonly";
else if (v == 4) s2 = "listonly";
else if (v == 6) s2 = "none";
+ break;
}
if (s2)
{
@@ -4400,7 +4409,7 @@ HRESULT CInArchive::ReadEntries(const CBlockHeader &bh)
s += 'F';
Add_UInt(key - kMy_VK_F1 + 1);
}
- else if (key >= 'A' && key <= 'Z' || key >= '0' && key <= '9')
+ else if ((key >= 'A' && key <= 'Z') || (key >= '0' && key <= '9'))
s += (char)key;
else
{
@@ -4687,6 +4696,7 @@ HRESULT CInArchive::ReadEntries(const CBlockHeader &bh)
s += "Text";
AddParam(params[1]);
}
+ break;
}
case EW_SECTIONSET:
@@ -4829,9 +4839,6 @@ HRESULT CInArchive::ReadEntries(const CBlockHeader &bh)
}
else
{
- if (curSectionIndex == 49)
- curSectionIndex = curSectionIndex;
-
if (PrintSectionBegin(sect, curSectionIndex))
curSectionIndex++;
else
@@ -4846,8 +4853,8 @@ HRESULT CInArchive::ReadEntries(const CBlockHeader &bh)
static int CompareItems(void *const *p1, void *const *p2, void *param)
{
- const CItem &i1 = **(CItem **)p1;
- const CItem &i2 = **(CItem **)p2;
+ const CItem &i1 = **(const CItem *const *)p1;
+ const CItem &i2 = **(const CItem *const *)p2;
RINOZ(MyCompare(i1.Pos, i2.Pos));
const CInArchive *inArchive = (const CInArchive *)param;
if (inArchive->IsUnicode)
@@ -4970,14 +4977,15 @@ HRESULT CInArchive::SortItems()
return S_OK;
}
+#ifdef NSIS_SCRIPT
// Flags for common_header.flags
-#define CH_FLAGS_DETAILS_SHOWDETAILS 1
-#define CH_FLAGS_DETAILS_NEVERSHOW 2
+// #define CH_FLAGS_DETAILS_SHOWDETAILS 1
+// #define CH_FLAGS_DETAILS_NEVERSHOW 2
#define CH_FLAGS_PROGRESS_COLORED 4
#define CH_FLAGS_SILENT 8
#define CH_FLAGS_SILENT_LOG 16
#define CH_FLAGS_AUTO_CLOSE 32
-#define CH_FLAGS_DIR_NO_SHOW 64 // unused now
+// #define CH_FLAGS_DIR_NO_SHOW 64 // unused now
#define CH_FLAGS_NO_ROOT_DIR 128
#define CH_FLAGS_COMP_ONLY_ON_CUSTOM 256
#define CH_FLAGS_NO_CUSTOM 512
@@ -4989,29 +4997,59 @@ static const char * const k_PostStrings[] =
, "uninstcmd" // NSIS 2.25+, used by uninstaller:
, "wininit" // NSIS 2.25+, used by move file on reboot
};
+#endif
+
+
+void CBlockHeader::Parse(const Byte *p, unsigned bhoSize)
+{
+ if (bhoSize == 12)
+ {
+ // UInt64 a = GetUi64(p);
+ if (GetUi32(p + 4) != 0)
+ throw 1;
+ }
+ Offset = GetUi32(p);
+ Num = GetUi32(p + bhoSize - 4);
+}
+
+#define PARSE_BH(k, bh) bh.Parse (p1 + 4 + bhoSize * k, bhoSize)
+
HRESULT CInArchive::Parse()
{
// UInt32 offset = ReadUInt32();
// ???? offset == FirstHeader.HeaderSize
- const Byte *p = _data;
+ const Byte * const p1 = _data;
+
+ if (_size < 4 + 12 * 8)
+ Is64Bit = false;
+ else
+ {
+ Is64Bit = true;
+ // here we test high 32-bit of possible UInt64 CBlockHeader::Offset field
+ for (int k = 0; k < 8; k++)
+ if (GetUi32(p1 + 4 + 12 * k + 4) != 0)
+ Is64Bit = false;
+ }
- if (_size < 4 + 8 * 8)
+ const unsigned bhoSize = Is64Bit ? 12 : 8;
+ if (_size < 4 + bhoSize * 8)
return S_FALSE;
CBlockHeader bhEntries, bhStrings, bhLangTables;
- bhEntries.Parse(p + 4 + 8 * 2);
- bhStrings.Parse(p + 4 + 8 * 3);
- bhLangTables.Parse(p + 4 + 8 * 4);
+
+ PARSE_BH (2, bhEntries);
+ PARSE_BH (3, bhStrings);
+ PARSE_BH (4, bhLangTables);
#ifdef NSIS_SCRIPT
CBlockHeader bhFont;
- bhPages.Parse(p + 4 + 8 * 0);
- bhSections.Parse(p + 4 + 8 * 1);
- bhCtlColors.Parse(p + 4 + 8 * 5);
- bhFont.Parse(p + 4 + 8 * 6);
- bhData.Parse(p + 4 + 8 * 7);
+ PARSE_BH (0, bhPages);
+ PARSE_BH (1, bhSections);
+ PARSE_BH (5, bhCtlColors);
+ PARSE_BH (6, bhFont);
+ PARSE_BH (7, bhData);
#endif
@@ -5084,6 +5122,7 @@ HRESULT CInArchive::Parse()
case NMethodType::kDeflate: m = "zlib"; break;
case NMethodType::kBZip2: m = "bzip2"; break;
case NMethodType::kLZMA: m = "lzma"; break;
+ default: break;
}
Script += "SetCompressor";
if (IsSolid)
@@ -5167,7 +5206,7 @@ HRESULT CInArchive::Parse()
memset(strUsed, 0, NumStringChars);
{
- UInt32 ehFlags = Get32(p);
+ UInt32 ehFlags = Get32(p1);
UInt32 showDetails = ehFlags & 3;// CH_FLAGS_DETAILS_SHOWDETAILS & CH_FLAGS_DETAILS_NEVERSHOW;
if (showDetails >= 1 && showDetails <= 2)
{
@@ -5208,11 +5247,16 @@ HRESULT CInArchive::Parse()
}
}
- unsigned paramsOffset = 4 + 8 * 8;
- if (bhPages.Offset == 276)
- paramsOffset -= 8;
+ unsigned paramsOffset;
+ {
+ unsigned numBhs = 8;
+ // probably its for old NSIS?
+ if (bhoSize == 8 && bhPages.Offset == 276)
+ numBhs = 7;
+ paramsOffset = 4 + bhoSize * numBhs;
+ }
- const Byte *p2 = p + paramsOffset;
+ const Byte *p2 = p1 + paramsOffset;
{
UInt32 rootKey = Get32(p2); // (rootKey = -1) in uninstaller by default (the bug in NSIS)
@@ -5261,7 +5305,8 @@ HRESULT CInArchive::Parse()
}
UInt32 license_bg = Get32(p2 + 36);
- if (license_bg != (UInt32)(Int32)-1 && license_bg != -15) // COLOR_BTNFACE
+ if (license_bg != (UInt32)(Int32)-1 &&
+ license_bg != (UInt32)(Int32)-15) // COLOR_BTNFACE
{
Script += "LicenseBkColor";
if ((Int32)license_bg == -5) // COLOR_WINDOW
@@ -5275,13 +5320,19 @@ HRESULT CInArchive::Parse()
AddLF();
}
- UInt32 langtable_size = Get32(p2 + 32);
if (bhLangTables.Num > 0)
{
+ const UInt32 langtable_size = Get32(p2 + 32);
+
if (langtable_size == (UInt32)(Int32)-1)
return E_NOTIMPL; // maybe it's old NSIS archive()
- UInt32 numStrings = (langtable_size - 10) / 4;
+ if (langtable_size < 10)
+ return S_FALSE;
+ if (bhLangTables.Num > (_size - bhLangTables.Offset) / langtable_size)
+ return S_FALSE;
+
+ const UInt32 numStrings = (langtable_size - 10) / 4;
_numLangStrings = numStrings;
AddLF();
Separator();
@@ -5289,12 +5340,12 @@ HRESULT CInArchive::Parse()
PrintNumComment("LANG STRINGS", numStrings);
AddLF();
- if (licenseLangIndex >= 0)
+ if (licenseLangIndex >= 0 && (unsigned)licenseLangIndex < numStrings)
{
for (UInt32 i = 0; i < bhLangTables.Num; i++)
{
- const Byte *p = _data + bhLangTables.Offset + langtable_size * i;
- LANGID langID = Get16(p);
+ const Byte * const p = _data + bhLangTables.Offset + langtable_size * i;
+ const UInt16 langID = Get16(p);
UInt32 val = Get32(p + 10 + (UInt32)licenseLangIndex * 4);
if (val != 0)
{
@@ -5309,33 +5360,24 @@ HRESULT CInArchive::Parse()
AddLF();
}
- UInt32 brandingText = 0;
- UInt32 caption = 0;
- UInt32 name = 0;
+ UInt32 names[3] = { 0 };
+
UInt32 i;
for (i = 0; i < bhLangTables.Num; i++)
{
- const Byte *p = _data + bhLangTables.Offset + langtable_size * i;
- LANGID langID = Get16(p);
+ const Byte * const p = _data + bhLangTables.Offset + langtable_size * i;
+ const UInt16 langID = Get16(p);
if (i == 0 || langID == 1033)
_mainLang = p + 10;
+ for (unsigned k = 0; k < ARRAY_SIZE(names) && k < numStrings; k++)
{
- UInt32 v = Get32(p + 10 + 0 * 4);
- if (v != 0 && (langID == 1033 || brandingText == 0))
- brandingText = v;
- }
- {
- UInt32 v = Get32(p + 10 + 1 * 4);
- if (v != 0 && (langID == 1033 || caption == 0))
- caption = v;
- }
- {
- UInt32 v = Get32(p + 10 + 2 * 4);
- if (v != 0 && (langID == 1033 || name == 0))
- name = v;
+ UInt32 v = Get32(p + 10 + k * 4);
+ if (v != 0 && (langID == 1033 || names[k] == 0))
+ names[k] = v;
}
}
-
+
+ const UInt32 name = names[2];
if (name != 0)
{
Script += "Name";
@@ -5346,6 +5388,7 @@ HRESULT CInArchive::Parse()
}
/*
+ const UInt32 caption = names[1];
if (caption != 0)
{
Script += "Caption";
@@ -5354,6 +5397,7 @@ HRESULT CInArchive::Parse()
}
*/
+ const UInt32 brandingText = names[0];
if (brandingText != 0)
{
Script += "BrandingText";
@@ -5365,8 +5409,8 @@ HRESULT CInArchive::Parse()
for (i = 0; i < bhLangTables.Num; i++)
{
- const Byte *p = _data + bhLangTables.Offset + langtable_size * i;
- LANGID langID = Get16(p);
+ const Byte * const p = _data + bhLangTables.Offset + langtable_size * i;
+ const UInt16 langID = Get16(p);
AddLF();
AddCommentAndString("LANG:");
@@ -5641,10 +5685,12 @@ HRESULT CInArchive::Open2(const Byte *sig, size_t size)
if (Get32((const Byte *)buf) != FirstHeader.HeaderSize)
return S_FALSE;
}
- size_t processedSize = FirstHeader.HeaderSize;
- RINOK(Decoder.Read(_data, &processedSize));
- if (processedSize != FirstHeader.HeaderSize)
- return S_FALSE;
+ {
+ size_t processedSize = FirstHeader.HeaderSize;
+ RINOK(Decoder.Read(_data, &processedSize));
+ if (processedSize != FirstHeader.HeaderSize)
+ return S_FALSE;
+ }
#ifdef NSIS_SCRIPT
if (IsSolid)
@@ -5824,14 +5870,25 @@ HRESULT CInArchive::Open(IInStream *inStream, const UInt64 *maxCheckStartPositio
DataStreamOffset = pos + kStartHeaderSize;
FirstHeader.Flags = Get32(buf);
if ((FirstHeader.Flags & (~kFlagsMask)) != 0)
+ {
+ // return E_NOTIMPL;
return S_FALSE;
+ }
IsInstaller = (FirstHeader.Flags & NFlags::kUninstall) == 0;
FirstHeader.HeaderSize = Get32(buf + kSignatureSize + 4);
FirstHeader.ArcSize = Get32(buf + kSignatureSize + 8);
if (FirstHeader.ArcSize <= kStartHeaderSize)
return S_FALSE;
-
+
+ /*
+ if ((FirstHeader.Flags & NFlags::k_BI_ExternalFileSupport) != 0)
+ {
+ UInt32 datablock_low = Get32(buf + kSignatureSize + 12);
+ UInt32 datablock_high = Get32(buf + kSignatureSize + 16);
+ }
+ */
+
RINOK(inStream->Seek(0, STREAM_SEEK_END, &_fileSize));
IsArc = true;
@@ -5872,7 +5929,8 @@ UString CInArchive::ConvertToUnicode(const AString &s) const
if (IsUnicode)
{
UString res;
- if (ConvertUTF8ToUnicode(s, res))
+ // if (
+ ConvertUTF8ToUnicode(s, res);
return res;
}
return MultiByteToUnicodeString(s);
@@ -5886,6 +5944,7 @@ void CInArchive::Clear2()
IsNsis200 = false;
LogCmdIsEnabled = false;
BadCmd = -1;
+ Is64Bit = false;
#ifdef NSIS_SCRIPT
Name.Empty();
diff --git a/CPP/7zip/Archive/Nsis/NsisIn.h b/CPP/7zip/Archive/Nsis/NsisIn.h
index 028e4a5d..5c88188d 100644
--- a/CPP/7zip/Archive/Nsis/NsisIn.h
+++ b/CPP/7zip/Archive/Nsis/NsisIn.h
@@ -34,6 +34,11 @@ namespace NFlags
const UInt32 kSilent = 2;
const UInt32 kNoCrc = 4;
const UInt32 kForceCrc = 8;
+ // NSISBI fork flags:
+ const UInt32 k_BI_LongOffset = 16;
+ const UInt32 k_BI_ExternalFileSupport = 32;
+ const UInt32 k_BI_ExternalFile = 64;
+ const UInt32 k_BI_IsStubInstaller = 128;
}
struct CFirstHeader
@@ -58,11 +63,7 @@ struct CBlockHeader
UInt32 Offset;
UInt32 Num;
- void Parse(const Byte *p)
- {
- Offset = GetUi32(p);
- Num = GetUi32(p + 4);
- }
+ void Parse(const Byte *p, unsigned bhoSize);
};
struct CItem
@@ -159,6 +160,7 @@ public:
CByteBuffer _data;
CObjectVector<CItem> Items;
bool IsUnicode;
+ bool Is64Bit;
private:
UInt32 _stringsPos; // relative to _data
UInt32 NumStringChars;
@@ -170,7 +172,6 @@ private:
ENsisType NsisType;
bool IsNsis200; // NSIS 2.03 and before
bool IsNsis225; // NSIS 2.25 and before
-
bool LogCmdIsEnabled;
int BadCmd; // -1: no bad command; in another cases lowest bad command id
diff --git a/CPP/7zip/Archive/NtfsHandler.cpp b/CPP/7zip/Archive/NtfsHandler.cpp
index 21372033..daa01fef 100644
--- a/CPP/7zip/Archive/NtfsHandler.cpp
+++ b/CPP/7zip/Archive/NtfsHandler.cpp
@@ -208,7 +208,7 @@ enum
Posix name can be after or before Win32 name
*/
-static const Byte kFileNameType_Posix = 0; // for hard links
+// static const Byte kFileNameType_Posix = 0; // for hard links
static const Byte kFileNameType_Win32 = 1; // after Dos name
static const Byte kFileNameType_Dos = 2; // short name
static const Byte kFileNameType_Win32Dos = 3; // short and full name are same
@@ -386,8 +386,8 @@ struct CAttr
static int CompareAttr(void *const *elem1, void *const *elem2, void *)
{
- const CAttr &a1 = *(*((const CAttr **)elem1));
- const CAttr &a2 = *(*((const CAttr **)elem2));
+ const CAttr &a1 = *(*((const CAttr *const *)elem1));
+ const CAttr &a2 = *(*((const CAttr *const *)elem2));
RINOZ(MyCompare(a1.Type, a2.Type));
if (a1.Name.IsEmpty())
{
@@ -717,12 +717,16 @@ static size_t Lznt1Dec(Byte *dest, size_t outBufLim, size_t destLen, const Byte
UInt32 dist = (v >> (16 - numDistBits));
if (dist >= sbOffset)
return 0;
- Int32 offs = -1 - dist;
- Byte *p = dest + destSize;
- for (UInt32 t = 0; t < len; t++)
- p[t] = p[t + offs];
+ const size_t offs = 1 + dist;
+ Byte *p = dest + destSize - offs;
destSize += len;
sbOffset += len;
+ const Byte *lim = p + len;
+ p[offs] = *p; ++p;
+ p[offs] = *p; ++p;
+ do
+ p[offs] = *p;
+ while (++p != lim);
}
}
}
@@ -1094,7 +1098,7 @@ struct CMftRec
void CMftRec::ParseDataNames()
{
DataRefs.Clear();
- DataAttrs.Sort(CompareAttr, 0);
+ DataAttrs.Sort(CompareAttr, NULL);
for (unsigned i = 0; i < DataAttrs.Size();)
{
@@ -2188,7 +2192,7 @@ STDMETHODIMP CHandler::GetRawProp(UInt32 index, PROPID propID, const void **data
*data = (const wchar_t *)EmptyString;
else
*data = s->GetRawPtr();
- *dataSize = (s->Len() + 1) * sizeof(wchar_t);
+ *dataSize = (s->Len() + 1) * (UInt32)sizeof(wchar_t);
*propType = PROP_DATA_TYPE_wchar_t_PTR_Z_LE;
#endif
return S_OK;
diff --git a/CPP/7zip/Archive/PeHandler.cpp b/CPP/7zip/Archive/PeHandler.cpp
index 675293ba..ee265571 100644
--- a/CPP/7zip/Archive/PeHandler.cpp
+++ b/CPP/7zip/Archive/PeHandler.cpp
@@ -363,8 +363,8 @@ struct CSection
CSection(): IsRealSect(false), IsDebug(false), IsAdditionalSection(false) {}
- const UInt32 GetSizeExtract() const { return PSize; }
- const UInt32 GetSizeMin() const { return MyMin(PSize, VSize); }
+ UInt32 GetSizeExtract() const { return PSize; }
+ UInt32 GetSizeMin() const { return MyMin(PSize, VSize); }
void UpdateTotalSize(UInt32 &totalSize) const
{
@@ -768,15 +768,15 @@ class CHandler:
bool _oneLang;
UString _resourcesPrefix;
CUsedBitmap _usedRes;
- bool _parseResources;
+ // bool _parseResources;
bool _checksumError;
bool IsOpt() const { return _header.OptHeaderSize != 0; }
COptHeader _optHeader;
- bool _allowTail;
bool _coffMode;
+ bool _allowTail;
HRESULT LoadDebugSections(IInStream *stream, bool &thereIsSection);
HRESULT Open2(IInStream *stream, IArchiveOpenCallback *callback);
@@ -2005,10 +2005,12 @@ HRESULT CHandler::OpenResources(unsigned sectionIndex, IInStream *stream, IArchi
const UInt32 mask = ((UInt32)1 << numBits) - 1;
const size_t end = (size_t)((sect.VSize + mask) & (UInt32)~mask);
if (end > sect.VSize)
+ {
if (end <= sect.PSize)
fileSize = end;
else
fileSize = sect.PSize;
+ }
}
}
@@ -2459,7 +2461,7 @@ HRESULT CHandler::Open2(IInStream *stream, IArchiveOpenCallback *callback)
return S_FALSE;
}
- _parseResources = true;
+ bool _parseResources = true;
// _parseResources = false;
UInt64 mainSize = 0, mainSize2 = 0;
@@ -2467,11 +2469,11 @@ HRESULT CHandler::Open2(IInStream *stream, IArchiveOpenCallback *callback)
for (i = 0; i < _sections.Size(); i++)
{
const CSection &sect = _sections[i];
- CMixItem mixItem;
- mixItem.SectionIndex = i;
if (IsOpt())
- if (_parseResources && sect.Name == ".rsrc" && _items.IsEmpty())
+ if (_parseResources && sect.Name == ".rsrc")
{
+ // 20.01: we try to parse only first copy of .rsrc section.
+ _parseResources = false;
const unsigned numMixItems = _mixItems.Size();
HRESULT res = OpenResources(i, stream, callback);
if (res == S_OK)
@@ -2483,6 +2485,8 @@ HRESULT CHandler::Open2(IInStream *stream, IArchiveOpenCallback *callback)
const CResItem &item = _items[j];
if (item.Enabled)
{
+ CMixItem mixItem;
+ mixItem.SectionIndex = i;
mixItem.ResourceIndex = j;
if (item.IsRcDataOrUnknown())
{
@@ -2531,6 +2535,7 @@ HRESULT CHandler::Open2(IInStream *stream, IArchiveOpenCallback *callback)
_mixItems.DeleteFrom(numMixItems);
CloseResources();
}
+
if (sect.IsAdditionalSection)
{
if (sect.PSize >= mainSize)
@@ -2542,6 +2547,9 @@ HRESULT CHandler::Open2(IInStream *stream, IArchiveOpenCallback *callback)
else if (sect.PSize >= mainSize2)
mainSize2 = sect.PSize;
}
+
+ CMixItem mixItem;
+ mixItem.SectionIndex = i;
_mixItems.Add(mixItem);
}
@@ -3017,7 +3025,7 @@ static const Byte kProps[] =
enum
{
- kpidSubSystem = kpidUserDefined,
+ kpidSubSystem = kpidUserDefined
// , kpidImageBase
};
diff --git a/CPP/7zip/Archive/PpmdHandler.cpp b/CPP/7zip/Archive/PpmdHandler.cpp
index c80400bc..05a07e53 100644
--- a/CPP/7zip/Archive/PpmdHandler.cpp
+++ b/CPP/7zip/Archive/PpmdHandler.cpp
@@ -1,5 +1,5 @@
/* PpmdHandler.cpp -- PPMd format handler
-2015-11-30 : Igor Pavlov : Public domain
+2020 : Igor Pavlov : Public domain
This code is based on:
PPMd var.H (2001) / var.I (2002): Dmitry Shkarin : Public domain
Carryless rangecoder (1999): Dmitry Subbotin : Public domain */
@@ -59,7 +59,7 @@ struct CItem
unsigned Restor;
HRESULT ReadHeader(ISequentialInStream *s, UInt32 &headerSize);
- bool IsSupported() const { return Ver == 7 || (Ver == 8 && Restor <= 1); }
+ bool IsSupported() const { return Ver == 7 || (Ver == 8 && Restor < PPMD8_RESTORE_METHOD_UNSUPPPORTED); }
};
HRESULT CItem::ReadHeader(ISequentialInStream *s, UInt32 &headerSize)
@@ -218,91 +218,11 @@ STDMETHODIMP CHandler::Close()
return S_OK;
}
-static const UInt32 kTopValue = (1 << 24);
-static const UInt32 kBot = (1 << 15);
-struct CRangeDecoder
-{
- IPpmd7_RangeDec vt;
- UInt32 Range;
- UInt32 Code;
- UInt32 Low;
- CByteInBufWrap *Stream;
-
-public:
- bool Init()
- {
- Code = 0;
- Low = 0;
- Range = 0xFFFFFFFF;
- for (int i = 0; i < 4; i++)
- Code = (Code << 8) | Stream->ReadByte();
- return Code < 0xFFFFFFFF;
- }
-
- void Normalize()
- {
- while ((Low ^ (Low + Range)) < kTopValue ||
- Range < kBot && ((Range = (0 - Low) & (kBot - 1)), 1))
- {
- Code = (Code << 8) | Stream->ReadByte();
- Range <<= 8;
- Low <<= 8;
- }
- }
-
- CRangeDecoder();
-};
-
-
-extern "C" {
-
-#define GET_RangeDecoder CRangeDecoder *p = CONTAINER_FROM_VTBL(pp, CRangeDecoder, vt);
-
-static UInt32 Range_GetThreshold(const IPpmd7_RangeDec *pp, UInt32 total)
-{
- GET_RangeDecoder
- return p->Code / (p->Range /= total);
-}
-
-static void Range_Decode(const IPpmd7_RangeDec *pp, UInt32 start, UInt32 size)
-{
- GET_RangeDecoder
- start *= p->Range;
- p->Low += start;
- p->Code -= start;
- p->Range *= size;
- p->Normalize();
-}
-
-static UInt32 Range_DecodeBit(const IPpmd7_RangeDec *pp, UInt32 size0)
-{
- GET_RangeDecoder
- if (p->Code / (p->Range >>= 14) < size0)
- {
- Range_Decode(&p->vt, 0, size0);
- return 0;
- }
- else
- {
- Range_Decode(&p->vt, size0, (1 << 14) - size0);
- return 1;
- }
-}
-
-}
-
-CRangeDecoder::CRangeDecoder()
-{
- vt.GetThreshold = Range_GetThreshold;
- vt.Decode = Range_Decode;
- vt.DecodeBit = Range_DecodeBit;
-}
struct CPpmdCpp
{
unsigned Ver;
- CRangeDecoder _rc;
CPpmd7 _ppmd7;
CPpmd8 _ppmd8;
@@ -339,20 +259,20 @@ struct CPpmdCpp
{
if (Ver == 7)
{
- _rc.Stream = inStream;
- return _rc.Init();
+ _ppmd7.rc.dec.Stream = &inStream->vt;
+ return (Ppmd7a_RangeDec_Init(&_ppmd7.rc.dec) != 0);
}
else
{
_ppmd8.Stream.In = &inStream->vt;
- return Ppmd8_RangeDec_Init(&_ppmd8) != 0;
+ return Ppmd8_Init_RangeDec(&_ppmd8) != 0;
}
}
bool IsFinishedOK()
{
if (Ver == 7)
- return Ppmd7z_RangeDec_IsFinishedOK(&_rc);
+ return Ppmd7z_RangeDec_IsFinishedOK(&_ppmd7.rc.dec);
return Ppmd8_RangeDec_IsFinishedOK(&_ppmd8);
}
};
@@ -416,14 +336,15 @@ STDMETHODIMP CHandler::Extract(const UInt32 *indices, UInt32 numItems,
size_t i;
int sym = 0;
+ Byte *buf = outBuf.Buf;
if (ppmd.Ver == 7)
{
for (i = 0; i < kBufSize; i++)
{
- sym = Ppmd7_DecodeSymbol(&ppmd._ppmd7, &ppmd._rc.vt);
+ sym = Ppmd7a_DecodeSymbol(&ppmd._ppmd7);
if (inBuf.Extra || sym < 0)
break;
- outBuf.Buf[i] = (Byte)sym;
+ buf[i] = (Byte)sym;
}
}
else
@@ -433,7 +354,7 @@ STDMETHODIMP CHandler::Extract(const UInt32 *indices, UInt32 numItems,
sym = Ppmd8_DecodeSymbol(&ppmd._ppmd8);
if (inBuf.Extra || sym < 0)
break;
- outBuf.Buf[i] = (Byte)sym;
+ buf[i] = (Byte)sym;
}
}
diff --git a/CPP/7zip/Archive/QcowHandler.cpp b/CPP/7zip/Archive/QcowHandler.cpp
index 065f59b3..200ec62d 100644
--- a/CPP/7zip/Archive/QcowHandler.cpp
+++ b/CPP/7zip/Archive/QcowHandler.cpp
@@ -8,6 +8,7 @@
#include "../../Common/ComTry.h"
#include "../../Common/IntToString.h"
+#include "../../Common/MyBuffer2.h"
#include "../../Windows/PropVariant.h"
@@ -31,13 +32,21 @@ namespace NQcow {
static const Byte k_Signature[] = SIGNATURE;
+/*
+VA to PA maps:
+ high bits (L1) : : in L1 Table : the reference to L1 Table
+ mid bits (L2) : _numMidBits : in L2 Table : the reference to cluster
+ low bits : _clusterBits
+*/
+
class CHandler: public CHandlerImg
{
unsigned _clusterBits;
unsigned _numMidBits;
UInt64 _compressedFlag;
- CObjectVector<CByteBuffer> _tables;
+ CObjArray2<UInt32> _dir;
+ CAlignedBuffer _table;
UInt64 _cacheCluster;
CByteBuffer _cache;
CByteBuffer _cacheCompressed;
@@ -63,7 +72,7 @@ class CHandler: public CHandlerImg
UInt32 _version;
UInt32 _cryptMethod;
- HRESULT Seek(UInt64 offset)
+ HRESULT Seek2(UInt64 offset)
{
_posInArc = offset;
return Stream->Seek(offset, STREAM_SEEK_SET, NULL);
@@ -72,7 +81,7 @@ class CHandler: public CHandlerImg
HRESULT InitAndSeek()
{
_virtPos = 0;
- return Seek(0);
+ return Seek2(0);
}
HRESULT Open2(IInStream *stream, IArchiveOpenCallback *openCallback);
@@ -85,10 +94,15 @@ public:
};
+static const UInt32 kEmptyDirItem = (UInt32)0 - 1;
+
STDMETHODIMP CHandler::Read(void *data, UInt32 size, UInt32 *processedSize)
{
if (processedSize)
*processedSize = 0;
+
+ // printf("\nRead _virtPos = %6d size = %6d\n", (UInt32)_virtPos, size);
+
if (_virtPos >= _size)
return S_OK;
{
@@ -101,9 +115,9 @@ STDMETHODIMP CHandler::Read(void *data, UInt32 size, UInt32 *processedSize)
for (;;)
{
- UInt64 cluster = _virtPos >> _clusterBits;
- size_t clusterSize = (size_t)1 << _clusterBits;
- size_t lowBits = (size_t)_virtPos & (clusterSize - 1);
+ const UInt64 cluster = _virtPos >> _clusterBits;
+ const size_t clusterSize = (size_t)1 << _clusterBits;
+ const size_t lowBits = (size_t)_virtPos & (clusterSize - 1);
{
size_t rem = clusterSize - lowBits;
if (size > rem)
@@ -113,21 +127,19 @@ STDMETHODIMP CHandler::Read(void *data, UInt32 size, UInt32 *processedSize)
if (cluster == _cacheCluster)
{
memcpy(data, _cache + lowBits, size);
- _virtPos += size;
- if (processedSize)
- *processedSize = size;
- return S_OK;
+ break;
}
- UInt64 high = cluster >> _numMidBits;
+ const UInt64 high = cluster >> _numMidBits;
- if (high < _tables.Size())
+ if (high < _dir.Size())
{
- const CByteBuffer &buffer = _tables[(unsigned)high];
+ const UInt32 tabl = _dir[(unsigned)high];
- if (buffer.Size() != 0)
+ if (tabl != kEmptyDirItem)
{
- size_t midBits = (size_t)cluster & (((size_t)1 << _numMidBits) - 1);
+ const Byte *buffer = _table + ((size_t)tabl << (_numMidBits + 3));
+ const size_t midBits = (size_t)cluster & (((size_t)1 << _numMidBits) - 1);
const Byte *p = (const Byte *)buffer + (midBits << 3);
UInt64 v = Get64(p);
@@ -137,19 +149,32 @@ STDMETHODIMP CHandler::Read(void *data, UInt32 size, UInt32 *processedSize)
{
if (_version <= 1)
return E_FAIL;
- unsigned numOffsetBits = (62 - (_clusterBits - 8));
- UInt64 offset = v & (((UInt64)1 << 62) - 1);
+
+ /*
+ the example of table record for 12-bit clusters (4KB uncompressed).
+ 2 bits : isCompressed status
+ 4 bits : num_sectors_minus1; packSize = (num_sectors_minus1 + 1) * 512;
+ it uses one additional bit over unpacked cluster_bits
+ 49 bits : offset of 512-sector
+ 9 bits : offset in 512-sector
+ */
+
+ const unsigned numOffsetBits = (62 - (_clusterBits - 9 + 1));
+ const UInt64 offset = v & (((UInt64)1 << 62) - 1);
const size_t dataSize = ((size_t)(offset >> numOffsetBits) + 1) << 9;
- offset &= ((UInt64)1 << numOffsetBits) - 1;
- UInt64 sectorOffset = offset >> 9 << 9;
- UInt64 offset2inCache = sectorOffset - _comprPos;
+ UInt64 sectorOffset = offset & (((UInt64)1 << numOffsetBits) - (1 << 9));
+ const UInt64 offset2inCache = sectorOffset - _comprPos;
+ // _comprPos is aligned for 512-bytes
+ // we try to use previous _cacheCompressed that contains compressed data
+ // that was read for previous unpacking
+
if (sectorOffset >= _comprPos && offset2inCache < _comprSize)
{
if (offset2inCache != 0)
{
_comprSize -= (size_t)offset2inCache;
- memmove(_cacheCompressed, _cacheCompressed + offset2inCache, _comprSize);
+ memmove(_cacheCompressed, _cacheCompressed + (size_t)offset2inCache, _comprSize);
_comprPos = sectorOffset;
}
sectorOffset += _comprSize;
@@ -160,25 +185,27 @@ STDMETHODIMP CHandler::Read(void *data, UInt32 size, UInt32 *processedSize)
_comprSize = 0;
}
- // printf("\nDeflate");
- if (sectorOffset != _posInArc)
+ if (dataSize > _comprSize)
{
- // printf("\nDeflate %12I64x %12I64x\n", sectorOffset, sectorOffset - _posInArc);
- RINOK(Seek(sectorOffset));
+ if (sectorOffset != _posInArc)
+ {
+ // printf("\nDeflate-Seek %12I64x %12I64x\n", sectorOffset, sectorOffset - _posInArc);
+ RINOK(Seek2(sectorOffset));
+ }
+ if (_cacheCompressed.Size() < dataSize)
+ return E_FAIL;
+ const size_t dataSize3 = dataSize - _comprSize;
+ size_t dataSize2 = dataSize3;
+ // printf("\n\n=======\nReadStream = %6d _comprPos = %6d \n", (UInt32)dataSize2, (UInt32)_comprPos);
+ RINOK(ReadStream(Stream, _cacheCompressed + _comprSize, &dataSize2));
+ _posInArc += dataSize2;
+ if (dataSize2 != dataSize3)
+ return E_FAIL;
+ _comprSize += dataSize2;
}
- if (_cacheCompressed.Size() < dataSize)
- return E_FAIL;
- size_t dataSize3 = dataSize - _comprSize;
- size_t dataSize2 = dataSize3;
- RINOK(ReadStream(Stream, _cacheCompressed + _comprSize, &dataSize2));
- _posInArc += dataSize2;
- if (dataSize2 != dataSize3)
- return E_FAIL;
- _comprSize += dataSize2;
-
const size_t kSectorMask = (1 << 9) - 1;
- size_t offsetInSector = ((size_t)offset & kSectorMask);
+ const size_t offsetInSector = ((size_t)offset & kSectorMask);
_bufInStreamSpec->Init(_cacheCompressed + offsetInSector, dataSize - offsetInSector);
_cacheCluster = (UInt64)(Int64)-1;
@@ -187,7 +214,7 @@ STDMETHODIMP CHandler::Read(void *data, UInt32 size, UInt32 *processedSize)
_bufOutStreamSpec->Init(_cache, clusterSize);
// Do we need to use smaller block than clusterSize for last cluster?
- UInt64 blockSize64 = clusterSize;
+ const UInt64 blockSize64 = clusterSize;
HRESULT res = _deflateDecoderSpec->Code(_bufInStream, _bufOutStream, NULL, &blockSize64, NULL);
/*
@@ -206,10 +233,7 @@ STDMETHODIMP CHandler::Read(void *data, UInt32 size, UInt32 *processedSize)
continue;
/*
memcpy(data, _cache + lowBits, size);
- _virtPos += size;
- if (processedSize)
- *processedSize = size;
- return S_OK;
+ break;
*/
}
@@ -221,7 +245,7 @@ STDMETHODIMP CHandler::Read(void *data, UInt32 size, UInt32 *processedSize)
if (v != _posInArc)
{
// printf("\n%12I64x\n", v - _posInArc);
- RINOK(Seek(v));
+ RINOK(Seek2(v));
}
HRESULT res = Stream->Read(data, size, &size);
_posInArc += size;
@@ -235,11 +259,13 @@ STDMETHODIMP CHandler::Read(void *data, UInt32 size, UInt32 *processedSize)
}
memset(data, 0, size);
- _virtPos += size;
- if (processedSize)
- *processedSize = size;
- return S_OK;
+ break;
}
+
+ _virtPos += size;
+ if (processedSize)
+ *processedSize = size;
+ return S_OK;
}
@@ -347,8 +373,8 @@ HRESULT CHandler::Open2(IInStream *stream, IArchiveOpenCallback *openCallback)
const UInt64 backOffset = Get64(buf + 8);
// UInt32 backSize = Get32(buf + 0x10);
- UInt64 l1Offset = 0;
- UInt32 l1Size = 0;
+ UInt64 l1Offset;
+ UInt32 l1Size;
if (_version == 1)
{
@@ -364,8 +390,8 @@ HRESULT CHandler::Open2(IInStream *stream, IArchiveOpenCallback *openCallback)
l1Offset = Get64(buf + 0x28);
if (l1Offset < 0x30)
return S_FALSE;
- unsigned numBits2 = (_clusterBits + _numMidBits);
- UInt64 l1Size64 = (_size + (((UInt64)1 << numBits2) - 1)) >> numBits2;
+ const unsigned numBits2 = (_clusterBits + _numMidBits);
+ const UInt64 l1Size64 = (_size + (((UInt64)1 << numBits2) - 1)) >> numBits2;
if (l1Size64 > ((UInt32)1 << 31))
return S_FALSE;
l1Size = (UInt32)l1Size64;
@@ -381,8 +407,8 @@ HRESULT CHandler::Open2(IInStream *stream, IArchiveOpenCallback *openCallback)
l1Size = Get32(buf + 0x24);
l1Offset = Get64(buf + 0x28); // must be aligned for cluster
- UInt64 refOffset = Get64(buf + 0x30); // must be aligned for cluster
- UInt32 refClusters = Get32(buf + 0x38);
+ const UInt64 refOffset = Get64(buf + 0x30); // must be aligned for cluster
+ const UInt32 refClusters = Get32(buf + 0x38);
// UInt32 numSnapshots = Get32(buf + 0x3C);
// UInt64 snapshotsOffset = Get64(buf + 0x40); // must be aligned for cluster
@@ -393,14 +419,14 @@ HRESULT CHandler::Open2(IInStream *stream, IArchiveOpenCallback *openCallback)
if (refClusters != 0)
{
- size_t numBytes = refClusters << _clusterBits;
+ const size_t numBytes = refClusters << _clusterBits;
/*
CByteBuffer refs;
refs.Alloc(numBytes);
RINOK(stream->Seek(refOffset, STREAM_SEEK_SET, NULL));
RINOK(ReadStream_FALSE(stream, refs, numBytes));
*/
- UInt64 end = refOffset + numBytes;
+ const UInt64 end = refOffset + numBytes;
if (_phySize < end)
_phySize = end;
/*
@@ -426,7 +452,7 @@ HRESULT CHandler::Open2(IInStream *stream, IArchiveOpenCallback *openCallback)
CByteBuffer table;
{
- size_t t1SizeBytes = (size_t)l1Size << 3;
+ const size_t t1SizeBytes = (size_t)l1Size << 3;
if ((t1SizeBytes >> 3) != l1Size)
return S_FALSE;
table.Alloc(t1SizeBytes);
@@ -442,41 +468,72 @@ HRESULT CHandler::Open2(IInStream *stream, IArchiveOpenCallback *openCallback)
}
}
- if (openCallback)
+ _compressedFlag = (_version <= 1) ? ((UInt64)1 << 63) : ((UInt64)1 << 62);
+ const UInt64 offsetMask = _compressedFlag - 1;
+
+ UInt32 numTables = 0;
+ UInt32 i;
+
+ for (i = 0; i < l1Size; i++)
{
- UInt64 totalBytes = (UInt64)l1Size << (_numMidBits + 3);
- RINOK(openCallback->SetTotal(NULL, &totalBytes));
+ const UInt64 v = Get64((const Byte *)table + (size_t)i * 8) & offsetMask;
+ if (v != 0)
+ numTables++;
}
- _compressedFlag = (_version <= 1) ? ((UInt64)1 << 63) : ((UInt64)1 << 62);
- const UInt64 offsetMask = _compressedFlag - 1;
+ if (numTables != 0)
+ {
+ const size_t size = (size_t)numTables << (_numMidBits + 3);
+ if (size >> (_numMidBits + 3) != numTables)
+ return E_OUTOFMEMORY;
+ _table.Alloc(size);
+ if (!_table.IsAllocated())
+ return E_OUTOFMEMORY;
+ }
+
+ _dir.SetSize(l1Size);
- for (UInt32 i = 0; i < l1Size; i++)
+ UInt32 curTable = 0;
+
+ if (openCallback)
{
- if (openCallback)
- {
- UInt64 numBytes = (UInt64)i << (_numMidBits + 3);
- RINOK(openCallback->SetCompleted(NULL, &numBytes));
- }
+ const UInt64 totalBytes = (UInt64)numTables << (_numMidBits + 3);
+ RINOK(openCallback->SetTotal(NULL, &totalBytes));
+ }
- CByteBuffer &buf2 = _tables.AddNew();
-
+ for (i = 0; i < l1Size; i++)
+ {
+ Byte *buf2;
+ const size_t midSize = (size_t)1 << (_numMidBits + 3);
+
{
- UInt64 v = Get64((const Byte *)table + (size_t)i * 8);
- v &= offsetMask;
+ const UInt64 v = Get64((const Byte *)table + (size_t)i * 8) & offsetMask;
if (v == 0)
+ {
+ _dir[i] = kEmptyDirItem;
continue;
+ }
+
+ _dir[i] = curTable;
+ const size_t tableOffset = ((size_t)curTable << (_numMidBits + 3));
+ buf2 = (Byte *)_table + tableOffset;
+ curTable++;
+
+ if (openCallback && (tableOffset & 0xFFFFF) == 0)
+ {
+ const UInt64 numBytes = tableOffset;
+ RINOK(openCallback->SetCompleted(NULL, &numBytes));
+ }
- buf2.Alloc((size_t)1 << (_numMidBits + 3));
RINOK(stream->Seek(v, STREAM_SEEK_SET, NULL));
- RINOK(ReadStream_FALSE(stream, buf2, clusterSize));
+ RINOK(ReadStream_FALSE(stream, buf2, midSize));
- const UInt64 end = v + clusterSize;
+ const UInt64 end = v + midSize;
if (_phySize < end)
_phySize = end;
}
- for (size_t k = 0; k < clusterSize; k += 8)
+ for (size_t k = 0; k < midSize; k += 8)
{
const UInt64 v = Get64((const Byte *)buf2 + (size_t)k);
if (v == 0)
@@ -519,12 +576,15 @@ HRESULT CHandler::Open2(IInStream *stream, IArchiveOpenCallback *openCallback)
}
}
- UInt64 end = offset + dataSize;
+ const UInt64 end = offset + dataSize;
if (_phySize < end)
_phySize = end;
}
}
+ if (curTable != numTables)
+ return E_FAIL;
+
if (_cryptMethod != 0)
_unsupported = true;
@@ -538,7 +598,8 @@ HRESULT CHandler::Open2(IInStream *stream, IArchiveOpenCallback *openCallback)
STDMETHODIMP CHandler::Close()
{
- _tables.Clear();
+ _table.Free();
+ _dir.Free();
_phySize = 0;
_size = 0;
@@ -588,7 +649,7 @@ STDMETHODIMP CHandler::GetStream(UInt32 /* index */, ISequentialInStream **strea
_deflateDecoderSpec->Set_NeedFinishInput(true);
}
- size_t clusterSize = (size_t)1 << _clusterBits;
+ const size_t clusterSize = (size_t)1 << _clusterBits;
_cache.AllocAtLeast(clusterSize);
_cacheCompressed.AllocAtLeast(clusterSize * 2);
}
diff --git a/CPP/7zip/Archive/Rar/Rar5Handler.cpp b/CPP/7zip/Archive/Rar/Rar5Handler.cpp
index 320771d5..bb8a2edb 100644
--- a/CPP/7zip/Archive/Rar/Rar5Handler.cpp
+++ b/CPP/7zip/Archive/Rar/Rar5Handler.cpp
@@ -124,19 +124,13 @@ static unsigned ReadVarInt(const Byte *p, size_t maxSize, UInt64 *val)
bool CLinkInfo::Parse(const Byte *p, unsigned size)
{
const Byte *pStart = p;
- unsigned num = ReadVarInt(p, size, &Type);
- if (num == 0) return false; p += num; size -= num;
-
- num = ReadVarInt(p, size, &Flags);
- if (num == 0) return false; p += num; size -= num;
-
+ unsigned num;
UInt64 len;
- num = ReadVarInt(p, size, &len);
- if (num == 0) return false; p += num; size -= num;
-
+ num = ReadVarInt(p, size, &Type); if (num == 0) { return false; } p += num; size -= num;
+ num = ReadVarInt(p, size, &Flags); if (num == 0) { return false; } p += num; size -= num;
+ num = ReadVarInt(p, size, &len); if (num == 0) { return false; } p += num; size -= num;
if (size != len)
return false;
-
NameLen = (unsigned)len;
NameOffset = (unsigned)(p - pStart);
return true;
@@ -319,10 +313,10 @@ bool CCryptoInfo::Parse(const Byte *p, size_t size)
Cnt = 0;
unsigned num = ReadVarInt(p, size, &Algo);
- if (num == 0) return false; p += num; size -= num;
+ if (num == 0) { return false; } p += num; size -= num;
num = ReadVarInt(p, size, &Flags);
- if (num == 0) return false; p += num; size -= num;
+ if (num == 0) { return false; } p += num; size -= num;
if (size > 0)
Cnt = p[0];
@@ -344,10 +338,10 @@ bool CItem::FindExtra_Version(UInt64 &version) const
UInt64 flags;
unsigned num = ReadVarInt(p, size, &flags);
- if (num == 0) return false; p += num; size -= num;
+ if (num == 0) { return false; } p += num; size -= num;
num = ReadVarInt(p, size, &version);
- if (num == 0) return false; p += num; size -= num;
+ if (num == 0) { return false; } p += num; size -= num;
return size == 0;
}
@@ -406,8 +400,8 @@ void CItem::Link_to_Prop(unsigned linkType, NWindows::NCOM::CPropVariant &prop)
s.SetFrom_CalcLen((const char *)(Extra + link.NameOffset), link.NameLen);
UString unicode;
- if (ConvertUTF8ToUnicode(s, unicode))
- prop = NItemName::GetOsPath(unicode);
+ ConvertUTF8ToUnicode(s, unicode);
+ prop = NItemName::GetOsPath(unicode);
}
bool CItem::GetAltStreamName(AString &name) const
@@ -596,11 +590,12 @@ public:
static HRESULT MySetPassword(ICryptoGetTextPassword *getTextPassword, NCrypto::NRar5::CDecoder *cryptoDecoderSpec)
{
- CMyComBSTR password;
+ CMyComBSTR_Wipe password;
RINOK(getTextPassword->CryptoGetTextPassword(&password));
- AString utf8;
+ AString_Wipe utf8;
const unsigned kPasswordLen_MAX = 127;
- UString unicode = (LPCOLESTR)password;
+ UString_Wipe unicode;
+ unicode.SetFromBstr(password);
if (unicode.Len() > kPasswordLen_MAX)
unicode.DeleteFrom(kPasswordLen_MAX);
ConvertUnicodeToUTF8(unicode, utf8);
@@ -1153,7 +1148,7 @@ HRESULT CUnpacker::Code(const CItem &item, const CItem &lastItem, UInt64 packSiz
}
else
{
- res = res;
+ // res = res;
}
if (isCryptoMode)
@@ -1434,8 +1429,8 @@ STDMETHODIMP CHandler::GetArchiveProperty(PROPID propID, PROPVARIANT *value)
AString s;
s.SetFrom_CalcLen((const char *)(const Byte *)cmt, (unsigned)cmt.Size());
UString unicode;
- if (ConvertUTF8ToUnicode(s, unicode))
- prop = unicode;
+ ConvertUTF8ToUnicode(s, unicode);
+ prop = unicode;
}
}
break;
@@ -1686,13 +1681,12 @@ STDMETHODIMP CHandler::GetProperty(UInt32 index, PROPID propID, PROPVARIANT *val
if (name[0] != ':')
s += ':';
s += name;
- if (!ConvertUTF8ToUnicode(s, unicodeName))
- break;
+ ConvertUTF8ToUnicode(s, unicodeName);
}
else
{
- if (!ConvertUTF8ToUnicode(item.Name, unicodeName))
- break;
+ ConvertUTF8ToUnicode(item.Name, unicodeName);
+
if (item.Version_Defined)
{
char temp[32];
@@ -1752,8 +1746,8 @@ STDMETHODIMP CHandler::GetProperty(UInt32 index, PROPID propID, PROPVARIANT *val
{
name.DeleteFrontal(1);
UString unicodeName;
- if (ConvertUTF8ToUnicode(name, unicodeName))
- prop = unicodeName;
+ ConvertUTF8ToUnicode(name, unicodeName);
+ prop = unicodeName;
}
}
break;
diff --git a/CPP/7zip/Archive/Rar/RarHandler.cpp b/CPP/7zip/Archive/Rar/RarHandler.cpp
index dd78e312..7491c50b 100644
--- a/CPP/7zip/Archive/Rar/RarHandler.cpp
+++ b/CPP/7zip/Archive/Rar/RarHandler.cpp
@@ -466,7 +466,7 @@ bool CInArchive::ReadHeaderReal(const Byte *p, unsigned size, CItem &item)
for (unsigned i = 0; i < sizeof(item.Salt); i++)
item.Salt[i] = p[i];
p += sizeof(item.Salt);
- size -= sizeof(item.Salt);
+ size -= (unsigned)sizeof(item.Salt);
}
// some rar archives have HasExtTime flag without field.
@@ -526,31 +526,36 @@ HRESULT CInArchive::GetNextItem(CItem &item, ICryptoGetTextPassword *getTextPass
}
// m_RarAESSpec->SetRar350Mode(ArcInfo.IsEncryptOld());
- // Salt
- const UInt32 kSaltSize = 8;
- Byte salt[kSaltSize];
- if (!ReadBytesAndTestSize(salt, kSaltSize))
- return S_FALSE;
- m_Position += kSaltSize;
- RINOK(m_RarAESSpec->SetDecoderProperties2(salt, kSaltSize))
- // Password
- CMyComBSTR password;
- RINOK(getTextPassword->CryptoGetTextPassword(&password))
- unsigned len = 0;
- if (password)
- len = MyStringLen(password);
- if (len > kPasswordLen_MAX)
- len = kPasswordLen_MAX;
-
- CByteArr buffer(len * 2);
- for (unsigned i = 0; i < len; i++)
{
- wchar_t c = password[i];
- ((Byte *)buffer)[i * 2] = (Byte)c;
- ((Byte *)buffer)[i * 2 + 1] = (Byte)(c >> 8);
+ // Salt
+ const UInt32 kSaltSize = 8;
+ Byte salt[kSaltSize];
+ if (!ReadBytesAndTestSize(salt, kSaltSize))
+ return S_FALSE;
+ m_Position += kSaltSize;
+ RINOK(m_RarAESSpec->SetDecoderProperties2(salt, kSaltSize))
}
- m_RarAESSpec->SetPassword((const Byte *)buffer, len * 2);
+ {
+ // Password
+ CMyComBSTR_Wipe password;
+ RINOK(getTextPassword->CryptoGetTextPassword(&password))
+ unsigned len = 0;
+ if (password)
+ len = MyStringLen(password);
+ if (len > kPasswordLen_MAX)
+ len = kPasswordLen_MAX;
+
+ CByteBuffer_Wipe buffer(len * 2);
+ for (unsigned i = 0; i < len; i++)
+ {
+ wchar_t c = password[i];
+ ((Byte *)buffer)[i * 2] = (Byte)c;
+ ((Byte *)buffer)[i * 2 + 1] = (Byte)(c >> 8);
+ }
+
+ m_RarAESSpec->SetPassword((const Byte *)buffer, len * 2);
+ }
const UInt32 kDecryptedBufferSize = (1 << 12);
if (m_DecryptedDataAligned.Size() == 0)
@@ -1621,7 +1626,7 @@ STDMETHODIMP CHandler::Extract(const UInt32 *indices, UInt32 numItems,
// if (getTextPassword)
{
- CMyComBSTR password;
+ CMyComBSTR_Wipe password;
RINOK(getTextPassword->CryptoGetTextPassword(&password));
if (item.UnPackVersion >= 29)
@@ -1631,7 +1636,7 @@ STDMETHODIMP CHandler::Extract(const UInt32 *indices, UInt32 numItems,
len = MyStringLen(password);
if (len > kPasswordLen_MAX)
len = kPasswordLen_MAX;
- CByteArr buffer(len * 2);
+ CByteBuffer_Wipe buffer(len * 2);
for (unsigned k = 0; k < len; k++)
{
wchar_t c = password[k];
@@ -1642,13 +1647,14 @@ STDMETHODIMP CHandler::Extract(const UInt32 *indices, UInt32 numItems,
}
else
{
- AString oemPassword;
+ AString_Wipe oemPassword;
if (password)
{
- UString unicode = (LPCOLESTR)password;
+ UString_Wipe unicode;
+ unicode.SetFromBstr(password);
if (unicode.Len() > kPasswordLen_MAX)
unicode.DeleteFrom(kPasswordLen_MAX);
- oemPassword = UnicodeStringToMultiByte(unicode, CP_OEMCP);
+ UnicodeStringToMultiByte2(oemPassword, unicode, CP_OEMCP);
}
rar20CryptoDecoderSpec->SetPassword((const Byte *)(const char *)oemPassword, oemPassword.Len());
}
diff --git a/CPP/7zip/Archive/Rar/RarHandler.h b/CPP/7zip/Archive/Rar/RarHandler.h
index e444bd77..a62b60cd 100644
--- a/CPP/7zip/Archive/Rar/RarHandler.h
+++ b/CPP/7zip/Archive/Rar/RarHandler.h
@@ -26,7 +26,7 @@ struct CInArcInfo
UInt32 DataCRC;
bool EndOfArchive_was_Read;
- CInArcInfo(): EndFlags(0), EndOfArchive_was_Read(false), VolNumber(0) {}
+ CInArcInfo(): EndFlags(0), VolNumber(0), EndOfArchive_was_Read(false) {}
UInt64 GetPhySize() const { return EndPos - StartPos; }
diff --git a/CPP/7zip/Archive/SplitHandler.cpp b/CPP/7zip/Archive/SplitHandler.cpp
index f4a10b1d..6705aee0 100644
--- a/CPP/7zip/Archive/SplitHandler.cpp
+++ b/CPP/7zip/Archive/SplitHandler.cpp
@@ -142,8 +142,8 @@ HRESULT CHandler::Open2(IInStream *stream, IArchiveOpenCallback *callback)
}
int dotPos = name.ReverseFind_Dot();
- const UString prefix = name.Left(dotPos + 1);
- const UString ext = name.Ptr(dotPos + 1);
+ const UString prefix = name.Left((unsigned)(dotPos + 1));
+ const UString ext = name.Ptr((unsigned)(dotPos + 1));
UString ext2 = ext;
ext2.MakeLower_Ascii();
diff --git a/CPP/7zip/Archive/SquashfsHandler.cpp b/CPP/7zip/Archive/SquashfsHandler.cpp
index 89de660f..74bc8fb8 100644
--- a/CPP/7zip/Archive/SquashfsHandler.cpp
+++ b/CPP/7zip/Archive/SquashfsHandler.cpp
@@ -41,9 +41,9 @@ static const unsigned kNumDirLevelsMax = (1 << 10);
#define Get64(p) (be ? GetBe64(p) : GetUi64(p))
*/
-UInt16 Get16b(const Byte *p, bool be) { return be ? GetBe16(p) : GetUi16(p); }
-UInt32 Get32b(const Byte *p, bool be) { return be ? GetBe32(p) : GetUi32(p); }
-UInt64 Get64b(const Byte *p, bool be) { return be ? GetBe64(p) : GetUi64(p); }
+static UInt16 Get16b(const Byte *p, bool be) { return be ? GetBe16(p) : GetUi16(p); }
+static UInt32 Get32b(const Byte *p, bool be) { return be ? GetBe32(p) : GetUi32(p); }
+static UInt64 Get64b(const Byte *p, bool be) { return be ? GetBe64(p) : GetUi64(p); }
#define Get16(p) Get16b(p, be)
#define Get32(p) Get32b(p, be)
@@ -121,6 +121,10 @@ static const char * const k_Flags[] =
, "ALWAYS_FRAGMENTS"
, "DUPLICATES_REMOVED"
, "EXPORTABLE"
+ , "UNCOMPRESSED_XATTRS"
+ , "NO_XATTRS"
+ , "COMPRESSOR_OPTIONS"
+ , "UNCOMPRESSED_IDS"
};
static const UInt32 kNotCompressedBit16 = (1 << 15);
@@ -129,10 +133,10 @@ static const UInt32 kNotCompressedBit32 = (1 << 24);
#define GET_COMPRESSED_BLOCK_SIZE(size) ((size) & ~kNotCompressedBit32)
#define IS_COMPRESSED_BLOCK(size) (((size) & kNotCompressedBit32) == 0)
-static const UInt32 kHeaderSize1 = 0x33;
-static const UInt32 kHeaderSize2 = 0x3F;
+// static const UInt32 kHeaderSize1 = 0x33;
+// static const UInt32 kHeaderSize2 = 0x3F;
static const UInt32 kHeaderSize3 = 0x77;
-static const UInt32 kHeaderSize4 = 0x60;
+// static const UInt32 kHeaderSize4 = 0x60;
struct CHeader
{
@@ -1243,7 +1247,8 @@ HRESULT CHandler::Decompress(ISequentialOutStream *outStream, Byte *outBuf, bool
&status, &g_Alloc);
if (res != 0)
return SResToHRESULT(res);
- if (status != LZMA_STATUS_FINISHED_WITH_MARK)
+ if (status != LZMA_STATUS_FINISHED_WITH_MARK
+ && status != LZMA_STATUS_MAYBE_FINISHED_WITHOUT_MARK)
return S_FALSE;
}
else
@@ -1310,7 +1315,7 @@ HRESULT CHandler::ReadData(CData &data, UInt64 start, UInt64 end)
{
if (end < start || end - start >= ((UInt64)1 << 32))
return S_FALSE;
- UInt32 size = (UInt32)(end - start);
+ const UInt32 size = (UInt32)(end - start);
RINOK(_stream->Seek(start, STREAM_SEEK_SET, NULL));
_dynOutStreamSpec->Init();
UInt32 packPos = 0;
@@ -1322,8 +1327,11 @@ HRESULT CHandler::ReadData(CData &data, UInt64 start, UInt64 end)
return S_FALSE;
UInt32 packSize = size - packPos;
RINOK(ReadMetadataBlock(packSize));
- if (_dynOutStreamSpec->GetSize() >= ((UInt64)1 << 32))
- return S_FALSE;
+ {
+ const size_t tSize = _dynOutStreamSpec->GetSize();
+ if (tSize != (UInt32)tSize)
+ return S_FALSE;
+ }
packPos += packSize;
}
data.UnpackPos.Add((UInt32)_dynOutStreamSpec->GetSize());
@@ -1487,7 +1495,7 @@ HRESULT CHandler::OpenDir(int parent, UInt32 startBlock, UInt32 offset, unsigned
if (_openCodePage == CP_UTF8)
{
tempString.SetFrom_CalcLen((const char *)p, size);
- if (!CheckUTF8(tempString))
+ if (!CheckUTF8_AString(tempString))
_openCodePage = CP_OEMCP;
}
@@ -1608,11 +1616,14 @@ HRESULT CHandler::Open2(IInStream *inStream)
{
UInt32 pos = 0;
UInt32 totalSize = (UInt32)_inodesData.Data.Size();
+ const unsigned kMinNodeParseSize = 4;
+ if (_h.NumInodes > totalSize / kMinNodeParseSize)
+ return S_FALSE;
_nodesPos.ClearAndReserve(_h.NumInodes);
_nodes.ClearAndReserve(_h.NumInodes);
// we use _blockToNode for binary search seed optimizations
_blockToNode.ClearAndReserve(_inodesData.GetNumBlocks() + 1);
- int curBlock = 0;
+ unsigned curBlock = 0;
for (UInt32 i = 0; i < _h.NumInodes; i++)
{
CNode n;
@@ -2090,9 +2101,9 @@ HRESULT CHandler::ReadBlock(UInt64 blockIndex, Byte *dest, size_t blockSize)
bool compressed;
if (blockIndex < _blockCompressed.Size())
{
- compressed = _blockCompressed[(int)blockIndex];
- blockOffset = _blockOffsets[(int)blockIndex];
- packBlockSize = (UInt32)(_blockOffsets[(int)blockIndex + 1] - blockOffset);
+ compressed = _blockCompressed[(unsigned)blockIndex];
+ blockOffset = _blockOffsets[(unsigned)blockIndex];
+ packBlockSize = (UInt32)(_blockOffsets[(unsigned)blockIndex + 1] - blockOffset);
blockOffset += node.StartBlock;
}
else
@@ -2126,14 +2137,16 @@ HRESULT CHandler::ReadBlock(UInt64 blockIndex, Byte *dest, size_t blockSize)
bool outBufWasWritten;
UInt32 outBufWasWrittenSize;
HRESULT res = Decompress(_outStream, _cachedBlock, &outBufWasWritten, &outBufWasWrittenSize, packBlockSize, _h.BlockSize);
+ RINOK(res);
if (outBufWasWritten)
_cachedUnpackBlockSize = outBufWasWrittenSize;
else
_cachedUnpackBlockSize = (UInt32)_outStreamSpec->GetPos();
- RINOK(res);
}
else
{
+ if (packBlockSize > _h.BlockSize)
+ return S_FALSE;
RINOK(ReadStream_FALSE(_limitedInStream, _cachedBlock, packBlockSize));
_cachedUnpackBlockSize = packBlockSize;
}
diff --git a/CPP/7zip/Archive/SwfHandler.cpp b/CPP/7zip/Archive/SwfHandler.cpp
index ebb6acfd..9666c69d 100644
--- a/CPP/7zip/Archive/SwfHandler.cpp
+++ b/CPP/7zip/Archive/SwfHandler.cpp
@@ -776,21 +776,21 @@ STDMETHODIMP CHandler::Open(IInStream *stream, const UInt64 *, IArchiveOpenCallb
static UInt16 Read16(CInBuffer &stream)
{
- UInt16 res = 0;
- for (int i = 0; i < 2; i++)
+ UInt32 res = 0;
+ for (unsigned i = 0; i < 2; i++)
{
Byte b;
if (!stream.ReadByte(b))
throw 1;
- res |= (UInt16)b << (i * 8);
+ res |= (UInt32)b << (i * 8);
}
- return res;
+ return (UInt16)res;
}
static UInt32 Read32(CInBuffer &stream)
{
UInt32 res = 0;
- for (int i = 0; i < 4; i++)
+ for (unsigned i = 0; i < 4; i++)
{
Byte b;
if (!stream.ReadByte(b))
@@ -826,7 +826,7 @@ UInt32 CBitReader::ReadBits(unsigned numBits)
res <<= numBits;
NumBits -= numBits;
res |= (Val >> NumBits);
- Val &= (1 << NumBits) - 1;
+ Val = (Byte)(Val & (((unsigned)1 << NumBits) - 1));
break;
}
else
diff --git a/CPP/7zip/Archive/Tar/TarHandler.cpp b/CPP/7zip/Archive/Tar/TarHandler.cpp
index 72fbf74e..bc00e3fc 100644
--- a/CPP/7zip/Archive/Tar/TarHandler.cpp
+++ b/CPP/7zip/Archive/Tar/TarHandler.cpp
@@ -24,7 +24,9 @@ using namespace NWindows;
namespace NArchive {
namespace NTar {
-static const UINT k_DefaultCodePage = CP_OEMCP; // it uses it if UTF8 check in names shows error
+// 21.02: we use UTF8 code page by default, even if some files show error
+// before 21.02 : CP_OEMCP;
+// static const UINT k_DefaultCodePage = CP_UTF8;
static const Byte kProps[] =
@@ -39,13 +41,15 @@ static const Byte kProps[] =
kpidGroup,
kpidSymLink,
kpidHardLink,
+ kpidCharacts
// kpidLinkType
};
static const Byte kArcProps[] =
{
kpidHeadersSize,
- kpidCodePage
+ kpidCodePage,
+ kpidCharacts
};
IMP_IInArchive_Props
@@ -67,8 +71,12 @@ STDMETHODIMP CHandler::GetArchiveProperty(PROPID propID, PROPVARIANT *value)
{
case k_ErrorType_UnexpectedEnd: flags = kpv_ErrorFlags_UnexpectedEnd; break;
case k_ErrorType_Corrupted: flags = kpv_ErrorFlags_HeadersError; break;
+ // case k_ErrorType_OK: break;
+ // case k_ErrorType_Warning: break;
+ default: break;
}
- prop = flags;
+ if (flags != 0)
+ prop = flags;
break;
}
@@ -96,6 +104,13 @@ STDMETHODIMP CHandler::GetArchiveProperty(PROPID propID, PROPVARIANT *value)
prop = name;
break;
}
+
+ case kpidCharacts:
+ {
+ AString s = _encodingCharacts.GetCharactsString();
+ prop = s;
+ break;
+ }
}
prop.Detach(value);
return S_OK;
@@ -119,12 +134,64 @@ HRESULT CHandler::ReadItem2(ISequentialInStream *stream, bool &filled, CItemEx &
*/
if (item.IsPaxExtendedHeader())
_thereIsPaxExtendedHeader = true;
+ if (item.IsThereWarning())
+ _warning = true;
}
_phySize += item.HeaderSize;
_headersSize += item.HeaderSize;
return S_OK;
}
+
+void CEncodingCharacts::Check(const AString &s)
+{
+ IsAscii = s.IsAscii();
+ if (!IsAscii)
+ {
+ /*
+ {
+ Oem_Checked = true;
+ UString u;
+ MultiByteToUnicodeString2(u, s, CP_OEMCP);
+ Oem_Ok = (u.Find((wchar_t)0xfffd) <= 0);
+ }
+ Utf_Checked = true;
+ */
+ UtfCheck.Check_AString(s);
+ }
+}
+
+
+AString CEncodingCharacts::GetCharactsString() const
+{
+ AString s;
+ if (IsAscii)
+ {
+ s += "ASCII";
+ }
+ /*
+ if (Oem_Checked)
+ {
+ s.Add_Space_if_NotEmpty();
+ s += (Oem_Ok ? "oem-ok" : "oem-error");
+ }
+ if (Utf_Checked)
+ */
+ else
+ {
+ s.Add_Space_if_NotEmpty();
+ s += (UtfCheck.IsOK() ? "UTF8" : "UTF8-ERROR"); // "UTF8-error"
+ {
+ AString s2;
+ UtfCheck.PrintStatus(s2);
+ s.Add_Space_if_NotEmpty();
+ s += s2;
+ }
+ }
+ return s;
+}
+
+
HRESULT CHandler::Open2(IInStream *stream, IArchiveOpenCallback *callback)
{
UInt64 endPos = 0;
@@ -135,12 +202,7 @@ HRESULT CHandler::Open2(IInStream *stream, IArchiveOpenCallback *callback)
_phySizeDefined = true;
- bool utf8_OK = true;
- if (!_forceCodePage)
- {
- if (!utf8_OK)
- _curCodePage = k_DefaultCodePage;
- }
+ // bool utf8_OK = true;
for (;;)
{
@@ -151,8 +213,8 @@ HRESULT CHandler::Open2(IInStream *stream, IArchiveOpenCallback *callback)
break;
_isArc = true;
- _items.Add(item);
+ /*
if (!_forceCodePage)
{
if (utf8_OK) utf8_OK = CheckUTF8(item.Name, item.NameCouldBeReduced);
@@ -160,8 +222,14 @@ HRESULT CHandler::Open2(IInStream *stream, IArchiveOpenCallback *callback)
if (utf8_OK) utf8_OK = CheckUTF8(item.User);
if (utf8_OK) utf8_OK = CheckUTF8(item.Group);
}
-
- RINOK(stream->Seek(item.GetPackSizeAligned(), STREAM_SEEK_CUR, &_phySize));
+ */
+
+ item.EncodingCharacts.Check(item.Name);
+ _encodingCharacts.Update(item.EncodingCharacts);
+
+ _items.Add(item);
+
+ RINOK(stream->Seek((Int64)item.GetPackSizeAligned(), STREAM_SEEK_CUR, &_phySize));
if (_phySize > endPos)
{
_error = k_ErrorType_UnexpectedEnd;
@@ -188,11 +256,13 @@ HRESULT CHandler::Open2(IInStream *stream, IArchiveOpenCallback *callback)
}
}
+ /*
if (!_forceCodePage)
{
if (!utf8_OK)
_curCodePage = k_DefaultCodePage;
}
+ */
_openCodePage = _curCodePage;
if (_items.Size() == 0)
@@ -255,6 +325,7 @@ STDMETHODIMP CHandler::Close()
_latestIsRead = false;
// _isSparse = false;
_thereIsPaxExtendedHeader = false;
+ _encodingCharacts.Clear();
_items.Clear();
_seqStream.Release();
_stream.Release();
@@ -315,7 +386,8 @@ void CHandler::TarStringToUnicode(const AString &s, NWindows::NCOM::CPropVariant
else
MultiByteToUnicodeString2(dest, s, _curCodePage);
if (toOs)
- NItemName::ReplaceToOsSlashes_Remove_TailSlash(dest);
+ NItemName::ReplaceToOsSlashes_Remove_TailSlash(dest,
+ true); // useBackslashReplacement
prop = dest;
}
@@ -358,6 +430,17 @@ STDMETHODIMP CHandler::GetProperty(UInt32 index, PROPID propID, PROPVARIANT *val
case kpidSymLink: if (item->LinkFlag == NFileHeader::NLinkFlag::kSymLink && !item->LinkName.IsEmpty()) TarStringToUnicode(item->LinkName, prop); break;
case kpidHardLink: if (item->LinkFlag == NFileHeader::NLinkFlag::kHardLink && !item->LinkName.IsEmpty()) TarStringToUnicode(item->LinkName, prop); break;
// case kpidLinkType: prop = (int)item->LinkFlag; break;
+ case kpidCharacts:
+ {
+ AString s = item->EncodingCharacts.GetCharactsString();
+ if (item->IsThereWarning())
+ {
+ s.Add_Space_if_NotEmpty();
+ s += "HEADER_ERROR";
+ }
+ prop = s;
+ break;
+ }
}
prop.Detach(value);
return S_OK;
@@ -407,7 +490,7 @@ HRESULT CHandler::Extract(const UInt32 *indices, UInt32 numItems,
Int32 askMode = testMode ?
NExtract::NAskMode::kTest :
NExtract::NAskMode::kExtract;
- Int32 index = allFilesMode ? i : indices[i];
+ const UInt32 index = allFilesMode ? i : indices[i];
const CItemEx *item;
if (seqMode)
{
@@ -475,7 +558,7 @@ HRESULT CHandler::Extract(const UInt32 *indices, UInt32 numItems,
{
if (!seqMode)
{
- RINOK(_stream->Seek(item->GetDataPosition(), STREAM_SEEK_SET, NULL));
+ RINOK(_stream->Seek((Int64)item->GetDataPosition(), STREAM_SEEK_SET, NULL));
}
streamSpec->Init(item->GetPackSizeAligned());
RINOK(copyCoder->Code(inStream2, outStream, NULL, NULL, progress));
@@ -566,7 +649,7 @@ STDMETHODIMP CSparseStream::Read(void *data, UInt32 size, UInt32 *processedSize)
UInt64 phyPos = PhyOffsets[left] + relat;
if (_needStartSeek || _phyPos != phyPos)
{
- RINOK(Handler->_stream->Seek(item.GetDataPosition() + phyPos, STREAM_SEEK_SET, NULL));
+ RINOK(Handler->_stream->Seek((Int64)(item.GetDataPosition() + phyPos), STREAM_SEEK_SET, NULL));
_needStartSeek = false;
_phyPos = phyPos;
}
@@ -604,7 +687,7 @@ STDMETHODIMP CSparseStream::Seek(Int64 offset, UInt32 seekOrigin, UInt64 *newPos
}
if (offset < 0)
return HRESULT_WIN32_ERROR_NEGATIVE_SEEK;
- _virtPos = offset;
+ _virtPos = (UInt64)offset;
if (newPosition)
*newPosition = _virtPos;
return S_OK;
@@ -650,7 +733,6 @@ STDMETHODIMP CHandler::GetStream(UInt32 index, ISequentialInStream **stream)
void CHandler::Init()
{
_forceCodePage = false;
- // _codePage = CP_OEMCP;
_curCodePage = _specifiedCodePage = CP_UTF8; // CP_OEMCP;
_thereIsPaxExtendedHeader = false;
}
diff --git a/CPP/7zip/Archive/Tar/TarHandler.h b/CPP/7zip/Archive/Tar/TarHandler.h
index eb9c049e..4834c2a7 100644
--- a/CPP/7zip/Archive/Tar/TarHandler.h
+++ b/CPP/7zip/Archive/Tar/TarHandler.h
@@ -48,6 +48,8 @@ private:
UInt32 _curCodePage;
UInt32 _openCodePage;
+ CEncodingCharacts _encodingCharacts;
+
NCompress::CCopyCoder *copyCoderSpec;
CMyComPtr<ICompressCoder> copyCoder;
diff --git a/CPP/7zip/Archive/Tar/TarHandlerOut.cpp b/CPP/7zip/Archive/Tar/TarHandlerOut.cpp
index 41934339..7a7a2cba 100644
--- a/CPP/7zip/Archive/Tar/TarHandlerOut.cpp
+++ b/CPP/7zip/Archive/Tar/TarHandlerOut.cpp
@@ -25,8 +25,8 @@ STDMETHODIMP CHandler::GetFileTimeType(UInt32 *type)
return S_OK;
}
-HRESULT GetPropString(IArchiveUpdateCallback *callback, UInt32 index, PROPID propId,
- AString &res, UINT codePage, bool convertSlash = false)
+HRESULT GetPropString(IArchiveUpdateCallback *callback, UInt32 index, PROPID propId, AString &res,
+ UINT codePage, unsigned utfFlags, bool convertSlash)
{
NCOM::CPropVariant prop;
RINOK(callback->GetProperty(index, propId, &prop));
@@ -39,7 +39,7 @@ HRESULT GetPropString(IArchiveUpdateCallback *callback, UInt32 index, PROPID pro
if (codePage == CP_UTF8)
{
- ConvertUnicodeToUTF8(s, res);
+ ConvertUnicodeToUTF8_Flags(s, res, utfFlags);
// if (!ConvertUnicodeToUTF8(s, res)) // return E_INVALIDARG;
}
else
@@ -56,8 +56,8 @@ HRESULT GetPropString(IArchiveUpdateCallback *callback, UInt32 index, PROPID pro
static int CompareUpdateItems(void *const *p1, void *const *p2, void *)
{
- const CUpdateItem &u1 = *(*((const CUpdateItem **)p1));
- const CUpdateItem &u2 = *(*((const CUpdateItem **)p2));
+ const CUpdateItem &u1 = *(*((const CUpdateItem *const *)p1));
+ const CUpdateItem &u2 = *(*((const CUpdateItem *const *)p2));
if (!u1.NewProps)
{
if (u2.NewProps)
@@ -78,8 +78,15 @@ STDMETHODIMP CHandler::UpdateItems(ISequentialOutStream *outStream, UInt32 numIt
if ((_stream && (_error != k_ErrorType_OK || _warning /* || _isSparse */)) || _seqStream)
return E_NOTIMPL;
CObjectVector<CUpdateItem> updateItems;
- UINT codePage = (_forceCodePage ? _specifiedCodePage : _openCodePage);
-
+ const UINT codePage = (_forceCodePage ? _specifiedCodePage : _openCodePage);
+ const unsigned utfFlags = g_Unicode_To_UTF8_Flags;
+ /*
+ // for debug only:
+ unsigned utfFlags = 0;
+ utfFlags |= UTF_FLAG__TO_UTF8__EXTRACT_BMP_ESCAPE;
+ utfFlags |= UTF_FLAG__TO_UTF8__SURROGATE_ERROR;
+ */
+
for (UInt32 i = 0; i < numItems; i++)
{
CUpdateItem ui;
@@ -94,7 +101,7 @@ STDMETHODIMP CHandler::UpdateItems(ISequentialOutStream *outStream, UInt32 numIt
ui.NewProps = IntToBool(newProps);
ui.NewData = IntToBool(newData);
- ui.IndexInArc = indexInArc;
+ ui.IndexInArc = (int)indexInArc;
ui.IndexInClient = i;
if (IntToBool(newProps))
@@ -138,11 +145,11 @@ STDMETHODIMP CHandler::UpdateItems(ISequentialOutStream *outStream, UInt32 numIt
ui.MTime = NTime::FileTimeToUnixTime64(prop.filetime);
}
- RINOK(GetPropString(callback, i, kpidPath, ui.Name, codePage, true));
+ RINOK(GetPropString(callback, i, kpidPath, ui.Name, codePage, utfFlags, true));
if (ui.IsDir && !ui.Name.IsEmpty() && ui.Name.Back() != '/')
ui.Name += '/';
- RINOK(GetPropString(callback, i, kpidUser, ui.User, codePage));
- RINOK(GetPropString(callback, i, kpidGroup, ui.Group, codePage));
+ RINOK(GetPropString(callback, i, kpidUser, ui.User, codePage, utfFlags, false));
+ RINOK(GetPropString(callback, i, kpidGroup, ui.Group, codePage, utfFlags, false));
}
if (IntToBool(newData))
@@ -168,7 +175,7 @@ STDMETHODIMP CHandler::UpdateItems(ISequentialOutStream *outStream, UInt32 numIt
updateItems.Sort(CompareUpdateItems, NULL);
}
- return UpdateArchive(_stream, outStream, _items, updateItems, codePage, callback);
+ return UpdateArchive(_stream, outStream, _items, updateItems, codePage, utfFlags, callback);
COM_TRY_END
}
diff --git a/CPP/7zip/Archive/Tar/TarHeader.h b/CPP/7zip/Archive/Tar/TarHeader.h
index 47971b58..249368f6 100644
--- a/CPP/7zip/Archive/Tar/TarHeader.h
+++ b/CPP/7zip/Archive/Tar/TarHeader.h
@@ -58,6 +58,7 @@ namespace NFileHeader
const char kGnu_LongLink = 'K';
const char kGnu_LongName = 'L';
const char kSparse = 'S';
+ const char kLabel = 'V';
const char kDumpDir = 'D'; /* GNUTYPE_DUMPDIR.
data: list of files created by the --incremental (-G) option
Each file name is preceded by either
diff --git a/CPP/7zip/Archive/Tar/TarIn.cpp b/CPP/7zip/Archive/Tar/TarIn.cpp
index 32761658..0099e6f7 100644
--- a/CPP/7zip/Archive/Tar/TarIn.cpp
+++ b/CPP/7zip/Archive/Tar/TarIn.cpp
@@ -81,14 +81,14 @@ static void ReadString(const char *s, unsigned size, AString &result)
static bool ParseInt64(const char *p, Int64 &val)
{
UInt32 h = GetBe32(p);
- val = GetBe64(p + 4);
+ val = (Int64)GetBe64(p + 4);
if (h == (UInt32)1 << 31)
return ((val >> 63) & 1) == 0;
if (h == (UInt32)(Int32)-1)
return ((val >> 63) & 1) != 0;
UInt64 uv;
bool res = OctalToNumber(p, 12, uv);
- val = uv;
+ val = (Int64)uv;
return res;
}
@@ -112,7 +112,9 @@ static bool ParseSize(const char *p, UInt64 &val)
val = GetBe64(p + 4);
return ((val >> 63) & 1) == 0;
}
- return OctalToNumber(p, 12, val);
+ return OctalToNumber(p, 12, val,
+ true // 20.03: allow empty size for 'V' Label entry
+ );
}
#define CHECK(x) { if (!(x)) return k_IsArc_Res_NO; }
@@ -201,8 +203,8 @@ static HRESULT GetNextItemReal(ISequentialInStream *stream, bool &filled, CItemE
// we allow empty Mode value for LongName prefix items
RIF(OctalToNumber32(p, 8, item.Mode, true)); p += 8;
- if (!OctalToNumber32(p, 8, item.UID)) item.UID = 0; p += 8;
- if (!OctalToNumber32(p, 8, item.GID)) item.GID = 0; p += 8;
+ if (!OctalToNumber32(p, 8, item.UID)) { item.UID = 0; } p += 8;
+ if (!OctalToNumber32(p, 8, item.GID)) { item.GID = 0; } p += 8;
RIF(ParseSize(p, item.PackSize));
item.Size = item.PackSize;
@@ -245,6 +247,15 @@ static HRESULT GetNextItemReal(ISequentialInStream *stream, bool &filled, CItemE
item.PackSize = 0;
item.Size = 0;
}
+
+ if (item.LinkFlag == NFileHeader::NLinkFlag::kDirectory)
+ {
+ // GNU tar ignores Size field, if LinkFlag is kDirectory
+ // 21.02 : we set PackSize = 0 to be more compatible with GNU tar
+ item.PackSize = 0;
+ // item.Size = 0;
+ }
+
/*
TAR standard requires sum of unsigned byte values.
But some TAR programs use sum of signed byte values.
@@ -269,7 +280,7 @@ static HRESULT GetNextItemReal(ISequentialInStream *stream, bool &filled, CItemE
if (item.LinkFlag == NFileHeader::NLinkFlag::kSparse)
{
- Byte isExtended = buf[482];
+ Byte isExtended = (Byte)buf[482];
if (isExtended != 0 && isExtended != 1)
return S_OK;
RIF(ParseSize(buf + 483, item.Size));
@@ -309,7 +320,7 @@ static HRESULT GetNextItemReal(ISequentialInStream *stream, bool &filled, CItemE
}
item.HeaderSize += NFileHeader::kRecordSize;
- isExtended = buf[21 * 24];
+ isExtended = (Byte)buf[21 * 24];
if (isExtended != 0 && isExtended != 1)
return S_OK;
for (unsigned i = 0; i < 21; i++)
@@ -442,9 +453,16 @@ HRESULT ReadItem(ISequentialInStream *stream, bool &filled, CItemEx &item, EErro
case 'x':
case 'X':
{
- // pax Extended Header
- if (item.Name.IsPrefixedBy("PaxHeader/")
- || item.Name.Find("PaxHeaders.4467/") >= 0)
+ const char *s = item.Name.Ptr();
+ if (IsString1PrefixedByString2(s, "./"))
+ s += 2;
+ if (IsString1PrefixedByString2(s, "./"))
+ s += 2;
+ if ( IsString1PrefixedByString2(s, "PaxHeader/")
+ || IsString1PrefixedByString2(s, "PaxHeaders.X/")
+ || IsString1PrefixedByString2(s, "PaxHeaders.4467/")
+ || StringsAreEqual_Ascii(s, "@PaxHeader")
+ )
{
RINOK(ReadDataToString(stream, item, pax, error));
if (error != k_ErrorType_OK)
diff --git a/CPP/7zip/Archive/Tar/TarItem.h b/CPP/7zip/Archive/Tar/TarItem.h
index bc3b4084..8c34b841 100644
--- a/CPP/7zip/Archive/Tar/TarItem.h
+++ b/CPP/7zip/Archive/Tar/TarItem.h
@@ -4,6 +4,7 @@
#define __ARCHIVE_TAR_ITEM_H
#include "../../../Common/MyLinux.h"
+#include "../../../Common/UTFConvert.h"
#include "../Common/ItemNameUtils.h"
@@ -108,8 +109,52 @@ struct CItem
}
UInt64 GetPackSizeAligned() const { return (PackSize + 0x1FF) & (~((UInt64)0x1FF)); }
+
+ bool IsThereWarning() const
+ {
+ // that Header Warning is possible if (Size != 0) for dir item
+ return (PackSize < Size) && (LinkFlag == NFileHeader::NLinkFlag::kDirectory);
+ }
};
+
+
+struct CEncodingCharacts
+{
+ bool IsAscii;
+ // bool Oem_Checked;
+ // bool Oem_Ok;
+ // bool Utf_Checked;
+ CUtf8Check UtfCheck;
+
+ void Clear()
+ {
+ IsAscii = true;
+ // Oem_Checked = false;
+ // Oem_Ok = false;
+ // Utf_Checked = false;
+ UtfCheck.Clear();
+ }
+
+ void Update(const CEncodingCharacts &ec)
+ {
+ if (!ec.IsAscii)
+ IsAscii = false;
+
+ // if (ec.Utf_Checked)
+ {
+ UtfCheck.Update(ec.UtfCheck);
+ // Utf_Checked = true;
+ }
+ }
+
+ CEncodingCharacts() { Clear(); }
+ void Check(const AString &s);
+ AString GetCharactsString() const;
+};
+
+
+
struct CItemEx: public CItem
{
UInt64 HeaderPos;
@@ -117,6 +162,8 @@ struct CItemEx: public CItem
bool NameCouldBeReduced;
bool LinkNameCouldBeReduced;
+ CEncodingCharacts EncodingCharacts;
+
UInt64 GetDataPosition() const { return HeaderPos + HeaderSize; }
UInt64 GetFullSize() const { return HeaderSize + PackSize; }
};
diff --git a/CPP/7zip/Archive/Tar/TarOut.cpp b/CPP/7zip/Archive/Tar/TarOut.cpp
index 51081e8b..e2da3238 100644
--- a/CPP/7zip/Archive/Tar/TarOut.cpp
+++ b/CPP/7zip/Archive/Tar/TarOut.cpp
@@ -62,7 +62,7 @@ static void WriteOctal_12_Signed(char *s, Int64 val)
{
if (val >= 0)
{
- WriteOctal_12(s, val);
+ WriteOctal_12(s, (UInt64)val);
return;
}
s[0] = s[1] = s[2] = s[3] = (char)(Byte)0xFF;
diff --git a/CPP/7zip/Archive/Tar/TarUpdate.cpp b/CPP/7zip/Archive/Tar/TarUpdate.cpp
index 0cdb30d1..c7598f8d 100644
--- a/CPP/7zip/Archive/Tar/TarUpdate.cpp
+++ b/CPP/7zip/Archive/Tar/TarUpdate.cpp
@@ -15,13 +15,10 @@
namespace NArchive {
namespace NTar {
-HRESULT GetPropString(IArchiveUpdateCallback *callback, UInt32 index, PROPID propId,
- AString &res, UINT codePage, bool convertSlash = false);
-
HRESULT UpdateArchive(IInStream *inStream, ISequentialOutStream *outStream,
const CObjectVector<NArchive::NTar::CItemEx> &inputItems,
const CObjectVector<CUpdateItem> &updateItems,
- UINT codePage,
+ UINT codePage, unsigned utfFlags,
IArchiveUpdateCallback *updateCallback)
{
COutArchive outArchive;
@@ -43,7 +40,7 @@ HRESULT UpdateArchive(IInStream *inStream, ISequentialOutStream *outStream,
if (ui.NewData)
complexity += ui.Size;
else
- complexity += inputItems[ui.IndexInArc].GetFullSize();
+ complexity += inputItems[(unsigned)ui.IndexInArc].GetFullSize();
}
RINOK(updateCallback->SetTotal(complexity));
@@ -95,12 +92,12 @@ HRESULT UpdateArchive(IInStream *inStream, ISequentialOutStream *outStream,
memcpy(item.Magic, NFileHeader::NMagic::kUsTar_00, 8);
}
else
- item = inputItems[ui.IndexInArc];
+ item = inputItems[(unsigned)ui.IndexInArc];
AString symLink;
if (ui.NewData || ui.NewProps)
{
- RINOK(GetPropString(updateCallback, ui.IndexInClient, kpidSymLink, symLink, codePage, true));
+ RINOK(GetPropString(updateCallback, ui.IndexInClient, kpidSymLink, symLink, codePage, utfFlags, true));
if (!symLink.IsEmpty())
{
item.LinkFlag = NFileHeader::NLinkFlag::kSymLink;
@@ -159,7 +156,7 @@ HRESULT UpdateArchive(IInStream *inStream, ISequentialOutStream *outStream,
{
AString hardLink;
- RINOK(GetPropString(updateCallback, ui.IndexInClient, kpidHardLink, hardLink, codePage, true));
+ RINOK(GetPropString(updateCallback, ui.IndexInClient, kpidHardLink, hardLink, codePage, utfFlags, true));
if (!hardLink.IsEmpty())
{
item.LinkFlag = NFileHeader::NLinkFlag::kHardLink;
@@ -189,7 +186,7 @@ HRESULT UpdateArchive(IInStream *inStream, ISequentialOutStream *outStream,
outArchive.Pos = fileHeaderStartPos;
item.PackSize = copyCoderSpec->TotalSize;
RINOK(outArchive.WriteHeader(item));
- RINOK(outSeekStream->Seek(item.PackSize, STREAM_SEEK_CUR, NULL));
+ RINOK(outSeekStream->Seek((Int64)item.PackSize, STREAM_SEEK_CUR, NULL));
outArchive.Pos += item.PackSize;
}
RINOK(outArchive.FillDataResidual(item.PackSize));
@@ -201,7 +198,7 @@ HRESULT UpdateArchive(IInStream *inStream, ISequentialOutStream *outStream,
}
else
{
- const CItemEx &existItem = inputItems[ui.IndexInArc];
+ const CItemEx &existItem = inputItems[(unsigned)ui.IndexInArc];
UInt64 size;
if (ui.NewProps)
@@ -231,12 +228,12 @@ HRESULT UpdateArchive(IInStream *inStream, ISequentialOutStream *outStream,
item.GID = existItem.GID;
RINOK(outArchive.WriteHeader(item));
- RINOK(inStream->Seek(existItem.GetDataPosition(), STREAM_SEEK_SET, NULL));
+ RINOK(inStream->Seek((Int64)existItem.GetDataPosition(), STREAM_SEEK_SET, NULL));
size = existItem.PackSize;
}
else
{
- RINOK(inStream->Seek(existItem.HeaderPos, STREAM_SEEK_SET, NULL));
+ RINOK(inStream->Seek((Int64)existItem.HeaderPos, STREAM_SEEK_SET, NULL));
size = existItem.GetFullSize();
}
diff --git a/CPP/7zip/Archive/Tar/TarUpdate.h b/CPP/7zip/Archive/Tar/TarUpdate.h
index b758635f..1e3d0217 100644
--- a/CPP/7zip/Archive/Tar/TarUpdate.h
+++ b/CPP/7zip/Archive/Tar/TarUpdate.h
@@ -13,7 +13,7 @@ namespace NTar {
struct CUpdateItem
{
int IndexInArc;
- int IndexInClient;
+ unsigned IndexInClient;
UInt64 Size;
Int64 MTime;
UInt32 Mode;
@@ -30,9 +30,12 @@ struct CUpdateItem
HRESULT UpdateArchive(IInStream *inStream, ISequentialOutStream *outStream,
const CObjectVector<CItemEx> &inputItems,
const CObjectVector<CUpdateItem> &updateItems,
- UINT codePage,
+ UINT codePage, unsigned utfFlags,
IArchiveUpdateCallback *updateCallback);
+HRESULT GetPropString(IArchiveUpdateCallback *callback, UInt32 index, PROPID propId, AString &res,
+ UINT codePage, unsigned utfFlags, bool convertSlash);
+
}}
#endif
diff --git a/CPP/7zip/Archive/Udf/UdfIn.cpp b/CPP/7zip/Archive/Udf/UdfIn.cpp
index cfe6c5ad..520ceeea 100644
--- a/CPP/7zip/Archive/Udf/UdfIn.cpp
+++ b/CPP/7zip/Archive/Udf/UdfIn.cpp
@@ -39,13 +39,13 @@ static const UInt64 kFileNameLengthTotalMax = (UInt64)1 << 33;
static const UInt64 kInlineExtentsSizeMax = (UInt64)1 << 33;
#define CRC16_INIT_VAL 0
-#define CRC16_GET_DIGEST(crc) (crc)
+// #define CRC16_GET_DIGEST(crc) (crc)
#define CRC16_UPDATE_BYTE(crc, b) ((UInt16)(g_Crc16Table[(((crc) >> 8) ^ (b)) & 0xFF] ^ ((crc) << 8)))
#define kCrc16Poly 0x1021
static UInt16 g_Crc16Table[256];
-void MY_FAST_CALL Crc16GenerateTable(void)
+static void MY_FAST_CALL Crc16GenerateTable(void)
{
UInt32 i;
for (i = 0; i < 256; i++)
@@ -57,7 +57,7 @@ void MY_FAST_CALL Crc16GenerateTable(void)
}
}
-UInt32 MY_FAST_CALL Crc16_Update(UInt32 v, const void *data, size_t size)
+static UInt32 MY_FAST_CALL Crc16_Update(UInt32 v, const void *data, size_t size)
{
const Byte *p = (const Byte *)data;
for (; size > 0 ; size--, p++)
@@ -65,7 +65,7 @@ UInt32 MY_FAST_CALL Crc16_Update(UInt32 v, const void *data, size_t size)
return v;
}
-UInt32 MY_FAST_CALL Crc16Calc(const void *data, size_t size)
+static UInt32 MY_FAST_CALL Crc16Calc(const void *data, size_t size)
{
return Crc16_Update(CRC16_INIT_VAL, data, size);
}
diff --git a/CPP/7zip/Archive/Udf/UdfIn.h b/CPP/7zip/Archive/Udf/UdfIn.h
index f7379401..c26f6099 100644
--- a/CPP/7zip/Archive/Udf/UdfIn.h
+++ b/CPP/7zip/Archive/Udf/UdfIn.h
@@ -351,7 +351,7 @@ class CInArchive
UInt64 _processedProgressBytes;
UInt64 _fileNameLengthTotal;
- int _numRefs;
+ unsigned _numRefs;
UInt32 _numExtents;
UInt64 _inlineExtentsSize;
bool CheckExtent(int volIndex, int partitionRef, UInt32 blockPos, UInt32 len) const;
diff --git a/CPP/7zip/Archive/UefiHandler.cpp b/CPP/7zip/Archive/UefiHandler.cpp
index 5892d568..67fe795a 100644
--- a/CPP/7zip/Archive/UefiHandler.cpp
+++ b/CPP/7zip/Archive/UefiHandler.cpp
@@ -52,7 +52,7 @@ static const Byte k_IntelMeSignature[] =
0x5A, 0xA5, 0xF0, 0x0F
};
-bool IsIntelMe(const Byte *p)
+static bool IsIntelMe(const Byte *p)
{
return memcmp(p, k_IntelMeSignature, sizeof(k_IntelMeSignature)) == 0;
}
@@ -318,19 +318,19 @@ static const CUInt32PCharPair g_FFS_FILE_ATTRIBUTES[] =
// SECTION_TYPE
-#define SECTION_ALL 0x00
+// #define SECTION_ALL 0x00
#define SECTION_COMPRESSION 0x01
#define SECTION_GUID_DEFINED 0x02
// Leaf section Type values
-#define SECTION_PE32 0x10
-#define SECTION_PIC 0x11
-#define SECTION_TE 0x12
+// #define SECTION_PE32 0x10
+// #define SECTION_PIC 0x11
+// #define SECTION_TE 0x12
#define SECTION_DXE_DEPEX 0x13
#define SECTION_VERSION 0x14
#define SECTION_USER_INTERFACE 0x15
-#define SECTION_COMPATIBILITY16 0x16
+// #define SECTION_COMPATIBILITY16 0x16
#define SECTION_FIRMWARE_VOLUME_IMAGE 0x17
#define SECTION_FREEFORM_SUBTYPE_GUID 0x18
#define SECTION_RAW 0x19
@@ -471,7 +471,7 @@ public:
bool Parse(const Byte *p)
{
- int i;
+ unsigned i;
for (i = 0; i < kFileHeaderSize; i++)
if (p[i] != 0xFF)
break;
@@ -719,11 +719,11 @@ class CHandler:
HRESULT ParseIntelMe(int bufIndex, UInt32 posBase,
UInt32 exactSize, UInt32 limitSize,
- int parent, int method, int level);
+ int parent, int method, unsigned level);
HRESULT ParseVolume(int bufIndex, UInt32 posBase,
UInt32 exactSize, UInt32 limitSize,
- int parent, int method, int level);
+ int parent, int method, unsigned level);
HRESULT OpenCapsule(IInStream *stream);
HRESULT OpenFv(IInStream *stream, const UInt64 *maxCheckStartPosition, IArchiveOpenCallback *callback);
@@ -857,13 +857,13 @@ STDMETHODIMP CHandler::GetArchiveProperty(PROPID propID, PROPVARIANT *value)
}
#ifdef SHOW_DEBUG_INFO
-static void PrintLevel(int level)
+static void PrintLevel(unsigned level)
{
PRF(printf("\n"));
- for (int i = 0; i < level; i++)
+ for (unsigned i = 0; i < level; i++)
PRF(printf(" "));
}
-static void MyPrint(UInt32 posBase, UInt32 size, int level, const char *name)
+static void MyPrint(UInt32 posBase, UInt32 size, unsigned level, const char *name)
{
PrintLevel(level);
PRF(printf("%s, pos = %6x, size = %6x", name, posBase, size));
@@ -1312,7 +1312,7 @@ bool CVolFfsHeader::Parse(const Byte *p)
HRESULT CHandler::ParseVolume(
int bufIndex, UInt32 posBase,
UInt32 exactSize, UInt32 limitSize,
- int parent, int method, int level)
+ int parent, int method, unsigned level)
{
if (level > kLevelMax)
return S_FALSE;
@@ -1333,7 +1333,7 @@ HRESULT CHandler::ParseVolume(
if (!Is_FF_Stream(p + kFfsGuidOffset, 16))
item.SetGuid(p + kFfsGuidOffset);
// if (item.Name.IsEmpty())
- item.Name += "[VOL]";
+ item.Name += "[VOL]";
AddItem(item);
return S_OK;
}
@@ -1512,7 +1512,7 @@ static const char * const kRegionName[] =
HRESULT CHandler::ParseIntelMe(
int bufIndex, UInt32 posBase,
UInt32 exactSize, UInt32 limitSize,
- int parent, int method, int level)
+ int parent, int method, unsigned level)
{
UNUSED_VAR(limitSize)
level++;
diff --git a/CPP/7zip/Archive/VdiHandler.cpp b/CPP/7zip/Archive/VdiHandler.cpp
index b8ef35bb..66cf39cd 100644
--- a/CPP/7zip/Archive/VdiHandler.cpp
+++ b/CPP/7zip/Archive/VdiHandler.cpp
@@ -18,7 +18,6 @@
#include "HandlerCont.h"
-#define Get16(p) GetUi16(p)
#define Get32(p) GetUi32(p)
#define Get64(p) GetUi64(p)
@@ -87,7 +86,7 @@ class CHandler: public CHandlerImg
Byte Guids[kNumGuids][16];
- HRESULT Seek(UInt64 offset)
+ HRESULT Seek2(UInt64 offset)
{
_posInArc = offset;
return Stream->Seek(offset, STREAM_SEEK_SET, NULL);
@@ -96,7 +95,7 @@ class CHandler: public CHandlerImg
HRESULT InitAndSeek()
{
_virtPos = 0;
- return Seek(0);
+ return Seek2(0);
}
HRESULT Open2(IInStream *stream, IArchiveOpenCallback *openCallback);
@@ -143,7 +142,7 @@ STDMETHODIMP CHandler::Read(void *data, UInt32 size, UInt32 *processedSize)
offset += lowBits;
if (offset != _posInArc)
{
- RINOK(Seek(offset));
+ RINOK(Seek2(offset));
}
HRESULT res = Stream->Read(data, size, &size);
_posInArc += size;
diff --git a/CPP/7zip/Archive/VhdHandler.cpp b/CPP/7zip/Archive/VhdHandler.cpp
index d79ae907..c70d667e 100644
--- a/CPP/7zip/Archive/VhdHandler.cpp
+++ b/CPP/7zip/Archive/VhdHandler.cpp
@@ -248,7 +248,7 @@ class CHandler: public CHandlerImg
}
void Reset_PosInArc() { _posInArc = (UInt64)0 - 1; }
- HRESULT Seek(UInt64 offset);
+ HRESULT Seek2(UInt64 offset);
HRESULT InitAndSeek();
HRESULT ReadPhy(UInt64 offset, void *data, UInt32 size);
@@ -316,7 +316,7 @@ public:
STDMETHOD(Read)(void *data, UInt32 size, UInt32 *processedSize);
};
-HRESULT CHandler::Seek(UInt64 offset) { return Stream->Seek(_startOffset + offset, STREAM_SEEK_SET, NULL); }
+HRESULT CHandler::Seek2(UInt64 offset) { return Stream->Seek(_startOffset + offset, STREAM_SEEK_SET, NULL); }
HRESULT CHandler::InitAndSeek()
{
@@ -327,7 +327,7 @@ HRESULT CHandler::InitAndSeek()
_virtPos = _posInArc = 0;
BitMapTag = kUnusedBlock;
BitMap.Alloc(Dyn.NumBitMapSectors() << kSectorSize_Log);
- return Seek(0);
+ return Seek2(0);
}
HRESULT CHandler::ReadPhy(UInt64 offset, void *data, UInt32 size)
@@ -337,7 +337,7 @@ HRESULT CHandler::ReadPhy(UInt64 offset, void *data, UInt32 size)
if (offset != _posInArc)
{
_posInArc = offset;
- RINOK(Seek(offset));
+ RINOK(Seek2(offset));
}
HRESULT res = ReadStream_FALSE(Stream, data, size);
if (res == S_OK)
diff --git a/CPP/7zip/Archive/VmdkHandler.cpp b/CPP/7zip/Archive/VmdkHandler.cpp
index 942bd792..096bd103 100644
--- a/CPP/7zip/Archive/VmdkHandler.cpp
+++ b/CPP/7zip/Archive/VmdkHandler.cpp
@@ -41,7 +41,7 @@ namespace NVmdk {
static const Byte k_Signature[] = SIGNATURE;
static const UInt32 k_Flags_NL = (UInt32)1 << 0;
-static const UInt32 k_Flags_RGD = (UInt32)1 << 1;
+// static const UInt32 k_Flags_RGD = (UInt32)1 << 1;
static const UInt32 k_Flags_ZeroGrain = (UInt32)1 << 2;
static const UInt32 k_Flags_Compressed = (UInt32)1 << 16;
static const UInt32 k_Flags_Marker = (UInt32)1 << 17;
@@ -855,11 +855,13 @@ STDMETHODIMP CHandler::GetArchiveProperty(PROPID propID, PROPVARIANT *value)
}
case kpidId:
+ {
if (desc && !desc->CID.IsEmpty())
{
prop = desc->CID;
- break;
}
+ break;
+ }
case kpidName:
{
diff --git a/CPP/7zip/Archive/Wim/WimHandler.cpp b/CPP/7zip/Archive/Wim/WimHandler.cpp
index 927a0b38..2553c175 100644
--- a/CPP/7zip/Archive/Wim/WimHandler.cpp
+++ b/CPP/7zip/Archive/Wim/WimHandler.cpp
@@ -350,7 +350,7 @@ STDMETHODIMP CHandler::GetArchiveProperty(PROPID propID, PROPVARIANT *value)
COM_TRY_END
}
-void GetFileTime(const Byte *p, NCOM::CPropVariant &prop)
+static void GetFileTime(const Byte *p, NCOM::CPropVariant &prop)
{
prop.vt = VT_FILETIME;
prop.filetime.dwLowDateTime = Get32(p);
diff --git a/CPP/7zip/Archive/Wim/WimHandlerOut.cpp b/CPP/7zip/Archive/Wim/WimHandlerOut.cpp
index 18740c70..6b4497fe 100644
--- a/CPP/7zip/Archive/Wim/WimHandlerOut.cpp
+++ b/CPP/7zip/Archive/Wim/WimHandlerOut.cpp
@@ -4,6 +4,7 @@
#include "../../../Common/ComTry.h"
#include "../../../Common/IntToString.h"
+#include "../../../Common/MyBuffer2.h"
#include "../../../Common/StringToInt.h"
#include "../../../Common/UTFConvert.h"
#include "../../../Common/Wildcard.h"
@@ -93,9 +94,15 @@ struct CMetaItem
CByteBuffer Reparse;
unsigned GetNumAltStreams() const { return AltStreams.Size() - NumSkipAltStreams; }
- CMetaItem(): UpdateIndex(-1), HashIndex(-1), SecurityId(-1),
- FileID(0), VolID(0),
- Skip(false), NumSkipAltStreams(0) {}
+ CMetaItem():
+ UpdateIndex(-1)
+ , HashIndex(-1)
+ , FileID(0)
+ , VolID(0)
+ , SecurityId(-1)
+ , Skip(false)
+ , NumSkipAltStreams(0)
+ {}
};
@@ -320,20 +327,23 @@ class CInStreamWithSha1:
{
CMyComPtr<ISequentialInStream> _stream;
UInt64 _size;
- NCrypto::NSha1::CContext _sha;
+ // NCrypto::NSha1::CContext _sha;
+ CAlignedBuffer _sha;
+ CSha1 *Sha() { return (CSha1 *)(void *)(Byte *)_sha; }
public:
MY_UNKNOWN_IMP1(IInStream)
STDMETHOD(Read)(void *data, UInt32 size, UInt32 *processedSize);
+ CInStreamWithSha1(): _sha(sizeof(CSha1)) {}
void SetStream(ISequentialInStream *stream) { _stream = stream; }
void Init()
{
_size = 0;
- _sha.Init();
+ Sha1_Init(Sha());
}
void ReleaseStream() { _stream.Release(); }
UInt64 GetSize() const { return _size; }
- void Final(Byte *digest) { _sha.Final(digest); }
+ void Final(Byte *digest) { Sha1_Final(Sha(), digest); }
};
STDMETHODIMP CInStreamWithSha1::Read(void *data, UInt32 size, UInt32 *processedSize)
@@ -341,7 +351,7 @@ STDMETHODIMP CInStreamWithSha1::Read(void *data, UInt32 size, UInt32 *processedS
UInt32 realProcessedSize;
HRESULT result = _stream->Read(data, size, &realProcessedSize);
_size += realProcessedSize;
- _sha.Update((const Byte *)data, realProcessedSize);
+ Sha1_Update(Sha(), (const Byte *)data, realProcessedSize);
if (processedSize)
*processedSize = realProcessedSize;
return result;
@@ -427,9 +437,9 @@ static size_t WriteItem(const CStreamInfo *streams, const CMetaItem &item, Byte
Set16(p + 0x64, (UInt16)fileNameLen);
unsigned i;
for (i = 0; i * 2 < fileNameLen; i++)
- Set16(p + kDirRecordSize + i * 2, item.Name[i]);
+ Set16(p + kDirRecordSize + i * 2, (UInt16)item.Name[i]);
for (i = 0; i * 2 < shortNameLen; i++)
- Set16(p + kDirRecordSize + fileNameLen2 + i * 2, item.ShortName[i]);
+ Set16(p + kDirRecordSize + fileNameLen2 + i * 2, (UInt16)item.ShortName[i]);
if (item.GetNumAltStreams() == 0)
{
@@ -468,7 +478,7 @@ static size_t WriteItem(const CStreamInfo *streams, const CMetaItem &item, Byte
memcpy(p + 0x10, streams[ss.HashIndex].Hash, kHashSize);
Set16(p + 0x24, (UInt16)fileNameLen);
for (i = 0; i * 2 < fileNameLen; i++)
- Set16(p + 0x26 + i * 2, ss.Name[i]);
+ Set16(p + 0x26 + i * 2, (UInt16)ss.Name[i]);
totalLen += curLen;
p += curLen;
}
@@ -690,7 +700,7 @@ static void AddTrees(CObjectVector<CDir> &trees, CObjectVector<CMetaItem> &metaI
}
-#define IS_LETTER_CHAR(c) ((c) >= 'a' && (c) <= 'z' || (c) >= 'A' && (c) <= 'Z')
+#define IS_LETTER_CHAR(c) (((c) >= 'a' && (c) <= 'z') || ((c) >= 'A' && (c) <= 'Z'))
@@ -1024,7 +1034,7 @@ STDMETHODIMP CHandler::UpdateItems(ISequentialOutStream *outSeqStream, UInt32 nu
imageIndex = (int)val - 1;
if (imageIndex < (int)isChangedImage.Size())
- if (!isChangedImage[imageIndex])
+ if (!isChangedImage[imageIndex])
return E_FAIL;
AddTrees(trees, db.MetaItems, ri, imageIndex);
@@ -1079,7 +1089,27 @@ STDMETHODIMP CHandler::UpdateItems(ISequentialOutStream *outSeqStream, UInt32 nu
fileName.Empty();
}
else
+ {
+ /*
+ #if WCHAR_MAX > 0xffff
+ if (c >= 0x10000)
+ {
+ c -= 0x10000;
+
+ if (c < (1 << 20))
+ {
+ wchar_t c0 = 0xd800 + ((c >> 10) & 0x3FF);
+ fileName += c0;
+ c = 0xdc00 + (c & 0x3FF);
+ }
+ else
+ c = '_'; // we change character unsupported by UTF16
+ }
+ #endif
+ */
+
fileName += c;
+ }
}
if (isAltStream)
@@ -1838,7 +1868,7 @@ STDMETHODIMP CHandler::UpdateItems(ISequentialOutStream *outSeqStream, UInt32 nu
if (_xmls.Size() == 1)
{
const CWimXml &_oldXml = _xmls[0];
- if ((int)i < _oldXml.Images.Size())
+ if (i < _oldXml.Images.Size())
{
// int ttt = _oldXml.Images[i].ItemIndexInXml;
item = _oldXml.Xml.Root.SubItems[_oldXml.Images[i].ItemIndexInXml];
@@ -1880,7 +1910,7 @@ STDMETHODIMP CHandler::UpdateItems(ISequentialOutStream *outSeqStream, UInt32 nu
CByteArr xmlBuf(xmlSize);
Set16((Byte *)xmlBuf, 0xFEFF);
for (i = 0; i < (unsigned)utf16.Len(); i++)
- Set16((Byte *)xmlBuf + 2 + i * 2, utf16[i]);
+ Set16((Byte *)xmlBuf + 2 + i * 2, (UInt16)utf16[i]);
RINOK(WriteStream(outStream, (const Byte *)xmlBuf, xmlSize));
}
diff --git a/CPP/7zip/Archive/Wim/WimIn.cpp b/CPP/7zip/Archive/Wim/WimIn.cpp
index 3c712084..fef6b34f 100644
--- a/CPP/7zip/Archive/Wim/WimIn.cpp
+++ b/CPP/7zip/Archive/Wim/WimIn.cpp
@@ -302,12 +302,12 @@ HRESULT CUnpacker::Unpack2(
UInt64 packDataSize;
size_t numChunks;
{
- UInt64 numChunks64 = (unpackSize + (((UInt32)1 << chunkSizeBits) - 1)) >> chunkSizeBits;
- UInt64 sizesBufSize64 = (numChunks64 - 1) << entrySizeShifts;
+ const UInt64 numChunks64 = (unpackSize + (((UInt32)1 << chunkSizeBits) - 1)) >> chunkSizeBits;
+ const UInt64 sizesBufSize64 = (numChunks64 - 1) << entrySizeShifts;
if (sizesBufSize64 > resource.PackSize)
return S_FALSE;
packDataSize = resource.PackSize - sizesBufSize64;
- size_t sizesBufSize = (size_t)sizesBufSize64;
+ const size_t sizesBufSize = (size_t)sizesBufSize64;
if (sizesBufSize != sizesBufSize64)
return E_OUTOFMEMORY;
sizesBuf.AllocAtLeast(sizesBufSize);
@@ -639,10 +639,10 @@ HRESULT CDatabase::ParseDirItem(size_t pos, int parent)
p += dirRecordSize;
{
- if (*(const UInt16 *)(p + fileNameLen) != 0)
+ if (*(const UInt16 *)(const void *)(p + fileNameLen) != 0)
return S_FALSE;
for (UInt32 j = 0; j < fileNameLen; j += 2)
- if (*(const UInt16 *)(p + j) == 0)
+ if (*(const UInt16 *)(const void *)(p + j) == 0)
return S_FALSE;
}
@@ -652,10 +652,10 @@ HRESULT CDatabase::ParseDirItem(size_t pos, int parent)
{
// empty shortName has no ZERO at the end ?
const Byte *p2 = p + fileNameLen2;
- if (*(const UInt16 *)(p2 + shortNameLen) != 0)
+ if (*(const UInt16 *)(const void *)(p2 + shortNameLen) != 0)
return S_FALSE;
for (UInt32 j = 0; j < shortNameLen; j += 2)
- if (*(const UInt16 *)(p2 + j) == 0)
+ if (*(const UInt16 *)(const void *)(p2 + j) == 0)
return S_FALSE;
}
@@ -703,10 +703,10 @@ HRESULT CDatabase::ParseDirItem(size_t pos, int parent)
{
const Byte *p3 = p2 + extraOffset + 2;
- if (*(const UInt16 *)(p3 + fileNameLen111) != 0)
+ if (*(const UInt16 *)(const void *)(p3 + fileNameLen111) != 0)
return S_FALSE;
for (UInt32 j = 0; j < fileNameLen111; j += 2)
- if (*(const UInt16 *)(p3 + j) == 0)
+ if (*(const UInt16 *)(const void *)(p3 + j) == 0)
return S_FALSE;
// PRF(printf("\n %S", p3));
@@ -1790,7 +1790,8 @@ void CImageInfo::Parse(const CXmlItem &item)
{
CTimeDefined = ParseTime(item, CTime, "CREATIONTIME");
MTimeDefined = ParseTime(item, MTime, "LASTMODIFICATIONTIME");
- NameDefined = ConvertUTF8ToUnicode(item.GetSubStringForTag("NAME"), Name);
+ NameDefined = true;
+ ConvertUTF8ToUnicode(item.GetSubStringForTag("NAME"), Name);
ParseNumber64(item.GetSubStringForTag("DIRCOUNT"), DirCount);
ParseNumber64(item.GetSubStringForTag("FILECOUNT"), FileCount);
diff --git a/CPP/7zip/Archive/XarHandler.cpp b/CPP/7zip/Archive/XarHandler.cpp
index f20b1eb9..35dd607a 100644
--- a/CPP/7zip/Archive/XarHandler.cpp
+++ b/CPP/7zip/Archive/XarHandler.cpp
@@ -82,11 +82,13 @@ struct CFile
int Parent;
- CFile(): IsDir(false), HasData(false), ModeDefined(false), Sha1IsDefined(false),
- /* packSha1IsDefined(false), */
- Parent(-1),
+ CFile():
Size(0), PackSize(0), Offset(0),
- CTime(0), MTime(0), ATime(0), Mode(0) {}
+ CTime(0), MTime(0), ATime(0), Mode(0),
+ IsDir(false), HasData(false), ModeDefined(false), Sha1IsDefined(false),
+ /* packSha1IsDefined(false), */
+ Parent(-1)
+ {}
bool IsCopyMethod() const
{
@@ -435,8 +437,8 @@ static void Utf8StringToProp(const AString &s, NCOM::CPropVariant &prop)
if (!s.IsEmpty())
{
UString us;
- if (ConvertUTF8ToUnicode(s, us))
- prop = us;
+ ConvertUTF8ToUnicode(s, us);
+ prop = us;
}
}
diff --git a/CPP/7zip/Archive/XzHandler.cpp b/CPP/7zip/Archive/XzHandler.cpp
index 801619fb..2803f6a8 100644
--- a/CPP/7zip/Archive/XzHandler.cpp
+++ b/CPP/7zip/Archive/XzHandler.cpp
@@ -61,20 +61,29 @@ class CHandler:
public CCommonMethodProps
#endif
{
- CXzStatInfo _stat;
- SRes MainDecodeSRes;
+ CXzStatInfo _stat; // it's stat from backward parsing
+ CXzStatInfo _stat2; // it's data from forward parsing, if the decoder was called
+ SRes _stat2_decode_SRes;
+ bool _stat_defined;
+ bool _stat2_defined;
+
+ const CXzStatInfo *GetStat() const
+ {
+ if (_stat_defined) return &_stat;
+ if (_stat2_defined) return &_stat2;
+ return NULL;
+ }
bool _isArc;
bool _needSeekToStart;
- bool _phySize_Defined;
bool _firstBlockWasRead;
AString _methodsString;
+
#ifndef EXTRACT_ONLY
UInt32 _filterId;
-
UInt64 _numSolidBytes;
void InitXz()
@@ -85,6 +94,7 @@ class CHandler:
#endif
+
void Init()
{
#ifndef EXTRACT_ONLY
@@ -109,18 +119,24 @@ class CHandler:
#endif
decoder._memUsage = _memUsage;
- MainDecodeSRes = SZ_OK;
-
- RINOK(decoder.Decode(seqInStream, outStream,
+ HRESULT hres = decoder.Decode(seqInStream, outStream,
NULL, // *outSizeLimit
true, // finishStream
- progress));
+ progress);
- _stat = decoder.Stat;
- MainDecodeSRes = decoder.MainDecodeSRes;
+ if (decoder.MainDecodeSRes_wasUsed
+ && decoder.MainDecodeSRes != SZ_ERROR_MEM
+ && decoder.MainDecodeSRes != SZ_ERROR_UNSUPPORTED)
+ {
+ // if (!_stat2_defined)
+ {
+ _stat2_decode_SRes = decoder.MainDecodeSRes;
+ _stat2 = decoder.Stat;
+ _stat2_defined = true;
+ }
+ }
- _phySize_Defined = true;
- return S_OK;
+ return hres;
}
public:
@@ -143,8 +159,8 @@ public:
INTERFACE_IOutArchive(;)
#endif
- size_t _blocksArraySize;
CBlockInfo *_blocks;
+ size_t _blocksArraySize;
UInt64 _maxBlocksSize;
CMyComPtr<IInStream> _stream;
CMyComPtr<ISequentialInStream> _seqStream;
@@ -156,7 +172,7 @@ public:
HRESULT SeekToPackPos(UInt64 pos)
{
- return _stream->Seek(pos, STREAM_SEEK_SET, NULL);
+ return _stream->Seek((Int64)pos, STREAM_SEEK_SET, NULL);
}
};
@@ -325,13 +341,16 @@ STDMETHODIMP CHandler::GetArchiveProperty(PROPID propID, PROPVARIANT *value)
{
COM_TRY_BEGIN
NCOM::CPropVariant prop;
+
+ const CXzStatInfo *stat = GetStat();
+
switch (propID)
{
- case kpidPhySize: if (_phySize_Defined) prop = _stat.InSize; break;
- case kpidNumStreams: if (_stat.NumStreams_Defined) prop = _stat.NumStreams; break;
- case kpidNumBlocks: if (_stat.NumBlocks_Defined) prop = _stat.NumBlocks; break;
- case kpidUnpackSize: if (_stat.UnpackSize_Defined) prop = _stat.OutSize; break;
- case kpidClusterSize: if (_stat.NumBlocks_Defined && _stat.NumBlocks > 1) prop = _maxBlocksSize; break;
+ case kpidPhySize: if (stat) prop = stat->InSize; break;
+ case kpidNumStreams: if (stat && stat->NumStreams_Defined) prop = stat->NumStreams; break;
+ case kpidNumBlocks: if (stat && stat->NumBlocks_Defined) prop = stat->NumBlocks; break;
+ case kpidUnpackSize: if (stat && stat->UnpackSize_Defined) prop = stat->OutSize; break;
+ case kpidClusterSize: if (_stat_defined && _stat.NumBlocks_Defined && stat->NumBlocks > 1) prop = _maxBlocksSize; break;
case kpidCharacts:
if (_firstBlockWasRead)
{
@@ -350,14 +369,14 @@ STDMETHODIMP CHandler::GetArchiveProperty(PROPID propID, PROPVARIANT *value)
case kpidErrorFlags:
{
UInt32 v = 0;
- SRes sres = MainDecodeSRes; // _stat.DecodeRes2; //
- if (!_isArc) v |= kpv_ErrorFlags_IsNotArc;
- if (/*_stat.UnexpectedEnd */ sres == SZ_ERROR_INPUT_EOF) v |= kpv_ErrorFlags_UnexpectedEnd;
- if (_stat.DataAfterEnd) v |= kpv_ErrorFlags_DataAfterEnd;
- if (/* _stat.HeadersError */ sres == SZ_ERROR_ARCHIVE) v |= kpv_ErrorFlags_HeadersError;
- if (/* _stat.Unsupported */ sres == SZ_ERROR_UNSUPPORTED) v |= kpv_ErrorFlags_UnsupportedMethod;
- if (/* _stat.DataError */ sres == SZ_ERROR_DATA) v |= kpv_ErrorFlags_DataError;
- if (/* _stat.CrcError */ sres == SZ_ERROR_CRC) v |= kpv_ErrorFlags_CrcError;
+ SRes sres = _stat2_decode_SRes;
+ if (!_isArc) v |= kpv_ErrorFlags_IsNotArc;
+ if (sres == SZ_ERROR_INPUT_EOF) v |= kpv_ErrorFlags_UnexpectedEnd;
+ if (_stat2_defined && _stat2.DataAfterEnd) v |= kpv_ErrorFlags_DataAfterEnd;
+ if (sres == SZ_ERROR_ARCHIVE) v |= kpv_ErrorFlags_HeadersError;
+ if (sres == SZ_ERROR_UNSUPPORTED) v |= kpv_ErrorFlags_UnsupportedMethod;
+ if (sres == SZ_ERROR_DATA) v |= kpv_ErrorFlags_DataError;
+ if (sres == SZ_ERROR_CRC) v |= kpv_ErrorFlags_CrcError;
if (v != 0)
prop = v;
break;
@@ -384,11 +403,12 @@ STDMETHODIMP CHandler::GetNumberOfItems(UInt32 *numItems)
STDMETHODIMP CHandler::GetProperty(UInt32, PROPID propID, PROPVARIANT *value)
{
COM_TRY_BEGIN
+ const CXzStatInfo *stat = GetStat();
NCOM::CPropVariant prop;
switch (propID)
{
- case kpidSize: if (_stat.UnpackSize_Defined) prop = _stat.OutSize; break;
- case kpidPackSize: if (_phySize_Defined) prop = _stat.InSize; break;
+ case kpidSize: if (stat && stat->UnpackSize_Defined) prop = stat->OutSize; break;
+ case kpidPackSize: if (stat) prop = stat->InSize; break;
case kpidMethod: if (!_methodsString.IsEmpty()) prop = _methodsString; break;
}
prop.Detach(value);
@@ -402,7 +422,9 @@ struct COpenCallbackWrap
ICompressProgress vt;
IArchiveOpenCallback *OpenCallback;
HRESULT Res;
- COpenCallbackWrap(IArchiveOpenCallback *progress);
+
+ // new clang shows "non-POD" warning for offsetof(), if we use constructor instead of Init()
+ void Init(IArchiveOpenCallback *progress);
};
static SRes OpenCallbackProgress(const ICompressProgress *pp, UInt64 inSize, UInt64 /* outSize */)
@@ -413,7 +435,7 @@ static SRes OpenCallbackProgress(const ICompressProgress *pp, UInt64 inSize, UIn
return HRESULT_To_SRes(p->Res, SZ_ERROR_PROGRESS);
}
-COpenCallbackWrap::COpenCallbackWrap(IArchiveOpenCallback *callback)
+void COpenCallbackWrap::Init(IArchiveOpenCallback *callback)
{
vt.Progress = OpenCallbackProgress;
OpenCallback = callback;
@@ -482,7 +504,11 @@ HRESULT CHandler::Open2(IInStream *inStream, /* UInt32 flags, */ IArchiveOpenCal
CSeqInStreamWrap inStreamWrap;
inStreamWrap.Init(inStream);
+
SRes res = Xz_ReadHeader(&st, &inStreamWrap.vt);
+
+ if (inStreamWrap.Res != S_OK)
+ return inStreamWrap.Res;
if (res != SZ_OK)
return SRes_to_Open_HRESULT(res);
@@ -490,8 +516,27 @@ HRESULT CHandler::Open2(IInStream *inStream, /* UInt32 flags, */ IArchiveOpenCal
CXzBlock block;
BoolInt isIndex;
UInt32 headerSizeRes;
+
SRes res2 = XzBlock_ReadHeader(&block, &inStreamWrap.vt, &isIndex, &headerSizeRes);
- if (res2 == SZ_OK && !isIndex)
+
+ if (inStreamWrap.Res != S_OK)
+ return inStreamWrap.Res;
+
+ if (res2 != SZ_OK)
+ {
+ if (res2 == SZ_ERROR_INPUT_EOF)
+ {
+ _stat2_decode_SRes = res2;
+ _stream = inStream;
+ _seqStream = inStream;
+ _isArc = true;
+ return S_OK;
+ }
+
+ if (res2 == SZ_ERROR_ARCHIVE)
+ return S_FALSE;
+ }
+ else if (!isIndex)
{
_firstBlockWasRead = true;
_firstBlock = block;
@@ -526,7 +571,8 @@ HRESULT CHandler::Open2(IInStream *inStream, /* UInt32 flags, */ IArchiveOpenCal
lookStream.realStream = &inStreamImp.vt;
LookToRead2_Init(&lookStream);
- COpenCallbackWrap openWrap(callback);
+ COpenCallbackWrap openWrap;
+ openWrap.Init(callback);
CXzsCPP xzs;
Int64 startPosition;
@@ -539,7 +585,7 @@ HRESULT CHandler::Open2(IInStream *inStream, /* UInt32 flags, */ IArchiveOpenCal
*/
if (res == SZ_OK && startPosition == 0)
{
- _phySize_Defined = true;
+ _stat_defined = true;
_stat.OutSize = Xzs_GetUnpackSize(&xzs.p);
_stat.UnpackSize_Defined = true;
@@ -615,6 +661,7 @@ HRESULT CHandler::Open2(IInStream *inStream, /* UInt32 flags, */ IArchiveOpenCal
}
RINOK(SRes_to_Open_HRESULT(res));
+
_stream = inStream;
_seqStream = inStream;
_isArc = true;
@@ -645,12 +692,15 @@ STDMETHODIMP CHandler::OpenSeq(ISequentialInStream *stream)
STDMETHODIMP CHandler::Close()
{
XzStatInfo_Clear(&_stat);
+ XzStatInfo_Clear(&_stat2);
+ _stat_defined = false;
+ _stat2_defined = false;
+ _stat2_decode_SRes = SZ_OK;
_isArc = false;
_needSeekToStart = false;
- _phySize_Defined = false;
_firstBlockWasRead = false;
-
+
_methodsString.Empty();
_stream.Release();
_seqStream.Release();
@@ -660,8 +710,6 @@ STDMETHODIMP CHandler::Close()
_blocksArraySize = 0;
_maxBlocksSize = 0;
- MainDecodeSRes = SZ_OK;
-
return S_OK;
}
@@ -729,7 +777,7 @@ CInStream::~CInStream()
}
-size_t FindBlock(const CBlockInfo *blocks, size_t numBlocks, UInt64 pos)
+static size_t FindBlock(const CBlockInfo *blocks, size_t numBlocks, UInt64 pos)
{
size_t left = 0, right = numBlocks;
for (;;)
@@ -900,9 +948,9 @@ STDMETHODIMP CInStream::Seek(Int64 offset, UInt32 seekOrigin, UInt64 *newPositio
}
if (offset < 0)
return HRESULT_WIN32_ERROR_NEGATIVE_SEEK;
- _virtPos = offset;
+ _virtPos = (UInt64)offset;
if (newPosition)
- *newPosition = offset;
+ *newPosition = (UInt64)offset;
return S_OK;
}
@@ -951,7 +999,7 @@ STDMETHODIMP CHandler::GetStream(UInt32 index, ISequentialInStream **stream)
static Int32 Get_Extract_OperationResult(const NCompress::NXz::CDecoder &decoder)
{
Int32 opRes;
- SRes sres = decoder.MainDecodeSRes; // decoder.Stat.DecodeRes2;
+ SRes sres = decoder.MainDecodeSRes;
if (sres == SZ_ERROR_NO_ARCHIVE) // (!IsArc)
opRes = NExtract::NOperationResult::kIsNotArc;
else if (sres == SZ_ERROR_INPUT_EOF) // (UnexpectedEnd)
@@ -985,8 +1033,10 @@ STDMETHODIMP CHandler::Extract(const UInt32 *indices, UInt32 numItems,
if (numItems != (UInt32)(Int32)-1 && (numItems != 1 || indices[0] != 0))
return E_INVALIDARG;
- if (_phySize_Defined)
- extractCallback->SetTotal(_stat.InSize);
+ const CXzStatInfo *stat = GetStat();
+
+ if (stat)
+ extractCallback->SetTotal(stat->InSize);
UInt64 currentTotalPacked = 0;
RINOK(extractCallback->SetCompleted(&currentTotalPacked));
@@ -1106,7 +1156,7 @@ STDMETHODIMP CHandler::UpdateItems(ISequentialOutStream *outStream, UInt32 numIt
*/
#ifndef _7ZIP_ST
- xzProps.numTotalThreads = _numThreads;
+ xzProps.numTotalThreads = (int)_numThreads;
#endif
xzProps.blockSize = _numSolidBytes;
@@ -1161,7 +1211,9 @@ STDMETHODIMP CHandler::UpdateItems(ISequentialOutStream *outStream, UInt32 numIt
CMyComPtr<ICompressProgressInfo> progress = lps;
lps->Init(updateCallback, true);
- return encoderSpec->Code(fileInStream, outStream, NULL, NULL, progress);
+ RINOK(encoderSpec->Code(fileInStream, outStream, NULL, NULL, progress));
+
+ return updateCallback->SetOperationResult(NArchive::NUpdate::NOperationResult::kOK);
}
if (indexInArchive != 0)
@@ -1176,8 +1228,9 @@ STDMETHODIMP CHandler::UpdateItems(ISequentialOutStream *outStream, UInt32 numIt
if (_stream)
{
- if (_phySize_Defined)
- RINOK(updateCallback->SetTotal(_stat.InSize));
+ const CXzStatInfo *stat = GetStat();
+ if (stat)
+ RINOK(updateCallback->SetTotal(stat->InSize));
RINOK(_stream->Seek(0, STREAM_SEEK_SET, NULL));
}
diff --git a/CPP/7zip/Archive/Zip/ZipAddCommon.cpp b/CPP/7zip/Archive/Zip/ZipAddCommon.cpp
index 1ee7e22f..2bb57d5c 100644
--- a/CPP/7zip/Archive/Zip/ZipAddCommon.cpp
+++ b/CPP/7zip/Archive/Zip/ZipAddCommon.cpp
@@ -88,14 +88,18 @@ STDMETHODIMP CLzmaEncoder::Code(ISequentialInStream *inStream, ISequentialOutStr
}
-CAddCommon::CAddCommon(const CCompressionMethodMode &options):
- _options(options),
+CAddCommon::CAddCommon():
_copyCoderSpec(NULL),
+ _isLzmaEos(false),
_cryptoStreamSpec(NULL),
- _buf(NULL),
- _isLzmaEos(false)
+ _buf(NULL)
{}
+void CAddCommon::SetOptions(const CCompressionMethodMode &options)
+{
+ _options = options;
+}
+
CAddCommon::~CAddCommon()
{
MidFree(_buf);
@@ -230,6 +234,11 @@ HRESULT CAddCommon::Compress(
unsigned numTestMethods = _options.MethodSequence.Size();
bool descriptorMode = outSeqMode;
+
+ // ZipCrypto without descriptor requires additional reading pass for
+ // inStream to calculate CRC for password check field.
+ // The descriptor allows to use ZipCrypto check field without CRC (InfoZip's modification).
+
if (!outSeqMode)
if (inSeqMode && _options.PasswordIsDefined && !_options.IsAesMode)
descriptorMode = true;
@@ -262,6 +271,15 @@ HRESULT CAddCommon::Compress(
RINOK(outStream->SetSize(0));
RINOK(outStream->Seek(0, STREAM_SEEK_SET, NULL));
}
+
+ method = _options.MethodSequence[i];
+ if (method == NCompressionMethod::kStore && descriptorMode)
+ {
+ // we still can create descriptor_mode archives with "Store" method, but they are not good for 100%
+ return E_NOTIMPL;
+ }
+
+ bool needCode = true;
if (_options.PasswordIsDefined)
{
@@ -314,23 +332,25 @@ HRESULT CAddCommon::Compress(
RINOK(_filterSpec->WriteHeader_Check16(outStream, (UInt16)check));
}
- RINOK(_cryptoStreamSpec->SetOutStream(outStream));
- RINOK(_cryptoStreamSpec->InitEncoder());
- outStreamReleaser.FilterCoder = _cryptoStreamSpec;
+ if (method == NCompressionMethod::kStore)
+ {
+ needCode = false;
+ RINOK(_cryptoStreamSpec->Code(inCrcStream, outStream, NULL, NULL, progress));
+ }
+ else
+ {
+ RINOK(_cryptoStreamSpec->SetOutStream(outStream));
+ RINOK(_cryptoStreamSpec->InitEncoder());
+ outStreamReleaser.FilterCoder = _cryptoStreamSpec;
+ }
}
- method = _options.MethodSequence[i];
-
- switch (method)
+ if (needCode)
{
+ switch (method)
+ {
case NCompressionMethod::kStore:
{
- if (descriptorMode)
- {
- // we still can create descriptor_mode archives with "Store" method, but they are not good for 100%
- return E_NOTIMPL;
- }
-
if (!_copyCoderSpec)
{
_copyCoderSpec = new NCompress::CCopyCoder;
@@ -438,15 +458,21 @@ HRESULT CAddCommon::Compress(
}
}
+ try {
RINOK(_compressEncoder->Code(inCrcStream, outStreamNew, NULL, NULL, progress));
+ } catch (...) { return E_FAIL; }
break;
}
+ } // switch end
+
+ if (_options.PasswordIsDefined)
+ {
+ RINOK(_cryptoStreamSpec->OutStreamFinish());
+ }
}
if (_options.PasswordIsDefined)
{
- RINOK(_cryptoStreamSpec->OutStreamFinish());
-
if (_options.IsAesMode)
{
RINOK(_filterAesSpec->WriteFooter(outStream));
diff --git a/CPP/7zip/Archive/Zip/ZipAddCommon.h b/CPP/7zip/Archive/Zip/ZipAddCommon.h
index ff3251db..0aa44adf 100644
--- a/CPP/7zip/Archive/Zip/ZipAddCommon.h
+++ b/CPP/7zip/Archive/Zip/ZipAddCommon.h
@@ -28,9 +28,15 @@ struct CCompressingResult
Byte ExtractVersion;
bool DescriptorMode;
bool LzmaEos;
+
+ CCompressingResult()
+ {
+ // for GCC:
+ UnpackSize = 0;
+ }
};
-class CAddCommon
+class CAddCommon MY_UNCOPYABLE
{
CCompressionMethodMode _options;
NCompress::CCopyCoder *_copyCoderSpec;
@@ -50,7 +56,9 @@ class CAddCommon
HRESULT CalcStreamCRC(ISequentialInStream *inStream, UInt32 &resultCRC);
public:
- CAddCommon(const CCompressionMethodMode &options);
+ // CAddCommon(const CCompressionMethodMode &options);
+ CAddCommon();
+ void SetOptions(const CCompressionMethodMode &options);
~CAddCommon();
HRESULT Set_Pre_CompressionResult(bool inSeqMode, bool outSeqMode, UInt64 unpackSize,
diff --git a/CPP/7zip/Archive/Zip/ZipCompressionMode.h b/CPP/7zip/Archive/Zip/ZipCompressionMode.h
index 1125f6ed..842991c4 100644
--- a/CPP/7zip/Archive/Zip/ZipCompressionMode.h
+++ b/CPP/7zip/Archive/Zip/ZipCompressionMode.h
@@ -35,7 +35,7 @@ struct CCompressionMethodMode: public CBaseProps
{
CRecordVector<Byte> MethodSequence;
bool PasswordIsDefined;
- AString Password;
+ AString Password; // _Wipe
UInt64 _dataSizeReduce;
bool _dataSizeReduceDefined;
@@ -47,6 +47,8 @@ struct CCompressionMethodMode: public CBaseProps
_dataSizeReduceDefined = false;
_dataSizeReduce = 0;
}
+
+ ~CCompressionMethodMode() { Password.Wipe_and_Empty(); }
};
}}
diff --git a/CPP/7zip/Archive/Zip/ZipHandler.cpp b/CPP/7zip/Archive/Zip/ZipHandler.cpp
index a4794f51..72a77cb7 100644
--- a/CPP/7zip/Archive/Zip/ZipHandler.cpp
+++ b/CPP/7zip/Archive/Zip/ZipHandler.cpp
@@ -18,6 +18,17 @@
#include "../../Common/StreamUtils.h"
#include "../../Compress/CopyCoder.h"
+
+#ifdef EXTERNAL_CODECS
+#ifndef SUPPORT_LZFSE
+#define SUPPORT_LZFSE
+#endif
+#endif
+
+#ifdef SUPPORT_LZFSE
+#include "../../Compress/LzfseDecoder.h"
+#endif
+
#include "../../Compress/LzmaDecoder.h"
#include "../../Compress/ImplodeDecoder.h"
#include "../../Compress/PpmdZip.h"
@@ -81,16 +92,24 @@ const char * const kMethodNames1[kNumMethodNames1] =
, "BZip2"
, NULL
, "LZMA"
+ , NULL
+ , NULL
+ , NULL
+ , NULL
+ , NULL
+ , "zstd-pk"
};
const char * const kMethodNames2[kNumMethodNames2] =
{
- "xz"
+ "zstd-wz"
+ , "MP3"
+ , "xz"
, "Jpeg"
, "WavPack"
, "PPMd"
- , "WzAES"
+ , "LZFSE" // , "WzAES"
};
#define kMethod_AES "AES"
@@ -240,6 +259,12 @@ STDMETHODIMP CHandler::GetArchiveProperty(PROPID propID, PROPVARIANT *value)
if (m_Archive.IsZip64)
s.Add_OptSpaced("Zip64");
+ if (m_Archive.IsCdUnsorted)
+ s.Add_OptSpaced("Unsorted_CD");
+
+ if (m_Archive.IsApk)
+ s.Add_OptSpaced("apk");
+
if (m_Archive.ExtraMinorError)
s.Add_OptSpaced("Minor_Extra_ERROR");
@@ -312,9 +337,8 @@ STDMETHODIMP CHandler::GetArchiveProperty(PROPID propID, PROPVARIANT *value)
// case kpidIsAltStream: prop = true; break;
}
- prop.Detach(value);
+ return prop.Detach(value);
COM_TRY_END
- return S_OK;
}
STDMETHODIMP CHandler::GetNumberOfItems(UInt32 *numItems)
@@ -336,7 +360,9 @@ STDMETHODIMP CHandler::GetProperty(UInt32 index, PROPID propID, PROPVARIANT *val
{
UString res;
item.GetUnicodeString(res, item.Name, false, _forceCodePage, _specifiedCodePage);
- NItemName::ReplaceToOsSlashes_Remove_TailSlash(res);
+ NItemName::ReplaceToOsSlashes_Remove_TailSlash(res,
+ item.Is_MadeBy_Unix() // useBackslashReplacement
+ );
/*
if (item.ParentOfAltStream >= 0)
{
@@ -359,7 +385,7 @@ STDMETHODIMP CHandler::GetProperty(UInt32 index, PROPID propID, PROPVARIANT *val
case kpidIsDir: prop = item.IsDir(); break;
case kpidSize:
{
- if (item.FromCentral || !item.FromLocal || !item.HasDescriptor() || item.DescriptorWasRead)
+ if (!item.IsBadDescriptor())
prop = item.Size;
break;
}
@@ -467,23 +493,27 @@ STDMETHODIMP CHandler::GetProperty(UInt32 index, PROPID propID, PROPVARIANT *val
case kpidMethod:
{
- unsigned id = item.Method;
AString m;
-
- if (item.IsEncrypted())
+ bool isWzAes = false;
+ unsigned id = item.Method;
+
+ if (id == NFileHeader::NCompressionMethod::kWzAES)
{
- if (id == NFileHeader::NCompressionMethod::kWzAES)
+ CWzAesExtra aesField;
+ if (extra.GetWzAes(aesField))
{
m += kMethod_AES;
- CWzAesExtra aesField;
- if (extra.GetWzAes(aesField))
- {
- m += '-';
- m.Add_UInt32(((unsigned)aesField.Strength + 1) * 64);
- id = aesField.Method;
- }
+ m += '-';
+ m.Add_UInt32(((unsigned)aesField.Strength + 1) * 64);
+ id = aesField.Method;
+ isWzAes = true;
}
- else if (item.IsStrongEncrypted())
+ }
+
+ if (item.IsEncrypted())
+ if (!isWzAes)
+ {
+ if (item.IsStrongEncrypted())
{
CStrongCryptoExtra f;
f.AlgId = 0;
@@ -506,8 +536,9 @@ STDMETHODIMP CHandler::GetProperty(UInt32 index, PROPID propID, PROPVARIANT *val
}
else
m += kMethod_ZipCrypto;
- m += ' ';
}
+
+ m.Add_Space_if_NotEmpty();
{
const char *s = NULL;
@@ -516,7 +547,7 @@ STDMETHODIMP CHandler::GetProperty(UInt32 index, PROPID propID, PROPVARIANT *val
else
{
int id2 = (int)id - (int)kMethodNames2Start;
- if (id2 >= 0 && id2 < kNumMethodNames2)
+ if (id2 >= 0 && (unsigned)id2 < kNumMethodNames2)
s = kMethodNames2[id2];
}
if (s)
@@ -532,7 +563,7 @@ STDMETHODIMP CHandler::GetProperty(UInt32 index, PROPID propID, PROPVARIANT *val
{
if (level & 1)
m += ":eos";
- level &= ~1;
+ level &= ~(unsigned)1;
}
else if (id == NFileHeader::NCompressionMethod::kDeflate)
{
@@ -576,7 +607,7 @@ STDMETHODIMP CHandler::GetProperty(UInt32 index, PROPID propID, PROPVARIANT *val
}
UInt32 flags = item.Flags;
- flags &= ~(6); // we don't need compression related bits here.
+ flags &= ~(unsigned)6; // we don't need compression related bits here.
if (flags != 0)
{
@@ -589,7 +620,7 @@ STDMETHODIMP CHandler::GetProperty(UInt32 index, PROPID propID, PROPVARIANT *val
}
}
- if (!item.FromCentral && item.FromLocal && item.HasDescriptor() && !item.DescriptorWasRead)
+ if (item.IsBadDescriptor())
s.Add_OptSpaced("Descriptor_ERROR");
if (!s.IsEmpty())
@@ -634,8 +665,7 @@ STDMETHODIMP CHandler::GetProperty(UInt32 index, PROPID propID, PROPVARIANT *val
*/
}
- prop.Detach(value);
- return S_OK;
+ return prop.Detach(value);
COM_TRY_END
}
@@ -860,11 +890,14 @@ public:
};
-static HRESULT SkipStreamData(ISequentialInStream *stream, bool &thereAreData)
+static HRESULT SkipStreamData(ISequentialInStream *stream,
+ ICompressProgressInfo *progress, UInt64 packSize, UInt64 unpackSize,
+ bool &thereAreData)
{
thereAreData = false;
const size_t kBufSize = 1 << 12;
Byte buf[kBufSize];
+ UInt64 prev = packSize;
for (;;)
{
size_t size = kBufSize;
@@ -872,10 +905,80 @@ static HRESULT SkipStreamData(ISequentialInStream *stream, bool &thereAreData)
if (size == 0)
return S_OK;
thereAreData = true;
+ packSize += size;
+ if ((packSize - prev) >= (1 << 22))
+ {
+ prev = packSize;
+ RINOK(progress->SetRatioInfo(&packSize, &unpackSize));
+ }
}
}
+
+class COutStreamWithPadPKCS7:
+ public ISequentialOutStream,
+ public CMyUnknownImp
+{
+ CMyComPtr<ISequentialOutStream> _stream;
+ UInt64 _size;
+ UInt64 _padPos;
+ UInt32 _padSize;
+ bool _padFailure;
+public:
+ MY_UNKNOWN_IMP
+ STDMETHOD(Write)(const void *data, UInt32 size, UInt32 *processedSize);
+ void SetStream(ISequentialOutStream *stream) { _stream = stream; }
+ void ReleaseStream() { _stream.Release(); }
+
+ // padSize == 0 means (no_pad Mode)
+ void Init(UInt64 padPos, UInt32 padSize)
+ {
+ _padPos = padPos;
+ _padSize = padSize;
+ _size = 0;
+ _padFailure = false;
+ }
+ UInt64 GetSize() const { return _size; }
+ bool WasPadFailure() const { return _padFailure; }
+};
+
+
+STDMETHODIMP COutStreamWithPadPKCS7::Write(const void *data, UInt32 size, UInt32 *processedSize)
+{
+ UInt32 written = 0;
+ HRESULT result = S_OK;
+ if (_size < _padPos)
+ {
+ const UInt64 rem = _padPos - _size;
+ UInt32 num = size;
+ if (num > rem)
+ num = (UInt32)rem;
+ result = _stream->Write(data, num, &written);
+ _size += written;
+ if (processedSize)
+ *processedSize = written;
+ if (_size != _padPos || result != S_OK)
+ return result;
+ size -= written;
+ data = ((const Byte *)data) + written;
+ }
+ _size += size;
+ written += size;
+ if (processedSize)
+ *processedSize = written;
+ if (_padSize != 0)
+ for (; size != 0; size--)
+ {
+ if (*(const Byte *)data != _padSize)
+ _padFailure = true;
+ data = ((const Byte *)data) + 1;
+ }
+ return result;
+}
+
+
+
HRESULT CZipDecoder::Decode(
DECL_EXTERNAL_CODECS_LOC_VARS
CInArchive &archive, const CItemEx &item,
@@ -895,9 +998,32 @@ HRESULT CZipDecoder::Decode(
bool needCRC = true;
bool wzAesMode = false;
bool pkAesMode = false;
+
+ bool badDescriptor = item.IsBadDescriptor();
+ if (badDescriptor)
+ needCRC = false;
+
unsigned id = item.Method;
+ CWzAesExtra aesField;
+ // LZFSE and WinZip's AES use same id - kWzAES.
+
+ if (id == NFileHeader::NCompressionMethod::kWzAES)
+ {
+ if (item.GetMainExtra().GetWzAes(aesField))
+ {
+ if (!item.IsEncrypted())
+ {
+ res = NExtract::NOperationResult::kUnsupportedMethod;
+ return S_OK;
+ }
+ wzAesMode = true;
+ needCRC = aesField.NeedCrc();
+ }
+ }
+
+ if (!wzAesMode)
if (item.IsEncrypted())
{
if (item.IsStrongEncrypted())
@@ -910,14 +1036,6 @@ HRESULT CZipDecoder::Decode(
}
pkAesMode = true;
}
- else if (id == NFileHeader::NCompressionMethod::kWzAES)
- {
- CWzAesExtra aesField;
- if (!item.GetMainExtra().GetWzAes(aesField))
- return S_OK;
- wzAesMode = true;
- needCRC = aesField.NeedCrc();
- }
}
COutStreamWithCRC *outStreamSpec = new COutStreamWithCRC;
@@ -957,9 +1075,6 @@ HRESULT CZipDecoder::Decode(
{
if (wzAesMode)
{
- CWzAesExtra aesField;
- if (!item.GetMainExtra().GetWzAes(aesField))
- return S_OK;
id = aesField.Method;
if (!_wzAesDecoder)
{
@@ -1002,12 +1117,12 @@ HRESULT CZipDecoder::Decode(
if (getTextPassword)
{
- CMyComBSTR password;
+ CMyComBSTR_Wipe password;
RINOK(getTextPassword->CryptoGetTextPassword(&password));
- AString charPassword;
+ AString_Wipe charPassword;
if (password)
{
- UnicodeStringToMultiByte2(charPassword, (const wchar_t *)password, CP_ACP);
+ UnicodeStringToMultiByte2(charPassword, (LPCOLESTR)password, CP_ACP);
/*
if (wzAesMode || pkAesMode)
{
@@ -1063,6 +1178,10 @@ HRESULT CZipDecoder::Decode(
mi.Coder = new NCompress::NXz::CComDecoder;
else if (id == NFileHeader::NCompressionMethod::kPPMd)
mi.Coder = new NCompress::NPpmdZip::CDecoder(true);
+ #ifdef SUPPORT_LZFSE
+ else if (id == NFileHeader::NCompressionMethod::kWzAES)
+ mi.Coder = new NCompress::NLzfse::CDecoder;
+ #endif
else
{
CMethodId szMethodID;
@@ -1089,7 +1208,8 @@ HRESULT CZipDecoder::Decode(
m = methodItems.Add(mi);
}
- ICompressCoder *coder = methodItems[m].Coder;
+ const CMethodItem &mi = methodItems[m];
+ ICompressCoder *coder = mi.Coder;
#ifndef _7ZIP_ST
@@ -1123,14 +1243,22 @@ HRESULT CZipDecoder::Decode(
}
- CMyComPtr<ISequentialInStream> inStreamNew;
-
bool isFullStreamExpected = (!item.HasDescriptor() || item.PackSize != 0);
bool needReminderCheck = false;
bool dataAfterEnd = false;
bool truncatedError = false;
bool lzmaEosError = false;
+ bool headersError = false;
+ bool padError = false;
+ bool readFromFilter = false;
+
+ const bool useUnpackLimit = (id == NFileHeader::NCompressionMethod::kStore
+ || !item.HasDescriptor()
+ || item.Size >= ((UInt64)1 << 32)
+ || item.LocalExtra.IsZip64
+ || item.CentralExtra.IsZip64
+ );
{
HRESULT result = S_OK;
@@ -1198,23 +1326,7 @@ HRESULT CZipDecoder::Decode(
}
}
}
-
- if (result == S_OK)
- {
- inStreamReleaser.FilterCoder = filterStreamSpec;
- RINOK(filterStreamSpec->SetInStream(inStream));
-
- /* IFilter::Init() does nothing in all zip crypto filters.
- So we can call any Initialize function in CFilterCoder. */
-
- RINOK(filterStreamSpec->Init_NoSubFilterInit());
- // RINOK(filterStreamSpec->SetOutStreamSize(NULL));
-
- inStreamNew = filterStream;
- }
}
- else
- inStreamNew = inStream;
if (result == S_OK)
{
@@ -1222,26 +1334,84 @@ HRESULT CZipDecoder::Decode(
coder->QueryInterface(IID_ICompressSetFinishMode, (void **)&setFinishMode);
if (setFinishMode)
{
- RINOK(setFinishMode->SetFinishMode(BoolToInt(true)));
+ RINOK(setFinishMode->SetFinishMode(BoolToUInt(true)));
}
const UInt64 coderPackSize = limitedStreamSpec->GetRem();
- bool useUnpackLimit = (id == 0
- || !item.HasDescriptor()
- || item.Size >= ((UInt64)1 << 32)
- || item.LocalExtra.IsZip64
- || item.CentralExtra.IsZip64
- );
+ if (id == NFileHeader::NCompressionMethod::kStore && item.IsEncrypted())
+ {
+ readFromFilter = false;
+
+ COutStreamWithPadPKCS7 *padStreamSpec = NULL;
+ CMyComPtr<ISequentialOutStream> padStream;
+ UInt32 padSize = 0;
+
+ if (pkAesMode)
+ {
+ padStreamSpec = new COutStreamWithPadPKCS7;
+ padStream = padStreamSpec;
+ padSize = _pkAesDecoderSpec->GetPadSize((UInt32)item.Size);
+ padStreamSpec->SetStream(outStream);
+ padStreamSpec->Init(item.Size, padSize);
+ }
+
+ // Here we decode minimal required size, including padding
+ const UInt64 expectedSize = item.Size + padSize;
+ UInt64 size = coderPackSize;
+ if (item.Size > coderPackSize)
+ headersError = true;
+ else if (expectedSize != coderPackSize)
+ {
+ headersError = true;
+ if (coderPackSize > expectedSize)
+ size = expectedSize;
+ }
- result = coder->Code(inStreamNew, outStream,
- isFullStreamExpected ? &coderPackSize : NULL,
- // NULL,
- useUnpackLimit ? &item.Size : NULL,
- compressProgress);
+ result = filterStreamSpec->Code(inStream, padStream ?
+ (ISequentialOutStream *)padStream :
+ (ISequentialOutStream *)outStream,
+ NULL, &size, compressProgress);
- if (result == S_OK)
+ if (outStreamSpec->GetSize() != item.Size)
+ truncatedError = true;
+
+ if (pkAesMode)
+ {
+ if (padStreamSpec->GetSize() != size)
+ truncatedError = true;
+ if (padStreamSpec->WasPadFailure())
+ padError = true;
+ }
+ }
+ else
{
+ if (item.IsEncrypted())
+ {
+ readFromFilter = true;
+ inStreamReleaser.FilterCoder = filterStreamSpec;
+ RINOK(filterStreamSpec->SetInStream(inStream));
+
+ /* IFilter::Init() does nothing in all zip crypto filters.
+ So we can call any Initialize function in CFilterCoder. */
+
+ RINOK(filterStreamSpec->Init_NoSubFilterInit());
+ // RINOK(filterStreamSpec->SetOutStreamSize(NULL));
+ }
+
+ try {
+ result = coder->Code(readFromFilter ?
+ (ISequentialInStream *)filterStream :
+ (ISequentialInStream *)inStream,
+ outStream,
+ isFullStreamExpected ? &coderPackSize : NULL,
+ // NULL,
+ useUnpackLimit ? &item.Size : NULL,
+ compressProgress);
+ } catch (...) { return E_FAIL; }
+
+ if (result == S_OK)
+ {
CMyComPtr<ICompressGetInStreamProcessedSize> getInStreamProcessedSize;
coder->QueryInterface(IID_ICompressGetInStreamProcessedSize, (void **)&getInStreamProcessedSize);
if (getInStreamProcessedSize && setFinishMode)
@@ -1259,7 +1429,32 @@ HRESULT CZipDecoder::Decode(
{
if (processed + padSize < coderPackSize)
dataAfterEnd = true;
- // also here we can check PKCS7 padding data from reminder (it can be inside stream buffer in coder).
+ else
+ {
+ // here we can PKCS7 padding data from reminder (it can be inside stream buffer in coder).
+ CMyComPtr<ICompressReadUnusedFromInBuf> readInStream;
+ coder->QueryInterface(IID_ICompressReadUnusedFromInBuf, (void **)&readInStream);
+ if (readInStream)
+ {
+ // change pad size, it we support another block size in ZipStron
+ // here we request more to detect error with data after end.
+ const UInt32 kBufSize = NCrypto::NZipStrong::kAesPadAllign + 16;
+ Byte buf[kBufSize];
+ UInt32 processedSize;
+ RINOK(readInStream->ReadUnusedFromInBuf(buf, kBufSize, &processedSize));
+ if (processedSize > padSize)
+ dataAfterEnd = true;
+ else
+ {
+ if (ReadStream_FALSE(filterStream, buf + processedSize, padSize - processedSize) != S_OK)
+ padError = true;
+ else
+ for (unsigned i = 0; i < padSize; i++)
+ if (buf[i] != padSize)
+ padError = true;
+ }
+ }
+ }
}
}
else
@@ -1270,11 +1465,15 @@ HRESULT CZipDecoder::Decode(
dataAfterEnd = true;
}
else if (processed > coderPackSize)
+ {
+ // that case is additional check, that can show the bugs in code (coder)
truncatedError = true;
+ }
needReminderCheck = isFullStreamExpected;
}
}
}
+ }
}
if (result == S_OK && id == NFileHeader::NCompressionMethod::kLZMA)
@@ -1298,19 +1497,33 @@ HRESULT CZipDecoder::Decode(
bool authOk = true;
if (needCRC)
crcOK = (outStreamSpec->GetCRC() == item.Crc);
+
+ if (useUnpackLimit)
+ if (outStreamSpec->GetSize() != item.Size)
+ truncatedError = true;
if (wzAesMode)
{
+ const UInt64 unpackSize = outStreamSpec->GetSize();
+ const UInt64 packSize = limitedStreamSpec->GetSize();
bool thereAreData = false;
- if (SkipStreamData(inStreamNew, thereAreData) != S_OK)
+ // read to the end from filter or from packed stream
+ if (SkipStreamData(readFromFilter ?
+ (ISequentialInStream *)filterStream :
+ (ISequentialInStream *)inStream,
+ compressProgress, packSize, unpackSize, thereAreData) != S_OK)
authOk = false;
-
if (needReminderCheck && thereAreData)
dataAfterEnd = true;
-
- limitedStreamSpec->Init(NCrypto::NWzAes::kMacSize);
- if (_wzAesDecoderSpec->CheckMac(inStream, authOk) != S_OK)
- authOk = false;
+
+ if (limitedStreamSpec->GetRem() != 0)
+ truncatedError = true;
+ else
+ {
+ limitedStreamSpec->Init(NCrypto::NWzAes::kMacSize);
+ if (_wzAesDecoderSpec->CheckMac(inStream, authOk) != S_OK)
+ authOk = false;
+ }
}
res = NExtract::NOperationResult::kCRCError;
@@ -1321,10 +1534,16 @@ HRESULT CZipDecoder::Decode(
if (dataAfterEnd)
res = NExtract::NOperationResult::kDataAfterEnd;
+ else if (padError)
+ res = NExtract::NOperationResult::kCRCError;
else if (truncatedError)
res = NExtract::NOperationResult::kUnexpectedEnd;
+ else if (headersError)
+ res = NExtract::NOperationResult::kHeadersError;
else if (lzmaEosError)
res = NExtract::NOperationResult::kHeadersError;
+ else if (badDescriptor)
+ res = NExtract::NOperationResult::kUnexpectedEnd;
// CheckDescriptor() supports only data descriptor with signature and
// it doesn't support "old" pkzip's data descriptor without signature.
diff --git a/CPP/7zip/Archive/Zip/ZipHandler.h b/CPP/7zip/Archive/Zip/ZipHandler.h
index bee57c00..3043e41c 100644
--- a/CPP/7zip/Archive/Zip/ZipHandler.h
+++ b/CPP/7zip/Archive/Zip/ZipHandler.h
@@ -15,8 +15,8 @@
namespace NArchive {
namespace NZip {
-const unsigned kNumMethodNames1 = NFileHeader::NCompressionMethod::kLZMA + 1;
-const unsigned kMethodNames2Start = NFileHeader::NCompressionMethod::kXz;
+const unsigned kNumMethodNames1 = NFileHeader::NCompressionMethod::kZstdPk + 1;
+const unsigned kMethodNames2Start = NFileHeader::NCompressionMethod::kZstdWz;
const unsigned kNumMethodNames2 = NFileHeader::NCompressionMethod::kWzAES + 1 - kMethodNames2Start;
extern const char * const kMethodNames1[kNumMethodNames1];
diff --git a/CPP/7zip/Archive/Zip/ZipHandlerOut.cpp b/CPP/7zip/Archive/Zip/ZipHandlerOut.cpp
index c21b5605..a9b3eae5 100644
--- a/CPP/7zip/Archive/Zip/ZipHandlerOut.cpp
+++ b/CPP/7zip/Archive/Zip/ZipHandlerOut.cpp
@@ -53,7 +53,7 @@ static int FindZipMethod(const char *s, const char * const *names, unsigned num)
{
const char *name = names[i];
if (name && StringsAreEqualNoCase_Ascii(s, name))
- return i;
+ return (int)i;
}
return -1;
}
@@ -65,7 +65,7 @@ static int FindZipMethod(const char *s)
return k;
k = FindZipMethod(s, kMethodNames2, kNumMethodNames2);
if (k >= 0)
- return kMethodNames2Start + k;
+ return (int)kMethodNames2Start + k;
return -1;
}
@@ -75,7 +75,7 @@ static int FindZipMethod(const char *s)
catch(const CSystemException &e) { return e.ErrorCode; } \
catch(...) { return E_OUTOFMEMORY; }
-static HRESULT GetTime(IArchiveUpdateCallback *callback, int index, PROPID propID, FILETIME &filetime)
+static HRESULT GetTime(IArchiveUpdateCallback *callback, unsigned index, PROPID propID, FILETIME &filetime)
{
filetime.dwHighDateTime = filetime.dwLowDateTime = 0;
NCOM::CPropVariant prop;
@@ -106,6 +106,10 @@ STDMETHODIMP CHandler::UpdateItems(ISequentialOutStream *outStream, UInt32 numIt
UInt64 largestSize = 0;
bool largestSizeDefined = false;
+ #ifdef _WIN32
+ const UINT oemCP = GetOEMCP();
+ #endif
+
UString name;
CUpdateItem ui;
@@ -125,7 +129,7 @@ STDMETHODIMP CHandler::UpdateItems(ISequentialOutStream *outStream, UInt32 numIt
ui.NewProps = IntToBool(newProps);
ui.NewData = IntToBool(newData);
- ui.IndexInArc = indexInArc;
+ ui.IndexInArc = (int)indexInArc;
ui.IndexInClient = i;
bool existInArchive = (indexInArc != (UInt32)(Int32)-1);
@@ -240,10 +244,25 @@ STDMETHODIMP CHandler::UpdateItems(ISequentialOutStream *outStream, UInt32 numIt
if (needSlash)
name += kSlash;
- UINT codePage = _forceCodePage ? _specifiedCodePage : CP_OEMCP;
-
+ const UINT codePage = _forceCodePage ? _specifiedCodePage : CP_OEMCP;
bool tryUtf8 = true;
- if ((m_ForceLocal || !m_ForceUtf8) && codePage != CP_UTF8)
+
+ /*
+ Windows 10 allows users to set UTF-8 in Region Settings via option:
+ "Beta: Use Unicode UTF-8 for worldwide language support"
+ In that case Windows uses CP_UTF8 when we use CP_OEMCP.
+ 21.02 fixed:
+ we set UTF-8 mark for non-latin files for such UTF-8 mode in Windows.
+ we write additional Info-Zip Utf-8 FileName Extra for non-latin names/
+ */
+
+ if ((codePage != CP_UTF8) &&
+ #ifdef _WIN32
+ (m_ForceLocal || !m_ForceUtf8) && (oemCP != CP_UTF8)
+ #else
+ (m_ForceLocal && !m_ForceUtf8)
+ #endif
+ )
{
bool defaultCharWasUsed;
ui.Name = UnicodeStringToMultiByte(name, codePage, '_', defaultCharWasUsed);
@@ -251,13 +270,26 @@ STDMETHODIMP CHandler::UpdateItems(ISequentialOutStream *outStream, UInt32 numIt
MultiByteToUnicodeString(ui.Name, codePage) != name));
}
+ const bool isNonLatin = !name.IsAscii();
+
if (tryUtf8)
{
- ui.IsUtf8 = !name.IsAscii();
+ ui.IsUtf8 = isNonLatin;
ConvertUnicodeToUTF8(name, ui.Name);
+
+ #ifndef _WIN32
+ if (ui.IsUtf8 && !CheckUTF8_AString(ui.Name))
+ {
+ // if it's non-Windows and there are non-UTF8 characters we clear UTF8-flag
+ ui.IsUtf8 = false;
+ }
+ #endif
}
+ else if (isNonLatin)
+ Convert_Unicode_To_UTF8_Buf(name, ui.Name_Utf);
- if (ui.Name.Len() >= (1 << 16))
+ if (ui.Name.Len() >= (1 << 16)
+ || ui.Name_Utf.Size() >= (1 << 16) - 128)
return E_INVALIDARG;
{
@@ -337,10 +369,10 @@ STDMETHODIMP CHandler::UpdateItems(ISequentialOutStream *outStream, UInt32 numIt
options._dataSizeReduceDefined = largestSizeDefined;
options.PasswordIsDefined = false;
- options.Password.Empty();
+ options.Password.Wipe_and_Empty();
if (getTextPassword)
{
- CMyComBSTR password;
+ CMyComBSTR_Wipe password;
Int32 passwordIsDefined;
RINOK(getTextPassword->CryptoGetTextPassword2(&passwordIsDefined, &password));
options.PasswordIsDefined = IntToBool(passwordIsDefined);
@@ -352,7 +384,7 @@ STDMETHODIMP CHandler::UpdateItems(ISequentialOutStream *outStream, UInt32 numIt
if (!IsSimpleAsciiString(password))
return E_INVALIDARG;
if (password)
- options.Password = UnicodeStringToMultiByte((LPCOLESTR)password, CP_OEMCP);
+ UnicodeStringToMultiByte2(options.Password, (LPCOLESTR)password, CP_OEMCP);
if (options.IsAesMode)
{
if (options.Password.Len() > NCrypto::NWzAes::kPasswordSizeMax)
@@ -496,7 +528,7 @@ STDMETHODIMP CHandler::SetProperties(const wchar_t * const *names, const PROPVAR
UInt32 id = prop.ulVal;
if (id > 0xFF)
return E_INVALIDARG;
- m_MainMethod = id;
+ m_MainMethod = (int)id;
}
else
{
@@ -518,7 +550,7 @@ STDMETHODIMP CHandler::SetProperties(const wchar_t * const *names, const PROPVAR
const char *end;
UInt32 id = ConvertStringToUInt32(methodName, &end);
if (*end == 0 && id <= 0xFF)
- m_MainMethod = id;
+ m_MainMethod = (int)id;
else if (methodName.IsEqualTo_Ascii_NoCase("Copy")) // it's alias for "Store"
m_MainMethod = 0;
}
diff --git a/CPP/7zip/Archive/Zip/ZipHeader.h b/CPP/7zip/Archive/Zip/ZipHeader.h
index 5e6f00e4..c5c7166e 100644
--- a/CPP/7zip/Archive/Zip/ZipHeader.h
+++ b/CPP/7zip/Archive/Zip/ZipHeader.h
@@ -56,7 +56,10 @@ namespace NFileHeader
kTerse = 18,
kLz77 = 19,
+ kZstdPk = 20,
+ kZstdWz = 93,
+ kMP3 = 94,
kXz = 95,
kJpeg = 96,
kWavPack = 97,
@@ -90,7 +93,10 @@ namespace NFileHeader
kUnixExtra = 0x5855,
kIzUnicodeComment = 0x6375,
kIzUnicodeName = 0x7075,
- kWzAES = 0x9901
+ kUnix2Extra = 0x7855,
+ kUnix3Extra = 0x7875,
+ kWzAES = 0x9901,
+ kApkAlign = 0xD935
};
}
diff --git a/CPP/7zip/Archive/Zip/ZipIn.cpp b/CPP/7zip/Archive/Zip/ZipIn.cpp
index 509753c2..880ff218 100644
--- a/CPP/7zip/Archive/Zip/ZipIn.cpp
+++ b/CPP/7zip/Archive/Zip/ZipIn.cpp
@@ -152,6 +152,9 @@ void CInArchive::Close()
IsArc = false;
IsZip64 = false;
+ IsApk = false;
+ IsCdUnsorted = false;
+
HeadersError = false;
HeadersWarning = false;
ExtraMinorError = false;
@@ -169,7 +172,7 @@ void CInArchive::Close()
IsMultiVol = false;
UseDisk_in_SingleVol = false;
EcdVolIndex = 0;
-
+
ArcInfo.Clear();
ClearRefs();
@@ -181,7 +184,7 @@ HRESULT CInArchive::Seek_SavePos(UInt64 offset)
{
// InitBuf();
// if (!Stream) return S_FALSE;
- return Stream->Seek(offset, STREAM_SEEK_SET, &_streamPos);
+ return Stream->Seek((Int64)offset, STREAM_SEEK_SET, &_streamPos);
}
HRESULT CInArchive::SeekToVol(int volIndex, UInt64 offset)
@@ -193,9 +196,9 @@ HRESULT CInArchive::SeekToVol(int volIndex, UInt64 offset)
{
if ((unsigned)volIndex >= Vols.Streams.Size())
return S_FALSE;
- if (!Vols.Streams[volIndex].Stream)
+ if (!Vols.Streams[(unsigned)volIndex].Stream)
return S_FALSE;
- Stream = Vols.Streams[volIndex].Stream;
+ Stream = Vols.Streams[(unsigned)volIndex].Stream;
}
else if (volIndex == -2)
{
@@ -277,11 +280,11 @@ HRESULT CInArchive::ReadFromCache(Byte *data, unsigned size, unsigned &processed
}
else
{
- UInt32 cur = 0;
- result = Stream->Read(data, size, &cur);
+ size_t cur = size;
+ result = ReadStream(Stream, data, &cur);
data += cur;
- size -= cur;
- processed += cur;
+ size -= (unsigned)cur;
+ processed += (unsigned)cur;
_streamPos += cur;
_cnt += cur;
if (cur != 0)
@@ -299,7 +302,7 @@ HRESULT CInArchive::ReadFromCache(Byte *data, unsigned size, unsigned &processed
|| (unsigned)Vols.StreamIndex + 1 >= Vols.Streams.Size())
break;
- const CVols::CSubStreamInfo &s = Vols.Streams[Vols.StreamIndex + 1];
+ const CVols::CSubStreamInfo &s = Vols.Streams[(unsigned)Vols.StreamIndex + 1];
if (!s.Stream)
break;
result = s.SeekToStart();
@@ -316,6 +319,16 @@ HRESULT CInArchive::ReadFromCache(Byte *data, unsigned size, unsigned &processed
}
+HRESULT CInArchive::ReadFromCache_FALSE(Byte *data, unsigned size)
+{
+ unsigned processed;
+ HRESULT res = ReadFromCache(data, size, processed);
+ if (res == S_OK && size != processed)
+ return S_FALSE;
+ return res;
+}
+
+
static bool CheckDosTime(UInt32 dosTime)
{
if (dosTime == 0)
@@ -412,8 +425,12 @@ API_FUNC_IsArc IsArc_Zip(const Byte *p, size_t size)
const unsigned nameSize = Get16(p + 22);
unsigned extraSize = Get16(p + 24);
const UInt32 extraOffset = kLocalHeaderSize + (UInt32)nameSize;
+
+ /*
+ // 21.02: fixed. we don't use the following check
if (extraOffset + extraSize > (1 << 16))
return k_IsArc_Res_NO;
+ */
p -= 4;
@@ -498,12 +515,9 @@ static const Byte *FindPK(const Byte *p, const Byte *limit)
{
for (;;)
{
- Byte b0 = p[0];
- if (p >= limit)
- return p;
- p++;
- if (b0 == 0x50)
- break;
+ Byte b0;
+ b0 = p[0]; if (p >= limit) return p; p++; if (b0 == 0x50) break;
+ b0 = p[0]; if (p >= limit) return p; p++; if (b0 == 0x50) break;
}
if (p[0] == 0x4B)
return p - 1;
@@ -540,10 +554,7 @@ HRESULT CInArchive::FindMarker(const UInt64 *searchLimit)
if (searchLimit && *searchLimit == 0)
{
Byte startBuf[kMarkerSize];
- unsigned processed;
- RINOK(ReadFromCache(startBuf, kMarkerSize, processed));
- if (processed != kMarkerSize)
- return S_FALSE;
+ RINOK(ReadFromCache_FALSE(startBuf, kMarkerSize));
UInt32 marker = Get32(startBuf);
_signature = marker;
@@ -551,9 +562,7 @@ HRESULT CInArchive::FindMarker(const UInt64 *searchLimit)
if ( marker == NSignature::kNoSpan
|| marker == NSignature::kSpan)
{
- RINOK(ReadFromCache(startBuf, kMarkerSize, processed));
- if (processed != kMarkerSize)
- return S_FALSE;
+ RINOK(ReadFromCache_FALSE(startBuf, kMarkerSize));
_signature = Get32(startBuf);
}
@@ -605,7 +614,7 @@ HRESULT CInArchive::FindMarker(const UInt64 *searchLimit)
SkipLookahed(avail);
- const CVols::CSubStreamInfo &s = Vols.Streams[Vols.StreamIndex + 1];
+ const CVols::CSubStreamInfo &s = Vols.Streams[(unsigned)Vols.StreamIndex + 1];
if (!s.Stream)
break;
@@ -645,14 +654,14 @@ HRESULT CInArchive::FindMarker(const UInt64 *searchLimit)
p = FindPK(p, limit);
if (p >= limit)
break;
- const size_t rem = pStart + avail - p;
+ const size_t rem = (size_t)(pStart + avail - p);
UInt32 res = IsArc_Zip_2(p, rem, isFinished);
if (res != k_IsArc_Res_NO)
{
if (rem < kMarkerSize)
return S_FALSE;
_signature = Get32(p);
- SkipLookahed(p - pStart);
+ SkipLookahed((size_t)(p - pStart));
ArcInfo.MarkerVolIndex = Vols.StreamIndex;
ArcInfo.MarkerPos = GetVirtStreamPos();
ArcInfo.MarkerPos2 = ArcInfo.MarkerPos;
@@ -674,7 +683,7 @@ HRESULT CInArchive::FindMarker(const UInt64 *searchLimit)
if (!IsMultiVol && isFinished)
break;
- SkipLookahed(p - pStart);
+ SkipLookahed((size_t)(p - pStart));
if (Callback && (_cnt - progressPrev) >= ((UInt32)1 << 23))
{
@@ -728,7 +737,7 @@ HRESULT CInArchive::IncreaseRealPosition(UInt64 offset, bool &isFinished)
if (!IsMultiVol)
{
_cnt += offset;
- return Stream->Seek(offset, STREAM_SEEK_CUR, &_streamPos);
+ return Stream->Seek((Int64)offset, STREAM_SEEK_CUR, &_streamPos);
}
for (;;)
@@ -744,7 +753,7 @@ HRESULT CInArchive::IncreaseRealPosition(UInt64 offset, bool &isFinished)
return S_OK;
}
{
- const CVols::CSubStreamInfo &s = Vols.Streams[Vols.StreamIndex];
+ const CVols::CSubStreamInfo &s = Vols.Streams[(unsigned)Vols.StreamIndex];
if (!s.Stream)
{
isFinished = true;
@@ -756,7 +765,7 @@ HRESULT CInArchive::IncreaseRealPosition(UInt64 offset, bool &isFinished)
if ((UInt64)offset <= rem)
{
_cnt += offset;
- return Stream->Seek(offset, STREAM_SEEK_CUR, &_streamPos);
+ return Stream->Seek((Int64)offset, STREAM_SEEK_CUR, &_streamPos);
}
RINOK(Seek_SavePos(s.Size));
offset -= rem;
@@ -771,7 +780,7 @@ HRESULT CInArchive::IncreaseRealPosition(UInt64 offset, bool &isFinished)
isFinished = true;
return S_OK;
}
- const CVols::CSubStreamInfo &s2 = Vols.Streams[Vols.StreamIndex];
+ const CVols::CSubStreamInfo &s2 = Vols.Streams[(unsigned)Vols.StreamIndex];
if (!s2.Stream)
{
isFinished = true;
@@ -834,7 +843,7 @@ HRESULT CInArchive::LookAhead(size_t minRequired)
|| (unsigned)Vols.StreamIndex + 1 >= Vols.Streams.Size())
return S_OK;
- const CVols::CSubStreamInfo &s = Vols.Streams[Vols.StreamIndex + 1];
+ const CVols::CSubStreamInfo &s = Vols.Streams[(unsigned)Vols.StreamIndex + 1];
if (!s.Stream)
return S_OK;
@@ -979,7 +988,7 @@ bool CInArchive::ReadFileName(unsigned size, AString &s)
#define ZIP64_IS_16_MAX(n) ((n) == 0xFFFF)
-bool CInArchive::ReadExtra(unsigned extraSize, CExtraBlock &extra,
+bool CInArchive::ReadExtra(const CLocalItem &item, unsigned extraSize, CExtraBlock &extra,
UInt64 &unpackSize, UInt64 &packSize, UInt64 &localOffset, UInt32 &disk)
{
extra.Clear();
@@ -1010,16 +1019,16 @@ bool CInArchive::ReadExtra(unsigned extraSize, CExtraBlock &extra,
bool isOK = true;
if (ZIP64_IS_32_MAX(unpackSize))
- if (size < 8) isOK = false; else { size -= 8; unpackSize = ReadUInt64(); }
+ { if (size < 8) isOK = false; else { size -= 8; unpackSize = ReadUInt64(); }}
if (isOK && ZIP64_IS_32_MAX(packSize))
- if (size < 8) isOK = false; else { size -= 8; packSize = ReadUInt64(); }
+ { if (size < 8) isOK = false; else { size -= 8; packSize = ReadUInt64(); }}
if (isOK && ZIP64_IS_32_MAX(localOffset))
- if (size < 8) isOK = false; else { size -= 8; localOffset = ReadUInt64(); }
+ { if (size < 8) isOK = false; else { size -= 8; localOffset = ReadUInt64(); }}
if (isOK && ZIP64_IS_16_MAX(disk))
- if (size < 4) isOK = false; else { size -= 4; disk = ReadUInt32(); }
+ { if (size < 4) isOK = false; else { size -= 4; disk = ReadUInt32(); }}
if (!isOK || size != 0)
{
@@ -1033,6 +1042,11 @@ bool CInArchive::ReadExtra(unsigned extraSize, CExtraBlock &extra,
{
ReadBuffer(subBlock.Data, size);
extra.SubBlocks.Add(subBlock);
+ if (subBlock.ID == NFileHeader::NExtraID::kIzUnicodeName)
+ {
+ if (!subBlock.CheckIzUnicode(item.Name))
+ extra.Error = true;
+ }
}
}
@@ -1054,7 +1068,7 @@ bool CInArchive::ReadLocalItem(CItemEx &item)
{
item.Disk = 0;
if (IsMultiVol && Vols.StreamIndex >= 0)
- item.Disk = Vols.StreamIndex;
+ item.Disk = (UInt32)Vols.StreamIndex;
const unsigned kPureHeaderSize = kLocalHeaderSize - 4;
Byte p[kPureHeaderSize];
SafeRead(p, kPureHeaderSize);
@@ -1088,7 +1102,7 @@ bool CInArchive::ReadLocalItem(CItemEx &item)
{
UInt64 localOffset = 0;
UInt32 disk = 0;
- if (!ReadExtra(extraSize, item.LocalExtra, item.Size, item.PackSize, localOffset, disk))
+ if (!ReadExtra(item, extraSize, item.LocalExtra, item.Size, item.PackSize, localOffset, disk))
{
/* Most of archives are OK for Extra. But there are some rare cases
that have error. And if error in first item, it can't open archive.
@@ -1111,33 +1125,39 @@ bool CInArchive::ReadLocalItem(CItemEx &item)
HeadersWarning = true;
}
- return item.LocalFullHeaderSize <= ((UInt32)1 << 16);
+ // return item.LocalFullHeaderSize <= ((UInt32)1 << 16);
+ return true;
}
-static bool FlagsAreSame(const CItem &i1, const CItem &i2)
+static bool FlagsAreSame(const CItem &i1, const CItem &i2_cd)
{
- if (i1.Method != i2.Method)
+ if (i1.Method != i2_cd.Method)
return false;
- if (i1.Flags == i2.Flags)
+
+ UInt32 mask = i1.Flags ^ i2_cd.Flags;
+ if (mask == 0)
return true;
- UInt32 mask = 0xFFFF;
switch (i1.Method)
{
case NFileHeader::NCompressionMethod::kDeflate:
- mask = 0x7FF9;
+ mask &= 0x7FF9;
break;
default:
if (i1.Method <= NFileHeader::NCompressionMethod::kImplode)
- mask = 0x7FFF;
+ mask &= 0x7FFF;
}
// we can ignore utf8 flag, if name is ascii
- if ((i1.Flags ^ i2.Flags) & NFileHeader::NFlags::kUtf8)
- if (i1.Name.IsAscii() && i2.Name.IsAscii())
+ if (mask & NFileHeader::NFlags::kUtf8)
+ if (i1.Name.IsAscii() && i2_cd.Name.IsAscii())
mask &= ~NFileHeader::NFlags::kUtf8;
+
+ // some bad archive in rare case can use descriptor without descriptor flag in Central Dir
+ // if (i1.HasDescriptor())
+ mask &= ~NFileHeader::NFlags::kDescriptorUsedMask;
- return ((i1.Flags & mask) == (i2.Flags & mask));
+ return (mask == 0);
}
@@ -1167,13 +1187,13 @@ static bool AreEqualPaths_IgnoreSlashes(const char *s1, const char *s2)
static bool AreItemsEqual(const CItemEx &localItem, const CItemEx &cdItem)
{
- if (!FlagsAreSame(cdItem, localItem))
+ if (!FlagsAreSame(localItem, cdItem))
return false;
if (!localItem.HasDescriptor())
{
if (cdItem.PackSize != localItem.PackSize
|| cdItem.Size != localItem.Size
- || cdItem.Crc != localItem.Crc && cdItem.Crc != 0) // some program writes 0 to crc field in central directory
+ || (cdItem.Crc != localItem.Crc && cdItem.Crc != 0)) // some program writes 0 to crc field in central directory
return false;
}
/* pkzip 2.50 creates incorrect archives. It uses
@@ -1235,7 +1255,7 @@ HRESULT CInArchive::ReadLocalItemAfterCdItem(CItemEx &item, bool &isAvail, bool
return S_FALSE;
}
Stream = Vols.Streams[item.Disk].Stream;
- Vols.StreamIndex = item.Disk;
+ Vols.StreamIndex = (int)item.Disk;
if (!Stream)
{
isAvail = false;
@@ -1251,7 +1271,7 @@ HRESULT CInArchive::ReadLocalItemAfterCdItem(CItemEx &item, bool &isAvail, bool
}
Stream = StreamRef;
- offset += ArcInfo.Base;
+ offset = (UInt64)((Int64)offset + ArcInfo.Base);
if (ArcInfo.Base < 0 && (Int64)offset < 0)
{
isAvail = false;
@@ -1281,6 +1301,11 @@ HRESULT CInArchive::ReadLocalItemAfterCdItem(CItemEx &item, bool &isAvail, bool
item.Crc = localItem.Crc;
headersError = true;
}
+ if ((item.Flags ^ localItem.Flags) & NFileHeader::NFlags::kDescriptorUsedMask)
+ {
+ item.Flags = (UInt16)(item.Flags ^ NFileHeader::NFlags::kDescriptorUsedMask);
+ headersError = true;
+ }
item.FromLocal = true;
}
catch(...) { return S_FALSE; }
@@ -1351,8 +1376,11 @@ HRESULT CInArchive::FindDescriptor(CItemEx &item, unsigned numFiles)
{
// we write to packSize all these available bytes.
// later it's simpler to work with such value than with 0
- if (item.PackSize == 0)
+ // if (item.PackSize == 0)
item.PackSize = packedSize + avail;
+ if (item.Method == 0)
+ item.Size = item.PackSize;
+ SkipLookahed(avail);
return S_OK;
}
@@ -1384,7 +1412,7 @@ HRESULT CInArchive::FindDescriptor(CItemEx &item, unsigned numFiles)
&& sig != NSignature::kCentralFileHeader)
continue;
- const UInt64 packSizeCur = packedSize + (p - pStart);
+ const UInt64 packSizeCur = packedSize + (size_t)(p - pStart);
if (descriptorSize4 == kDataDescriptorSize64 + kNextSignatureSize) // if (item.LocalExtra.IsZip64)
{
const UInt64 descriptorPackSize = Get64(p + 8);
@@ -1406,14 +1434,14 @@ HRESULT CInArchive::FindDescriptor(CItemEx &item, unsigned numFiles)
item.DescriptorWasRead = true;
item.Crc = Get32(p + 4);
- const size_t skip = (p - pStart) + descriptorSize4 - kNextSignatureSize;
+ const size_t skip = (size_t)(p - pStart) + descriptorSize4 - kNextSignatureSize;
SkipLookahed(skip);
return S_OK;
}
- const size_t skip = (p - pStart);
+ const size_t skip = (size_t)(p - pStart);
SkipLookahed(skip);
packedSize += skip;
@@ -1529,7 +1557,7 @@ HRESULT CInArchive::ReadCdItem(CItemEx &item)
ReadFileName(nameSize, item.Name);
if (extraSize > 0)
- ReadExtra(extraSize, item.CentralExtra, item.Size, item.PackSize, item.LocalHeaderPos, item.Disk);
+ ReadExtra(item, extraSize, item.CentralExtra, item.Size, item.PackSize, item.LocalHeaderPos, item.Disk);
// May be these strings must be deleted
/*
@@ -1549,11 +1577,7 @@ HRESULT CInArchive::TryEcd64(UInt64 offset, CCdInfo &cdInfo)
Byte buf[kEcd64_FullSize];
RINOK(SeekToVol(Vols.StreamIndex, offset));
- unsigned processed = 0;
- ReadFromCache(buf, kEcd64_FullSize, processed);
-
- if (processed != kEcd64_FullSize)
- return S_FALSE;
+ RINOK(ReadFromCache_FALSE(buf, kEcd64_FullSize));
if (Get32(buf) != NSignature::kEcd64)
return S_FALSE;
@@ -1636,8 +1660,12 @@ HRESULT CInArchive::FindCd(bool checkOffsetMode)
{
CLocator locator;
locator.Parse(buf + locatorIndex + 4);
- if ((cdInfo.ThisDisk == locator.NumDisks - 1 || ZIP64_IS_16_MAX(cdInfo.ThisDisk))
- && locator.Ecd64Disk < locator.NumDisks)
+ UInt32 numDisks = locator.NumDisks;
+ // we ignore the error, where some zip creators use (NumDisks == 0)
+ if (numDisks == 0)
+ numDisks = 1;
+ if ((cdInfo.ThisDisk == numDisks - 1 || ZIP64_IS_16_MAX(cdInfo.ThisDisk))
+ && locator.Ecd64Disk < numDisks)
{
if (locator.Ecd64Disk != cdInfo.ThisDisk && !ZIP64_IS_16_MAX(cdInfo.ThisDisk))
return E_NOTIMPL;
@@ -1657,7 +1685,7 @@ HRESULT CInArchive::FindCd(bool checkOffsetMode)
if (mainEcd64Size == kEcd64_MainSize)
{
cdInfo.ParseEcd64e(ecd64 + 12);
- ArcInfo.Base = absEcd64 - locator.Ecd64Offset;
+ ArcInfo.Base = (Int64)(absEcd64 - locator.Ecd64Offset);
// ArcInfo.BaseVolIndex = cdInfo.ThisDisk;
return S_OK;
}
@@ -1685,7 +1713,7 @@ HRESULT CInArchive::FindCd(bool checkOffsetMode)
{
if (TryEcd64(ArcInfo.MarkerPos + locator.Ecd64Offset, cdInfo) == S_OK)
{
- ArcInfo.Base = ArcInfo.MarkerPos;
+ ArcInfo.Base = (Int64)ArcInfo.MarkerPos;
// ArcInfo.BaseVolIndex = cdInfo.ThisDisk;
return S_OK;
}
@@ -1719,7 +1747,7 @@ HRESULT CInArchive::FindCd(bool checkOffsetMode)
}
else
*/
- ArcInfo.Base = absEcdPos - cdEnd;
+ ArcInfo.Base = (Int64)(absEcdPos - cdEnd);
}
return S_OK;
}
@@ -1730,11 +1758,12 @@ HRESULT CInArchive::FindCd(bool checkOffsetMode)
HRESULT CInArchive::TryReadCd(CObjectVector<CItemEx> &items, const CCdInfo &cdInfo, UInt64 cdOffset, UInt64 cdSize)
{
items.Clear();
+ IsCdUnsorted = false;
// _startLocalFromCd_Disk = (UInt32)(Int32)-1;
// _startLocalFromCd_Offset = (UInt64)(Int64)-1;
- RINOK(SeekToVol(IsMultiVol ? cdInfo.CdDisk : -1, cdOffset));
+ RINOK(SeekToVol(IsMultiVol ? (int)cdInfo.CdDisk : -1, cdOffset));
_inBufMode = true;
_cnt = 0;
@@ -1767,6 +1796,15 @@ HRESULT CInArchive::TryReadCd(CObjectVector<CItemEx> &items, const CCdInfo &cdIn
}
*/
+ if (items.Size() > 0 && !IsCdUnsorted)
+ {
+ const CItemEx &prev = items.Back();
+ if (cdItem.Disk < prev.Disk
+ || (cdItem.Disk == prev.Disk &&
+ cdItem.LocalHeaderPos < prev.LocalHeaderPos))
+ IsCdUnsorted = true;
+ }
+
items.Add(cdItem);
}
if (Callback && (items.Size() & 0xFFF) == 0)
@@ -1793,6 +1831,22 @@ HRESULT CInArchive::TryReadCd(CObjectVector<CItemEx> &items, const CCdInfo &cdIn
}
+/*
+static int CompareCdItems(void *const *elem1, void *const *elem2, void *)
+{
+ const CItemEx *i1 = *(const CItemEx **)elem1;
+ const CItemEx *i2 = *(const CItemEx **)elem2;
+
+ if (i1->Disk < i2->Disk) return -1;
+ if (i1->Disk > i2->Disk) return 1;
+ if (i1->LocalHeaderPos < i2->LocalHeaderPos) return -1;
+ if (i1->LocalHeaderPos > i2->LocalHeaderPos) return 1;
+ if (i1 < i2) return -1;
+ if (i1 > i2) return 1;
+ return 0;
+}
+*/
+
HRESULT CInArchive::ReadCd(CObjectVector<CItemEx> &items, UInt32 &cdDisk, UInt64 &cdOffset, UInt64 &cdSize)
{
bool checkOffsetMode = true;
@@ -1801,7 +1855,7 @@ HRESULT CInArchive::ReadCd(CObjectVector<CItemEx> &items, UInt32 &cdDisk, UInt64
{
if (Vols.EndVolIndex == -1)
return S_FALSE;
- Stream = Vols.Streams[Vols.EndVolIndex].Stream;
+ Stream = Vols.Streams[(unsigned)Vols.EndVolIndex].Stream;
if (!Vols.StartIsZip)
checkOffsetMode = false;
}
@@ -1827,7 +1881,7 @@ HRESULT CInArchive::ReadCd(CObjectVector<CItemEx> &items, UInt32 &cdDisk, UInt64
return S_FALSE;
}
- const UInt64 base = (IsMultiVol ? 0 : ArcInfo.Base);
+ const UInt64 base = (IsMultiVol ? 0 : (UInt64)ArcInfo.Base);
res = TryReadCd(items, cdInfo, base + cdOffset, cdSize);
if (res == S_FALSE && !IsMultiVol && base != ArcInfo.MarkerPos)
@@ -1835,9 +1889,11 @@ HRESULT CInArchive::ReadCd(CObjectVector<CItemEx> &items, UInt32 &cdDisk, UInt64
// do we need that additional attempt to read cd?
res = TryReadCd(items, cdInfo, ArcInfo.MarkerPos + cdOffset, cdSize);
if (res == S_OK)
- ArcInfo.Base = ArcInfo.MarkerPos;
+ ArcInfo.Base = (Int64)ArcInfo.MarkerPos;
}
+ // Some rare case files are unsorted
+ // items.Sort(CompareCdItems, NULL);
return res;
}
@@ -1849,14 +1905,14 @@ static int FindItem(const CObjectVector<CItemEx> &items, const CItemEx &item)
{
if (left >= right)
return -1;
- unsigned index = (left + right) / 2;
+ const unsigned index = (left + right) / 2;
const CItemEx &item2 = items[index];
if (item.Disk < item2.Disk)
right = index;
else if (item.Disk > item2.Disk)
left = index + 1;
else if (item.LocalHeaderPos == item2.LocalHeaderPos)
- return index;
+ return (int)index;
else if (item.LocalHeaderPos < item2.LocalHeaderPos)
right = index;
else
@@ -1921,7 +1977,7 @@ HRESULT CInArchive::ReadLocals(CObjectVector<CItemEx> &items)
item.LocalHeaderPos = GetVirtStreamPos() - 4;
if (!IsMultiVol)
- item.LocalHeaderPos -= ArcInfo.Base;
+ item.LocalHeaderPos = (UInt64)((Int64)item.LocalHeaderPos - ArcInfo.Base);
try
{
@@ -1950,7 +2006,7 @@ HRESULT CInArchive::ReadLocals(CObjectVector<CItemEx> &items)
}
catch (CUnexpectEnd &)
{
- if (items.IsEmpty() || items.Size() == 1 && IsStrangeItem(items[0]))
+ if (items.IsEmpty() || (items.Size() == 1 && IsStrangeItem(items[0])))
return S_FALSE;
throw;
}
@@ -1986,11 +2042,11 @@ HRESULT CVols::ParseArcName(IArchiveOpenVolumeCallback *volCallback)
name = prop.bstrVal;
}
- int dotPos = name.ReverseFind_Dot();
+ const int dotPos = name.ReverseFind_Dot();
if (dotPos < 0)
return S_OK;
- const UString ext = name.Ptr(dotPos + 1);
- name.DeleteFrom(dotPos + 1);
+ const UString ext = name.Ptr((unsigned)(dotPos + 1));
+ name.DeleteFrom((unsigned)(dotPos + 1));
StartVolIndex = (Int32)(-1);
@@ -2047,7 +2103,7 @@ HRESULT CVols::ParseArcName(IArchiveOpenVolumeCallback *volCallback)
UInt32 volNum = ConvertStringToUInt32(ext.Ptr(1), &end);
if (*end != 0 || volNum < 1 || volNum > ((UInt32)1 << 30))
return S_OK;
- StartVolIndex = volNum - 1;
+ StartVolIndex = (Int32)(volNum - 1);
BaseName = name;
StartIsZ = true;
}
@@ -2147,7 +2203,7 @@ HRESULT CInArchive::ReadVols2(IArchiveOpenVolumeCallback *volCallback,
UInt64 pos;
RINOK(stream->Seek(0, STREAM_SEEK_CUR, &pos));
RINOK(stream->Seek(0, STREAM_SEEK_END, &size));
- RINOK(stream->Seek(pos, STREAM_SEEK_SET, NULL));
+ RINOK(stream->Seek((Int64)pos, STREAM_SEEK_SET, NULL));
while (i >= Vols.Streams.Size())
Vols.Streams.AddNew();
@@ -2161,7 +2217,7 @@ HRESULT CInArchive::ReadVols2(IArchiveOpenVolumeCallback *volCallback,
if ((int)i == zipDisk)
{
- Vols.EndVolIndex = Vols.Streams.Size() - 1;
+ Vols.EndVolIndex = (int)(Vols.Streams.Size() - 1);
break;
}
}
@@ -2211,7 +2267,7 @@ HRESULT CInArchive::ReadVols()
CCdInfo &ecd = Vols.ecd;
if (res == S_OK)
{
- zipDisk = ecd.ThisDisk;
+ zipDisk = (int)ecd.ThisDisk;
Vols.ecd_wasRead = true;
// if is not multivol or bad multivol, we return to main single stream code
@@ -2220,9 +2276,9 @@ HRESULT CInArchive::ReadVols()
|| ecd.ThisDisk < ecd.CdDisk)
return S_OK;
- cdDisk = ecd.CdDisk;
+ cdDisk = (int)ecd.CdDisk;
if (Vols.StartVolIndex < 0)
- Vols.StartVolIndex = ecd.ThisDisk;
+ Vols.StartVolIndex = (Int32)ecd.ThisDisk;
else if ((UInt32)Vols.StartVolIndex >= ecd.ThisDisk)
return S_OK;
@@ -2232,7 +2288,7 @@ HRESULT CInArchive::ReadVols()
if (cdDisk != zipDisk)
{
// get volumes required for cd.
- RINOK(ReadVols2(volCallback, cdDisk, zipDisk, zipDisk, 0, numMissingVols));
+ RINOK(ReadVols2(volCallback, (unsigned)cdDisk, zipDisk, zipDisk, 0, numMissingVols));
if (numMissingVols != 0)
{
// cdOK = false;
@@ -2269,10 +2325,10 @@ HRESULT CInArchive::ReadVols()
if (Vols.StartVolIndex > (1 << 20))
return S_OK;
if ((unsigned)Vols.StartVolIndex >= Vols.Streams.Size()
- || !Vols.Streams[Vols.StartVolIndex].Stream)
+ || !Vols.Streams[(unsigned)Vols.StartVolIndex].Stream)
{
// we get volumes starting from StartVolIndex, if they we not requested before know the volume index (if FindCd() was ok)
- RINOK(ReadVols2(volCallback, Vols.StartVolIndex, zipDisk, zipDisk, 0, numMissingVols));
+ RINOK(ReadVols2(volCallback, (unsigned)Vols.StartVolIndex, zipDisk, zipDisk, 0, numMissingVols));
}
}
@@ -2285,7 +2341,7 @@ HRESULT CInArchive::ReadVols()
if (zipDisk >= 0)
{
// we create item in Streams for ZipStream, if we know the volume index (if FindCd() was ok)
- RINOK(ReadVols2(volCallback, zipDisk, zipDisk + 1, zipDisk, 0, numMissingVols));
+ RINOK(ReadVols2(volCallback, (unsigned)zipDisk, zipDisk + 1, zipDisk, 0, numMissingVols));
}
}
@@ -2331,7 +2387,7 @@ HRESULT CVols::Read(void *data, UInt32 size, UInt32 *processedSize)
return S_OK;
if ((unsigned)StreamIndex >= Streams.Size())
return S_OK;
- const CVols::CSubStreamInfo &s = Streams[StreamIndex];
+ const CVols::CSubStreamInfo &s = Streams[(unsigned)StreamIndex];
if (!s.Stream)
return S_FALSE;
if (NeedSeek)
@@ -2473,7 +2529,7 @@ HRESULT CInArchive::ReadHeaders(CObjectVector<CItemEx> &items)
if (!ecd.IsEmptyArc())
return S_FALSE;
- ArcInfo.Base = ArcInfo.MarkerPos;
+ ArcInfo.Base = (Int64)ArcInfo.MarkerPos;
IsArc = true; // check it: we need more tests?
RINOK(SeekToVol(ArcInfo.MarkerVolIndex, ArcInfo.MarkerPos2));
@@ -2514,16 +2570,44 @@ HRESULT CInArchive::ReadHeaders(CObjectVector<CItemEx> &items)
res = S_FALSE;
else
{
- firstItem.LocalHeaderPos = ArcInfo.MarkerPos2 - ArcInfo.Base;
- int index = FindItem(items, firstItem);
+ firstItem.LocalHeaderPos = (UInt64)((Int64)ArcInfo.MarkerPos2 - ArcInfo.Base);
+ int index = -1;
+
+ UInt32 min_Disk = (UInt32)(Int32)-1;
+ UInt64 min_LocalHeaderPos = (UInt64)(Int64)-1;
+
+ if (!IsCdUnsorted)
+ index = FindItem(items, firstItem);
+ else
+ {
+ FOR_VECTOR (i, items)
+ {
+ const CItemEx &cdItem = items[i];
+ if (cdItem.Disk == firstItem.Disk
+ && (cdItem.LocalHeaderPos == firstItem.LocalHeaderPos))
+ index = (int)i;
+
+ if (i == 0
+ || cdItem.Disk < min_Disk
+ || (cdItem.Disk == min_Disk && cdItem.LocalHeaderPos < min_LocalHeaderPos))
+ {
+ min_Disk = cdItem.Disk;
+ min_LocalHeaderPos = cdItem.LocalHeaderPos;
+ }
+ }
+ }
+
if (index == -1)
res = S_FALSE;
- else if (!AreItemsEqual(firstItem, items[index]))
+ else if (!AreItemsEqual(firstItem, items[(unsigned)index]))
res = S_FALSE;
else
{
ArcInfo.CdWasRead = true;
- ArcInfo.FirstItemRelatOffset = items[0].LocalHeaderPos;
+ if (IsCdUnsorted)
+ ArcInfo.FirstItemRelatOffset = min_LocalHeaderPos;
+ else
+ ArcInfo.FirstItemRelatOffset = items[0].LocalHeaderPos;
// ArcInfo.FirstItemRelatOffset = _startLocalFromCd_Offset;
}
@@ -2588,7 +2672,7 @@ HRESULT CInArchive::ReadHeaders(CObjectVector<CItemEx> &items)
The (Base) can be corrected later after ECD reading.
But sfx volume with stub and (No)Span-marker in (!IsMultiVol) mode will have incorrect (Base) here.
*/
- ArcInfo.Base = ArcInfo.MarkerPos2;
+ ArcInfo.Base = (Int64)ArcInfo.MarkerPos2;
}
RINOK(SeekToVol(ArcInfo.MarkerVolIndex, ArcInfo.MarkerPos2));
@@ -2607,15 +2691,42 @@ HRESULT CInArchive::ReadHeaders(CObjectVector<CItemEx> &items)
// GetVirtStreamPos() - 4
if (items.IsEmpty())
return S_FALSE;
- NoCentralDir = true;
- HeadersError = true;
- return S_OK;
+
+ bool isError = true;
+
+ const UInt32 apkSize = _signature;
+ const unsigned kApkFooterSize = 16 + 8;
+ if (apkSize >= kApkFooterSize && apkSize <= (1 << 20))
+ {
+ if (ReadUInt32() == 0)
+ {
+ CByteBuffer apk;
+ apk.Alloc(apkSize);
+ SafeRead(apk, apkSize);
+ ReadSignature();
+ const Byte *footer = apk + apkSize - kApkFooterSize;
+ if (_signature == NSignature::kCentralFileHeader)
+ if (GetUi64(footer) == apkSize)
+ if (memcmp(footer + 8, "APK Sig Block 42", 16) == 0)
+ {
+ isError = false;
+ IsApk = true;
+ }
+ }
+ }
+
+ if (isError)
+ {
+ NoCentralDir = true;
+ HeadersError = true;
+ return S_OK;
+ }
}
_inBufMode = true;
cdAbsOffset = GetVirtStreamPos() - 4;
- cdDisk = Vols.StreamIndex;
+ cdDisk = (UInt32)Vols.StreamIndex;
#ifdef ZIP_SELF_CHECK
if (!IsMultiVol && _cnt != GetVirtStreamPos() - ArcInfo.MarkerPos2)
@@ -2656,7 +2767,7 @@ HRESULT CInArchive::ReadHeaders(CObjectVector<CItemEx> &items)
needSetBase = true;
numCdItems = cdItems.Size();
- cdRelatOffset = cdAbsOffset - ArcInfo.Base;
+ cdRelatOffset = (UInt64)((Int64)cdAbsOffset - ArcInfo.Base);
if (!cdItems.IsEmpty())
{
@@ -2712,6 +2823,8 @@ HRESULT CInArchive::ReadHeaders(CObjectVector<CItemEx> &items)
Byte buf[kBufSize];
SafeRead(buf, kBufSize);
locator.Parse(buf);
+ // we ignore the error, where some zip creators use (NumDisks == 0)
+ // if (locator.NumDisks == 0) HeadersWarning = true;
}
ReadSignature();
@@ -2764,12 +2877,12 @@ HRESULT CInArchive::ReadHeaders(CObjectVector<CItemEx> &items)
if (IsMultiVol)
{
- if (cdDisk != (int)cdInfo.CdDisk)
+ if (cdDisk != cdInfo.CdDisk)
HeadersError = true;
}
else if (needSetBase && cdOK)
{
- const UInt64 oldBase = ArcInfo.Base;
+ const UInt64 oldBase = (UInt64)ArcInfo.Base;
// localsWereRead == true
// ArcInfo.Base == ArcInfo.MarkerPos2
// cdRelatOffset == (cdAbsOffset - ArcInfo.Base)
@@ -2778,13 +2891,13 @@ HRESULT CInArchive::ReadHeaders(CObjectVector<CItemEx> &items)
{
if (ecd64Disk == Vols.StartVolIndex)
{
- const Int64 newBase = (Int64)ecd64AbsOffset - locator.Ecd64Offset;
+ const Int64 newBase = (Int64)ecd64AbsOffset - (Int64)locator.Ecd64Offset;
if (newBase <= (Int64)ecd64AbsOffset)
{
if (!localsWereRead || newBase <= (Int64)ArcInfo.MarkerPos2)
{
ArcInfo.Base = newBase;
- cdRelatOffset = cdAbsOffset - newBase;
+ cdRelatOffset = (UInt64)((Int64)cdAbsOffset - newBase);
}
else
cdOK = false;
@@ -2795,7 +2908,7 @@ HRESULT CInArchive::ReadHeaders(CObjectVector<CItemEx> &items)
{
if ((int)cdDisk == Vols.StartVolIndex)
{
- const Int64 newBase = (Int64)cdAbsOffset - cdInfo.Offset;
+ const Int64 newBase = (Int64)cdAbsOffset - (Int64)cdInfo.Offset;
if (newBase <= (Int64)cdAbsOffset)
{
if (!localsWereRead || newBase <= (Int64)ArcInfo.MarkerPos2)
@@ -2828,7 +2941,7 @@ HRESULT CInArchive::ReadHeaders(CObjectVector<CItemEx> &items)
if (localsWereRead)
{
- const UInt64 delta = oldBase - ArcInfo.Base;
+ const UInt64 delta = (UInt64)((Int64)oldBase - ArcInfo.Base);
if (delta != 0)
{
FOR_VECTOR (i, items)
@@ -2864,7 +2977,7 @@ HRESULT CInArchive::ReadHeaders(CObjectVector<CItemEx> &items)
if (isZip64)
{
- if (cdInfo.ThisDisk == 0 && ecd64AbsOffset != ArcInfo.Base + locator.Ecd64Offset
+ if ((cdInfo.ThisDisk == 0 && ecd64AbsOffset != (UInt64)(ArcInfo.Base + (Int64)locator.Ecd64Offset))
// || cdInfo.NumEntries_in_ThisDisk != numCdItems
|| cdInfo.NumEntries != numCdItems
|| cdInfo.Size != cdSize
@@ -2902,10 +3015,10 @@ HRESULT CInArchive::ReadHeaders(CObjectVector<CItemEx> &items)
{
if ((unsigned)nextLocalIndex < items.Size())
{
- CItemEx &item = items[nextLocalIndex];
+ CItemEx &item = items[(unsigned)nextLocalIndex];
if (item.Disk == cdItem.Disk &&
(item.LocalHeaderPos == cdItem.LocalHeaderPos
- || Overflow32bit && (UInt32)item.LocalHeaderPos == cdItem.LocalHeaderPos))
+ || (Overflow32bit && (UInt32)item.LocalHeaderPos == cdItem.LocalHeaderPos)))
index = nextLocalIndex++;
else
nextLocalIndex = -1;
@@ -2924,7 +3037,7 @@ HRESULT CInArchive::ReadHeaders(CObjectVector<CItemEx> &items)
continue;
}
- CItemEx &item = items[index];
+ CItemEx &item = items[(unsigned)index];
if (item.Name != cdItem.Name
// || item.Name.Len() != cdItem.Name.Len()
|| item.PackSize != cdItem.PackSize
@@ -2965,7 +3078,7 @@ HRESULT CInArchive::ReadHeaders(CObjectVector<CItemEx> &items)
if (isZip64)
{
if (cdInfo.NumEntries != items.Size()
- || ecd.NumEntries != items.Size() && ecd.NumEntries != 0xFFFF)
+ || (ecd.NumEntries != items.Size() && ecd.NumEntries != 0xFFFF))
HeadersError = true;
}
else
@@ -3069,7 +3182,9 @@ HRESULT CInArchive::Open(IInStream *stream, const UInt64 *searchLimit,
else
{
// printf("\nOpen offset = %u\n", (unsigned)startPos);
- if (IsMultiVol && (unsigned)Vols.StartParsingVol < Vols.Streams.Size() && Vols.Streams[Vols.StartParsingVol].Stream)
+ if (IsMultiVol
+ && (unsigned)Vols.StartParsingVol < Vols.Streams.Size()
+ && Vols.Streams[(unsigned)Vols.StartParsingVol].Stream)
{
RINOK(SeekToVol(Vols.StartParsingVol, Vols.StreamIndex == Vols.StartVolIndex ? startPos : 0));
}
@@ -3117,7 +3232,7 @@ HRESULT CInArchive::Open(IInStream *stream, const UInt64 *searchLimit,
{
if ((unsigned)Vols.StartVolIndex < Vols.Streams.Size())
{
- Stream = Vols.Streams[Vols.StartVolIndex].Stream;
+ Stream = Vols.Streams[(unsigned)Vols.StartVolIndex].Stream;
if (Stream)
{
RINOK(Seek_SavePos(curPos));
@@ -3173,7 +3288,7 @@ HRESULT CInArchive::Open(IInStream *stream, const UInt64 *searchLimit,
{
ArcInfo.FinishPos = ArcInfo.FileEndPos;
if ((unsigned)Vols.StreamIndex < Vols.Streams.Size())
- if (GetVirtStreamPos() < Vols.Streams[Vols.StreamIndex].Size)
+ if (GetVirtStreamPos() < Vols.Streams[(unsigned)Vols.StreamIndex].Size)
ArcInfo.ThereIsTail = true;
}
else
@@ -3204,8 +3319,8 @@ HRESULT CInArchive::GetItemStream(const CItemEx &item, bool seekPackData, CMyCom
{
if (UseDisk_in_SingleVol && item.Disk != EcdVolIndex)
return S_OK;
- pos += ArcInfo.Base;
- RINOK(StreamRef->Seek(pos, STREAM_SEEK_SET, NULL));
+ pos = (UInt64)((Int64)pos + ArcInfo.Base);
+ RINOK(StreamRef->Seek((Int64)pos, STREAM_SEEK_SET, NULL));
stream = StreamRef;
return S_OK;
}
@@ -3216,10 +3331,10 @@ HRESULT CInArchive::GetItemStream(const CItemEx &item, bool seekPackData, CMyCom
IInStream *str2 = Vols.Streams[item.Disk].Stream;
if (!str2)
return S_OK;
- RINOK(str2->Seek(pos, STREAM_SEEK_SET, NULL));
+ RINOK(str2->Seek((Int64)pos, STREAM_SEEK_SET, NULL));
Vols.NeedSeek = false;
- Vols.StreamIndex = item.Disk;
+ Vols.StreamIndex = (int)item.Disk;
CVolStream *volsStreamSpec = new CVolStream;
volsStreamSpec->Vols = &Vols;
diff --git a/CPP/7zip/Archive/Zip/ZipIn.h b/CPP/7zip/Archive/Zip/ZipIn.h
index f46f1f07..31e524b6 100644
--- a/CPP/7zip/Archive/Zip/ZipIn.h
+++ b/CPP/7zip/Archive/Zip/ZipIn.h
@@ -32,6 +32,11 @@ public:
{ return LocalFullHeaderSize + GetPackSizeWithDescriptor(); }
UInt64 GetDataPosition() const
{ return LocalHeaderPos + LocalFullHeaderSize; }
+
+ bool IsBadDescriptor() const
+ {
+ return !FromCentral && FromLocal && HasDescriptor() && !DescriptorWasRead;
+ }
};
@@ -282,6 +287,7 @@ class CInArchive
HRESULT SeekToVol(int volIndex, UInt64 offset);
HRESULT ReadFromCache(Byte *data, unsigned size, unsigned &processed);
+ HRESULT ReadFromCache_FALSE(Byte *data, unsigned size);
HRESULT ReadVols2(IArchiveOpenVolumeCallback *volCallback,
unsigned start, int lastDisk, int zipDisk, unsigned numMissingVolsMax, unsigned &numMissingVols);
@@ -305,7 +311,7 @@ class CInArchive
bool ReadFileName(unsigned nameSize, AString &dest);
- bool ReadExtra(unsigned extraSize, CExtraBlock &extra,
+ bool ReadExtra(const CLocalItem &item, unsigned extraSize, CExtraBlock &extra,
UInt64 &unpackSize, UInt64 &packSize, UInt64 &localOffset, UInt32 &disk);
bool ReadLocalItem(CItemEx &item);
HRESULT FindDescriptor(CItemEx &item, unsigned numFiles);
@@ -325,6 +331,9 @@ public:
bool IsArc;
bool IsZip64;
+
+ bool IsApk;
+ bool IsCdUnsorted;
bool HeadersError;
bool HeadersWarning;
@@ -345,14 +354,19 @@ public:
CVols Vols;
- CInArchive(): Stream(NULL), StartStream(NULL), Callback(NULL), IsArcOpen(false) {}
+ CInArchive():
+ IsArcOpen(false),
+ Stream(NULL),
+ StartStream(NULL),
+ Callback(NULL)
+ {}
UInt64 GetPhySize() const
{
if (IsMultiVol)
return ArcInfo.FinishPos;
else
- return ArcInfo.FinishPos - ArcInfo.Base;
+ return (UInt64)((Int64)ArcInfo.FinishPos - ArcInfo.Base);
}
UInt64 GetOffset() const
@@ -360,7 +374,7 @@ public:
if (IsMultiVol)
return 0;
else
- return ArcInfo.Base;
+ return (UInt64)ArcInfo.Base;
}
@@ -393,7 +407,7 @@ public:
return ArcInfo.FirstItemRelatOffset;
if (IsMultiVol)
return 0;
- return ArcInfo.MarkerPos2 - ArcInfo.Base;
+ return (UInt64)((Int64)ArcInfo.MarkerPos2 - ArcInfo.Base);
}
@@ -412,7 +426,9 @@ public:
|| ArcInfo.Base < 0
|| (Int64)ArcInfo.MarkerPos2 < ArcInfo.Base
|| ArcInfo.ThereIsTail
- || GetEmbeddedStubSize() != 0)
+ || GetEmbeddedStubSize() != 0
+ || IsApk
+ || IsCdUnsorted)
return false;
// 7-zip probably can update archives with embedded stubs.
diff --git a/CPP/7zip/Archive/Zip/ZipItem.cpp b/CPP/7zip/Archive/Zip/ZipItem.cpp
index 5cff1735..38921dce 100644
--- a/CPP/7zip/Archive/Zip/ZipItem.cpp
+++ b/CPP/7zip/Archive/Zip/ZipItem.cpp
@@ -33,9 +33,12 @@ static const CUInt32PCharPair g_ExtraTypes[] =
{ NExtraID::kStrongEncrypt, "StrongCrypto" },
{ NExtraID::kUnixTime, "UT" },
{ NExtraID::kUnixExtra, "UX" },
+ { NExtraID::kUnix2Extra, "Ux" },
+ { NExtraID::kUnix3Extra, "ux" },
{ NExtraID::kIzUnicodeComment, "uc" },
{ NExtraID::kIzUnicodeName, "up" },
- { NExtraID::kWzAES, "WzAES" }
+ { NExtraID::kWzAES, "WzAES" },
+ { NExtraID::kApkAlign, "ApkAlign" }
};
void CExtraSubBlock::PrintInfo(AString &s) const
@@ -46,6 +49,22 @@ void CExtraSubBlock::PrintInfo(AString &s) const
if (pair.Value == ID)
{
s += pair.Name;
+ /*
+ if (ID == NExtraID::kApkAlign && Data.Size() >= 2)
+ {
+ char sz[32];
+ sz[0] = ':';
+ ConvertUInt32ToHex(GetUi16(Data), sz + 1);
+ s += sz;
+ for (unsigned j = 2; j < Data.Size(); j++)
+ {
+ char sz[32];
+ sz[0] = '-';
+ ConvertUInt32ToHex(Data[j], sz + 1);
+ s += sz;
+ }
+ }
+ */
return;
}
}
@@ -209,6 +228,7 @@ bool CLocalItem::IsDir() const
bool CItem::IsDir() const
{
+ // FIXME: we can check InfoZip UTF-8 name at first.
if (NItemName::HasTailSlash(Name, GetCodePage()))
return true;
@@ -315,10 +335,30 @@ bool CItem::GetPosixAttrib(UInt32 &attrib) const
return false;
}
+
+bool CExtraSubBlock::CheckIzUnicode(const AString &s) const
+{
+ size_t size = Data.Size();
+ if (size < 1 + 4)
+ return false;
+ const Byte *p = (const Byte *)Data;
+ if (p[0] > 1)
+ return false;
+ if (CrcCalc(s, s.Len()) != GetUi32(p + 1))
+ return false;
+ size -= 5;
+ p += 5;
+ for (size_t i = 0; i < size; i++)
+ if (p[i] == 0)
+ return false;
+ return Check_UTF8_Buf((const char *)(const void *)p, size, false);
+}
+
+
void CItem::GetUnicodeString(UString &res, const AString &s, bool isComment, bool useSpecifiedCodePage, UINT codePage) const
{
bool isUtf8 = IsUtf8();
- bool ignore_Utf8_Errors = true;
+ // bool ignore_Utf8_Errors = true;
if (!isUtf8)
{
@@ -333,10 +373,14 @@ void CItem::GetUnicodeString(UString &res, const AString &s, bool isComment, boo
const CExtraSubBlock &sb = subBlocks[i];
if (sb.ID == id)
{
- AString utf;
- if (sb.ExtractIzUnicode(CrcCalc(s, s.Len()), utf))
- if (ConvertUTF8ToUnicode(utf, res))
+ if (sb.CheckIzUnicode(s))
+ {
+ // const unsigned kIzUnicodeHeaderSize = 5;
+ if (Convert_UTF8_Buf_To_Unicode(
+ (const char *)(const void *)(const Byte *)sb.Data + 5,
+ sb.Data.Size() - 5, res))
return;
+ }
break;
}
}
@@ -351,15 +395,21 @@ void CItem::GetUnicodeString(UString &res, const AString &s, bool isComment, boo
We try to get name as UTF-8.
Do we need to do it in POSIX version also? */
isUtf8 = true;
- ignore_Utf8_Errors = false;
+
+ /* 21.02: we want to ignore UTF-8 errors to support file paths that are mixed
+ of UTF-8 and non-UTF-8 characters. */
+ // ignore_Utf8_Errors = false;
+ // ignore_Utf8_Errors = true;
}
#endif
}
if (isUtf8)
- if (ConvertUTF8ToUnicode(s, res) || ignore_Utf8_Errors)
- return;
+ {
+ ConvertUTF8ToUnicode(s, res);
+ return;
+ }
MultiByteToUnicodeString2(res, s, useSpecifiedCodePage ? codePage : GetCodePage());
}
diff --git a/CPP/7zip/Archive/Zip/ZipItem.h b/CPP/7zip/Archive/Zip/ZipItem.h
index e5769711..6ee87658 100644
--- a/CPP/7zip/Archive/Zip/ZipItem.h
+++ b/CPP/7zip/Archive/Zip/ZipItem.h
@@ -33,23 +33,8 @@ struct CExtraSubBlock
bool ExtractNtfsTime(unsigned index, FILETIME &ft) const;
bool ExtractUnixTime(bool isCentral, unsigned index, UInt32 &res) const;
bool ExtractUnixExtraTime(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);
- }
+
+ bool CheckIzUnicode(const AString &s) const;
void PrintInfo(AString &s) const;
};
@@ -202,8 +187,14 @@ struct CExtraBlock
for (unsigned i = SubBlocks.Size(); i != 0;)
{
i--;
- if (SubBlocks[i].ID != NFileHeader::NExtraID::kWzAES)
- SubBlocks.Delete(i);
+ switch (SubBlocks[i].ID)
+ {
+ case NFileHeader::NExtraID::kStrongEncrypt:
+ case NFileHeader::NExtraID::kWzAES:
+ break;
+ default:
+ SubBlocks.Delete(i);
+ }
}
}
};
@@ -266,9 +257,9 @@ private:
void SetFlag(unsigned bitMask, bool enable)
{
if (enable)
- Flags |= bitMask;
+ Flags = (UInt16)(Flags | bitMask);
else
- Flags &= ~bitMask;
+ Flags = (UInt16)(Flags & ~bitMask);
}
public:
@@ -279,7 +270,12 @@ public:
// void SetFlag_AltStream(bool isAltStream) { SetFlag(NFileHeader::NFlags::kAltStream, isAltStream); }
void SetDescriptorMode(bool useDescriptor) { SetFlag(NFileHeader::NFlags::kDescriptorUsedMask, useDescriptor); }
- UINT GetCodePage() const { return CP_OEMCP; }
+ UINT GetCodePage() const
+ {
+ if (IsUtf8())
+ return CP_UTF8;
+ return CP_OEMCP;
+ }
};
@@ -330,10 +326,19 @@ public:
}
return (Crc != 0 || !IsDir());
}
+
+ bool Is_MadeBy_Unix() const
+ {
+ if (!FromCentral)
+ return false;
+ return (MadeByVersion.HostOS == NFileHeader::NHostOS::kUnix);
+ }
UINT GetCodePage() const
{
// 18.06: now we use HostOS only from Central::MadeByVersion
+ if (IsUtf8())
+ return CP_UTF8;
if (!FromCentral)
return CP_OEMCP;
Byte hostOS = MadeByVersion.HostOS;
diff --git a/CPP/7zip/Archive/Zip/ZipOut.cpp b/CPP/7zip/Archive/Zip/ZipOut.cpp
index 945bd020..efed0a41 100644
--- a/CPP/7zip/Archive/Zip/ZipOut.cpp
+++ b/CPP/7zip/Archive/Zip/ZipOut.cpp
@@ -2,6 +2,8 @@
#include "StdAfx.h"
+#include "../../../../C/7zCrc.h"
+
#include "../../Common/OffsetStream.h"
#include "ZipOut.h"
@@ -23,7 +25,7 @@ HRESULT COutArchive::Create(IOutStream *outStream)
void COutArchive::SeekToCurPos()
{
- HRESULT res = m_Stream->Seek(m_Base + m_CurPos, STREAM_SEEK_SET, NULL);
+ HRESULT res = m_Stream->Seek((Int64)(m_Base + m_CurPos), STREAM_SEEK_SET, NULL);
if (res != S_OK)
throw CSystemException(res);
}
@@ -97,6 +99,17 @@ void COutArchive::WriteCommonItemInfo(const CLocalItem &item, bool isZip64)
#define WRITE_32_VAL_SPEC(__v, __isZip64) Write32((__isZip64) ? 0xFFFFFFFF : (UInt32)(__v));
+void COutArchive::WriteUtfName(const CItemOut &item)
+{
+ if (item.Name_Utf.Size() == 0)
+ return;
+ Write16(NFileHeader::NExtraID::kIzUnicodeName);
+ Write16((UInt16)(5 + item.Name_Utf.Size()));
+ Write8(1); // (1 = version) of that extra field
+ Write32(CrcCalc(item.Name.Ptr(), item.Name.Len()));
+ WriteBytes(item.Name_Utf, (UInt16)item.Name_Utf.Size());
+}
+
void COutArchive::WriteLocalHeader(CItemOut &item, bool needCheck)
{
m_LocalHeaderPos = m_CurPos;
@@ -109,7 +122,10 @@ void COutArchive::WriteLocalHeader(CItemOut &item, bool needCheck)
if (needCheck && m_IsZip64)
isZip64 = true;
- const UInt32 localExtraSize = (UInt32)((isZip64 ? (4 + 8 + 8): 0) + item.LocalExtra.GetSize());
+ const UInt32 localExtraSize = (UInt32)(
+ (isZip64 ? (4 + 8 + 8): 0)
+ + item.Get_UtfName_ExtraSize()
+ + item.LocalExtra.GetSize());
if ((UInt16)localExtraSize != localExtraSize)
throw CSystemException(E_FAIL);
if (needCheck && m_ExtraSize != localExtraSize)
@@ -152,6 +168,8 @@ void COutArchive::WriteLocalHeader(CItemOut &item, bool needCheck)
Write64(packSize);
}
+ WriteUtfName(item);
+
WriteExtra(item.LocalExtra);
// Why don't we write NTFS timestamps to local header?
@@ -230,14 +248,19 @@ void COutArchive::WriteCentralHeader(const CItemOut &item)
Write16((UInt16)item.Name.Len());
- UInt16 zip64ExtraSize = (UInt16)((isUnPack64 ? 8: 0) + (isPack64 ? 8: 0) + (isPosition64 ? 8: 0));
+ const UInt16 zip64ExtraSize = (UInt16)((isUnPack64 ? 8: 0) + (isPack64 ? 8: 0) + (isPosition64 ? 8: 0));
const UInt16 kNtfsExtraSize = 4 + 2 + 2 + (3 * 8);
- const UInt16 centralExtraSize = (UInt16)(
- (isZip64 ? 4 + zip64ExtraSize : 0) +
- (item.NtfsTimeIsDefined ? 4 + kNtfsExtraSize : 0) +
- item.CentralExtra.GetSize());
+ const size_t centralExtraSize =
+ (isZip64 ? 4 + zip64ExtraSize : 0)
+ + (item.NtfsTimeIsDefined ? 4 + kNtfsExtraSize : 0)
+ + item.Get_UtfName_ExtraSize()
+ + item.CentralExtra.GetSize();
+
+ const UInt16 centralExtraSize16 = (UInt16)centralExtraSize;
+ if (centralExtraSize16 != centralExtraSize)
+ throw CSystemException(E_FAIL);
- Write16(centralExtraSize); // test it;
+ Write16(centralExtraSize16);
const UInt16 commentSize = (UInt16)item.Comment.Size();
@@ -271,6 +294,8 @@ void COutArchive::WriteCentralHeader(const CItemOut &item)
WriteNtfsTime(item.Ntfs_ATime);
WriteNtfsTime(item.Ntfs_CTime);
}
+
+ WriteUtfName(item);
WriteExtra(item.CentralExtra);
if (commentSize != 0)
diff --git a/CPP/7zip/Archive/Zip/ZipOut.h b/CPP/7zip/Archive/Zip/ZipOut.h
index 0a0ac0c8..3546411c 100644
--- a/CPP/7zip/Archive/Zip/ZipOut.h
+++ b/CPP/7zip/Archive/Zip/ZipOut.h
@@ -21,6 +21,16 @@ public:
bool NtfsTimeIsDefined;
// It's possible that NtfsTime is not defined, but there is NtfsTime in Extra.
+
+ CByteBuffer Name_Utf; // for Info-Zip (kIzUnicodeName) Extra
+
+ size_t Get_UtfName_ExtraSize() const
+ {
+ const size_t size = Name_Utf.Size();
+ if (size == 0)
+ return 0;
+ return 4 + 5 + size;
+ }
CItemOut(): NtfsTimeIsDefined(false) {}
};
@@ -52,6 +62,7 @@ class COutArchive
Write32(ft.dwHighDateTime);
}
+ void WriteUtfName(const CItemOut &item);
void WriteExtra(const CExtraBlock &extra);
void WriteCommonItemInfo(const CLocalItem &item, bool isZip64);
void WriteCentralHeader(const CItemOut &item);
diff --git a/CPP/7zip/Archive/Zip/ZipUpdate.cpp b/CPP/7zip/Archive/Zip/ZipUpdate.cpp
index e65c2b8b..4468c7c5 100644
--- a/CPP/7zip/Archive/Zip/ZipUpdate.cpp
+++ b/CPP/7zip/Archive/Zip/ZipUpdate.cpp
@@ -62,6 +62,21 @@ static void AddAesExtra(CItem &item, Byte aesKeyMode, UInt16 method)
}
+static void Copy_From_UpdateItem_To_ItemOut(const CUpdateItem &ui, CItemOut &item)
+{
+ item.Name = ui.Name;
+ item.Name_Utf = ui.Name_Utf;
+ item.Comment = ui.Comment;
+ item.SetUtf8(ui.IsUtf8);
+ // item.SetFlag_AltStream(ui.IsAltStream);
+ // item.ExternalAttrib = ui.Attrib;
+ item.Time = ui.Time;
+ item.Ntfs_MTime = ui.Ntfs_MTime;
+ item.Ntfs_ATime = ui.Ntfs_ATime;
+ item.Ntfs_CTime = ui.Ntfs_CTime;
+ item.NtfsTimeIsDefined = ui.NtfsTimeIsDefined;
+}
+
static void SetFileHeader(
const CCompressionMethodMode &options,
const CUpdateItem &ui,
@@ -69,22 +84,15 @@ static void SetFileHeader(
CItemOut &item)
{
item.Size = ui.Size;
- bool isDir = ui.IsDir;
+ const bool isDir = ui.IsDir;
item.ClearFlags();
if (ui.NewProps)
{
- item.Name = ui.Name;
- item.Comment = ui.Comment;
- item.SetUtf8(ui.IsUtf8);
+ Copy_From_UpdateItem_To_ItemOut(ui, item);
// item.SetFlag_AltStream(ui.IsAltStream);
item.ExternalAttrib = ui.Attrib;
- item.Time = ui.Time;
- item.Ntfs_MTime = ui.Ntfs_MTime;
- item.Ntfs_ATime = ui.Ntfs_ATime;
- item.Ntfs_CTime = ui.Ntfs_CTime;
- item.NtfsTimeIsDefined = ui.NtfsTimeIsDefined;
}
/*
else
@@ -148,6 +156,35 @@ static void SetItemInfoFromCompressingResult(const CCompressingResult &compressi
#ifndef _7ZIP_ST
+struct CMtSem
+{
+ NWindows::NSynchronization::CSemaphore Semaphore;
+ NWindows::NSynchronization::CCriticalSection CS;
+ CIntVector Indexes;
+ int Head;
+
+ void ReleaseItem(unsigned index)
+ {
+ {
+ CCriticalSectionLock lock(CS);
+ Indexes[index] = Head;
+ Head = (int)index;
+ }
+ Semaphore.Release();
+ }
+
+ int GetFreeItem()
+ {
+ int i;
+ {
+ CCriticalSectionLock lock(CS);
+ i = Head;
+ Head = Indexes[(unsigned)i];
+ }
+ return i;
+ }
+};
+
static THREAD_FUNC_DECL CoderThread(void *threadCoderInfo);
struct CThreadInfo
@@ -156,7 +193,9 @@ struct CThreadInfo
NWindows::CThread Thread;
NWindows::NSynchronization::CAutoResetEvent CompressEvent;
- NWindows::NSynchronization::CAutoResetEvent CompressionCompletedEvent;
+ CMtSem *MtSem;
+ unsigned ThreadIndex;
+
bool ExitThread;
CMtCompressProgress *ProgressSpec;
@@ -177,34 +216,43 @@ struct CThreadInfo
UInt32 FileTime;
UInt64 ExpectedDataSize;
- CThreadInfo(const CCompressionMethodMode &options):
+ CThreadInfo():
ExitThread(false),
- ProgressSpec(0),
- OutStreamSpec(0),
- Coder(options),
+ ProgressSpec(NULL),
+ OutStreamSpec(NULL),
InSeqMode(false),
OutSeqMode(false),
FileTime(0),
ExpectedDataSize((UInt64)(Int64)-1)
{}
+
+ void SetOptions(const CCompressionMethodMode &options)
+ {
+ Coder.SetOptions(options);
+ }
HRESULT CreateEvents()
{
- RINOK(CompressEvent.CreateIfNotCreated());
- return CompressionCompletedEvent.CreateIfNotCreated();
+ WRes wres = CompressEvent.CreateIfNotCreated_Reset();
+ return HRESULT_FROM_WIN32(wres);
+ }
+
+ HRESULT CreateThread()
+ {
+ WRes wres = Thread.Create(CoderThread, this);
+ return HRESULT_FROM_WIN32(wres);
}
- HRes CreateThread() { return Thread.Create(CoderThread, this); }
void WaitAndCode();
- void StopWaitClose()
+
+ void StopWait_Close()
{
ExitThread = true;
- if (OutStreamSpec != 0)
+ if (OutStreamSpec)
OutStreamSpec->StopWriting(E_ABORT);
if (CompressEvent.IsCreated())
CompressEvent.Set();
- Thread.Wait();
- Thread.Close();
+ Thread.Wait_Close();
}
};
@@ -215,7 +263,7 @@ void CThreadInfo::WaitAndCode()
CompressEvent.Lock();
if (ExitThread)
return;
-
+
Result = Coder.Compress(
EXTERNAL_CODECS_LOC_VARS
InStream, OutStream,
@@ -224,7 +272,8 @@ void CThreadInfo::WaitAndCode()
if (Result == S_OK && Progress)
Result = Progress->SetRatioInfo(&CompressingResult.UnpackSize, &CompressingResult.PackSize);
- CompressionCompletedEvent.Set();
+
+ MtSem->ReleaseItem(ThreadIndex);
}
}
@@ -241,7 +290,7 @@ public:
~CThreads()
{
FOR_VECTOR (i, Threads)
- Threads[i].StopWaitClose();
+ Threads[i].StopWait_Close();
}
};
@@ -253,7 +302,8 @@ struct CMemBlocks2: public CMemLockBlocks
bool Finished;
CCompressingResult CompressingResult;
- CMemBlocks2(): Skip(false), InSeqMode(false), PreDescriptorMode(false), Finished(false) {}
+ CMemBlocks2(): Skip(false), InSeqMode(false), PreDescriptorMode(false), Finished(false),
+ CompressingResult() {}
};
class CMemRefs
@@ -359,7 +409,6 @@ STDMETHODIMP CMtProgressMixer::SetRatioInfo(const UInt64 *inSize, const UInt64 *
#endif
-
static HRESULT UpdateItemOldData(
COutArchive &archive,
CInArchive *inArchive,
@@ -385,21 +434,11 @@ static HRESULT UpdateItemOldData(
if (item.HasDescriptor())
return E_NOTIMPL;
- // use old name size.
-
// we keep ExternalAttrib and some another properties from old archive
// item.ExternalAttrib = ui.Attrib;
-
// if we don't change Comment, we keep Comment from OldProperties
- item.Comment = ui.Comment;
- item.Name = ui.Name;
- item.SetUtf8(ui.IsUtf8);
+ Copy_From_UpdateItem_To_ItemOut(ui, item);
// item.SetFlag_AltStream(ui.IsAltStream);
- item.Time = ui.Time;
- item.Ntfs_MTime = ui.Ntfs_MTime;
- item.Ntfs_ATime = ui.Ntfs_ATime;
- item.Ntfs_CTime = ui.Ntfs_CTime;
- item.NtfsTimeIsDefined = ui.NtfsTimeIsDefined;
item.CentralExtra.RemoveUnknownSubBlocks();
item.LocalExtra.RemoveUnknownSubBlocks();
@@ -452,16 +491,16 @@ static void UpdatePropsFromStream(CUpdateItem &item, ISequentialInStream *fileIn
FILETIME cTime, aTime, mTime;
UInt64 size;
- // UInt32 attrib;
- if (getProps->GetProps(&size, &cTime, &aTime, &mTime, NULL) != S_OK)
+ UInt32 attrib;
+ if (getProps->GetProps(&size, &cTime, &aTime, &mTime, &attrib) != S_OK)
return;
if (size != item.Size && size != (UInt64)(Int64)-1)
{
- Int64 newComplexity = totalComplexity + ((Int64)size - (Int64)item.Size);
+ const Int64 newComplexity = (Int64)totalComplexity + ((Int64)size - (Int64)item.Size);
if (newComplexity > 0)
{
- totalComplexity = newComplexity;
+ totalComplexity = (UInt64)newComplexity;
updateCallback->SetTotal(totalComplexity);
}
item.Size = size;
@@ -481,7 +520,7 @@ static void UpdatePropsFromStream(CUpdateItem &item, ISequentialInStream *fileIn
if (!IsZero_FILETIME(cTime)) item.Ntfs_CTime = cTime;
if (!IsZero_FILETIME(aTime)) item.Ntfs_ATime = aTime;
- // item.Attrib = attrib;
+ item.Attrib = attrib;
}
@@ -501,7 +540,8 @@ static HRESULT Update2St(
CMyComPtr<ICompressProgressInfo> progress = lps;
lps->Init(updateCallback, true);
- CAddCommon compressor(*options);
+ CAddCommon compressor;
+ compressor.SetOptions(*options);
CObjectVector<CItemOut> items;
UInt64 unpackSizeTotal = 0, packSizeTotal = 0;
@@ -519,7 +559,7 @@ static HRESULT Update2St(
{
// Note: for (ui.NewProps && !ui.NewData) it copies Props from old archive,
// But we will rewrite all important properties later. But we can keep some properties like Comment
- itemEx = inputItems[ui.IndexInArc];
+ itemEx = inputItems[(unsigned)ui.IndexInArc];
if (inArchive->ReadLocalItemAfterCdItemFull(itemEx) != S_OK)
return E_NOTIMPL;
(CItem &)item = itemEx;
@@ -659,7 +699,7 @@ static HRESULT Update2(
}
else
{
- CItemEx inputItem = inputItems[ui.IndexInArc];
+ CItemEx inputItem = inputItems[(unsigned)ui.IndexInArc];
if (inArchive->ReadLocalItemAfterCdItemFull(inputItem) != S_OK)
return E_NOTIMPL;
complexity += inputItem.GetLocalFullSize();
@@ -686,7 +726,8 @@ static HRESULT Update2(
options2._methods.AddNew();
}
- CAddCommon compressor(options2);
+ CAddCommon compressor;
+ compressor.SetOptions(options2);
complexity = 0;
@@ -715,15 +756,24 @@ static HRESULT Update2(
UInt32 numThreads = options._numThreads;
- const UInt32 kNumMaxThreads = 64;
- if (numThreads > kNumMaxThreads)
- numThreads = kNumMaxThreads;
- if (numThreads > MAXIMUM_WAIT_OBJECTS) // is 64 in Windows (is it 64 in all versions?)
+ {
+ const UInt32 kNumMaxThreads =
+ #ifdef _WIN32
+ 64; // _WIN32 supports only 64 threads in one group. So no need for more threads here
+ #else
+ 128;
+ #endif
+ if (numThreads > kNumMaxThreads)
+ numThreads = kNumMaxThreads;
+ }
+ /*
+ if (numThreads > MAXIMUM_WAIT_OBJECTS) // is 64 in Windows
numThreads = MAXIMUM_WAIT_OBJECTS;
+ */
if (numThreads < 1)
numThreads = 1;
- const size_t kMemPerThread = (1 << 25);
+ const size_t kMemPerThread = (size_t)1 << 25;
const size_t kBlockSize = 1 << 16;
bool mtMode = (numThreads > 1);
@@ -731,6 +781,8 @@ static HRESULT Update2(
if (numFilesToCompress <= 1)
mtMode = false;
+ // mtMode = true; // debug: to test mtMode
+
if (!mtMode)
{
FOR_VECTOR (mi, options2._methods)
@@ -788,7 +840,7 @@ static HRESULT Update2(
if (t > numThreads)
t = numThreads;
oneMethodMain->AddProp_NumThreads(t);
- numXzThreads = t;
+ numXzThreads = (int)t;
}
numThreads /= (unsigned)numXzThreads;
}
@@ -830,8 +882,16 @@ static HRESULT Update2(
CMemBlockManagerMt memManager(kBlockSize);
CMemRefs refs(&memManager);
+ CMtSem mtSem;
CThreads threads;
- CRecordVector<HANDLE> compressingCompletedEvents;
+ mtSem.Head = -1;
+ mtSem.Indexes.ClearAndSetSize(numThreads);
+ {
+ WRes wres = mtSem.Semaphore.Create(0, numThreads);
+ if (wres != 0)
+ return HRESULT_FROM_WIN32(wres);
+ }
+
CUIntVector threadIndices; // list threads in order of updateItems
{
@@ -840,26 +900,32 @@ static HRESULT Update2(
refs.Refs.Add(CMemBlocks2());
for (i = 0; i < numThreads; i++)
- threads.Threads.Add(CThreadInfo(options2));
+ {
+ threads.Threads.AddNew();
+ // mtSem.Indexes[i] = -1; // actually we don't use these values
+ }
for (i = 0; i < numThreads; i++)
{
CThreadInfo &threadInfo = threads.Threads[i];
+ threadInfo.SetOptions(options2); ;
#ifdef EXTERNAL_CODECS
threadInfo.__externalCodecs = __externalCodecs;
#endif
RINOK(threadInfo.CreateEvents());
threadInfo.OutStreamSpec = new COutMemStream(&memManager);
- RINOK(threadInfo.OutStreamSpec->CreateEvents());
+ RINOK(threadInfo.OutStreamSpec->CreateEvents(SYNC_WFMO(&memManager.Synchro)));
threadInfo.OutStream = threadInfo.OutStreamSpec;
threadInfo.IsFree = true;
threadInfo.ProgressSpec = new CMtCompressProgress();
threadInfo.Progress = threadInfo.ProgressSpec;
- threadInfo.ProgressSpec->Init(&mtCompressProgressMixer, (int)i);
+ threadInfo.ProgressSpec->Init(&mtCompressProgressMixer, i);
threadInfo.InSeqMode = false;
threadInfo.OutSeqMode = false;
threadInfo.FileTime = 0;
threadInfo.ExpectedDataSize = (UInt64)(Int64)-1;
+ threadInfo.ThreadIndex = i;
+ threadInfo.MtSem = &mtSem;
RINOK(threadInfo.CreateThread());
}
}
@@ -890,7 +956,7 @@ static HRESULT Update2(
}
else
{
- itemEx = inputItems[ui.IndexInArc];
+ itemEx = inputItems[(unsigned)ui.IndexInArc];
if (inArchive->ReadLocalItemAfterCdItemFull(itemEx) != S_OK)
return E_NOTIMPL;
(CItem &)item = itemEx;
@@ -958,10 +1024,9 @@ static HRESULT Update2(
threadInfo.OutSeqMode = outSeqMode;
threadInfo.FileTime = ui.Time; // FileTime is used for ZipCrypto only in seqMode
threadInfo.ExpectedDataSize = ui.Size;
-
+
threadInfo.CompressEvent.Set();
- compressingCompletedEvents.Add(threadInfo.CompressionCompletedEvent);
threadIndices.Add(k);
}
}
@@ -982,7 +1047,7 @@ static HRESULT Update2(
if (!ui.NewProps || !ui.NewData)
{
- itemEx = inputItems[ui.IndexInArc];
+ itemEx = inputItems[(unsigned)ui.IndexInArc];
if (inArchive->ReadLocalItemAfterCdItemFull(itemEx) != S_OK)
return E_NOTIMPL;
(CItem &)item = itemEx;
@@ -1004,7 +1069,7 @@ static HRESULT Update2(
if (memRef.Finished)
{
if (lastRealStreamItemIndex < (int)itemIndex)
- lastRealStreamItemIndex = itemIndex;
+ lastRealStreamItemIndex = (int)itemIndex;
SetFileHeader(options, ui, memRef.CompressingResult.DescriptorMode, item);
@@ -1030,7 +1095,7 @@ static HRESULT Update2(
{
// LocalHeader was not written for current itemIndex still
- lastRealStreamItemIndex = itemIndex;
+ lastRealStreamItemIndex = (int)itemIndex;
// thread was started before for that item already, and memRef.SeqMode was set
@@ -1060,24 +1125,30 @@ static HRESULT Update2(
}
}
- DWORD result = ::WaitForMultipleObjects(compressingCompletedEvents.Size(),
- &compressingCompletedEvents.Front(), FALSE, INFINITE);
- if (result == WAIT_FAILED)
- {
- DWORD lastError = GetLastError();
- return lastError != 0 ? lastError : E_FAIL;
- }
-
- unsigned t = (unsigned)(result - WAIT_OBJECT_0);
- if (t >= compressingCompletedEvents.Size())
+ WRes wres = mtSem.Semaphore.Lock();
+ if (wres != 0)
+ return HRESULT_FROM_WIN32(wres);
+
+ int ti = mtSem.GetFreeItem();
+ if (ti < 0)
return E_FAIL;
- CThreadInfo &threadInfo = threads.Threads[threadIndices[t]];
+ CThreadInfo &threadInfo = threads.Threads[(unsigned)ti];
threadInfo.InStream.Release();
threadInfo.IsFree = true;
RINOK(threadInfo.Result);
+
+ unsigned t = 0;
+
+ for (;;)
+ {
+ if (t == threadIndices.Size())
+ return E_FAIL;
+ if (threadIndices[t] == (unsigned)ti)
+ break;
+ t++;
+ }
threadIndices.Delete(t);
- compressingCompletedEvents.Delete(t);
if (t == 0)
{
@@ -1187,7 +1258,7 @@ HRESULT CCacheOutStream::Init(ISequentialOutStream *seqStream, IOutStream *strea
{
RINOK(_stream->Seek(0, STREAM_SEEK_CUR, &_virtPos));
RINOK(_stream->Seek(0, STREAM_SEEK_END, &_virtSize));
- RINOK(_stream->Seek(_virtPos, STREAM_SEEK_SET, &_virtPos));
+ RINOK(_stream->Seek((Int64)_virtPos, STREAM_SEEK_SET, &_virtPos));
}
_phyPos = _virtPos;
_phySize = _virtSize;
@@ -1204,7 +1275,7 @@ HRESULT CCacheOutStream::MyWrite(size_t size)
{
if (!_stream)
return E_FAIL;
- RINOK(_stream->Seek(_cachedPos, STREAM_SEEK_SET, &_phyPos));
+ RINOK(_stream->Seek((Int64)_cachedPos, STREAM_SEEK_SET, &_phyPos));
}
size_t pos = (size_t)_cachedPos & kCacheMask;
size_t curSize = MyMin(kCacheSize - pos, _cachedSize);
@@ -1233,7 +1304,7 @@ CCacheOutStream::~CCacheOutStream()
if (_virtSize != _phySize)
_stream->SetSize(_virtSize);
if (_virtPos != _phyPos)
- _stream->Seek(_virtPos, STREAM_SEEK_SET, NULL);
+ _stream->Seek((Int64)_virtPos, STREAM_SEEK_SET, NULL);
}
::MidFree(_cache);
}
@@ -1332,9 +1403,9 @@ STDMETHODIMP CCacheOutStream::Seek(Int64 offset, UInt32 seekOrigin, UInt64 *newP
}
if (offset < 0)
return HRESULT_WIN32_ERROR_NEGATIVE_SEEK;
- _virtPos = offset;
+ _virtPos = (UInt64)offset;
if (newPosition)
- *newPosition = offset;
+ *newPosition = (UInt64)offset;
return S_OK;
}
@@ -1391,7 +1462,7 @@ HRESULT Update(
{
IInStream *baseStream = inArchive->GetBaseStream();
RINOK(baseStream->Seek(0, STREAM_SEEK_SET, NULL));
- RINOK(NCompress::CopyStream_ExactSize(baseStream, seqOutStream, inArchive->ArcInfo.Base, NULL));
+ RINOK(NCompress::CopyStream_ExactSize(baseStream, seqOutStream, (UInt64)inArchive->ArcInfo.Base, NULL));
}
}
@@ -1412,7 +1483,7 @@ HRESULT Update(
{
IInStream *baseStream = inArchive->GetBaseStream();
RINOK(baseStream->Seek(inArchive->ArcInfo.Base, STREAM_SEEK_SET, NULL));
- UInt64 embStubSize = inArchive->ArcInfo.MarkerPos2 - inArchive->ArcInfo.Base;
+ const UInt64 embStubSize = (UInt64)((Int64)inArchive->ArcInfo.MarkerPos2 - inArchive->ArcInfo.Base);
RINOK(NCompress::CopyStream_ExactSize(baseStream, outStream, embStubSize, NULL));
outArchive.MoveCurPos(embStubSize);
}
diff --git a/CPP/7zip/Archive/Zip/ZipUpdate.h b/CPP/7zip/Archive/Zip/ZipUpdate.h
index 8785ae60..95e72a47 100644
--- a/CPP/7zip/Archive/Zip/ZipUpdate.h
+++ b/CPP/7zip/Archive/Zip/ZipUpdate.h
@@ -34,11 +34,12 @@ struct CUpdateItem
bool IsUtf8;
// bool IsAltStream;
int IndexInArc;
- int IndexInClient;
+ unsigned IndexInClient;
UInt32 Attrib;
UInt32 Time;
UInt64 Size;
AString Name;
+ CByteBuffer Name_Utf; // for Info-Zip (kIzUnicodeName) Extra
CByteBuffer Comment;
// bool Commented;
// CUpdateRange CommentRange;
@@ -54,6 +55,7 @@ struct CUpdateItem
// IsAltStream = false;
Size = 0;
Name.Empty();
+ Name_Utf.Free();
Comment.Free();
}