Update to 7-Zip Version 21.02

This commit is contained in:
Tino Reichardt
2021-05-13 16:39:14 +02:00
parent 3724ecfedc
commit 48fa49f76c
620 changed files with 35032 additions and 10925 deletions

1183
CPP/7zip/7zip_gcc.mak Normal file
View File

File diff suppressed because it is too large Load Diff

View File

@@ -1,7 +1,10 @@
C_OBJS = $(C_OBJS) \
$O\Aes.obj
!IF "$(PLATFORM)" != "ia64" && "$(PLATFORM)" != "mips" && "$(PLATFORM)" != "arm" && "$(PLATFORM)" != "arm64"
!IF defined(USE_C_AES) || "$(PLATFORM)" == "arm" || "$(PLATFORM)" == "arm64"
C_OBJS = $(C_OBJS) \
$O\AesOpt.obj
!ELSEIF "$(PLATFORM)" != "ia64" && "$(PLATFORM)" != "mips" && "$(PLATFORM)" != "arm" && "$(PLATFORM)" != "arm64"
ASM_OBJS = $(ASM_OBJS) \
$O\AesOpt.obj
!ENDIF

View File

@@ -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(); }
};
}}

View File

@@ -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];

View File

@@ -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;
}
}

View File

@@ -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;

View File

@@ -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;
}
}

View File

@@ -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));
}
@@ -650,7 +665,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;
@@ -753,7 +768,7 @@ STDMETHODIMP CHandler::GetProperty(UInt32 index, PROPID propID, PROPVARIANT *val
#endif
}
// prop.Detach(value);
// return prop.Detach(value);
return S_OK;
// COM_TRY_END
}
@@ -824,7 +839,7 @@ STDMETHODIMP CHandler::Close()
#ifndef _NO_CRYPTO
_isEncrypted = false;
_passwordIsDefined = false;
_password.Empty();
_password.Wipe_and_Empty();
#endif
return S_OK;
COM_TRY_END

View File

@@ -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

View File

@@ -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);
@@ -752,7 +778,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++];
@@ -830,7 +856,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)
{

View File

@@ -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;

View File

@@ -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;
// (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)

View File

@@ -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;

View File

@@ -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;
}

View File

@@ -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);
}
}

View File

@@ -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;

View File

@@ -31,7 +31,7 @@ struct CTreeFolder
struct CUpdateItem
{
int IndexInArchive;
int IndexInClient;
unsigned IndexInClient;
UInt64 CTime;
UInt64 ATime;

View File

@@ -240,7 +240,7 @@ STDMETHODIMP CHandler::GetArchiveProperty(PROPID propID, PROPVARIANT *value)
mainIndex = -1;
break;
}
mainIndex = i;
mainIndex = (int)i;
}
}
if (mainIndex >= 0)

View File

@@ -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,

View File

@@ -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;

View File

@@ -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;

View File

@@ -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)
}}

View File

@@ -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;

View File

@@ -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();
}

View File

@@ -100,7 +100,7 @@ struct CDatabase
int GetNumberOfNewFolders() const
{
int res = Folders.Size();
int res = (int)Folders.Size();
if (IsTherePrevFolder())
res--;
return res;

View File

@@ -56,8 +56,8 @@ struct CItem
if (ContinuedFromPrev())
return 0;
if (ContinuedToNext())
return numFolders - 1;
return FolderIndex;
return (int)numFolders - 1;
return (int)FolderIndex;
}
};

View File

@@ -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:

View File

@@ -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 += ": ";
}

View File

@@ -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;

View File

@@ -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));

View File

@@ -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(

View File

@@ -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);
}

View File

@@ -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 == '/');
}

View File

@@ -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);

View File

@@ -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;
}

View File

@@ -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;

View File

@@ -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

View File

@@ -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)

View File

@@ -22,11 +22,24 @@
#include "IArchive.h"
HINSTANCE g_hInstance;
#define NT_CHECK_FAIL_ACTION return FALSE;
#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*/);
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;

View File

@@ -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)

View File

@@ -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[] =
{

View File

@@ -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;
}

View File

@@ -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++)

View File

@@ -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;

View File

@@ -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;

View File

@@ -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);

View File

@@ -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++)

View File

@@ -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));
}
}

View File

@@ -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.
}

View File

@@ -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

View File

@@ -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;
}
}

View File

@@ -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)
{

View File

@@ -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;

View File

@@ -451,7 +451,7 @@ STDMETHODIMP CHandler::Extract(const UInt32 *indices, UInt32 numItems,
}
REGISTER_ARC_I(
"lzip", "lz tlz", "* .tar", 0xC5,
"lzip", "lz tlz", "* .tar", 0xC4,
k_Signature,
0,
NArcInfoFlags::kKeepName,

View File

@@ -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);

View File

@@ -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)

View File

@@ -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

View File

@@ -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()));

View File

@@ -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);
}

View File

@@ -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;

View File

@@ -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 + 8 * 8)
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;
}
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();

View File

@@ -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

View File

@@ -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;

View File

@@ -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
};

View File

@@ -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;
}
}

View File

@@ -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)
{
UInt64 totalBytes = (UInt64)l1Size << (_numMidBits + 3);
RINOK(openCallback->SetTotal(NULL, &totalBytes));
}
_compressedFlag = (_version <= 1) ? ((UInt64)1 << 63) : ((UInt64)1 << 62);
const UInt64 offsetMask = _compressedFlag - 1;
for (UInt32 i = 0; i < l1Size; i++)
UInt32 numTables = 0;
UInt32 i;
for (i = 0; i < l1Size; i++)
{
if (openCallback)
{
UInt64 numBytes = (UInt64)i << (_numMidBits + 3);
RINOK(openCallback->SetCompleted(NULL, &numBytes));
}
const UInt64 v = Get64((const Byte *)table + (size_t)i * 8) & offsetMask;
if (v != 0)
numTables++;
}
CByteBuffer &buf2 = _tables.AddNew();
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);
UInt32 curTable = 0;
if (openCallback)
{
const UInt64 totalBytes = (UInt64)numTables << (_numMidBits + 3);
RINOK(openCallback->SetTotal(NULL, &totalBytes));
}
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;
buf2.Alloc((size_t)1 << (_numMidBits + 3));
RINOK(stream->Seek(v, STREAM_SEEK_SET, NULL));
RINOK(ReadStream_FALSE(stream, buf2, clusterSize));
}
const UInt64 end = v + clusterSize;
_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));
}
RINOK(stream->Seek(v, STREAM_SEEK_SET, NULL));
RINOK(ReadStream_FALSE(stream, buf2, midSize));
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);
}

View File

@@ -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;

View File

@@ -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());
}

View File

@@ -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; }

View File

@@ -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();

View File

@@ -43,9 +43,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)
@@ -127,6 +127,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);
@@ -135,10 +139,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
{
@@ -1282,7 +1286,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
@@ -1349,7 +1354,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;
@@ -1361,8 +1366,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());
@@ -1526,7 +1534,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;
}
@@ -1649,11 +1657,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;
@@ -2131,9 +2142,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
@@ -2167,14 +2178,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;
}

View File

@@ -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

View File

@@ -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;
}

View File

@@ -48,6 +48,8 @@ private:
UInt32 _curCodePage;
UInt32 _openCodePage;
CEncodingCharacts _encodingCharacts;
NCompress::CCopyCoder *copyCoderSpec;
CMyComPtr<ICompressCoder> copyCoder;

View File

@@ -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
}

View File

@@ -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

View File

@@ -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)

View File

@@ -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; }
};

View File

@@ -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;

View File

@@ -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();
}

View File

@@ -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

View File

@@ -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);
}

View File

@@ -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;

View File

@@ -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++;

View File

@@ -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;

View File

@@ -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)

View File

@@ -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:
{

View File

@@ -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);

View File

@@ -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));
}

View File

@@ -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);

View File

@@ -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;
}
}

View File

@@ -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));
}

View File

@@ -89,14 +89,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);
@@ -232,6 +236,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;
@@ -264,6 +273,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)
{
@@ -316,23 +334,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;
@@ -446,15 +466,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));

View File

@@ -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,

View File

@@ -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(); }
};
}}

View File

@@ -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"
@@ -82,18 +93,24 @@ const char * const kMethodNames1[kNumMethodNames1] =
, "BZip2"
, NULL
, "LZMA"
, NULL
, NULL
, NULL
, NULL
, NULL
, "zstd-pk"
};
const char * const kMethodNames2[kNumMethodNames2] =
{
"zstd"
, NULL
, "MP3"
, "xz"
, "Jpeg"
, "WavPack"
, "PPMd"
, "WzAES"
, "LZFSE" // , "WzAES"
};
#define kMethod_AES "AES"
@@ -243,6 +260,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");
@@ -315,9 +338,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)
@@ -339,7 +361,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)
{
@@ -362,7 +386,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;
}
@@ -470,23 +494,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;
@@ -509,8 +537,9 @@ STDMETHODIMP CHandler::GetProperty(UInt32 index, PROPID propID, PROPVARIANT *val
}
else
m += kMethod_ZipCrypto;
m += ' ';
}
m.Add_Space_if_NotEmpty();
{
const char *s = NULL;
@@ -519,7 +548,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)
@@ -535,7 +564,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)
{
@@ -579,7 +608,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)
{
@@ -592,7 +621,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())
@@ -637,8 +666,7 @@ STDMETHODIMP CHandler::GetProperty(UInt32 index, PROPID propID, PROPVARIANT *val
*/
}
prop.Detach(value);
return S_OK;
return prop.Detach(value);
COM_TRY_END
}
@@ -889,11 +917,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;
@@ -901,10 +932,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,
@@ -924,9 +1025,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())
@@ -939,14 +1063,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;
@@ -986,9 +1102,6 @@ HRESULT CZipDecoder::Decode(
{
if (wzAesMode)
{
CWzAesExtra aesField;
if (!item.GetMainExtra().GetWzAes(aesField))
return S_OK;
id = aesField.Method;
if (!_wzAesDecoder)
{
@@ -1031,12 +1144,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)
{
@@ -1090,10 +1203,16 @@ HRESULT CZipDecoder::Decode(
}
else if (id ==NFileHeader::NCompressionMethod::kZstd)
mi.Coder = new CZstdDecoder();
else if (id ==NFileHeader::NCompressionMethod::kZstdPk)
mi.Coder = new CZstdDecoder();
else if (id == NFileHeader::NCompressionMethod::kXz)
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;
@@ -1120,7 +1239,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
@@ -1154,14 +1274,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;
@@ -1229,23 +1357,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)
{
@@ -1253,26 +1365,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
);
result = coder->Code(inStreamNew, outStream,
isFullStreamExpected ? &coderPackSize : NULL,
// NULL,
useUnpackLimit ? &item.Size : NULL,
compressProgress);
if (result == S_OK)
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 = filterStreamSpec->Code(inStream, padStream ?
(ISequentialOutStream *)padStream :
(ISequentialOutStream *)outStream,
NULL, &size, compressProgress);
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)
@@ -1290,7 +1460,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
@@ -1301,11 +1496,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)
@@ -1329,19 +1528,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;
@@ -1352,10 +1565,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.

View File

@@ -15,7 +15,7 @@
namespace NArchive {
namespace NZip {
const unsigned kNumMethodNames1 = NFileHeader::NCompressionMethod::kLZMA + 1;
const unsigned kNumMethodNames1 = NFileHeader::NCompressionMethod::kZstdPk + 1;
const unsigned kMethodNames2Start = NFileHeader::NCompressionMethod::kZstd;
const unsigned kNumMethodNames2 = NFileHeader::NCompressionMethod::kWzAES + 1 - kMethodNames2Start;

View File

@@ -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);
}
if (ui.Name.Len() >= (1 << 16))
#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)
|| 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;
}

View File

@@ -49,24 +49,25 @@ namespace NFileHeader
kDeflate = 8,
kDeflate64 = 9,
kPKImploding = 10,
kBZip2 = 12,
kLZMA = 14,
kTerse = 18,
kLz77 = 19,
kZstd = 93,
kXz = 95,
kJpeg = 96,
kWavPack = 97,
kPPMd = 98,
kWzAES = 99
kBZip2 = 12, // File is compressed using BZIP2 algorithm
kLZMA = 14, // LZMA
kTerse = 18, // File is compressed using IBM TERSE (new)
kLz77 = 19, // IBM LZ77 z Architecture
kZstdPk = 20, // deprecated (use method 93 for zstd)
kZstd = 93, // Zstandard (zstd) Compression
kMP3 = 94, // MP3 Compression
kXz = 95, // XZ Compression
kJpeg = 96, // JPEG variant
kWavPack = 97, // WavPack compressed data
kPPMd = 98, // PPMd version I, Rev 1
kWzAES = 99 // AE-x encryption marker (see APPENDIX E)
};
const Byte kMadeByProgramVersion = 63;
const Byte kExtractVersion_Default = 10;
const Byte kExtractVersion_Dir = 20;
const Byte kExtractVersion_ZipCrypto = 20;
@@ -77,7 +78,7 @@ namespace NFileHeader
const Byte kExtractVersion_Aes = 51;
const Byte kExtractVersion_LZMA = 63;
const Byte kExtractVersion_PPMd = 63;
const Byte kExtractVersion_Xz = 20; // test it
const Byte kExtractVersion_Xz = 20; // test it
const Byte kExtractVersion_Zstd = 20; // WinZip mark it
}
@@ -92,7 +93,10 @@ namespace NFileHeader
kUnixExtra = 0x5855,
kIzUnicodeComment = 0x6375,
kIzUnicodeName = 0x7075,
kWzAES = 0x9901
kUnix2Extra = 0x7855,
kUnix3Extra = 0x7875,
kWzAES = 0x9901,
kApkAlign = 0xD935
};
}

View File

@@ -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;

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