This commit is contained in:
Igor Pavlov
2023-12-22 17:17:05 +00:00
committed by Kornel
parent ec44a8a070
commit a36c48cece
954 changed files with 42199 additions and 25482 deletions

View File

@@ -19,7 +19,7 @@
#include "../../Compress/CopyCoder.h"
#ifdef EXTERNAL_CODECS
#ifdef Z7_EXTERNAL_CODECS
#ifndef SUPPORT_LZFSE
#define SUPPORT_LZFSE
#endif
@@ -92,18 +92,20 @@ const char * const kMethodNames1[kNumMethodNames1] =
, "BZip2"
, NULL
, "LZMA"
/*
, NULL
, NULL
, NULL
, NULL
, NULL
, "zstd-pk"
, "zstd-pk" // deprecated
*/
};
const char * const kMethodNames2[kNumMethodNames2] =
{
"zstd-wz"
"zstd"
, "MP3"
, "xz"
, "Jpeg"
@@ -129,6 +131,7 @@ static const CUInt32PCharPair g_HeaderCharacts[] =
{
{ 0, "Encrypt" },
{ 3, "Descriptor" },
// { 4, "Enhanced" },
// { 5, "Patched" },
{ 6, kMethod_StrongCrypto },
{ 11, "UTF8" },
@@ -221,7 +224,7 @@ static AString BytesToString(const CByteBuffer &data)
IMP_IInArchive_Props
IMP_IInArchive_ArcProps
STDMETHODIMP CHandler::GetArchiveProperty(PROPID propID, PROPVARIANT *value)
Z7_COM7F_IMF(CHandler::GetArchiveProperty(PROPID propID, PROPVARIANT *value))
{
COM_TRY_BEGIN
NWindows::NCOM::CPropVariant prop;
@@ -343,7 +346,7 @@ STDMETHODIMP CHandler::GetArchiveProperty(PROPID propID, PROPVARIANT *value)
COM_TRY_END
}
STDMETHODIMP CHandler::GetNumberOfItems(UInt32 *numItems)
Z7_COM7F_IMF(CHandler::GetNumberOfItems(UInt32 *numItems))
{
*numItems = m_Items.Size();
return S_OK;
@@ -377,7 +380,7 @@ static bool NtfsUnixTimeToProp(bool fromCentral,
}
STDMETHODIMP CHandler::GetProperty(UInt32 index, PROPID propID, PROPVARIANT *value)
Z7_COM7F_IMF(CHandler::GetProperty(UInt32 index, PROPID propID, PROPVARIANT *value))
{
COM_TRY_BEGIN
NWindows::NCOM::CPropVariant prop;
@@ -521,7 +524,7 @@ STDMETHODIMP CHandler::GetProperty(UInt32 index, PROPID propID, PROPVARIANT *val
if (extra.GetWzAes(aesField))
{
m += kMethod_AES;
m += '-';
m.Add_Minus();
m.Add_UInt32(((unsigned)aesField.Strength + 1) * 64);
id = aesField.Method;
isWzAes = true;
@@ -537,7 +540,7 @@ STDMETHODIMP CHandler::GetProperty(UInt32 index, PROPID propID, PROPVARIANT *val
f.AlgId = 0;
if (extra.GetStrongCrypto(f))
{
const char *s = FindNameForId(k_StrongCryptoPairs, ARRAY_SIZE(k_StrongCryptoPairs), f.AlgId);
const char *s = FindNameForId(k_StrongCryptoPairs, Z7_ARRAY_SIZE(k_StrongCryptoPairs), f.AlgId);
if (s)
m += s;
else
@@ -629,7 +632,7 @@ STDMETHODIMP CHandler::GetProperty(UInt32 index, PROPID propID, PROPVARIANT *val
if (flags != 0)
{
AString s2 = FlagsToString(g_HeaderCharacts, ARRAY_SIZE(g_HeaderCharacts), flags);
const AString s2 = FlagsToString(g_HeaderCharacts, Z7_ARRAY_SIZE(g_HeaderCharacts), flags);
if (!s2.IsEmpty())
{
if (!s.IsEmpty())
@@ -690,13 +693,13 @@ STDMETHODIMP CHandler::GetProperty(UInt32 index, PROPID propID, PROPVARIANT *val
/*
STDMETHODIMP CHandler::GetNumRawProps(UInt32 *numProps)
Z7_COM7F_IMF(CHandler::GetNumRawProps(UInt32 *numProps)
{
*numProps = 0;
return S_OK;
}
STDMETHODIMP CHandler::GetRawPropInfo(UInt32 index, BSTR *name, PROPID *propID)
Z7_COM7F_IMF(CHandler::GetRawPropInfo(UInt32 index, BSTR *name, PROPID *propID)
{
UNUSED_VAR(index);
*propID = 0;
@@ -704,7 +707,7 @@ STDMETHODIMP CHandler::GetRawPropInfo(UInt32 index, BSTR *name, PROPID *propID)
return S_OK;
}
STDMETHODIMP CHandler::GetParent(UInt32 index, UInt32 *parent, UInt32 *parentType)
Z7_COM7F_IMF(CHandler::GetParent(UInt32 index, UInt32 *parent, UInt32 *parentType)
{
*parentType = NParentType::kDir;
*parent = (UInt32)(Int32)-1;
@@ -720,7 +723,7 @@ STDMETHODIMP CHandler::GetParent(UInt32 index, UInt32 *parent, UInt32 *parentTyp
return S_OK;
}
STDMETHODIMP CHandler::GetRawProp(UInt32 index, PROPID propID, const void **data, UInt32 *dataSize, UInt32 *propType)
Z7_COM7F_IMF(CHandler::GetRawProp(UInt32 index, PROPID propID, const void **data, UInt32 *dataSize, UInt32 *propType)
{
UNUSED_VAR(index);
UNUSED_VAR(propID);
@@ -767,13 +770,16 @@ void CHandler::MarkAltStreams(CObjectVector<CItemEx> &items)
}
*/
STDMETHODIMP CHandler::Open(IInStream *inStream,
const UInt64 *maxCheckStartPosition, IArchiveOpenCallback *callback)
Z7_COM7F_IMF(CHandler::Open(IInStream *inStream,
const UInt64 *maxCheckStartPosition, IArchiveOpenCallback *callback))
{
COM_TRY_BEGIN
try
{
Close();
m_Archive.Force_ReadLocals_Mode = _force_OpenSeq;
// m_Archive.Disable_VolsRead = _force_OpenSeq;
// m_Archive.Disable_FindMarker = _force_OpenSeq;
HRESULT res = m_Archive.Open(inStream, maxCheckStartPosition, callback, m_Items);
if (res != S_OK)
{
@@ -787,7 +793,7 @@ STDMETHODIMP CHandler::Open(IInStream *inStream,
COM_TRY_END
}
STDMETHODIMP CHandler::Close()
Z7_COM7F_IMF(CHandler::Close())
{
m_Items.Clear();
m_Archive.Close();
@@ -795,25 +801,16 @@ STDMETHODIMP CHandler::Close()
}
class CLzmaDecoder:
public ICompressCoder,
public ICompressSetFinishMode,
public ICompressGetInStreamProcessedSize,
public CMyUnknownImp
{
Z7_CLASS_IMP_NOQIB_3(
CLzmaDecoder
, ICompressCoder
, ICompressSetFinishMode
, ICompressGetInStreamProcessedSize
)
public:
NCompress::NLzma::CDecoder *DecoderSpec;
CMyComPtr<ICompressCoder> Decoder;
MY_UNKNOWN_IMP2(
ICompressSetFinishMode,
ICompressGetInStreamProcessedSize)
STDMETHOD(Code)(ISequentialInStream *inStream, ISequentialOutStream *outStream,
const UInt64 *inSize, const UInt64 *outSize, ICompressProgressInfo *progress);
STDMETHOD(SetFinishMode)(UInt32 finishMode);
STDMETHOD(GetInStreamProcessedSize)(UInt64 *value);
CLzmaDecoder();
};
@@ -825,14 +822,14 @@ CLzmaDecoder::CLzmaDecoder()
static const unsigned kZipLzmaPropsSize = 4 + LZMA_PROPS_SIZE;
HRESULT CLzmaDecoder::Code(ISequentialInStream *inStream, ISequentialOutStream *outStream,
const UInt64 *inSize, const UInt64 *outSize, ICompressProgressInfo *progress)
Z7_COM7F_IMF(CLzmaDecoder::Code(ISequentialInStream *inStream, ISequentialOutStream *outStream,
const UInt64 *inSize, const UInt64 *outSize, ICompressProgressInfo *progress))
{
Byte buf[kZipLzmaPropsSize];
RINOK(ReadStream_FALSE(inStream, buf, kZipLzmaPropsSize));
RINOK(ReadStream_FALSE(inStream, buf, kZipLzmaPropsSize))
if (buf[2] != LZMA_PROPS_SIZE || buf[3] != 0)
return E_NOTIMPL;
RINOK(DecoderSpec->SetDecoderProperties2(buf + 4, LZMA_PROPS_SIZE));
RINOK(DecoderSpec->SetDecoderProperties2(buf + 4, LZMA_PROPS_SIZE))
UInt64 inSize2 = 0;
if (inSize)
{
@@ -844,13 +841,13 @@ HRESULT CLzmaDecoder::Code(ISequentialInStream *inStream, ISequentialOutStream *
return Decoder->Code(inStream, outStream, inSize ? &inSize2 : NULL, outSize, progress);
}
STDMETHODIMP CLzmaDecoder::SetFinishMode(UInt32 finishMode)
Z7_COM7F_IMF(CLzmaDecoder::SetFinishMode(UInt32 finishMode))
{
DecoderSpec->FinishStream = (finishMode != 0);
return S_OK;
}
STDMETHODIMP CLzmaDecoder::GetInStreamProcessedSize(UInt64 *value)
Z7_COM7F_IMF(CLzmaDecoder::GetInStreamProcessedSize(UInt64 *value))
{
*value = DecoderSpec->GetInputProcessedSize() + kZipLzmaPropsSize;
return S_OK;
@@ -888,11 +885,11 @@ class CZipDecoder
CLzmaDecoder *lzmaDecoderSpec;
public:
CZipDecoder():
_zipCryptoDecoderSpec(0),
_pkAesDecoderSpec(0),
_wzAesDecoderSpec(0),
filterStreamSpec(0),
lzmaDecoderSpec(0)
_zipCryptoDecoderSpec(NULL),
_pkAesDecoderSpec(NULL),
_wzAesDecoderSpec(NULL),
filterStreamSpec(NULL),
lzmaDecoderSpec(NULL)
{}
HRESULT Decode(
@@ -901,7 +898,7 @@ public:
ISequentialOutStream *realOutStream,
IArchiveExtractCallback *extractCallback,
ICompressProgressInfo *compressProgress,
#ifndef _7ZIP_ST
#ifndef Z7_ST
UInt32 numThreads, UInt64 memUsage,
#endif
Int32 &res);
@@ -919,7 +916,7 @@ static HRESULT SkipStreamData(ISequentialInStream *stream,
for (;;)
{
size_t size = kBufSize;
RINOK(ReadStream(stream, buf, &size));
RINOK(ReadStream(stream, buf, &size))
if (size == 0)
return S_OK;
thereAreData = true;
@@ -927,25 +924,23 @@ static HRESULT SkipStreamData(ISequentialInStream *stream,
if ((packSize - prev) >= (1 << 22))
{
prev = packSize;
RINOK(progress->SetRatioInfo(&packSize, &unpackSize));
RINOK(progress->SetRatioInfo(&packSize, &unpackSize))
}
}
}
class COutStreamWithPadPKCS7:
public ISequentialOutStream,
public CMyUnknownImp
{
Z7_CLASS_IMP_NOQIB_1(
COutStreamWithPadPKCS7
, ISequentialOutStream
)
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(); }
@@ -962,7 +957,7 @@ public:
};
STDMETHODIMP COutStreamWithPadPKCS7::Write(const void *data, UInt32 size, UInt32 *processedSize)
Z7_COM7F_IMF(COutStreamWithPadPKCS7::Write(const void *data, UInt32 size, UInt32 *processedSize))
{
UInt32 written = 0;
HRESULT result = S_OK;
@@ -1003,7 +998,7 @@ HRESULT CZipDecoder::Decode(
ISequentialOutStream *realOutStream,
IArchiveExtractCallback *extractCallback,
ICompressProgressInfo *compressProgress,
#ifndef _7ZIP_ST
#ifndef Z7_ST
UInt32 numThreads, UInt64 memUsage,
#endif
Int32 &res)
@@ -1074,7 +1069,7 @@ HRESULT CZipDecoder::Decode(
return S_OK;
packSize -= NCrypto::NWzAes::kMacSize;
}
RINOK(archive.GetItemStream(item, true, packStream));
RINOK(archive.GetItemStream(item, true, packStream))
if (!packStream)
{
res = NExtract::NOperationResult::kUnavailable;
@@ -1126,7 +1121,7 @@ HRESULT CZipDecoder::Decode(
}
CMyComPtr<ICryptoSetPassword> cryptoSetPassword;
RINOK(cryptoFilter.QueryInterface(IID_ICryptoSetPassword, &cryptoSetPassword));
RINOK(cryptoFilter.QueryInterface(IID_ICryptoSetPassword, &cryptoSetPassword))
if (!cryptoSetPassword)
return E_FAIL;
@@ -1136,12 +1131,12 @@ HRESULT CZipDecoder::Decode(
if (getTextPassword)
{
CMyComBSTR_Wipe password;
RINOK(getTextPassword->CryptoGetTextPassword(&password));
RINOK(getTextPassword->CryptoGetTextPassword(&password))
AString_Wipe charPassword;
if (password)
{
/*
// 22.00: do we need UTF-8 passwords here ?
// 22.00: do we need UTF-8 passwords here ?
if (item.IsUtf8()) // 22.00
{
// throw 1;
@@ -1226,7 +1221,7 @@ HRESULT CZipDecoder::Decode(
szMethodID = kMethodId_ZipBase + (Byte)id;
}
RINOK(CreateCoder_Id(EXTERNAL_CODECS_LOC_VARS szMethodID, false, mi.Coder));
RINOK(CreateCoder_Id(EXTERNAL_CODECS_LOC_VARS szMethodID, false, mi.Coder))
if (!mi.Coder)
{
@@ -1241,13 +1236,13 @@ HRESULT CZipDecoder::Decode(
ICompressCoder *coder = mi.Coder;
#ifndef _7ZIP_ST
#ifndef Z7_ST
{
CMyComPtr<ICompressSetCoderMt> setCoderMt;
coder->QueryInterface(IID_ICompressSetCoderMt, (void **)&setCoderMt);
if (setCoderMt)
{
RINOK(setCoderMt->SetNumberOfThreads(numThreads));
RINOK(setCoderMt->SetNumberOfThreads(numThreads))
}
}
// if (memUsage != 0)
@@ -1256,7 +1251,7 @@ HRESULT CZipDecoder::Decode(
coder->QueryInterface(IID_ICompressSetMemLimit, (void **)&setMemLimit);
if (setMemLimit)
{
RINOK(setMemLimit->SetMemLimit(memUsage));
RINOK(setMemLimit->SetMemLimit(memUsage))
}
}
#endif
@@ -1267,7 +1262,7 @@ HRESULT CZipDecoder::Decode(
if (setDecoderProperties)
{
Byte properties = (Byte)item.Flags;
RINOK(setDecoderProperties->SetDecoderProperties2(&properties, 1));
RINOK(setDecoderProperties->SetDecoderProperties2(&properties, 1))
}
}
@@ -1363,7 +1358,7 @@ HRESULT CZipDecoder::Decode(
coder->QueryInterface(IID_ICompressSetFinishMode, (void **)&setFinishMode);
if (setFinishMode)
{
RINOK(setFinishMode->SetFinishMode(BoolToUInt(true)));
RINOK(setFinishMode->SetFinishMode(BoolToUInt(true)))
}
const UInt64 coderPackSize = limitedStreamSpec->GetRem();
@@ -1421,12 +1416,12 @@ HRESULT CZipDecoder::Decode(
{
readFromFilter = true;
inStreamReleaser.FilterCoder = filterStreamSpec;
RINOK(filterStreamSpec->SetInStream(inStream));
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->Init_NoSubFilterInit())
// RINOK(filterStreamSpec->SetOutStreamSize(NULL));
}
@@ -1448,7 +1443,7 @@ HRESULT CZipDecoder::Decode(
if (getInStreamProcessedSize && setFinishMode)
{
UInt64 processed;
RINOK(getInStreamProcessedSize->GetInStreamProcessedSize(&processed));
RINOK(getInStreamProcessedSize->GetInStreamProcessedSize(&processed))
if (processed != (UInt64)(Int64)-1)
{
if (pkAesMode)
@@ -1474,7 +1469,7 @@ HRESULT CZipDecoder::Decode(
UInt32 processedSize = 0;
if (readInStream)
{
RINOK(readInStream->ReadUnusedFromInBuf(buf, kBufSize, &processedSize));
RINOK(readInStream->ReadUnusedFromInBuf(buf, kBufSize, &processedSize))
}
if (processedSize > padSize)
dataAfterEnd = true;
@@ -1532,7 +1527,7 @@ HRESULT CZipDecoder::Decode(
return S_OK;
}
RINOK(result);
RINOK(result)
}
bool crcOK = true;
@@ -1600,66 +1595,59 @@ HRESULT CZipDecoder::Decode(
}
STDMETHODIMP CHandler::Extract(const UInt32 *indices, UInt32 numItems,
Int32 testMode, IArchiveExtractCallback *extractCallback)
Z7_COM7F_IMF(CHandler::Extract(const UInt32 *indices, UInt32 numItems,
Int32 testMode, IArchiveExtractCallback *extractCallback))
{
COM_TRY_BEGIN
CZipDecoder myDecoder;
UInt64 totalUnPacked = 0, totalPacked = 0;
bool allFilesMode = (numItems == (UInt32)(Int32)-1);
const bool allFilesMode = (numItems == (UInt32)(Int32)-1);
if (allFilesMode)
numItems = m_Items.Size();
if (numItems == 0)
return S_OK;
UInt64 total = 0; // , totalPacked = 0;
UInt32 i;
for (i = 0; i < numItems; i++)
{
const CItemEx &item = m_Items[allFilesMode ? i : indices[i]];
totalUnPacked += item.Size;
totalPacked += item.PackSize;
total += item.Size;
// totalPacked += item.PackSize;
}
RINOK(extractCallback->SetTotal(totalUnPacked));
RINOK(extractCallback->SetTotal(total))
UInt64 currentTotalUnPacked = 0, currentTotalPacked = 0;
UInt64 currentItemUnPacked, currentItemPacked;
CZipDecoder myDecoder;
UInt64 cur_Unpacked, cur_Packed;
CLocalProgress *lps = new CLocalProgress;
CMyComPtr<ICompressProgressInfo> progress = lps;
lps->Init(extractCallback, false);
for (i = 0; i < numItems; i++,
currentTotalUnPacked += currentItemUnPacked,
currentTotalPacked += currentItemPacked)
for (i = 0;; i++,
lps->OutSize += cur_Unpacked,
lps->InSize += cur_Packed)
{
currentItemUnPacked = 0;
currentItemPacked = 0;
RINOK(lps->SetCur())
if (i >= numItems)
return S_OK;
const UInt32 index = allFilesMode ? i : indices[i];
CItemEx item = m_Items[index];
cur_Unpacked = item.Size;
cur_Packed = item.PackSize;
lps->InSize = currentTotalPacked;
lps->OutSize = currentTotalUnPacked;
RINOK(lps->SetCur());
CMyComPtr<ISequentialOutStream> realOutStream;
Int32 askMode = testMode ?
const bool isLocalOffsetOK = m_Archive.IsLocalOffsetOK(item);
const bool skip = !isLocalOffsetOK && !item.IsDir();
const Int32 askMode = skip ?
NExtract::NAskMode::kSkip : testMode ?
NExtract::NAskMode::kTest :
NExtract::NAskMode::kExtract;
UInt32 index = allFilesMode ? i : indices[i];
CItemEx item = m_Items[index];
bool isLocalOffsetOK = m_Archive.IsLocalOffsetOK(item);
bool skip = !isLocalOffsetOK && !item.IsDir();
if (skip)
askMode = NExtract::NAskMode::kSkip;
currentItemUnPacked = item.Size;
currentItemPacked = item.PackSize;
RINOK(extractCallback->GetStream(index, &realOutStream, askMode));
CMyComPtr<ISequentialOutStream> realOutStream;
RINOK(extractCallback->GetStream(index, &realOutStream, askMode))
if (!isLocalOffsetOK)
{
RINOK(extractCallback->PrepareOperation(askMode));
RINOK(extractCallback->PrepareOperation(askMode))
realOutStream.Release();
RINOK(extractCallback->SetOperationResult(NExtract::NOperationResult::kUnavailable));
RINOK(extractCallback->SetOperationResult(NExtract::NOperationResult::kUnavailable))
continue;
}
@@ -1668,30 +1656,30 @@ STDMETHODIMP CHandler::Extract(const UInt32 *indices, UInt32 numItems,
if (!item.FromLocal)
{
bool isAvail = true;
HRESULT res = m_Archive.ReadLocalItemAfterCdItem(item, isAvail, headersError);
if (res == S_FALSE)
const HRESULT hres = m_Archive.Read_LocalItem_After_CdItem(item, isAvail, headersError);
if (hres == S_FALSE)
{
if (item.IsDir() || realOutStream || testMode)
{
RINOK(extractCallback->PrepareOperation(askMode));
RINOK(extractCallback->PrepareOperation(askMode))
realOutStream.Release();
RINOK(extractCallback->SetOperationResult(
isAvail ?
NExtract::NOperationResult::kHeadersError :
NExtract::NOperationResult::kUnavailable));
NExtract::NOperationResult::kUnavailable))
}
continue;
}
RINOK(res);
RINOK(hres)
}
if (item.IsDir())
{
// if (!testMode)
{
RINOK(extractCallback->PrepareOperation(askMode));
RINOK(extractCallback->PrepareOperation(askMode))
realOutStream.Release();
RINOK(extractCallback->SetOperationResult(NExtract::NOperationResult::kOK));
RINOK(extractCallback->SetOperationResult(NExtract::NOperationResult::kOK))
}
continue;
}
@@ -1699,19 +1687,19 @@ STDMETHODIMP CHandler::Extract(const UInt32 *indices, UInt32 numItems,
if (!testMode && !realOutStream)
continue;
RINOK(extractCallback->PrepareOperation(askMode));
RINOK(extractCallback->PrepareOperation(askMode))
Int32 res;
HRESULT hres = myDecoder.Decode(
const HRESULT hres = myDecoder.Decode(
EXTERNAL_CODECS_VARS
m_Archive, item, realOutStream, extractCallback,
progress,
#ifndef _7ZIP_ST
#ifndef Z7_ST
_props._numThreads, _props._memUsage_Decompress,
#endif
res);
RINOK(hres);
RINOK(hres)
realOutStream.Release();
if (res == NExtract::NOperationResult::kOK && headersError)
@@ -1720,9 +1708,6 @@ STDMETHODIMP CHandler::Extract(const UInt32 *indices, UInt32 numItems,
RINOK(extractCallback->SetOperationResult(res))
}
lps->InSize = currentTotalPacked;
lps->OutSize = currentTotalUnPacked;
return lps->SetCur();
COM_TRY_END
}