Merge branch 'pr/1'

This commit is contained in:
conor42
2019-03-18 00:21:14 +10:00
261 changed files with 8112 additions and 8922 deletions

View File

@@ -1,7 +1,7 @@
C_OBJS = $(C_OBJS) \
$O\Aes.obj
!IF "$(CPU)" != "IA64" && "$(CPU)" != "MIPS" && "$(CPU)" != "ARM" && "$(CPU)" != "ARM64"
!IF "$(PLATFORM)" != "ia64" && "$(PLATFORM)" != "mips" && "$(PLATFORM)" != "arm" && "$(PLATFORM)" != "arm64"
ASM_OBJS = $(ASM_OBJS) \
$O\AesOpt.obj
!ENDIF

View File

@@ -355,7 +355,9 @@ HRESULT CDecoder::Decode(
unsigned i;
#if !defined(_7ZIP_ST)
bool mt_wasUsed = false;
#endif
for (i = 0; i < folderInfo.Coders.Size(); i++)
{

View File

@@ -236,6 +236,13 @@ STDMETHODIMP CHandler::GetArchiveProperty(PROPID propID, PROPVARIANT *value)
prop = v;
break;
}
case kpidReadOnly:
{
if (!_db.CanUpdate())
prop = true;
break;
}
}
prop.Detach(value);
return S_OK;
@@ -507,7 +514,7 @@ HRESULT CHandler::SetMethodToProp(CNum folderIndex, PROPVARIANT *prop) const
else if (id == k_LZ4)
{
name = "LZ4";
if (propsSize == 5)
if (propsSize == 3 || propsSize == 5)
{
char *dest = s;
*dest++ = 'v';
@@ -525,7 +532,7 @@ HRESULT CHandler::SetMethodToProp(CNum folderIndex, PROPVARIANT *prop) const
else if (id == k_LZ5)
{
name = "LZ5";
if (propsSize == 5)
if (propsSize == 3 || propsSize == 5)
{
char *dest = s;
*dest++ = 'v';
@@ -543,9 +550,10 @@ HRESULT CHandler::SetMethodToProp(CNum folderIndex, PROPVARIANT *prop) const
else if (id == k_ZSTD)
{
name = "ZSTD";
if (propsSize == 5)
if (propsSize == 3 || propsSize == 5)
{
char *dest = s;
UInt32 l = props[2];
*dest++ = 'v';
ConvertUInt32ToString(props[0], dest);
dest += MyStringLen(dest);
@@ -553,8 +561,14 @@ HRESULT CHandler::SetMethodToProp(CNum folderIndex, PROPVARIANT *prop) const
ConvertUInt32ToString(props[1], dest);
dest += MyStringLen(dest);
*dest++ = ',';
*dest++ = 'l';
ConvertUInt32ToString(props[2], dest);
if (l <= 22) {
*dest++ = 'l';
ConvertUInt32ToString(l, dest);
} else {
*dest++ = 'f';
*dest++ = 'l';
ConvertUInt32ToString(l - 32, dest);
}
dest += MyStringLen(dest);
}
}

View File

@@ -267,6 +267,9 @@ STDMETHODIMP CHandler::UpdateItems(ISequentialOutStream *outStream, UInt32 numIt
db = &_db;
#endif
if (db && !db->CanUpdate())
return E_NOTIMPL;
/*
CMyComPtr<IArchiveGetRawProps> getRawProps;
updateCallback->QueryInterface(IID_IArchiveGetRawProps, (void **)&getRawProps);

View File

@@ -1465,21 +1465,24 @@ void CDbEx::FillLinks()
}
if (indexInFolder != 0)
{
folderIndex++;
/*
if (indexInFolder != 0)
ThrowIncorrect();
*/
// 18.06
ThereIsHeaderError = true;
// ThrowIncorrect();
}
for (;;)
{
if (folderIndex >= NumFolders)
return;
FolderStartFileIndex[folderIndex] = i;
/*
if (NumUnpackStreamsVector[folderIndex] != 0)
ThrowIncorrect();;
*/
{
// 18.06
ThereIsHeaderError = true;
// ThrowIncorrect();
}
folderIndex++;
}
}

View File

@@ -257,6 +257,16 @@ struct CDbEx: public CDatabase
PhySize = 0;
}
bool CanUpdate() const
{
if (ThereIsHeaderError
|| UnexpectedEnd
|| StartHeaderWasRecovered
|| UnsupportedFeatureError)
return false;
return true;
}
void FillLinks();
UInt64 GetFolderStreamPos(CNum folderIndex, unsigned indexInFolder) const

View File

@@ -124,13 +124,13 @@ static int Parse_EXE(const Byte *buf, size_t size, CFilterMode *filterMode)
#define ELF_DATA_2LSB 1
#define ELF_DATA_2MSB 2
static UInt16 Get16(const Byte *p, Bool be) { if (be) return (UInt16)GetBe16(p); return (UInt16)GetUi16(p); }
static UInt32 Get32(const Byte *p, Bool be) { if (be) return GetBe32(p); return GetUi32(p); }
// static UInt64 Get64(const Byte *p, Bool be) { if (be) return GetBe64(p); return GetUi64(p); }
static UInt16 Get16(const Byte *p, BoolInt be) { if (be) return (UInt16)GetBe16(p); return (UInt16)GetUi16(p); }
static UInt32 Get32(const Byte *p, BoolInt be) { if (be) return GetBe32(p); return GetUi32(p); }
// static UInt64 Get64(const Byte *p, BoolInt be) { if (be) return GetBe64(p); return GetUi64(p); }
static int Parse_ELF(const Byte *buf, size_t size, CFilterMode *filterMode)
{
Bool /* is32, */ be;
BoolInt /* is32, */ be;
UInt32 filterId;
if (size < 512 || buf[6] != 1) /* ver */
@@ -200,7 +200,7 @@ static unsigned Parse_MACH(const Byte *buf, size_t size, CFilterMode *filterMode
if (size < 512)
return 0;
Bool /* mode64, */ be;
BoolInt /* mode64, */ be;
switch (GetUi32(buf))
{
case MACH_SIG_BE_32: /* mode64 = False; */ be = True; break;
@@ -239,7 +239,7 @@ static unsigned Parse_MACH(const Byte *buf, size_t size, CFilterMode *filterMode
#define RIFF_SIG 0x46464952
static Bool Parse_WAV(const Byte *buf, size_t size, CFilterMode *filterMode)
static BoolInt Parse_WAV(const Byte *buf, size_t size, CFilterMode *filterMode)
{
UInt32 subChunkSize, pos;
if (size < 0x2C)
@@ -285,7 +285,7 @@ static Bool Parse_WAV(const Byte *buf, size_t size, CFilterMode *filterMode)
return False;
}
static Bool ParseFile(const Byte *buf, size_t size, CFilterMode *filterMode)
static BoolInt ParseFile(const Byte *buf, size_t size, CFilterMode *filterMode)
{
filterMode->Id = 0;
filterMode->Delta = 0;
@@ -894,7 +894,7 @@ HRESULT CAnalysis::GetFilterGroup(UInt32 index, const CUpdateItem &ui, CFilterMo
// RINOK(Callback->SetOperationResult2(index, NUpdate::NOperationResult::kOK));
if (result == S_OK)
{
Bool parseRes = ParseFile(Buffer, size, &filterModeTemp);
BoolInt parseRes = ParseFile(Buffer, size, &filterModeTemp);
if (parseRes && filterModeTemp.Delta == 0)
{
filterModeTemp.SetDelta();
@@ -1648,6 +1648,9 @@ HRESULT Update(
for (CNum fi = db->FolderStartFileIndex[i]; indexInFolder < numUnpackStreams; fi++)
{
if (fi >= db->Files.Size())
return E_FAIL;
const CFileItem &file = db->Files[fi];
if (file.HasStream)
{

View File

@@ -170,8 +170,8 @@ static bool OctalToNumber32(const char *s, unsigned size, UInt32 &res)
res = 0;
char sz[32];
size = RemoveTailSpaces(sz, s, size);
if (size == 0)
return true; // some items doesn't contaion any numbers
if (size == 0 || strcmp(sz, "-1") == 0)
return true; // some items don't contain any numbers
const char *end;
UInt64 res64 = ConvertOctStringToUInt64(sz, &end);
if ((unsigned)(end - sz) != size)
@@ -185,8 +185,8 @@ static bool DecimalToNumber(const char *s, unsigned size, UInt64 &res)
res = 0;
char sz[32];
size = RemoveTailSpaces(sz, s, size);
if (size == 0)
return true; // some items doesn't contaion any numbers
if (size == 0 || strcmp(sz, "-1") == 0)
return true; // some items don't contain any numbers
const char *end;
res = ConvertStringToUInt64(sz, &end);
return ((unsigned)(end - sz) == size);

View File

@@ -366,7 +366,13 @@ STDMETHODIMP CHandler::UpdateItems(ISequentialOutStream *outStream, UInt32 numIt
return E_INVALIDARG;
size = prop.uhVal.QuadPart;
}
return UpdateArchive(size, outStream, _props, updateCallback);
CMethodProps props2 = _props;
#ifndef _7ZIP_ST
props2.AddProp_NumThreads(_props._numThreads);
#endif
return UpdateArchive(size, outStream, props2, updateCallback);
}
if (indexInArchive != 0)

View File

@@ -91,6 +91,7 @@ HRESULT CCoder::CheckDataAfterEnd(bool &dataAfterEnd_Error /* , bool &InternalPa
{
CMyComPtr<ICompressGetInStreamProcessedSize2> getInStreamProcessedSize2;
Coder2.QueryInterface(IID_ICompressGetInStreamProcessedSize2, (void **)&getInStreamProcessedSize2);
if (getInStreamProcessedSize2)
FOR_VECTOR (i, PackSizePointers)
{
if (!PackSizePointers[i])

View File

@@ -788,9 +788,21 @@ HRESULT CHandler::Open2(IInStream *stream)
if (headSize != RSRC_HEAD_SIZE
|| footerOffset >= rsrcPair.Len
|| mainDataSize >= rsrcPair.Len
|| footerOffset + footerSize != rsrcPair.Len
|| footerOffset < mainDataSize
|| footerOffset != headSize + mainDataSize)
return S_FALSE;
const UInt32 footerEnd = footerOffset + footerSize;
if (footerEnd != rsrcPair.Len)
{
// there is rare case dmg example, where there are 4 additional bytes
UInt64 rem = rsrcPair.Len - footerOffset;
if (rem < footerSize
|| rem - footerSize != 4
|| Get32(p + footerEnd) != 0)
return S_FALSE;
}
if (footerSize < 16)
return S_FALSE;
if (memcmp(p, p + footerOffset, 16) != 0)

View File

@@ -1596,6 +1596,17 @@ STDMETHODIMP CHandler::Close()
}
static void ChangeSeparatorsInName(char *s, unsigned num)
{
for (unsigned i = 0; i < num; i++)
{
char c = s[i];
if (c == CHAR_PATH_SEPARATOR || c == '/')
s[i] = '_';
}
}
void CHandler::GetPath(unsigned index, AString &s) const
{
s.Empty();
@@ -1612,6 +1623,8 @@ void CHandler::GetPath(unsigned index, AString &s) const
if (!s.IsEmpty())
s.InsertAtFront(CHAR_PATH_SEPARATOR);
s.Insert(0, item.Name);
// 18.06
ChangeSeparatorsInName(s.GetBuf(), item.Name.Len());
if (item.ParentNode == k_INODE_ROOT)
return;

View File

@@ -161,7 +161,8 @@ bool CHeader::Parse(const Byte *p)
return false;
// we also support images that contain 0 in offset field.
bool isOkOffset = (codeOffset == 0 || (p[0] == 0xEB && p[1] == 0));
bool isOkOffset = (codeOffset == 0)
|| (codeOffset == (p[0] == 0xEB ? 2 : 3));
UInt16 numRootDirEntries = Get16(p + 17);
if (numRootDirEntries == 0)
@@ -732,7 +733,13 @@ HRESULT CDatabase::Open()
RINOK(OpenProgressFat());
if ((Fat[0] & 0xFF) != Header.MediaType)
return S_FALSE;
{
// that case can mean error in FAT,
// but xdf file: (MediaType == 0xF0 && Fat[0] == 0xFF9)
// 19.00: so we use non-strict check
if ((Fat[0] & 0xFF) < 0xF0)
return S_FALSE;
}
RINOK(ReadDir(-1, Header.RootCluster, 0));

View File

@@ -419,7 +419,13 @@ void CDatabase::GetItemPath(unsigned index, NWindows::NCOM::CPropVariant &path)
const wchar_t *src = (const wchar_t *)*s;
wchar_t *dest = p + len;
for (unsigned j = 0; j < curLen; j++)
dest[j] = src[j];
{
wchar_t c = src[j];
// 18.06
if (c == CHAR_PATH_SEPARATOR || c == '/')
c = '_';
dest[j] = c;
}
if (len == 0)
break;

View File

@@ -131,13 +131,7 @@ HRESULT CDecoder::Code(const CHeader &header, ISequentialOutStream *outStream,
if (header.FilterID > 1)
return E_NOTIMPL;
{
CMyComPtr<ICompressSetDecoderProperties2> setDecoderProperties;
_lzmaDecoder.QueryInterface(IID_ICompressSetDecoderProperties2, &setDecoderProperties);
if (!setDecoderProperties)
return E_NOTIMPL;
RINOK(setDecoderProperties->SetDecoderProperties2(header.LzmaProps, 5));
}
RINOK(_lzmaDecoderSpec->SetDecoderProperties2(header.LzmaProps, 5));
bool filteredMode = (header.FilterID == 1);
@@ -357,24 +351,54 @@ API_FUNC_static_IsArc IsArc_Lzma86(const Byte *p, size_t size)
}
}
STDMETHODIMP CHandler::Open(IInStream *inStream, const UInt64 *, IArchiveOpenCallback *)
{
Close();
const UInt32 kBufSize = 1 + 5 + 8 + 2;
const unsigned headerSize = GetHeaderSize();
const UInt32 kBufSize = 1 << 7;
Byte buf[kBufSize];
RINOK(ReadStream_FALSE(inStream, buf, kBufSize));
size_t processedSize = kBufSize;
RINOK(ReadStream(inStream, buf, &processedSize));
if (processedSize < headerSize + 2)
return S_FALSE;
if (!_header.Parse(buf, _lzma86))
return S_FALSE;
const Byte *start = buf + GetHeaderSize();
const Byte *start = buf + headerSize;
if (start[0] != 0 /* || (start[1] & 0x80) != 0 */ ) // empty stream with EOS is not 0x80
return S_FALSE;
RINOK(inStream->Seek(0, STREAM_SEEK_END, &_packSize));
if (_packSize >= 24 && _header.Size == 0 && _header.FilterID == 0 && _header.LzmaProps[0] == 0)
SizeT srcLen = processedSize - headerSize;
if (srcLen > 10
&& _header.Size == 0
// && _header.FilterID == 0
&& _header.LzmaProps[0] == 0
)
return S_FALSE;
CDecoder state;
const UInt32 outLimit = 1 << 11;
Byte outBuf[outLimit];
SizeT outSize = outLimit;
if (outSize > _header.Size)
outSize = (SizeT)_header.Size;
SizeT destLen = outSize;
ELzmaStatus status;
SRes res = LzmaDecode(outBuf, &destLen, start, &srcLen,
_header.LzmaProps, 5, LZMA_FINISH_ANY,
&status, &g_Alloc);
if (res != SZ_OK)
if (res != SZ_ERROR_INPUT_EOF)
return S_FALSE;
_isArc = true;
_stream = inStream;
_seqStream = inStream;

View File

@@ -2445,23 +2445,24 @@ void CInArchive::DetectNsisType(const CBlockHeader &bh, const Byte *p)
bool strongPark = false;
bool strongNsis = false;
if (NumStringChars > 2)
{
const Byte *strData = _data + _stringsPos;
if (IsUnicode)
{
UInt32 num = NumStringChars;
UInt32 num = NumStringChars - 2;
for (UInt32 i = 0; i < num; i++)
{
if (Get16(strData + i * 2) == 0)
{
unsigned c2 = Get16(strData + 2 + i * 2);
// it can be TXT/RTF with marker char (1 or 2). so we must check next char
// if (c2 <= NS_3_CODE_SKIP && c2 != NS_3_CODE_SHELL)
if (c2 == NS_3_CODE_VAR)
{
// it can be TXT/RTF string with marker char (1 or 2). so we must next char
// const wchar_t *p2 = (const wchar_t *)(strData + i * 2 + 2);
// p2 = p2;
if ((Get16(strData + 3 + i * 2) & 0x8000) != 0)
// 18.06: fixed: is it correct ?
// if ((Get16(strData + 3 + i * 2) & 0x8000) != 0)
if ((Get16(strData + 4 + i * 2) & 0x8080) == 0x8080)
{
NsisType = k_NsisType_Nsis3;
strongNsis = true;
@@ -2478,7 +2479,7 @@ void CInArchive::DetectNsisType(const CBlockHeader &bh, const Byte *p)
}
else
{
UInt32 num = NumStringChars;
UInt32 num = NumStringChars - 2;
for (UInt32 i = 0; i < num; i++)
{
if (strData[i] == 0)

View File

@@ -1475,6 +1475,21 @@ void CDatabase::ClearAndClose()
InStream.Release();
}
static void CopyName(wchar_t *dest, const wchar_t *src)
{
for (;;)
{
wchar_t c = *src++;
// 18.06
if (c == '\\' || c == '/')
c = '_';
*dest++ = c;
if (c == 0)
return;
}
}
void CDatabase::GetItemPath(unsigned index, NCOM::CPropVariant &path) const
{
const CItem *item = &Items[index];
@@ -1492,7 +1507,7 @@ void CDatabase::GetItemPath(unsigned index, NCOM::CPropVariant &path) const
wchar_t *s = path.AllocBstr(data.Name.Len() + 1);
s[0] = L':';
if (!data.Name.IsEmpty())
MyStringCopy(s + 1, data.Name.GetRawPtr());
CopyName(s + 1, data.Name.GetRawPtr());
return;
}
@@ -1541,7 +1556,7 @@ void CDatabase::GetItemPath(unsigned index, NCOM::CPropVariant &path) const
if (!name.IsEmpty())
{
size -= name.Len();
MyStringCopy(s + size, name.GetRawPtr());
CopyName(s + size, name.GetRawPtr());
}
s[--size] = ':';
needColon = true;
@@ -1551,7 +1566,7 @@ void CDatabase::GetItemPath(unsigned index, NCOM::CPropVariant &path) const
const UString2 &name = rec.FileNames[item->NameIndex].Name;
unsigned len = name.Len();
if (len != 0)
MyStringCopy(s + size - len, name.GetRawPtr());
CopyName(s + size - len, name.GetRawPtr());
if (needColon)
s[size] = ':';
size -= len;
@@ -1575,7 +1590,7 @@ void CDatabase::GetItemPath(unsigned index, NCOM::CPropVariant &path) const
if (len != 0)
{
size -= len;
MyStringCopy(s + size, name.GetRawPtr());
CopyName(s + size, name.GetRawPtr());
}
s[size + len] = WCHAR_PATH_SEPARATOR;
continue;

View File

@@ -41,9 +41,8 @@ static const UInt32 k_Signature32 = 0x00004550;
static HRESULT CalcCheckSum(ISequentialInStream *stream, UInt32 size, UInt32 excludePos, UInt32 &res)
{
const UInt32 kBufSizeMax = (UInt32)1 << 16;
UInt32 bufSize = MyMin(kBufSizeMax, size);
bufSize += (bufSize & 1);
const UInt32 kBufSizeMax = (UInt32)1 << 15;
UInt32 bufSize = kBufSizeMax;
CByteBuffer buffer(bufSize);
Byte *buf = buffer;
UInt32 sum = 0;
@@ -58,9 +57,6 @@ static HRESULT CalcCheckSum(ISequentialInStream *stream, UInt32 size, UInt32 exc
size_t processed = rem;
RINOK(ReadStream(stream, buf, &processed));
if ((processed & 1) != 0)
buf[processed] = 0;
for (unsigned j = 0; j < 4; j++)
{
UInt32 e = excludePos + j;
@@ -72,11 +68,30 @@ static HRESULT CalcCheckSum(ISequentialInStream *stream, UInt32 size, UInt32 exc
}
}
for (size_t i = 0; i < processed; i += 2)
const unsigned kStep = (1 << 4);
{
sum += Get16(buf + i);
sum = (sum + (sum >> 16)) & 0xFFFF;
for (size_t i = processed; (i & (kStep - 1)) != 0; i++)
buf[i] = 0;
}
{
const Byte *buf2 = buf;
const Byte *bufLimit = buf + processed;
UInt64 sum2 = 0;
for (; buf2 < bufLimit; buf2 += kStep)
{
UInt64 sum3 = (UInt64)Get32(buf2)
+ Get32(buf2 + 4)
+ Get32(buf2 + 8)
+ Get32(buf2 + 12);
sum2 += sum3;
}
sum2 = (UInt32)(sum2) + (UInt64)(sum2 >> 32);
UInt32 sum3 = ((UInt32)sum2 + (UInt32)(sum2 >> 32));
sum += (sum3 & 0xFFFF) + (sum3 >> 16);
sum = (sum & 0xFFFF) + (sum >> 16);
sum = (sum & 0xFFFF) + (sum >> 16);
}
pos += (UInt32)processed;
if (rem != processed)
break;

View File

@@ -7,6 +7,7 @@
#include "../../../Common/ComTry.h"
#include "../../../Common/IntToString.h"
#include "../../../Common/MyBuffer2.h"
#include "../../../Common/UTFConvert.h"
#include "../../../Windows/PropVariantUtils.h"
@@ -104,37 +105,6 @@ static const char * const g_LinkTypes[] =
static const char g_ExtraTimeFlags[] = { 'u', 'M', 'C', 'A', 'n' };
template <unsigned alignMask>
struct CAlignedBuffer
{
Byte *_buf;
Byte *_bufBase;
size_t _size;
CAlignedBuffer(): _buf(NULL), _bufBase(NULL), _size(0) {}
~CAlignedBuffer() { ::MyFree(_bufBase); }
public:
operator Byte *() { return _buf; }
operator const Byte *() const { return _buf; }
void AllocAtLeast(size_t size)
{
if (_buf && _size >= size)
return;
::MyFree(_bufBase);
_buf = NULL;
_size = 0;
_bufBase = (Byte *)::MyAlloc(size + alignMask);
if (_bufBase)
{
_size = size;
// _buf = (Byte *)(((uintptr_t)_bufBase + alignMask) & ~(uintptr_t)alignMask);
_buf = (Byte *)(((ptrdiff_t)_bufBase + alignMask) & ~(ptrdiff_t)alignMask);
}
}
};
static unsigned ReadVarInt(const Byte *p, size_t maxSize, UInt64 *val)
{
*val = 0;
@@ -578,7 +548,7 @@ STDMETHODIMP COutStreamWithHash::Write(const void *data, UInt32 size, UInt32 *pr
class CInArchive
{
CAlignedBuffer<AES_BLOCK_SIZE - 1> _buf;
CAlignedBuffer _buf;
size_t _bufSize;
size_t _bufPos;
ISequentialInStream *_stream;
@@ -586,7 +556,7 @@ class CInArchive
NCrypto::NRar5::CDecoder *m_CryptoDecoderSpec;
CMyComPtr<ICompressFilter> m_CryptoDecoder;
CLASS_NO_COPY(CInArchive)
HRESULT ReadStream_Check(void *data, size_t size);
@@ -610,6 +580,8 @@ public:
UInt64 DataSize;
};
CInArchive() {}
HRESULT ReadBlockHeader(CHeader &h);
bool ReadFileHeader(const CHeader &header, CItem &item);
void AddToSeekValue(UInt64 addValue)
@@ -1000,7 +972,7 @@ bool CInArchive::ReadFileHeader(const CHeader &header, CItem &item)
struct CLinkFile
{
unsigned Index;
unsigned NumLinks;
unsigned NumLinks; // the number of links to Data
CByteBuffer Data;
HRESULT Res;
bool crcOK;
@@ -1015,7 +987,7 @@ struct CUnpacker
CMyComPtr<ICompressCoder> copyCoder;
CMyComPtr<ICompressCoder> LzCoders[2];
bool NeedClearSolid[2];
bool SolidAllowed;
CFilterCoder *filterStreamSpec;
CMyComPtr<ISequentialInStream> filterStream;
@@ -1032,7 +1004,7 @@ struct CUnpacker
CLinkFile *linkFile;
CUnpacker(): linkFile(NULL) { NeedClearSolid[0] = NeedClearSolid[1] = true; }
CUnpacker(): linkFile(NULL) { SolidAllowed = false; }
HRESULT Create(DECL_EXTERNAL_CODECS_LOC_VARS const CItem &item, bool isSolid, bool &wrongPassword);
@@ -1142,7 +1114,9 @@ HRESULT CUnpacker::Code(const CItem &item, const CItem &lastItem, UInt64 packSiz
if (method > kLzMethodMax)
return E_NOTIMPL;
if (linkFile && !lastItem.Is_UnknownSize())
bool needBuf = (linkFile && linkFile->NumLinks != 0);
if (needBuf && !lastItem.Is_UnknownSize())
{
size_t dataSize = (size_t)lastItem.Size;
if (dataSize != lastItem.Size)
@@ -1167,15 +1141,15 @@ HRESULT CUnpacker::Code(const CItem &item, const CItem &lastItem, UInt64 packSiz
ICompressCoder *commonCoder = (method == 0) ? copyCoder : LzCoders[item.IsService() ? 1 : 0];
outStreamSpec->SetStream(realOutStream);
outStreamSpec->Init(lastItem, (linkFile ? (Byte *)linkFile->Data : NULL));
NeedClearSolid[item.IsService() ? 1 : 0] = false;
outStreamSpec->Init(lastItem, (needBuf ? (Byte *)linkFile->Data : NULL));
HRESULT res = S_OK;
if (packSize != 0 || lastItem.Is_UnknownSize() || lastItem.Size != 0)
{
res = commonCoder->Code(inStream, outStream, &packSize,
lastItem.Is_UnknownSize() ? NULL : &lastItem.Size, progress);
if (!item.IsService())
SolidAllowed = true;
}
else
{
@@ -1210,7 +1184,9 @@ HRESULT CUnpacker::Code(const CItem &item, const CItem &lastItem, UInt64 packSiz
{
linkFile->Res = res;
linkFile->crcOK = isCrcOK;
if (!lastItem.Is_UnknownSize() && processedSize != lastItem.Size)
if (needBuf
&& !lastItem.Is_UnknownSize()
&& processedSize != lastItem.Size)
linkFile->Data.ChangeSize_KeepData((size_t)processedSize, (size_t)processedSize);
}
@@ -2578,6 +2554,15 @@ STDMETHODIMP CHandler::Extract(const UInt32 *indices, UInt32 numItems,
const Byte kStatus_Skip = 1 << 1;
const Byte kStatus_Link = 1 << 2;
/*
In original RAR:
1) service streams are not allowed to be solid,
and solid flag must be ignored for service streams.
2) If RAR creates new solid block and first file in solid block is Link file,
then it can clear solid flag for Link file and
clear solid flag for first non-Link file after Link file.
*/
CObjectVector<CLinkFile> linkFiles;
{
@@ -2603,13 +2588,15 @@ STDMETHODIMP CHandler::Extract(const UInt32 *indices, UInt32 numItems,
if (ref.Link >= 0)
{
if (!testMode)
// 18.06 fixed: we use links for Test mode too
// if (!testMode)
{
if ((unsigned)ref.Link < index)
{
const CRefItem &linkRef = _refs[(unsigned)ref.Link];
const CItem &linkItem = _items[linkRef.Item];
if (linkItem.IsSolid() && linkItem.Size <= k_CopyLinkFile_MaxSize)
if (linkItem.IsSolid())
if (testMode || linkItem.Size <= k_CopyLinkFile_MaxSize)
{
if (extractStatuses[(unsigned)ref.Link] == 0)
{
@@ -2664,19 +2651,25 @@ STDMETHODIMP CHandler::Extract(const UInt32 *indices, UInt32 numItems,
{
unsigned solidLimit = 0;
FOR_VECTOR(i, _refs)
FOR_VECTOR (i, _refs)
{
if ((extractStatuses[i] & kStatus_Link) == 0)
continue;
// We use CLinkFile for testMode too.
// So we can show errors for copy files.
// if (!testMode)
{
CLinkFile &linkFile = linkFiles.AddNew();
linkFile.Index = i;
}
const CItem &item = _items[_refs[i].Item];
/*
if (item.IsService())
continue;
*/
CLinkFile &linkFile = linkFiles.AddNew();
linkFile.Index = i;
if (item.IsSolid())
{
unsigned j = i;
@@ -2707,6 +2700,7 @@ STDMETHODIMP CHandler::Extract(const UInt32 *indices, UInt32 numItems,
solidLimit = i + 1;
}
if (!testMode)
for (UInt32 t = 0; t < numItems; t++)
{
unsigned index = allFilesMode ? t : indices[t];
@@ -2748,7 +2742,7 @@ STDMETHODIMP CHandler::Extract(const UInt32 *indices, UInt32 numItems,
// bool needClearSolid = true;
FOR_VECTOR(i, _refs)
FOR_VECTOR (i, _refs)
{
if (extractStatuses[i] == 0)
continue;
@@ -2761,15 +2755,19 @@ STDMETHODIMP CHandler::Extract(const UInt32 *indices, UInt32 numItems,
CMyComPtr<ISequentialOutStream> realOutStream;
// isExtract means that we don't skip that item. So we need read data.
bool isExtract = ((extractStatuses[i] & kStatus_Extract) != 0);
Int32 askMode =
((extractStatuses[i] & kStatus_Extract) != 0) ? (testMode ?
isExtract ? (testMode ?
NExtract::NAskMode::kTest :
NExtract::NAskMode::kExtract) :
NExtract::NAskMode::kSkip;
unpacker.linkFile = NULL;
if (((extractStatuses[i] & kStatus_Link) != 0))
// if (!testMode)
if ((extractStatuses[i] & kStatus_Link) != 0)
{
int bufIndex = FindLinkBuf(linkFiles, i);
if (bufIndex < 0)
@@ -2791,13 +2789,12 @@ STDMETHODIMP CHandler::Extract(const UInt32 *indices, UInt32 numItems,
RINOK(extractCallback->GetStream(index, &realOutStream, askMode));
bool isSolid;
bool isSolid = false;
if (!item->IsService())
{
bool &needClearSolid = unpacker.NeedClearSolid[item->IsService() ? 1 : 0];
isSolid = (item->IsSolid() && !needClearSolid);
if (item->IsService())
isSolid = false;
needClearSolid = !item->IsSolid();
if (item->IsSolid())
isSolid = unpacker.SolidAllowed;
unpacker.SolidAllowed = isSolid;
}
if (item->IsDir())
@@ -2826,18 +2823,30 @@ STDMETHODIMP CHandler::Extract(const UInt32 *indices, UInt32 numItems,
curUnpackSize = 0;
curPackSize = GetPackSize(index2);
}
else if ((unsigned)index2 < index)
bufIndex = FindLinkBuf(linkFiles, index2);
else
{
if ((unsigned)index2 < index)
bufIndex = FindLinkBuf(linkFiles, index2);
}
}
bool needCallback = true;
if (!realOutStream)
{
if (testMode)
{
if (item->NeedUse_as_CopyLink_or_HardLink())
{
Int32 opRes = NExtract::NOperationResult::kOK;
if (bufIndex >= 0)
{
const CLinkFile &linkFile = linkFiles[bufIndex];
opRes = DecoderRes_to_OpRes(linkFile.Res, linkFile.crcOK);
}
RINOK(extractCallback->PrepareOperation(askMode));
RINOK(extractCallback->SetOperationResult(NExtract::NOperationResult::kOK));
RINOK(extractCallback->SetOperationResult(opRes));
continue;
}
}
@@ -2846,10 +2855,10 @@ STDMETHODIMP CHandler::Extract(const UInt32 *indices, UInt32 numItems,
if (item->IsService())
continue;
if (item->NeedUse_as_HardLink())
continue;
needCallback = false;
bool needDecode = false;
if (!item->NeedUse_as_HardLink())
if (index2 < 0)
for (unsigned n = i + 1; n < _refs.Size(); n++)
{
@@ -2860,41 +2869,56 @@ STDMETHODIMP CHandler::Extract(const UInt32 *indices, UInt32 numItems,
break;
if (extractStatuses[i] != 0)
{
needDecode = true;
needCallback = true;
break;
}
}
if (!needDecode)
continue;
askMode = NExtract::NAskMode::kSkip;
}
}
RINOK(extractCallback->PrepareOperation(askMode));
if (needCallback)
{
RINOK(extractCallback->PrepareOperation(askMode));
}
if (bufIndex >= 0)
{
CLinkFile &linkFile = linkFiles[bufIndex];
if (linkFile.NumLinks == 0)
return E_FAIL;
if (realOutStream)
if (isExtract)
{
RINOK(CopyData_with_Progress(linkFile.Data, linkFile.Data.Size(), realOutStream, progress));
if (linkFile.NumLinks == 0)
return E_FAIL;
if (needCallback)
if (realOutStream)
{
RINOK(CopyData_with_Progress(linkFile.Data, linkFile.Data.Size(), realOutStream, progress));
}
if (--linkFile.NumLinks == 0)
linkFile.Data.Free();
}
if (needCallback)
{
RINOK(extractCallback->SetOperationResult(DecoderRes_to_OpRes(linkFile.Res, linkFile.crcOK)));
}
if (--linkFile.NumLinks == 0)
linkFile.Data.Free();
RINOK(extractCallback->SetOperationResult(DecoderRes_to_OpRes(linkFile.Res, linkFile.crcOK)));
continue;
}
if (!needCallback)
continue;
if (item->NeedUse_as_CopyLink())
{
RINOK(extractCallback->SetOperationResult(
realOutStream ?
NExtract::NOperationResult::kUnsupportedMethod:
NExtract::NOperationResult::kOK));
int opRes = realOutStream ?
NExtract::NOperationResult::kUnsupportedMethod:
NExtract::NOperationResult::kOK;
realOutStream.Release();
RINOK(extractCallback->SetOperationResult(opRes));
continue;
}
@@ -2941,7 +2965,7 @@ STDMETHODIMP CHandler::Extract(const UInt32 *indices, UInt32 numItems,
}
{
FOR_VECTOR(i, linkFiles)
FOR_VECTOR (i, linkFiles)
if (linkFiles[i].NumLinks != 0)
return E_FAIL;
}

View File

@@ -6,6 +6,7 @@
#include "../../../Common/ComTry.h"
#include "../../../Common/IntToString.h"
#include "../../../Common/MyBuffer2.h"
#include "../../../Common/UTFConvert.h"
#include "../../../Windows/PropVariantUtils.h"
@@ -136,8 +137,7 @@ class CInArchive
NHeader::NBlock::CBlock m_BlockHeader;
NCrypto::NRar3::CDecoder *m_RarAESSpec;
CMyComPtr<ICompressFilter> m_RarAES;
CByteBuffer m_DecryptedData;
Byte *m_DecryptedDataAligned;
CAlignedBuffer m_DecryptedDataAligned;
UInt32 m_DecryptedDataSize;
bool m_CryptoMode;
UInt32 m_CryptoPos;
@@ -415,6 +415,8 @@ bool CInArchive::ReadHeaderReal(const Byte *p, unsigned size, CItem &item)
if (size < 8)
return false;
item.PackSize |= ((UInt64)Get32(p) << 32);
if (item.PackSize >= ((UInt64)1 << 63))
return false;
item.Size |= ((UInt64)Get32(p + 4) << 32);
p += 8;
size -= 8;
@@ -551,11 +553,12 @@ HRESULT CInArchive::GetNextItem(CItem &item, ICryptoGetTextPassword *getTextPass
m_RarAESSpec->SetPassword((const Byte *)buffer, len * 2);
const UInt32 kDecryptedBufferSize = (1 << 12);
if (m_DecryptedData.Size() == 0)
if (m_DecryptedDataAligned.Size() == 0)
{
const UInt32 kAlign = 16;
m_DecryptedData.Alloc(kDecryptedBufferSize + kAlign);
m_DecryptedDataAligned = (Byte *)((ptrdiff_t)((Byte *)m_DecryptedData + kAlign - 1) & ~(ptrdiff_t)(kAlign - 1));
// const UInt32 kAlign = 16;
m_DecryptedDataAligned.AllocAtLeast(kDecryptedBufferSize);
if (!m_DecryptedDataAligned.IsAllocated())
return E_OUTOFMEMORY;
}
RINOK(m_RarAES->Init());
size_t decryptedDataSizeT = kDecryptedBufferSize;
@@ -667,7 +670,8 @@ HRESULT CInArchive::GetNextItem(CItem &item, ICryptoGetTextPassword *getTextPass
{
if (processed < offset + 2)
error = k_ErrorType_Corrupted;
ArcInfo.VolNumber = (UInt32)Get16(m_FileHeaderData + offset);
else
ArcInfo.VolNumber = (UInt32)Get16(m_FileHeaderData + offset);
}
ArcInfo.EndOfArchive_was_Read = true;

View File

@@ -4,6 +4,7 @@
#include "../../../C/Alloc.h"
#include "../../../C/CpuArch.h"
#include "../../../C/LzmaDec.h"
#include "../../../C/Xz.h"
#include "../../Common/ComTry.h"
@@ -24,7 +25,7 @@
#include "../Compress/CopyCoder.h"
#include "../Compress/ZlibDecoder.h"
#include "../Compress/LzmaDecoder.h"
// #include "../Compress/LzmaDecoder.h"
namespace NArchive {
namespace NSquashfs {
@@ -866,8 +867,8 @@ class CHandler:
CBufPtrSeqOutStream *_outStreamSpec;
CMyComPtr<ISequentialOutStream> _outStream;
NCompress::NLzma::CDecoder *_lzmaDecoderSpec;
CMyComPtr<ICompressCoder> _lzmaDecoder;
// NCompress::NLzma::CDecoder *_lzmaDecoderSpec;
// CMyComPtr<ICompressCoder> _lzmaDecoder;
NCompress::NZlib::CDecoder *_zlibDecoderSpec;
CMyComPtr<ICompressCoder> _zlibDecoder;
@@ -1155,12 +1156,13 @@ HRESULT CHandler::Decompress(ISequentialOutStream *outStream, Byte *outBuf, bool
if (inSize != _zlibDecoderSpec->GetInputProcessedSize())
return S_FALSE;
}
/*
else if (method == kMethod_LZMA)
{
if (!_lzmaDecoder)
{
_lzmaDecoderSpec = new NCompress::NLzma::CDecoder();
_lzmaDecoderSpec->FinishStream = true;
// _lzmaDecoderSpec->FinishStream = true;
_lzmaDecoder = _lzmaDecoderSpec;
}
const UInt32 kPropsSize = LZMA_PROPS_SIZE + 8;
@@ -1187,6 +1189,7 @@ HRESULT CHandler::Decompress(ISequentialOutStream *outStream, Byte *outBuf, bool
if (inSize != propsSize + _lzmaDecoderSpec->GetInputProcessedSize())
return S_FALSE;
}
*/
else
{
if (_inputBuffer.Size() < inSize)
@@ -1200,11 +1203,49 @@ HRESULT CHandler::Decompress(ISequentialOutStream *outStream, Byte *outBuf, bool
if (!dest)
return E_OUTOFMEMORY;
}
SizeT destLen = outSizeMax, srcLen = inSize;
if (method == kMethod_LZO)
{
RINOK(LzoDecode(dest, &destLen, _inputBuffer, &srcLen));
}
else if (method == kMethod_LZMA)
{
Byte props[5];
const Byte *src = _inputBuffer;
if (_noPropsLZMA)
{
props[0] = 0x5D;
SetUi32(&props[1], _h.BlockSize);
}
else
{
const UInt32 kPropsSize = LZMA_PROPS_SIZE + 8;
if (inSize < kPropsSize)
return S_FALSE;
memcpy(props, src, LZMA_PROPS_SIZE);
UInt64 outSize = GetUi64(src + LZMA_PROPS_SIZE);
if (outSize > outSizeMax)
return S_FALSE;
destLen = (SizeT)outSize;
src += kPropsSize;
inSize -= kPropsSize;
srcLen = inSize;
}
ELzmaStatus status;
SRes res = LzmaDecode(dest, &destLen,
src, &srcLen,
props, LZMA_PROPS_SIZE,
LZMA_FINISH_END,
&status, &g_Alloc);
if (res != 0)
return SResToHRESULT(res);
if (status != LZMA_STATUS_FINISHED_WITH_MARK)
return S_FALSE;
}
else
{
ECoderStatus status;
@@ -1217,6 +1258,7 @@ HRESULT CHandler::Decompress(ISequentialOutStream *outStream, Byte *outBuf, bool
if (status != CODER_STATUS_NEEDS_MORE_INPUT || !XzUnpacker_IsStreamWasFinished(&_xz))
return S_FALSE;
}
if (inSize != srcLen)
return S_FALSE;
if (outBuf)

View File

@@ -46,7 +46,7 @@ static const Byte SWF_COMPRESSED_LZMA = 'Z';
static const Byte SWF_MIN_COMPRESSED_ZLIB_VER = 6;
static const Byte SWF_MIN_COMPRESSED_LZMA_VER = 13;
static const Byte kVerLim = 20;
static const Byte kVerLim = 64;
API_FUNC_static_IsArc IsArc_Swf(const Byte *p, size_t size)
{

View File

@@ -443,14 +443,14 @@ HRESULT ReadItem(ISequentialInStream *stream, bool &filled, CItemEx &item, EErro
case 'X':
{
// pax Extended Header
if (item.Name.IsPrefixedBy("PaxHeader/"))
if (item.Name.IsPrefixedBy("PaxHeader/")
|| item.Name.Find("PaxHeaders.4467/") >= 0)
{
RINOK(ReadDataToString(stream, item, pax, error));
if (error != k_ErrorType_OK)
return S_OK;
continue;
}
break;
}
case NFileHeader::NLinkFlag::kDumpDir:
@@ -488,7 +488,11 @@ HRESULT ReadItem(ISequentialInStream *stream, bool &filled, CItemEx &item, EErro
if (ParsePaxLongName(pax, name))
item.Name = name;
else
error = k_ErrorType_Warning;
{
// no "path" property is allowed in pax4467
// error = k_ErrorType_Warning;
}
pax.Empty();
}
return S_OK;

View File

@@ -791,20 +791,24 @@ STDMETHODIMP CHandler::GetProperty(UInt32 index, PROPID propID, PROPVARIANT *val
void CHandler::AddCommentString(const char *name, UInt32 pos)
{
UString s;
const Byte *buf = _bufs[0];
if (pos < _h.HeaderSize)
return;
for (UInt32 i = pos;; i += 2)
if (pos >= _h.OffsetToCapsuleBody)
return;
UInt32 limit = (_h.OffsetToCapsuleBody - pos) & ~(UInt32)1;
const Byte *buf = _bufs[0] + pos;
for (UInt32 i = 0;;)
{
if (s.Len() > (1 << 16) || i >= _h.OffsetToCapsuleBody)
if (s.Len() > (1 << 16) || i >= limit)
return;
wchar_t c = Get16(buf + i);
i += 2;
if (c == 0)
{
i += 2;
if (i >= _h.OffsetToCapsuleBody)
if (i >= limit)
return;
c = Get16(buf + i);
i += 2;
if (c == 0)
break;
s.Add_LF();

View File

@@ -671,7 +671,7 @@ void CHeader::SetDefaultFields(bool useLZX)
ChunkSize = kChunkSize;
ChunkSizeBits = kChunkSizeBits;
}
g_RandomGenerator.Generate(Guid, 16);
MY_RAND_GEN(Guid, 16);
PartNumber = 1;
NumParts = 1;
NumImages = 1;

View File

@@ -111,7 +111,9 @@ HRESULT CUnpacker::UnpackChunk(
}
else if (method == NMethod::kLZX)
{
lzxDecoderSpec->SetExternalWindow(unpackBuf.Data, chunkSizeBits);
res = lzxDecoderSpec->SetExternalWindow(unpackBuf.Data, chunkSizeBits);
if (res != S_OK)
return E_NOTIMPL;
lzxDecoderSpec->KeepHistoryForNext = false;
lzxDecoderSpec->SetKeepHistory(false);
res = lzxDecoderSpec->Code(packBuf.Data, inSize, (UInt32)outSize);
@@ -563,7 +565,13 @@ void CDatabase::GetItemPath(unsigned index1, bool showImageNumber, NWindows::NCO
wchar_t *dest = s + size;
meta += 2;
for (unsigned i = 0; i < len; i++)
dest[i] = Get16(meta + i * 2);
{
wchar_t c = Get16(meta + i * 2);
// 18.06
if (c == CHAR_PATH_SEPARATOR || c == '/')
c = '_';
dest[i] = c;
}
}
if (index < 0)
return;
@@ -866,7 +874,11 @@ HRESULT CDatabase::ParseImageDirs(CByteBuffer &buf, int parent)
if (DirProcessed == DirSize - 8 && Get64(p + DirSize - 8) != 0)
return S_OK;
return S_FALSE;
// 18.06: we support cases, when some old dism can capture images
// where DirProcessed much smaller than DirSize
HeadersError = true;
return S_OK;
// return S_FALSE;
}

View File

@@ -468,7 +468,7 @@ public:
int ExludedItem; // -1 : if there are no exclude items
CUIntVector VirtualRoots; // we use them for old 1.10 WIM archives
bool ThereIsError() const { return RefCountError; }
bool ThereIsError() const { return RefCountError || HeadersError; }
unsigned GetNumUserItemsInImage(unsigned imageIndex) const
{
@@ -544,7 +544,10 @@ public:
HeadersError = false;
}
CDatabase(): RefCountError(false) {}
CDatabase():
RefCountError(false),
HeadersError(false)
{}
void GetShortName(unsigned index, NWindows::NCOM::CPropVariant &res) const;
void GetItemName(unsigned index1, NWindows::NCOM::CPropVariant &res) const;

View File

@@ -488,7 +488,7 @@ HRESULT CHandler::Open2(IInStream *inStream, /* UInt32 flags, */ IArchiveOpenCal
{
CXzBlock block;
Bool isIndex;
BoolInt isIndex;
UInt32 headerSizeRes;
SRes res2 = XzBlock_ReadHeader(&block, &inStreamWrap.vt, &isIndex, &headerSizeRes);
if (res2 == SZ_OK && !isIndex)
@@ -820,7 +820,7 @@ static HRESULT DecodeBlock(CXzUnpackerCPP2 &xzu,
packRem -= inLen;
Bool blockFinished = XzUnpacker_IsBlockFinished(&xzu.p);
BoolInt blockFinished = XzUnpacker_IsBlockFinished(&xzu.p);
if ((inLen == 0 && outLen == 0) || blockFinished)
{

View File

@@ -599,8 +599,12 @@ STDMETHODIMP CHandler::GetProperty(UInt32 index, PROPID propID, PROPVARIANT *val
case kpidHostOS:
{
const Byte hostOS = item.GetHostOS();
TYPE_TO_PROP(kHostOS, hostOS, prop);
if (item.FromCentral)
{
// 18.06: now we use HostOS only from Central::MadeByVersion
const Byte hostOS = item.MadeByVersion.HostOS;
TYPE_TO_PROP(kHostOS, hostOS, prop);
}
break;
}

View File

@@ -155,6 +155,7 @@ void CInArchive::Close()
HeadersError = false;
HeadersWarning = false;
ExtraMinorError = false;
UnexpectedEnd = false;
LocalsWereRead = false;
LocalsCenterMerged = false;
@@ -1729,6 +1730,9 @@ HRESULT CInArchive::FindCd(bool checkOffsetMode)
HRESULT CInArchive::TryReadCd(CObjectVector<CItemEx> &items, const CCdInfo &cdInfo, UInt64 cdOffset, UInt64 cdSize)
{
items.Clear();
// _startLocalFromCd_Disk = (UInt32)(Int32)-1;
// _startLocalFromCd_Offset = (UInt64)(Int64)-1;
RINOK(SeekToVol(IsMultiVol ? cdInfo.CdDisk : -1, cdOffset));
@@ -1752,6 +1756,17 @@ HRESULT CInArchive::TryReadCd(CObjectVector<CItemEx> &items, const CCdInfo &cdIn
{
CItemEx cdItem;
RINOK(ReadCdItem(cdItem));
/*
if (cdItem.Disk < _startLocalFromCd_Disk ||
cdItem.Disk == _startLocalFromCd_Disk &&
cdItem.LocalHeaderPos < _startLocalFromCd_Offset)
{
_startLocalFromCd_Disk = cdItem.Disk;
_startLocalFromCd_Offset = cdItem.LocalHeaderPos;
}
*/
items.Add(cdItem);
}
if (Callback && (items.Size() & 0xFFF) == 0)
@@ -2509,6 +2524,8 @@ HRESULT CInArchive::ReadHeaders(CObjectVector<CItemEx> &items)
{
ArcInfo.CdWasRead = true;
ArcInfo.FirstItemRelatOffset = items[0].LocalHeaderPos;
// ArcInfo.FirstItemRelatOffset = _startLocalFromCd_Offset;
}
}
}
@@ -2535,6 +2552,10 @@ HRESULT CInArchive::ReadHeaders(CObjectVector<CItemEx> &items)
items.Clear();
localsWereRead = true;
HeadersError = false;
HeadersWarning = false;
ExtraMinorError = false;
// we can use any mode: with buffer and without buffer
// without buffer : skips packed data : fast for big files : slow for small files
// with buffer : reads packed data : slow for big files : fast for small files

View File

@@ -250,6 +250,9 @@ class CInArchive
UInt64 _streamPos;
UInt64 _cnt;
// UInt32 _startLocalFromCd_Disk;
// UInt64 _startLocalFromCd_Offset;
size_t GetAvail() const { return _bufCached - _bufPos; }
void InitBuf() { _bufPos = 0; _bufCached = 0; }
@@ -383,6 +386,9 @@ public:
UInt64 GetEmbeddedStubSize() const
{
// it's possible that first item in CD doesn refers to first local item
// so FirstItemRelatOffset is not first local item
if (ArcInfo.CdWasRead)
return ArcInfo.FirstItemRelatOffset;
if (IsMultiVol)

View File

@@ -214,6 +214,12 @@ class CLocalItem
public:
UInt16 Flags;
UInt16 Method;
/*
Zip specification doesn't mention that ExtractVersion field uses HostOS subfield.
18.06: 7-Zip now doesn't use ExtractVersion::HostOS to detect codePage
*/
CVersion ExtractVersion;
UInt64 Size;
@@ -309,7 +315,8 @@ public:
UInt32 GetWinAttrib() const;
bool GetPosixAttrib(UInt32 &attrib) const;
Byte GetHostOS() const { return FromCentral ? MadeByVersion.HostOS : ExtractVersion.HostOS; }
// 18.06: 0 instead of ExtractVersion.HostOS for local item
Byte GetHostOS() const { return FromCentral ? MadeByVersion.HostOS : (Byte)0; }
void GetUnicodeString(UString &res, const AString &s, bool isComment, bool useSpecifiedCodePage, UINT codePage) const;
@@ -326,7 +333,10 @@ public:
UINT GetCodePage() const
{
Byte hostOS = GetHostOS();
// 18.06: now we use HostOS only from Central::MadeByVersion
if (!FromCentral)
return CP_OEMCP;
Byte hostOS = MadeByVersion.HostOS;
return (UINT)((
hostOS == NFileHeader::NHostOS::kFAT
|| hostOS == NFileHeader::NHostOS::kNTFS

View File

@@ -40,7 +40,10 @@ static const Byte kHostOS =
#endif
static const Byte kMadeByHostOS = kHostOS;
static const Byte kExtractHostOS = kHostOS;
// 18.06: now we always write zero to high byte of ExtractVersion field.
// Previous versions of p7zip wrote (NFileHeader::NHostOS::kUnix) there, that is not correct
static const Byte kExtractHostOS = 0;
static const Byte kMethodForDirectory = NFileHeader::NCompressionMethod::kStore;

View File

@@ -2500,6 +2500,15 @@ SOURCE=..\..\..\..\C\Delta.h
# End Source File
# Begin Source File
SOURCE=..\..\..\..\C\DllSecur.c
# SUBTRACT CPP /YX /Yc /Yu
# End Source File
# Begin Source File
SOURCE=..\..\..\..\C\DllSecur.h
# End Source File
# Begin Source File
SOURCE=..\..\..\..\C\HuffEnc.c
!IF "$(CFG)" == "Alone - Win32 Release"

View File

@@ -3,10 +3,9 @@ MY_CONSOLE = 1
CFLAGS = $(CFLAGS)
!IFNDEF UNDER_CE
CFLAGS = $(CFLAGS) -DWIN_LONG_PATH -D_7ZIP_LARGE_PAGES -DSUPPORT_DEVICE_FILE -DZSTD_MULTITHREAD
CFLAGS = $(CFLAGS) -DWIN_LONG_PATH -D_7ZIP_LARGE_PAGES -DSUPPORT_DEVICE_FILE
!ENDIF
COMMON_OBJS = \
$O\CommandLineParser.obj \
$O\CRC.obj \
@@ -291,6 +290,8 @@ ZSTD_OBJS = \
$O\xxhash.obj \
$O\zstd_common.obj \
$O\zstd_compress.obj \
$O\zstd_ddict.obj \
$O\zstd_decompress_block.obj \
$O\zstd_decompress.obj \
$O\zstd_double_fast.obj \
$O\zstd_fast.obj \

View File

@@ -1646,6 +1646,15 @@ SOURCE=..\..\..\..\C\Delta.h
# End Source File
# Begin Source File
SOURCE=..\..\..\..\C\DllSecur.c
# SUBTRACT CPP /YX /Yc /Yu
# End Source File
# Begin Source File
SOURCE=..\..\..\..\C\DllSecur.h
# End Source File
# Begin Source File
SOURCE=..\..\..\..\C\IStream.h
# End Source File
# Begin Source File

View File

@@ -1,10 +1,6 @@
PROG = 7zr.exe
MY_CONSOLE = 1
CFLAGS = $(CFLAGS) -DPROG_VARIANT_R
!IFNDEF UNDER_CE
CFLAGS = $(CFLAGS) -DWIN_LONG_PATH -D_7ZIP_LARGE_PAGES -DSUPPORT_DEVICE_FILE
!ENDIF
CFLAGS = $(CFLAGS) \
-DPROG_VARIANT_R \
COMMON_OBJS = \
$O\CommandLineParser.obj \

View File

@@ -1,6 +1,6 @@
PROG = brotli.dll
DEF_FILE = ../../Compress/Codec.def
CFLAGS = $(CFLAGS) -DNEED_7ZIP_GUID
CFLAGS = $(CFLAGS)
7ZIP_COMMON_OBJS = \
$O\StreamUtils.obj \

View File

@@ -1,6 +1,6 @@
#include "../../../../C/7zVersionTr.h"
#include "../../../../C/7zVersion.rc"
MY_VERSION_INFO_DLL("7-Zip Brotli Plugin v1.0.6", "Brotli")
MY_VERSION_INFO_DLL("7-Zip Brotli Plugin v1.0.7", "Brotli")
101 ICON "../../Archive/Icons/7z.ico"

View File

@@ -1,6 +1,6 @@
PROG = flzma2.dll
DEF_FILE = ../../Compress/Codec.def
CFLAGS = $(CFLAGS) -DNEED_7ZIP_GUID -DNO_XXHASH
CFLAGS = $(CFLAGS) -DNO_XXHASH
7ZIP_COMMON_OBJS = \
$O\CWrappers.obj \

View File

@@ -1,6 +1,6 @@
PROG = lizard.dll
DEF_FILE = ../../Compress/Codec.def
CFLAGS = $(CFLAGS) -DNEED_7ZIP_GUID
CFLAGS = $(CFLAGS)
7ZIP_COMMON_OBJS = \
$O\StreamUtils.obj \

View File

@@ -1,6 +1,6 @@
PROG = lz4.dll
DEF_FILE = ../../Compress/Codec.def
CFLAGS = $(CFLAGS) -DNEED_7ZIP_GUID
CFLAGS = $(CFLAGS)
7ZIP_COMMON_OBJS = \
$O\StreamUtils.obj \

View File

@@ -1,6 +1,6 @@
PROG = lz5.dll
DEF_FILE = ../../Compress/Codec.def
CFLAGS = $(CFLAGS) -DNEED_7ZIP_GUID
CFLAGS = $(CFLAGS)
7ZIP_COMMON_OBJS = \
$O\StreamUtils.obj \

View File

@@ -1,6 +1,6 @@
PROG = zstd-min.dll
PROG = zstd.dll
DEF_FILE = ../../Compress/Codec.def
CFLAGS = $(CFLAGS) -DNEED_7ZIP_GUID -DZSTD_MULTITHREAD
CFLAGS = $(CFLAGS) -DZSTD_LEGACY_SUPPORT -DZSTD_MULTITHREAD
7ZIP_COMMON_OBJS = \
$O\StreamUtils.obj \
@@ -35,6 +35,8 @@ ZSTD_OBJS = \
$O\xxhash.obj \
$O\zstd_common.obj \
$O\zstd_compress.obj \
$O\zstd_ddict.obj \
$O\zstd_decompress_block.obj \
$O\zstd_decompress.obj \
$O\zstd_double_fast.obj \
$O\zstd_fast.obj \
@@ -42,6 +44,13 @@ ZSTD_OBJS = \
$O\zstd_ldm.obj \
$O\zstdmt_compress.obj \
$O\zstd_opt.obj \
$O\zstd_v01.obj \
$O\zstd_v02.obj \
$O\zstd_v03.obj \
$O\zstd_v04.obj \
$O\zstd_v05.obj \
$O\zstd_v06.obj \
$O\zstd_v07.obj \
ZSTDMT_OBJS = \
$O\zstd-mt_threading.obj \

View File

@@ -1,6 +1,6 @@
#include "../../../../C/7zVersionTr.h"
#include "../../../../C/7zVersion.rc"
MY_VERSION_INFO_DLL("7-Zip ZS Plugin v1.3.7", "zstd")
MY_VERSION_INFO_DLL("7-Zip ZS Plugin v1.3.8", "zstd")
101 ICON "../../Archive/Icons/zst.ico"

View File

@@ -1,3 +0,0 @@
// StdAfx.cpp
#include "StdAfx.h"

View File

@@ -1,8 +0,0 @@
// StdAfx.h
#ifndef __STDAFX_H
#define __STDAFX_H
#include "../../../Common/Common.h"
#endif

View File

@@ -1,56 +0,0 @@
PROG = zstd.dll
DEF_FILE = ../../Compress/Codec.def
CFLAGS = $(CFLAGS) -DNEED_7ZIP_GUID -DZSTD_LEGACY_SUPPORT -DZSTD_MULTITHREAD
7ZIP_COMMON_OBJS = \
$O\StreamUtils.obj \
WIN_OBJS = \
$O\System.obj \
COMPRESS_OBJS = \
$O\CodecExports.obj \
$O\DllExportsCompress.obj \
C_OBJS = \
$O\Alloc.obj \
$O\Threads.obj \
COMPRESS_OBJS = $(COMPRESS_OBJS) \
$O\ZstdDecoder.obj \
$O\ZstdEncoder.obj \
$O\ZstdRegister.obj \
ZSTD_OBJS = \
$O\debug.obj \
$O\entropy_common.obj \
$O\error_private.obj \
$O\fse_compress.obj \
$O\fse_decompress.obj \
$O\hist.obj \
$O\huf_compress.obj \
$O\huf_decompress.obj \
$O\pool.obj \
$O\threading.obj \
$O\xxhash.obj \
$O\zstd_common.obj \
$O\zstd_compress.obj \
$O\zstd_decompress.obj \
$O\zstd_double_fast.obj \
$O\zstd_fast.obj \
$O\zstd_lazy.obj \
$O\zstd_ldm.obj \
$O\zstdmt_compress.obj \
$O\zstd_opt.obj \
$O\zstd_v01.obj \
$O\zstd_v02.obj \
$O\zstd_v03.obj \
$O\zstd_v04.obj \
$O\zstd_v05.obj \
$O\zstd_v06.obj \
$O\zstd_v07.obj \
ZSTDMT_OBJS = \
$O\zstd-mt_threading.obj \
!include "../../7zip.mak"

View File

@@ -1,6 +0,0 @@
#include "../../../../C/7zVersionTr.h"
#include "../../../../C/7zVersion.rc"
MY_VERSION_INFO_DLL("7-Zip ZS Plugin v1.3.7", "zstd")
101 ICON "../../Archive/Icons/zst.ico"

View File

@@ -985,6 +985,15 @@ SOURCE=..\..\..\..\C\CpuArch.h
# End Source File
# Begin Source File
SOURCE=..\..\..\..\C\DllSecur.c
# SUBTRACT CPP /YX /Yc /Yu
# End Source File
# Begin Source File
SOURCE=..\..\..\..\C\DllSecur.h
# End Source File
# Begin Source File
SOURCE=..\..\..\..\C\LzFind.c
# SUBTRACT CPP /YX /Yc /Yu
# End Source File

View File

@@ -1,14 +1,4 @@
PROG = 7zFM.exe
CFLAGS = $(CFLAGS) \
-DLANG \
-DNEW_FOLDER_INTERFACE \
!IFDEF UNDER_CE
LIBS = $(LIBS) ceshell.lib Commctrl.lib
!ELSE
LIBS = $(LIBS) comctl32.lib htmlhelp.lib comdlg32.lib Mpr.lib Gdi32.lib
CFLAGS = $(CFLAGS) -DWIN_LONG_PATH -DSUPPORT_DEVICE_FILE
!ENDIF
!include "../Format7zF/Arc.mak"

View File

@@ -213,6 +213,8 @@ ZSTD_OBJS = \
$O\xxhash.obj \
$O\zstd_common.obj \
$O\zstd_compress.obj \
$O\zstd_ddict.obj \
$O\zstd_decompress_block.obj \
$O\zstd_decompress.obj \
$O\zstd_double_fast.obj \
$O\zstd_fast.obj \

View File

@@ -1,8 +1,6 @@
PROG = 7zxa.dll
DEF_FILE = ../../Archive/Archive2.def
CFLAGS = $(CFLAGS) \
-DNEED_7ZIP_GUID \
-DEXTRACT_ONLY \
CFLAGS = $(CFLAGS) -DEXTRACT_ONLY \
COMMON_OBJS = \
$O\CRC.obj \
@@ -175,6 +173,8 @@ ZSTD_OBJS = \
$O\xxhash.obj \
$O\zstd_common.obj \
$O\zstd_compress.obj \
$O\zstd_ddict.obj \
$O\zstd_decompress_block.obj \
$O\zstd_decompress.obj \
$O\zstd_double_fast.obj \
$O\zstd_fast.obj \

View File

@@ -88,6 +88,8 @@ ZSTD_OBJS = \
$O\xxhash.obj \
$O\zstd_common.obj \
$O\zstd_compress.obj \
$O\zstd_ddict.obj \
$O\zstd_decompress_block.obj \
$O\zstd_decompress.obj \
$O\zstd_double_fast.obj \
$O\zstd_fast.obj \

View File

@@ -1,306 +0,0 @@
COMMON_OBJS = \
$O\CRC.obj \
$O\CrcReg.obj \
$O\DynLimBuf.obj \
$O\IntToString.obj \
$O\Md2Reg.obj \
$O\Md4Reg.obj \
$O\Md5Reg.obj \
$O\MyMap.obj \
$O\MyString.obj \
$O\MyVector.obj \
$O\MyXml.obj \
$O\NewHandler.obj \
$O\Sha1Reg.obj \
$O\Sha256Reg.obj \
$O\Sha384Reg.obj \
$O\Sha512Reg.obj \
$O\StringConvert.obj \
$O\StringToInt.obj \
$O\UTFConvert.obj \
$O\Wildcard.obj \
$O\XXH32Reg.obj \
$O\XXH64Reg.obj \
$O\XzCrc64Init.obj \
$O\XzCrc64Reg.obj \
WIN_OBJS = \
$O\FileDir.obj \
$O\FileFind.obj \
$O\FileIO.obj \
$O\FileName.obj \
$O\PropVariant.obj \
$O\PropVariantUtils.obj \
$O\Synchronization.obj \
$O\System.obj \
$O\TimeUtils.obj \
7ZIP_COMMON_OBJS = \
$O\CreateCoder.obj \
$O\CWrappers.obj \
$O\InBuffer.obj \
$O\InOutTempBuffer.obj \
$O\FilterCoder.obj \
$O\LimitedStreams.obj \
$O\LockedStream.obj \
$O\MemBlocks.obj \
$O\MethodId.obj \
$O\MethodProps.obj \
$O\OffsetStream.obj \
$O\OutBuffer.obj \
$O\OutMemStream.obj \
$O\ProgressMt.obj \
$O\ProgressUtils.obj \
$O\PropId.obj \
$O\StreamBinder.obj \
$O\StreamObjects.obj \
$O\StreamUtils.obj \
$O\UniqBlocks.obj \
$O\VirtThread.obj \
AR_OBJS = \
$O\ApmHandler.obj \
$O\ArHandler.obj \
$O\ArjHandler.obj \
$O\Bz2Handler.obj \
$O\ComHandler.obj \
$O\CpioHandler.obj \
$O\CramfsHandler.obj \
$O\DeflateProps.obj \
$O\DmgHandler.obj \
$O\ElfHandler.obj \
$O\ExtHandler.obj \
$O\FatHandler.obj \
$O\FlvHandler.obj \
$O\GzHandler.obj \
$O\GptHandler.obj \
$O\HandlerCont.obj \
$O\HfsHandler.obj \
$O\IhexHandler.obj \
$O\LzHandler.obj \
$O\Lz4Handler.obj \
$O\Lz5Handler.obj \
$O\LizardHandler.obj \
$O\LzhHandler.obj \
$O\LzmaHandler.obj \
$O\MachoHandler.obj \
$O\MbrHandler.obj \
$O\MslzHandler.obj \
$O\MubHandler.obj \
$O\NtfsHandler.obj \
$O\PeHandler.obj \
$O\PpmdHandler.obj \
$O\QcowHandler.obj \
$O\RpmHandler.obj \
$O\SplitHandler.obj \
$O\SquashfsHandler.obj \
$O\SwfHandler.obj \
$O\UefiHandler.obj \
$O\VdiHandler.obj \
$O\VhdHandler.obj \
$O\VmdkHandler.obj \
$O\XarHandler.obj \
$O\XzHandler.obj \
$O\ZHandler.obj \
$O\ZstdHandler.obj \
AR_COMMON_OBJS = \
$O\CoderMixer2.obj \
$O\DummyOutStream.obj \
$O\FindSignature.obj \
$O\InStreamWithCRC.obj \
$O\ItemNameUtils.obj \
$O\MultiStream.obj \
$O\OutStreamWithCRC.obj \
$O\OutStreamWithSha1.obj \
$O\HandlerOut.obj \
$O\ParseProperties.obj \
7Z_OBJS = \
$O\7zCompressionMode.obj \
$O\7zDecode.obj \
$O\7zEncode.obj \
$O\7zExtract.obj \
$O\7zFolderInStream.obj \
$O\7zHandler.obj \
$O\7zHandlerOut.obj \
$O\7zHeader.obj \
$O\7zIn.obj \
$O\7zOut.obj \
$O\7zProperties.obj \
$O\7zSpecStream.obj \
$O\7zUpdate.obj \
$O\7zRegister.obj \
CAB_OBJS = \
$O\CabBlockInStream.obj \
$O\CabHandler.obj \
$O\CabHeader.obj \
$O\CabIn.obj \
$O\CabRegister.obj \
CHM_OBJS = \
$O\ChmHandler.obj \
$O\ChmIn.obj \
ISO_OBJS = \
$O\IsoHandler.obj \
$O\IsoHeader.obj \
$O\IsoIn.obj \
$O\IsoRegister.obj \
NSIS_OBJS = \
$O\NsisDecode.obj \
$O\NsisHandler.obj \
$O\NsisIn.obj \
$O\NsisRegister.obj \
RAR_OBJS = \
$O\RarHandler.obj \
$O\Rar5Handler.obj \
TAR_OBJS = \
$O\TarHandler.obj \
$O\TarHandlerOut.obj \
$O\TarHeader.obj \
$O\TarIn.obj \
$O\TarOut.obj \
$O\TarUpdate.obj \
$O\TarRegister.obj \
UDF_OBJS = \
$O\UdfHandler.obj \
$O\UdfIn.obj \
WIM_OBJS = \
$O\WimHandler.obj \
$O\WimHandlerOut.obj \
$O\WimIn.obj \
$O\WimRegister.obj \
ZIP_OBJS = \
$O\ZipAddCommon.obj \
$O\ZipHandler.obj \
$O\ZipHandlerOut.obj \
$O\ZipIn.obj \
$O\ZipItem.obj \
$O\ZipOut.obj \
$O\ZipUpdate.obj \
$O\ZipRegister.obj \
COMPRESS_OBJS = \
$O\Bcj2Coder.obj \
$O\Bcj2Register.obj \
$O\BcjCoder.obj \
$O\BcjRegister.obj \
$O\BitlDecoder.obj \
$O\BranchMisc.obj \
$O\BranchRegister.obj \
$O\ByteSwap.obj \
$O\BZip2Crc.obj \
$O\BZip2Decoder.obj \
$O\BZip2Encoder.obj \
$O\BZip2Register.obj \
$O\CopyCoder.obj \
$O\CopyRegister.obj \
$O\Deflate64Register.obj \
$O\DeflateDecoder.obj \
$O\DeflateEncoder.obj \
$O\DeflateRegister.obj \
$O\DeltaFilter.obj \
$O\ImplodeDecoder.obj \
$O\LzfseDecoder.obj \
$O\LzhDecoder.obj \
$O\Lzma2Decoder.obj \
$O\Lzma2Encoder.obj \
$O\Lzma2Register.obj \
$O\LzmaDecoder.obj \
$O\LzmaEncoder.obj \
$O\LzmaRegister.obj \
$O\LzmsDecoder.obj \
$O\LzOutWindow.obj \
$O\LzxDecoder.obj \
$O\PpmdDecoder.obj \
$O\PpmdEncoder.obj \
$O\PpmdRegister.obj \
$O\PpmdZip.obj \
$O\QuantumDecoder.obj \
$O\Rar1Decoder.obj \
$O\Rar2Decoder.obj \
$O\Rar3Decoder.obj \
$O\Rar3Vm.obj \
$O\Rar5Decoder.obj \
$O\RarCodecsRegister.obj \
$O\ShrinkDecoder.obj \
$O\XpressDecoder.obj \
$O\XzDecoder.obj \
$O\XzEncoder.obj \
$O\ZlibDecoder.obj \
$O\ZlibEncoder.obj \
$O\ZDecoder.obj \
CRYPTO_OBJS = \
$O\7zAes.obj \
$O\7zAesRegister.obj \
$O\HmacSha1.obj \
$O\HmacSha256.obj \
$O\MyAes.obj \
$O\MyAesReg.obj \
$O\Pbkdf2HmacSha1.obj \
$O\RandGen.obj \
$O\Rar20Crypto.obj \
$O\Rar5Aes.obj \
$O\RarAes.obj \
$O\WzAes.obj \
$O\ZipCrypto.obj \
$O\ZipStrong.obj \
HASHES_OBJS = \
$O\md2.obj \
$O\md4.obj \
$O\md5.obj \
$O\sha512.obj \
C_OBJS = \
$O\7zBuf2.obj \
$O\7zStream.obj \
$O\Alloc.obj \
$O\Bcj2.obj \
$O\Bcj2Enc.obj \
$O\Blake2s.obj \
$O\Bra.obj \
$O\Bra86.obj \
$O\BraIA64.obj \
$O\BwtSort.obj \
$O\CpuArch.obj \
$O\Delta.obj \
$O\HuffEnc.obj \
$O\LzFind.obj \
$O\LzFindMt.obj \
$O\Lzma2Dec.obj \
$O\Lzma2DecMt.obj \
$O\Lzma2Enc.obj \
$O\LzmaDec.obj \
$O\LzmaEnc.obj \
$O\MtCoder.obj \
$O\MtDec.obj \
$O\Ppmd7.obj \
$O\Ppmd7Dec.obj \
$O\Ppmd7Enc.obj \
$O\Ppmd8.obj \
$O\Ppmd8Dec.obj \
$O\Ppmd8Enc.obj \
$O\Sha1.obj \
$O\Sha256.obj \
$O\Sort.obj \
$O\Threads.obj \
$O\Xz.obj \
$O\XzDec.obj \
$O\XzEnc.obj \
$O\XzIn.obj \
!include "../../Aes.mak"
!include "../../Crc.mak"
!include "../../Crc64.mak"
!include "../../LzmaDec.mak"

View File

File diff suppressed because it is too large Load Diff

View File

@@ -1,29 +0,0 @@
Microsoft Developer Studio Workspace File, Format Version 6.00
# WARNING: DO NOT EDIT OR DELETE THIS WORKSPACE FILE!
###############################################################################
Project: "7z"=.\Format7z.dsp - Package Owner=<4>
Package=<5>
{{{
}}}
Package=<4>
{{{
}}}
###############################################################################
Global:
Package=<5>
{{{
}}}
Package=<3>
{{{
}}}
###############################################################################

View File

@@ -1,3 +0,0 @@
// StdAfx.cpp
#include "StdAfx.h"

View File

@@ -1,8 +0,0 @@
// StdAfx.h
#ifndef __STDAFX_H
#define __STDAFX_H
#include "../../../Common/Common.h"
#endif

View File

@@ -1,134 +0,0 @@
PROG = 7z.dll
DEF_FILE = ../../Archive/Archive2.def
CFLAGS = $(CFLAGS) -DNEED_7ZIP_GUID -DEXTERNAL_CODECS -DZSTD_LEGACY_SUPPORT -DZSTD_MULTITHREAD
!IFNDEF UNDER_CE
CFLAGS = $(CFLAGS) -DNEED_7ZIP_GUID -D_7ZIP_LARGE_PAGES
!ENDIF
!include "Arc.mak"
COMPRESS_OBJS = $(COMPRESS_OBJS) \
$O\CodecExports.obj \
AR_OBJS = $(AR_OBJS) \
$O\ArchiveExports.obj \
$O\DllExports2.obj \
COMPRESS_OBJS = $(COMPRESS_OBJS) \
$O\BrotliDecoder.obj \
$O\BrotliEncoder.obj \
$O\BrotliRegister.obj \
$O\Lz4Decoder.obj \
$O\Lz4Encoder.obj \
$O\Lz4Register.obj \
$O\LizardDecoder.obj \
$O\LizardEncoder.obj \
$O\LizardRegister.obj \
$O\Lz5Decoder.obj \
$O\Lz5Encoder.obj \
$O\Lz5Register.obj \
$O\ZstdDecoder.obj \
$O\ZstdEncoder.obj \
$O\ZstdRegister.obj \
$O\FastLzma2Register.obj \
BROTLI_OBJS = \
$O/br_backward_references.obj \
$O/br_backward_references_hq.obj \
$O/br_bit_cost.obj \
$O/br_bit_reader.obj \
$O/br_block_splitter.obj \
$O/br_brotli_bit_stream.obj \
$O/br_cluster.obj \
$O/br_compress_fragment.obj \
$O/br_compress_fragment_two_pass.obj \
$O/br_decode.obj \
$O/br_dictionary.obj \
$O/br_dictionary_hash.obj \
$O/br_encode.obj \
$O/br_encoder_dict.obj \
$O/br_entropy_encode.obj \
$O/br_histogram.obj \
$O/br_huffman.obj \
$O/br_literal_cost.obj \
$O/br_memory.obj \
$O/br_metablock.obj \
$O/br_state.obj \
$O/br_static_dict.obj \
$O/br_transform.obj \
$O/br_utf8_util.obj \
LIZARD_OBJS = \
$O/lizard_compress.obj \
$O/lizard_decompress.obj \
$O/lizard_frame.obj \
LZ4_OBJS = \
$O\lz4.obj \
$O\lz4frame.obj \
$O\lz4hc.obj \
LZ5_OBJS = \
$O\lz5.obj \
$O\lz5frame.obj \
$O\lz5hc.obj \
ZSTD_OBJS = \
$O\debug.obj \
$O\entropy_common.obj \
$O\error_private.obj \
$O\fse_compress.obj \
$O\fse_decompress.obj \
$O\hist.obj \
$O\huf_compress.obj \
$O\huf_decompress.obj \
$O\pool.obj \
$O\threading.obj \
$O\xxhash.obj \
$O\zstd_common.obj \
$O\zstd_compress.obj \
$O\zstd_decompress.obj \
$O\zstd_double_fast.obj \
$O\zstd_fast.obj \
$O\zstd_lazy.obj \
$O\zstd_ldm.obj \
$O\zstdmt_compress.obj \
$O\zstd_opt.obj \
$O\zstd_v01.obj \
$O\zstd_v02.obj \
$O\zstd_v03.obj \
$O\zstd_v04.obj \
$O\zstd_v05.obj \
$O\zstd_v06.obj \
$O\zstd_v07.obj \
ZSTDMT_OBJS = \
$O\brotli-mt_common.obj \
$O\brotli-mt_compress.obj \
$O\brotli-mt_decompress.obj \
$O\lizard-mt_common.obj \
$O\lizard-mt_compress.obj \
$O\lizard-mt_decompress.obj \
$O\lz4-mt_common.obj \
$O\lz4-mt_compress.obj \
$O\lz4-mt_decompress.obj \
$O\lz5-mt_common.obj \
$O\lz5-mt_compress.obj \
$O\lz5-mt_decompress.obj \
$O\zstd-mt_threading.obj \
FASTLZMA2_OBJS = \
$O\dict_buffer.obj \
$O\fl2_common.obj \
$O\fl2_compress.obj \
$O\fl2_pool.obj \
$O\fl2_threading.obj \
$O\lzma2_enc.obj \
$O\radix_bitpack.obj \
$O\radix_mf.obj \
$O\radix_struct.obj \
$O\range_enc.obj \
$O\util.obj \
!include "../../7zip.mak"

View File

@@ -1,40 +0,0 @@
#include "../../MyVersionInfo.rc"
MY_VERSION_INFO_DLL("7z Plugin" , "7z")
0 ICON "../../Archive/Icons/7z.ico"
1 ICON "../../Archive/Icons/zip.ico"
2 ICON "../../Archive/Icons/bz2.ico"
3 ICON "../../Archive/Icons/rar.ico"
4 ICON "../../Archive/Icons/arj.ico"
5 ICON "../../Archive/Icons/z.ico"
6 ICON "../../Archive/Icons/lzh.ico"
7 ICON "../../Archive/Icons/cab.ico"
8 ICON "../../Archive/Icons/iso.ico"
9 ICON "../../Archive/Icons/split.ico"
10 ICON "../../Archive/Icons/rpm.ico"
11 ICON "../../Archive/Icons/deb.ico"
12 ICON "../../Archive/Icons/cpio.ico"
13 ICON "../../Archive/Icons/tar.ico"
14 ICON "../../Archive/Icons/gz.ico"
15 ICON "../../Archive/Icons/wim.ico"
16 ICON "../../Archive/Icons/lzma.ico"
17 ICON "../../Archive/Icons/dmg.ico"
18 ICON "../../Archive/Icons/hfs.ico"
19 ICON "../../Archive/Icons/xar.ico"
20 ICON "../../Archive/Icons/vhd.ico"
21 ICON "../../Archive/Icons/fat.ico"
22 ICON "../../Archive/Icons/ntfs.ico"
23 ICON "../../Archive/Icons/xz.ico"
24 ICON "../../Archive/Icons/squashfs.ico"
25 ICON "../../Archive/Icons/zst.ico"
26 ICON "../../Archive/Icons/lz4.ico"
27 ICON "../../Archive/Icons/lz5.ico"
28 ICON "../../Archive/Icons/liz.ico"
STRINGTABLE
BEGIN
100 "7z:0 zip:1 rar:3 001:9 cab:7 iso:8 xz:23 txz:23 lzma:16 tar:13 cpio:12 bz2:2 bzip2:2 tbz2:2 tbz:2 gz:14 gzip:14 tgz:14 tpz:14 z:5 taz:5 lz:16 tlz:16 liz:28 lz4:26 lz5:27 lzh:6 lha:6 rpm:10 deb:11 arj:4 vhd:20 wim:15 swm:15 fat:21 ntfs:22 dmg:17 hfs:18 xar:19 squashfs:24 zst:25"
END

View File

@@ -1,3 +0,0 @@
// StdAfx.cpp
#include "StdAfx.h"

View File

@@ -1,8 +0,0 @@
// StdAfx.h
#ifndef __STDAFX_H
#define __STDAFX_H
#include "../../../Common/Common.h"
#endif

View File

@@ -1,251 +0,0 @@
PROG = 7zu.dll
DEF_FILE = ../../Archive/Archive2.def
CFLAGS = $(CFLAGS) -DNEED_7ZIP_GUID -DZSTD_MULTITHREAD
COMMON_OBJS = \
$O\CRC.obj \
$O\CrcReg.obj \
$O\IntToString.obj \
$O\NewHandler.obj \
$O\MyString.obj \
$O\Sha256Reg.obj \
$O\StringConvert.obj \
$O\StringToInt.obj \
$O\MyVector.obj \
$O\Wildcard.obj \
WIN_OBJS = \
$O\FileDir.obj \
$O\FileFind.obj \
$O\FileIO.obj \
$O\FileName.obj \
$O\PropVariant.obj \
$O\Synchronization.obj \
$O\System.obj \
7ZIP_COMMON_OBJS = \
$O\CreateCoder.obj \
$O\CWrappers.obj \
$O\InBuffer.obj \
$O\InOutTempBuffer.obj \
$O\FilterCoder.obj \
$O\LimitedStreams.obj \
$O\MethodId.obj \
$O\MethodProps.obj \
$O\OutBuffer.obj \
$O\ProgressUtils.obj \
$O\PropId.obj \
$O\StreamBinder.obj \
$O\StreamObjects.obj \
$O\StreamUtils.obj \
$O\UniqBlocks.obj \
$O\VirtThread.obj \
AR_OBJS = \
$O\ArchiveExports.obj \
$O\DllExports2.obj \
AR_COMMON_OBJS = \
$O\CoderMixer2.obj \
$O\HandlerOut.obj \
$O\InStreamWithCRC.obj \
$O\ItemNameUtils.obj \
$O\OutStreamWithCRC.obj \
$O\ParseProperties.obj \
7Z_OBJS = \
$O\7zCompressionMode.obj \
$O\7zDecode.obj \
$O\7zEncode.obj \
$O\7zExtract.obj \
$O\7zFolderInStream.obj \
$O\7zHandler.obj \
$O\7zHandlerOut.obj \
$O\7zHeader.obj \
$O\7zIn.obj \
$O\7zOut.obj \
$O\7zProperties.obj \
$O\7zSpecStream.obj \
$O\7zUpdate.obj \
$O\7zRegister.obj \
COMPRESS_OBJS = \
$O\CodecExports.obj \
$O\Bcj2Coder.obj \
$O\Bcj2Register.obj \
$O\BcjCoder.obj \
$O\BcjRegister.obj \
$O\BitlDecoder.obj \
$O\BranchMisc.obj \
$O\BranchRegister.obj \
$O\ByteSwap.obj \
$O\BZip2Crc.obj \
$O\BZip2Decoder.obj \
$O\BZip2Encoder.obj \
$O\BZip2Register.obj \
$O\CopyCoder.obj \
$O\CopyRegister.obj \
$O\DeflateDecoder.obj \
$O\DeflateEncoder.obj \
$O\DeflateRegister.obj \
$O\DeltaFilter.obj \
$O\Lzma2Decoder.obj \
$O\Lzma2Encoder.obj \
$O\Lzma2Register.obj \
$O\LzmaDecoder.obj \
$O\LzmaEncoder.obj \
$O\LzmaRegister.obj \
$O\LzOutWindow.obj \
$O\PpmdDecoder.obj \
$O\PpmdEncoder.obj \
$O\PpmdRegister.obj \
CRYPTO_OBJS = \
$O\7zAes.obj \
$O\7zAesRegister.obj \
$O\MyAes.obj \
$O\MyAesReg.obj \
$O\RandGen.obj \
C_OBJS = \
$O\Alloc.obj \
$O\Bcj2.obj \
$O\Bcj2Enc.obj \
$O\Bra.obj \
$O\Bra86.obj \
$O\BraIA64.obj \
$O\BwtSort.obj \
$O\CpuArch.obj \
$O\Delta.obj \
$O\HuffEnc.obj \
$O\LzFind.obj \
$O\LzFindMt.obj \
$O\Lzma2Dec.obj \
$O\Lzma2DecMt.obj \
$O\Lzma2Enc.obj \
$O\LzmaDec.obj \
$O\LzmaEnc.obj \
$O\MtCoder.obj \
$O\MtDec.obj \
$O\Ppmd7.obj \
$O\Ppmd7Dec.obj \
$O\Ppmd7Enc.obj \
$O\Sha256.obj \
$O\Sort.obj \
$O\Threads.obj \
!include "../../Aes.mak"
!include "../../Crc.mak"
COMPRESS_OBJS = $(COMPRESS_OBJS) \
$O\BrotliDecoder.obj \
$O\BrotliEncoder.obj \
$O\BrotliRegister.obj \
$O\Lz4Decoder.obj \
$O\Lz4Encoder.obj \
$O\Lz4Register.obj \
$O\LizardDecoder.obj \
$O\LizardEncoder.obj \
$O\LizardRegister.obj \
$O\Lz5Decoder.obj \
$O\Lz5Encoder.obj \
$O\Lz5Register.obj \
$O\ZstdDecoder.obj \
$O\ZstdEncoder.obj \
$O\ZstdRegister.obj \
$O\FastLzma2Register.obj \
BROTLI_OBJS = \
$O/br_backward_references.obj \
$O/br_backward_references_hq.obj \
$O/br_bit_cost.obj \
$O/br_bit_reader.obj \
$O/br_block_splitter.obj \
$O/br_brotli_bit_stream.obj \
$O/br_cluster.obj \
$O/br_compress_fragment.obj \
$O/br_compress_fragment_two_pass.obj \
$O/br_decode.obj \
$O/br_dictionary.obj \
$O/br_dictionary_hash.obj \
$O/br_encode.obj \
$O/br_encoder_dict.obj \
$O/br_entropy_encode.obj \
$O/br_histogram.obj \
$O/br_huffman.obj \
$O/br_literal_cost.obj \
$O/br_memory.obj \
$O/br_metablock.obj \
$O/br_state.obj \
$O/br_static_dict.obj \
$O/br_transform.obj \
$O/br_utf8_util.obj \
LIZARD_OBJS = \
$O/lizard_compress.obj \
$O/lizard_decompress.obj \
$O/lizard_frame.obj \
LZ4_OBJS = \
$O\lz4.obj \
$O\lz4frame.obj \
$O\lz4hc.obj \
LZ5_OBJS = \
$O\lz5.obj \
$O\lz5frame.obj \
$O\lz5hc.obj \
ZSTD_OBJS = \
$O\debug.obj \
$O\entropy_common.obj \
$O\error_private.obj \
$O\fse_compress.obj \
$O\fse_decompress.obj \
$O\hist.obj \
$O\huf_compress.obj \
$O\huf_decompress.obj \
$O\pool.obj \
$O\threading.obj \
$O\xxhash.obj \
$O\zstd_common.obj \
$O\zstd_compress.obj \
$O\zstd_decompress.obj \
$O\zstd_double_fast.obj \
$O\zstd_fast.obj \
$O\zstd_lazy.obj \
$O\zstd_ldm.obj \
$O\zstdmt_compress.obj \
$O\zstd_opt.obj \
ZSTDMT_OBJS = \
$O\brotli-mt_common.obj \
$O\brotli-mt_compress.obj \
$O\brotli-mt_decompress.obj \
$O\lizard-mt_common.obj \
$O\lizard-mt_compress.obj \
$O\lizard-mt_decompress.obj \
$O\lz4-mt_common.obj \
$O\lz4-mt_compress.obj \
$O\lz4-mt_decompress.obj \
$O\lz5-mt_common.obj \
$O\lz5-mt_compress.obj \
$O\lz5-mt_decompress.obj \
$O\zstd-mt_threading.obj \
FASTLZMA2_OBJS = \
$O\dict_buffer.obj \
$O\fl2_common.obj \
$O\fl2_compress.obj \
$O\fl2_pool.obj \
$O\fl2_threading.obj \
$O\lzma2_enc.obj \
$O\radix_bitpack.obj \
$O\radix_mf.obj \
$O\radix_struct.obj \
$O\range_enc.obj \
$O\util.obj \
!include "../../7zip.mak"

View File

@@ -1,5 +0,0 @@
#include "../../MyVersionInfo.rc"
MY_VERSION_INFO_DLL("7z Standalone Plugin", "7za")
101 ICON "../../Archive/Icons/7z.ico"

View File

@@ -1,6 +1,5 @@
PROG = lzma.exe
MY_CONSOLE = 1
CFLAGS = $(CFLAGS)
CURRENT_OBJS = \
$O\LzmaAlone.obj \
@@ -55,5 +54,6 @@ C_OBJS = \
$O\Threads.obj \
!include "../../Crc.mak"
!include "../../LzmaDec.mak"
!include "../../7zip.mak"

View File

@@ -6,7 +6,6 @@ CFLAGS = $(CFLAGS) \
-DEXTRACT_ONLY \
-DNO_READ_FROM_CODER \
-D_SFX \
-D_CONSOLE \
CURRENT_OBJS = \
$O\SfxCon.obj \
@@ -134,29 +133,20 @@ C_OBJS = \
COMPRESS_OBJS = $(COMPRESS_OBJS) \
$O\ZstdDecoder.obj \
$O\ZstdEncoder.obj \
$O\ZstdRegister.obj \
ZSTD_OBJS = \
$O\debug.obj \
$O\entropy_common.obj \
$O\error_private.obj \
$O\fse_compress.obj \
$O\fse_decompress.obj \
$O\hist.obj \
$O\huf_compress.obj \
$O\huf_decompress.obj \
$O\pool.obj \
$O\threading.obj \
$O\xxhash.obj \
$O\zstd_common.obj \
$O\zstd_compress.obj \
$O\zstd_ddict.obj \
$O\zstd_decompress_block.obj \
$O\zstd_decompress.obj \
$O\zstd_double_fast.obj \
$O\zstd_fast.obj \
$O\zstd_lazy.obj \
$O\zstd_ldm.obj \
$O\zstdmt_compress.obj \
$O\zstd_opt.obj \
!include "../../7zip.mak"

View File

@@ -152,29 +152,21 @@ C_OBJS = \
COMPRESS_OBJS = $(COMPRESS_OBJS) \
$O\ZstdDecoder.obj \
$O\ZstdEncoder.obj \
$O\ZstdRegister.obj \
ZSTD_OBJS = \
$O\debug.obj \
$O\entropy_common.obj \
$O\error_private.obj \
$O\fse_compress.obj \
$O\fse_decompress.obj \
$O\hist.obj \
$O\huf_compress.obj \
$O\huf_decompress.obj \
$O\pool.obj \
$O\threading.obj \
$O\xxhash.obj \
$O\zstd_common.obj \
$O\zstd_compress.obj \
$O\zstd_ddict.obj \
$O\zstd_decompress_block.obj \
$O\zstd_decompress.obj \
$O\zstd_double_fast.obj \
$O\zstd_fast.obj \
$O\zstd_lazy.obj \
$O\zstd_ldm.obj \
$O\zstdmt_compress.obj \
$O\zstd_opt.obj \
!include "../../7zip.mak"

View File

@@ -7,6 +7,23 @@
#include "FilterCoder.h"
#include "StreamUtils.h"
#ifdef _WIN32
#define alignedMidBuffer_Alloc g_MidAlloc
#else
#define alignedMidBuffer_Alloc g_AlignedAlloc
#endif
CAlignedMidBuffer::~CAlignedMidBuffer()
{
ISzAlloc_Free(&alignedMidBuffer_Alloc, _buf);
}
void CAlignedMidBuffer::AllocAligned(size_t size)
{
ISzAlloc_Free(&alignedMidBuffer_Alloc, _buf);
_buf = (Byte *)ISzAlloc_Alloc(&alignedMidBuffer_Alloc, size);
}
/*
AES filters need 16-bytes alignment for HARDWARE-AES instructions.
So we call IFilter::Filter(, size), where (size != 16 * N) only for last data block.
@@ -36,7 +53,7 @@ HRESULT CFilterCoder::Alloc()
size = kMinSize;
if (!_buf || _bufSize != size)
{
AllocAlignedMask(size, 16 - 1);
AllocAligned(size);
if (!_buf)
return E_OUTOFMEMORY;
_bufSize = size;

View File

@@ -19,41 +19,11 @@
struct CAlignedMidBuffer
{
#ifdef _WIN32
Byte *_buf;
CAlignedMidBuffer(): _buf(NULL) {}
~CAlignedMidBuffer() { ::MidFree(_buf); }
void AllocAlignedMask(size_t size, size_t)
{
::MidFree(_buf);
_buf = (Byte *)::MidAlloc(size);
}
#else
Byte *_bufBase;
Byte *_buf;
CAlignedMidBuffer(): _bufBase(NULL), _buf(NULL) {}
~CAlignedMidBuffer() { ::MidFree(_bufBase); }
void AllocAlignedMask(size_t size, size_t alignMask)
{
::MidFree(_bufBase);
_buf = NULL;
_bufBase = (Byte *)::MidAlloc(size + alignMask);
if (_bufBase)
{
// _buf = (Byte *)(((uintptr_t)_bufBase + alignMask) & ~(uintptr_t)alignMask);
_buf = (Byte *)(((ptrdiff_t)_bufBase + alignMask) & ~(ptrdiff_t)alignMask);
}
}
#endif
~CAlignedMidBuffer();
void AllocAligned(size_t size);
};
class CFilterCoder:

View File

@@ -279,7 +279,21 @@ static const CNameToPropID g_NameToPropID[] =
{ VT_UI4, "b" },
{ VT_UI4, "check" },
{ VT_BSTR, "filter" },
{ VT_UI8, "memuse" }
{ VT_UI8, "memuse" },
{ VT_UI4, "strat" },
{ VT_UI4, "fast" },
{ VT_UI4, "long" },
{ VT_UI4, "wlog" },
{ VT_UI4, "hlog" },
{ VT_UI4, "clog" },
{ VT_UI4, "slog" },
{ VT_UI4, "slen" },
{ VT_UI4, "tlen" },
{ VT_UI4, "ovlog" },
{ VT_UI4, "ldmhlog" },
{ VT_UI4, "ldmslen" },
{ VT_UI4, "ldmblog" },
{ VT_UI4, "ldmhevery" }
};
static int FindPropIdExact(const UString &name)

View File

@@ -446,6 +446,14 @@ void CCoder::SetOutStreamSizeResume(const UInt64 *outSize)
STDMETHODIMP CCoder::SetOutStreamSize(const UInt64 *outSize)
{
/*
18.06:
We want to support GetInputProcessedSize() before CCoder::Read()
So we call m_InBitStream.Init() even before buffer allocations
m_InBitStream.Init() just sets variables to default values
But later we will call m_InBitStream.Init() again with real buffer pointers
*/
m_InBitStream.Init();
_needInitInStream = true;
SetOutStreamSizeResume(outSize);
return S_OK;

View File

@@ -87,12 +87,16 @@ STDMETHODIMP CDecoder::SetDecoderProperties2(const Byte * prop, UInt32 size)
{
DProps *pProps = (DProps *)prop;
if (size != sizeof(DProps))
switch (size) {
case 3:
memcpy(&_props, pProps, 3);
return S_OK;
case 5:
memcpy(&_props, pProps, 5);
return S_OK;
default:
return E_NOTIMPL;
memcpy(&_props, pProps, sizeof (DProps));
return S_OK;
}
}
STDMETHODIMP CDecoder::SetNumberOfThreads(UInt32 numThreads)

View File

@@ -87,12 +87,16 @@ STDMETHODIMP CDecoder::SetDecoderProperties2(const Byte * prop, UInt32 size)
{
DProps *pProps = (DProps *)prop;
if (size != sizeof(DProps))
switch (size) {
case 3:
memcpy(&_props, pProps, 3);
return S_OK;
case 5:
memcpy(&_props, pProps, 5);
return S_OK;
default:
return E_NOTIMPL;
memcpy(&_props, pProps, sizeof (DProps));
return S_OK;
}
}
STDMETHODIMP CDecoder::SetNumberOfThreads(UInt32 numThreads)

View File

@@ -517,9 +517,9 @@ HRESULT CDecoder::CodeReal(const Byte *in, size_t inSize, Byte *_win, size_t out
if (len > outSize - _pos)
return S_FALSE;
if (dist > _pos)
return S_FALSE;
size_t span = (size_t)1 << power;
if ((UInt64)dist + span > _pos)
return S_FALSE;
Byte *dest = _win + _pos - span;
const Byte *src = dest - dist;
_pos += len;

View File

@@ -148,7 +148,8 @@ void CDecoder::ExecuteFilter(unsigned tempFilterIndex, NVm::CBlockRef &outBlockR
if (!_vm.Execute(filter, tempFilter, outBlockRef, filter->GlobalData))
_unsupportedFilter = true;
delete tempFilter;
_tempFilters[tempFilterIndex] = 0;
_tempFilters[tempFilterIndex] = NULL;
_numEmptyTempFilters++;
}
HRESULT CDecoder::WriteBuf()
@@ -225,6 +226,7 @@ HRESULT CDecoder::WriteBuf()
void CDecoder::InitFilters()
{
_lastFilter = 0;
_numEmptyTempFilters = 0;
unsigned i;
for (i = 0; i < _tempFilters.Size(); i++)
delete _tempFilters[i];
@@ -274,24 +276,27 @@ bool CDecoder::AddVmCode(UInt32 firstByte, UInt32 codeSize)
filter->ExecCount++;
}
unsigned numEmptyItems = 0;
if (_numEmptyTempFilters != 0)
{
FOR_VECTOR (i, _tempFilters)
unsigned num = _tempFilters.Size();
CTempFilter **tempFilters = &_tempFilters.Front();
unsigned w = 0;
for (unsigned i = 0; i < num; i++)
{
_tempFilters[i - numEmptyItems] = _tempFilters[i];
if (!_tempFilters[i])
numEmptyItems++;
if (numEmptyItems != 0)
_tempFilters[i] = NULL;
CTempFilter *tf = tempFilters[i];
if (tf)
tempFilters[w++] = tf;
}
_tempFilters.DeleteFrom(w);
_numEmptyTempFilters = 0;
}
if (numEmptyItems == 0)
{
_tempFilters.Add(NULL);
numEmptyItems = 1;
}
if (_tempFilters.Size() > MAX_UNPACK_FILTERS)
return false;
CTempFilter *tempFilter = new CTempFilter;
_tempFilters[_tempFilters.Size() - numEmptyItems] = tempFilter;
_tempFilters.Add(tempFilter);
tempFilter->FilterIndex = filterIndex;
UInt32 blockStart = inp.ReadEncodedUInt32();

View File

@@ -189,6 +189,7 @@ class CDecoder:
NVm::CVm _vm;
CRecordVector<CFilter *> _filters;
CRecordVector<CTempFilter *> _tempFilters;
unsigned _numEmptyTempFilters;
UInt32 _lastFilter;
bool _isSolid;

View File

@@ -33,10 +33,11 @@ struct CBitStream
bs.Value = (bs.Value << 16) | GetUi16(in); \
in += 2; bs.BitPos += 16; }
const unsigned kNumHuffBits = 15;
const unsigned kNumLenSlots = 16;
const unsigned kNumPosSlots = 16;
const unsigned kNumSyms = 256 + kNumPosSlots * kNumLenSlots;
static const unsigned kNumHuffBits = 15;
static const unsigned kNumLenBits = 4;
static const unsigned kLenMask = (1 << kNumLenBits) - 1;
static const unsigned kNumPosSlots = 16;
static const unsigned kNumSyms = 256 + (kNumPosSlots << kNumLenBits);
HRESULT Decode(const Byte *in, size_t inSize, Byte *out, size_t outSize)
{
@@ -83,10 +84,10 @@ HRESULT Decode(const Byte *in, size_t inSize, Byte *out, size_t outSize)
else
{
sym -= 256;
UInt32 dist = sym / kNumLenSlots;
UInt32 len = sym & (kNumLenSlots - 1);
UInt32 dist = sym >> kNumLenBits;
UInt32 len = sym & kLenMask;
if (len == kNumLenSlots - 1)
if (len == kLenMask)
{
if (in > lim)
return S_FALSE;
@@ -99,7 +100,7 @@ HRESULT Decode(const Byte *in, size_t inSize, Byte *out, size_t outSize)
in += 2;
}
else
len += kNumLenSlots - 1;
len += kLenMask;
}
bs.BitPos -= dist;
@@ -108,7 +109,7 @@ HRESULT Decode(const Byte *in, size_t inSize, Byte *out, size_t outSize)
BIT_STREAM_NORMALIZE
if (len > outSize - pos)
if (len + 3 > outSize - pos)
return S_FALSE;
if (dist > pos)
return S_FALSE;

View File

@@ -37,10 +37,17 @@ STDMETHODIMP CDecoder::SetDecoderProperties2(const Byte * prop, UInt32 size)
{
DProps *pProps = (DProps *)prop;
#if DEBUG
printf("prop size =%u\n", size);
fflush(stdout);
#endif
switch (size) {
case 3:
memcpy(&_props, pProps, 3);
return S_OK;
case 5:
memcpy(&_props, pProps, sizeof (DProps));
memcpy(&_props, pProps, 5);
return S_OK;
default:
return E_NOTIMPL;
@@ -84,10 +91,6 @@ HRESULT CDecoder::CodeSpec(ISequentialInStream * inStream,
ZSTD_resetDStream(_ctx);
}
zIn.src = _srcBuf;
zIn.size = _srcBufSize;
zIn.pos = 0;
zOut.dst = _dstBuf;
srcBufLen = _srcBufSize;
@@ -95,6 +98,10 @@ HRESULT CDecoder::CodeSpec(ISequentialInStream * inStream,
RINOK(ReadStream(inStream, _srcBuf, &srcBufLen));
_processedIn += srcBufLen;
zIn.src = _srcBuf;
zIn.size = srcBufLen;
zIn.pos = 0;
/* Main decompression Loop */
for (;;) {
for (;;) {
@@ -103,16 +110,16 @@ HRESULT CDecoder::CodeSpec(ISequentialInStream * inStream,
zOut.pos = 0;
result = ZSTD_decompressStream(_ctx, &zOut, &zIn);
if (ZSTD_isError(result)) {
if (ZSTD_isError(result))
return E_FAIL;
}
#if DEBUG
printf("res =%u\n", (unsigned)result);
printf("zIn.size =%u\n", (unsigned)zIn.size);
printf("zIn.pos =%u\n", (unsigned)zIn.pos);
printf("zOut.size =%u\n", (unsigned)zOut.size);
printf("zOut.pos =%u\n", (unsigned)zOut.pos);
printf("res = %u\n", (unsigned)result);
printf("zIn.size = %u\n", (unsigned)zIn.size);
printf("zIn.pos = %u\n", (unsigned)zIn.pos);
printf("zOut.size = %u\n", (unsigned)zOut.size);
printf("zOut.pos = %u\n", (unsigned)zOut.pos);
printf("---------------------\n");
fflush(stdout);
#endif
@@ -120,13 +127,12 @@ HRESULT CDecoder::CodeSpec(ISequentialInStream * inStream,
if (zOut.pos) {
RINOK(WriteStream(outStream, _dstBuf, zOut.pos));
_processedOut += zOut.pos;
RINOK(progress->SetRatioInfo(&_processedIn, &_processedOut));
if (progress)
{
RINOK(progress->SetRatioInfo(&_processedIn, &_processedOut));
}
}
/* one more round */
if ((zIn.pos == zIn.size) && (result == 1) && zOut.pos)
continue;
/* finished with buffer */
if (zIn.pos == zIn.size)
break;
@@ -136,6 +142,11 @@ HRESULT CDecoder::CodeSpec(ISequentialInStream * inStream,
result = ZSTD_resetDStream(_ctx);
if (ZSTD_isError(result))
return E_FAIL;
/* end of frame, but more data */
if (zIn.pos < zIn.size)
continue;
/* read next input, or eof */
break;
}
@@ -145,6 +156,9 @@ HRESULT CDecoder::CodeSpec(ISequentialInStream * inStream,
srcBufLen = _srcBufSize;
RINOK(ReadStream(inStream, _srcBuf, &srcBufLen));
_processedIn += srcBufLen;
#if DEBUG
printf("READ = %u\n", (unsigned)srcBufLen);
#endif
/* finished */
if (srcBufLen == 0)

View File

@@ -22,7 +22,21 @@ CEncoder::CEncoder():
_dstBufSize(ZSTD_CStreamOutSize()),
_processedIn(0),
_processedOut(0),
_numThreads(NWindows::NSystem::GetNumberOfProcessors())
_numThreads(NWindows::NSystem::GetNumberOfProcessors()),
_Long(-1),
_Level(ZSTD_CLEVEL_DEFAULT),
_Strategy(-1),
_WindowLog(-1),
_HashLog(-1),
_ChainLog(-1),
_SearchLog(-1),
_MinMatch(-1),
_TargetLen(-1),
_OverlapLog(-1),
_LdmHashLog(-1),
_LdmMinMatch(-1),
_LdmBucketSizeLog(-1),
_LdmHashRateLog(-1)
{
_props.clear();
_hMutex = CreateMutex(NULL, FALSE, NULL);
@@ -49,24 +63,145 @@ STDMETHODIMP CEncoder::SetCoderProperties(const PROPID * propIDs, const PROPVARI
UInt32 v = (UInt32)prop.ulVal;
switch (propID)
{
case NCoderPropID::kLevel:
{
if (prop.vt != VT_UI4)
return E_INVALIDARG;
/* level 1..22 */
_props._level = static_cast < Byte > (prop.ulVal);
Byte mylevel = static_cast < Byte > (ZSTD_LEVEL_MAX);
if (_props._level > mylevel)
_props._level = mylevel;
break;
}
case NCoderPropID::kNumThreads:
{
SetNumberOfThreads(v);
break;
}
case NCoderPropID::kStrategy:
{
if (v < 1) v = 1;
if (v > 8) v = 8;
_Strategy = v;
break;
}
case NCoderPropID::kLevel:
{
_Level = v;
if (v < 1) {
_Level = 1;
} else if ((Int32)v > ZSTD_maxCLevel()) {
_Level = ZSTD_maxCLevel();
}
/**
* zstd default levels: _Level => 1..ZSTD_maxCLevel()
*/
_props._level = static_cast < Byte > (_Level);
break;
}
case NCoderPropID::kFast:
{
/* like --fast in zstd cli program */
UInt32 _Fast = v;
if (v < 1) {
_Fast = 1;
} else if (v > 64) {
_Fast = 64;
}
/**
* zstd fast levels:
* _Fast => 1..ZSTD_minCLevel() (_Level => _Fast + 32)
*/
_props._level = static_cast < Byte > (_Fast + 32);
/* negative levels are the fast ones */
_Level = _Fast * -1;
break;
}
case NCoderPropID::kLong:
{
/* like --long in zstd cli program */
_Long = 1;
if (v == 0) {
// m0=zstd:long:tlen=x
_WindowLog = 27;
} else if (v < 10) {
_WindowLog = 10;
} else if (v > ZSTD_WINDOWLOG_MAX) {
_WindowLog = ZSTD_WINDOWLOG_MAX;
}
break;
}
case NCoderPropID::kWindowLog:
{
if (v < ZSTD_WINDOWLOG_MIN) v = ZSTD_WINDOWLOG_MIN;
if (v > ZSTD_WINDOWLOG_MAX) v = ZSTD_WINDOWLOG_MAX;
_WindowLog = v;
break;
}
case NCoderPropID::kHashLog:
{
if (v < ZSTD_HASHLOG_MIN) v = ZSTD_HASHLOG_MIN;
if (v > ZSTD_HASHLOG_MAX) v = ZSTD_HASHLOG_MAX;
_HashLog = v;
break;
}
case NCoderPropID::kChainLog:
{
if (v < ZSTD_CHAINLOG_MIN) v = ZSTD_CHAINLOG_MIN;
if (v > ZSTD_CHAINLOG_MAX) v = ZSTD_CHAINLOG_MAX;
_ChainLog = v;
break;
}
case NCoderPropID::kSearchLog:
{
if (v < ZSTD_SEARCHLOG_MIN) v = ZSTD_SEARCHLOG_MIN;
if (v > ZSTD_SEARCHLOG_MAX) v = ZSTD_SEARCHLOG_MAX;
_SearchLog = v;
break;
}
case NCoderPropID::kMinMatch:
{
if (v < ZSTD_MINMATCH_MIN) v = ZSTD_MINMATCH_MIN;
if (v > ZSTD_MINMATCH_MAX) v = ZSTD_MINMATCH_MAX;
_MinMatch = v;
break;
}
case NCoderPropID::kTargetLen:
{
if (v < ZSTD_TARGETLENGTH_MIN) v = ZSTD_TARGETLENGTH_MIN;
if (v > ZSTD_TARGETLENGTH_MAX) v = ZSTD_TARGETLENGTH_MAX;
_TargetLen = 0;
break;
}
case NCoderPropID::kOverlapLog:
{
if (v < 0) v = 0; /* no overlap */
if (v > 9) v = 9; /* full size */
_OverlapLog = v;
break;
}
case NCoderPropID::kLdmHashLog:
{
if (v < ZSTD_HASHLOG_MIN) v = ZSTD_HASHLOG_MIN;
if (v > ZSTD_HASHLOG_MAX) v = ZSTD_HASHLOG_MAX;
_LdmHashLog = v;
break;
}
case NCoderPropID::kLdmSearchLength:
{
if (v < ZSTD_LDM_MINMATCH_MIN) v = ZSTD_LDM_MINMATCH_MIN;
if (v > ZSTD_LDM_MINMATCH_MAX) v = ZSTD_LDM_MINMATCH_MAX;
_LdmMinMatch = v;
break;
}
case NCoderPropID::kLdmBucketSizeLog:
{
if (v < 1) v = 1;
if (v > ZSTD_LDM_BUCKETSIZELOG_MAX) v = ZSTD_LDM_BUCKETSIZELOG_MAX;
_LdmBucketSizeLog = v;
break;
}
case NCoderPropID::kLdmHashRateLog:
{
if (v < 0) v = 0; /* 0 => automatic mode */
if (v > (ZSTD_WINDOWLOG_MAX - ZSTD_HASHLOG_MIN)) v = (ZSTD_WINDOWLOG_MAX - ZSTD_HASHLOG_MIN);
_LdmHashRateLog = v;
break;
}
default:
{
break;
@@ -105,20 +240,86 @@ STDMETHODIMP CEncoder::Code(ISequentialInStream *inStream,
return E_OUTOFMEMORY;
/* setup level */
err = ZSTD_CCtx_setParameter(_ctx, ZSTD_p_compressionLevel, _props._level);
if (ZSTD_isError(err)) return E_FAIL;
err = ZSTD_CCtx_setParameter(_ctx, ZSTD_c_compressionLevel, (UInt32)_Level);
if (ZSTD_isError(err)) return E_INVALIDARG;
/* setup thread count */
err = ZSTD_CCtx_setParameter(_ctx, ZSTD_p_nbWorkers, _numThreads);
if (ZSTD_isError(err)) return E_FAIL;
err = ZSTD_CCtx_setParameter(_ctx, ZSTD_c_nbWorkers, _numThreads);
if (ZSTD_isError(err)) return E_INVALIDARG;
/* set the content size flag */
err = ZSTD_CCtx_setParameter(_ctx, ZSTD_p_contentSizeFlag, 1);
if (ZSTD_isError(err)) return E_FAIL;
err = ZSTD_CCtx_setParameter(_ctx, ZSTD_c_contentSizeFlag, 1);
if (ZSTD_isError(err)) return E_INVALIDARG;
/* todo: make this optional */
err = ZSTD_CCtx_setParameter(_ctx, ZSTD_p_enableLongDistanceMatching, 1);
if (ZSTD_isError(err)) return E_FAIL;
/* enable ldm for large windowlog values */
if (_WindowLog > 27 && _Long == 0)
_Long = 1;
/* set ldm */
if (_Long != -1) {
err = ZSTD_CCtx_setParameter(_ctx, ZSTD_c_enableLongDistanceMatching, _Long);
if (ZSTD_isError(err)) return E_INVALIDARG;
}
if (_Strategy != -1) {
err = ZSTD_CCtx_setParameter(_ctx, ZSTD_c_strategy, _Strategy);
if (ZSTD_isError(err)) return E_INVALIDARG;
}
if (_WindowLog != -1) {
err = ZSTD_CCtx_setParameter(_ctx, ZSTD_c_windowLog, _WindowLog);
if (ZSTD_isError(err)) return E_INVALIDARG;
}
if (_HashLog != -1) {
err = ZSTD_CCtx_setParameter(_ctx, ZSTD_c_hashLog, _HashLog);
if (ZSTD_isError(err)) return E_INVALIDARG;
}
if (_ChainLog != -1) {
err = ZSTD_CCtx_setParameter(_ctx, ZSTD_c_chainLog, _ChainLog);
if (ZSTD_isError(err)) return E_INVALIDARG;
}
if (_SearchLog != -1) {
err = ZSTD_CCtx_setParameter(_ctx, ZSTD_c_searchLog, _SearchLog);
if (ZSTD_isError(err)) return E_INVALIDARG;
}
if (_MinMatch != -1) {
err = ZSTD_CCtx_setParameter(_ctx, ZSTD_c_minMatch, _MinMatch);
if (ZSTD_isError(err)) return E_INVALIDARG;
}
if (_TargetLen != -1) {
err = ZSTD_CCtx_setParameter(_ctx, ZSTD_c_targetLength, _TargetLen);
if (ZSTD_isError(err)) return E_INVALIDARG;
}
if (_OverlapLog != -1) {
err = ZSTD_CCtx_setParameter(_ctx, ZSTD_c_overlapLog, _OverlapLog);
if (ZSTD_isError(err)) return E_INVALIDARG;
}
if (_LdmHashLog != -1) {
err = ZSTD_CCtx_setParameter(_ctx, ZSTD_c_ldmHashLog, _LdmHashLog);
if (ZSTD_isError(err)) return E_INVALIDARG;
}
if (_LdmMinMatch != -1) {
err = ZSTD_CCtx_setParameter(_ctx, ZSTD_c_ldmMinMatch, _LdmMinMatch);
if (ZSTD_isError(err)) return E_INVALIDARG;
}
if (_LdmBucketSizeLog != -1) {
err = ZSTD_CCtx_setParameter(_ctx, ZSTD_c_ldmBucketSizeLog, _LdmBucketSizeLog);
if (ZSTD_isError(err)) return E_INVALIDARG;
}
if (_LdmHashRateLog != -1) {
err = ZSTD_CCtx_setParameter(_ctx, ZSTD_c_ldmHashRateLog, _LdmHashRateLog);
if (ZSTD_isError(err)) return E_INVALIDARG;
}
}
for (;;) {
@@ -151,7 +352,7 @@ STDMETHODIMP CEncoder::Code(ISequentialInStream *inStream,
inBuff.pos = 0;
}
err = ZSTD_compress_generic(_ctx, &outBuff, &inBuff, ZSTD_todo);
err = ZSTD_compressStream2(_ctx, &outBuff, &inBuff, ZSTD_todo);
if (ZSTD_isError(err)) return E_FAIL;
#if DEBUG

View File

@@ -51,6 +51,22 @@ class CEncoder:
UInt32 _numThreads;
HANDLE _hMutex;
/* zstd advanced compression options */
Int32 _Long;
Int32 _Level;
Int32 _Strategy;
Int32 _WindowLog;
Int32 _HashLog;
Int32 _ChainLog;
Int32 _SearchLog;
Int32 _MinMatch;
Int32 _TargetLen;
Int32 _OverlapLog;
Int32 _LdmHashLog;
Int32 _LdmMinMatch;
Int32 _LdmBucketSizeLog;
Int32 _LdmHashRateLog;
public:
MY_QUERYINTERFACE_BEGIN2(ICompressCoder)
MY_QUERYINTERFACE_ENTRY(ICompressSetCoderMt)

View File

@@ -1,6 +1,6 @@
C_OBJS = $(C_OBJS) \
$O\7zCrc.obj
!IF "$(CPU)" == "IA64" || "$(CPU)" == "MIPS" || "$(CPU)" == "ARM" || "$(CPU)" == "ARM64"
!IF "$(PLATFORM)" == "ia64" || "$(PLATFORM)" == "mips" || "$(PLATFORM)" == "arm" || "$(PLATFORM)" == "arm64"
C_OBJS = $(C_OBJS) \
!ELSE
ASM_OBJS = $(ASM_OBJS) \

View File

@@ -1,6 +1,6 @@
C_OBJS = $(C_OBJS) \
$O\XzCrc64.obj
!IF "$(CPU)" == "IA64" || "$(CPU)" == "MIPS" || "$(CPU)" == "ARM" || "$(CPU)" == "ARM64"
!IF "$(PLATFORM)" == "ia64" || "$(PLATFORM)" == "mips" || "$(PLATFORM)" == "arm" || "$(PLATFORM)" == "arm64"
C_OBJS = $(C_OBJS) \
!ELSE
ASM_OBJS = $(ASM_OBJS) \

View File

@@ -164,8 +164,8 @@ STDMETHODIMP CEncoder::ResetInitVector()
{
for (unsigned i = 0; i < sizeof(_iv); i++)
_iv[i] = 0;
_ivSize = 8;
g_RandomGenerator.Generate(_iv, _ivSize);
_ivSize = 16;
MY_RAND_GEN(_iv, _ivSize);
return S_OK;
}

View File

@@ -2,14 +2,44 @@
#include "StdAfx.h"
#include "RandGen.h"
#ifndef USE_STATIC_SYSTEM_RAND
#ifndef _7ZIP_ST
#include "../../Windows/Synchronization.h"
#endif
#include "RandGen.h"
#ifndef _WIN32
#ifdef _WIN32
#ifdef _WIN64
#define USE_STATIC_RtlGenRandom
#endif
#ifdef USE_STATIC_RtlGenRandom
#include <ntsecapi.h>
EXTERN_C_BEGIN
#ifndef RtlGenRandom
#define RtlGenRandom SystemFunction036
BOOLEAN WINAPI RtlGenRandom(PVOID RandomBuffer, ULONG RandomBufferLength);
#endif
EXTERN_C_END
#else
EXTERN_C_BEGIN
typedef BOOLEAN (WINAPI * Func_RtlGenRandom)(PVOID RandomBuffer, ULONG RandomBufferLength);
EXTERN_C_END
#endif
#else
#include <unistd.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#define USE_POSIX_TIME
#define USE_POSIX_TIME2
#endif
@@ -21,11 +51,9 @@
#endif
#endif
// This is not very good random number generator.
// Please use it only for salt.
// First generated data block depends from timer and processID.
// The seed and first generated data block depend from processID,
// theadID, timer and system random generator, if available.
// Other generated data blocks depend from previous state
// Maybe it's possible to restore original timer value from generated value.
#define HASH_UPD(x) Sha256_Update(&hash, (const Byte *)&x, sizeof(x));
@@ -34,25 +62,102 @@ void CRandomGenerator::Init()
CSha256 hash;
Sha256_Init(&hash);
unsigned numIterations = 1000;
{
#ifndef UNDER_CE
const unsigned kNumIterations_Small = 100;
const unsigned kBufSize = 32;
Byte buf[kBufSize];
#endif
#ifdef _WIN32
DWORD w = ::GetCurrentProcessId();
HASH_UPD(w);
w = ::GetCurrentThreadId();
HASH_UPD(w);
#ifdef UNDER_CE
/*
if (CeGenRandom(kBufSize, buf))
{
numIterations = kNumIterations_Small;
Sha256_Update(&hash, buf, kBufSize);
}
*/
#elif defined(USE_STATIC_RtlGenRandom)
if (RtlGenRandom(buf, kBufSize))
{
numIterations = kNumIterations_Small;
Sha256_Update(&hash, buf, kBufSize);
}
#else
{
HMODULE hModule = ::LoadLibrary(TEXT("Advapi32.dll"));
if (hModule)
{
// SystemFunction036() is real name of RtlGenRandom() function
Func_RtlGenRandom my_RtlGenRandom = (Func_RtlGenRandom)GetProcAddress(hModule, "SystemFunction036");
if (my_RtlGenRandom)
{
if (my_RtlGenRandom(buf, kBufSize))
{
numIterations = kNumIterations_Small;
Sha256_Update(&hash, buf, kBufSize);
}
}
::FreeLibrary(hModule);
}
}
#endif
#else
pid_t pid = getpid();
HASH_UPD(pid);
pid = getppid();
HASH_UPD(pid);
{
int f = open("/dev/urandom", O_RDONLY);
unsigned numBytes = kBufSize;
if (f >= 0)
{
do
{
int n = read(f, buf, numBytes);
if (n <= 0)
break;
Sha256_Update(&hash, buf, n);
numBytes -= n;
}
while (numBytes);
close(f);
if (numBytes == 0)
numIterations = kNumIterations_Small;
}
}
/*
{
int n = getrandom(buf, kBufSize, 0);
if (n > 0)
{
Sha256_Update(&hash, buf, n);
if (n == kBufSize)
numIterations = kNumIterations_Small;
}
}
*/
#endif
}
#ifdef _DEBUG
numIterations = 2;
#endif
for (unsigned i = 0; i <
#ifdef _DEBUG
2;
#else
1000;
#endif
i++)
do
{
#ifdef _WIN32
LARGE_INTEGER v;
@@ -85,6 +190,8 @@ void CRandomGenerator::Init()
Sha256_Update(&hash, _buff, SHA256_DIGEST_SIZE);
}
}
while (--numIterations);
Sha256_Final(&hash, _buff);
_needInit = false;
}
@@ -122,3 +229,5 @@ void CRandomGenerator::Generate(Byte *data, unsigned size)
}
CRandomGenerator g_RandomGenerator;
#endif

View File

@@ -5,6 +5,21 @@
#include "../../../C/Sha256.h"
#ifdef _WIN64
// #define USE_STATIC_SYSTEM_RAND
#endif
#ifdef USE_STATIC_SYSTEM_RAND
#ifdef _WIN32
#include <ntsecapi.h>
#define MY_RAND_GEN(data, size) RtlGenRandom(data, size)
#else
#define MY_RAND_GEN(data, size) getrandom(data, size, 0)
#endif
#else
class CRandomGenerator
{
Byte _buff[SHA256_DIGEST_SIZE];
@@ -18,4 +33,8 @@ public:
extern CRandomGenerator g_RandomGenerator;
#define MY_RAND_GEN(data, size) g_RandomGenerator.Generate(data, size)
#endif
#endif

View File

@@ -96,7 +96,7 @@ STDMETHODIMP CBaseCoder::Init()
HRESULT CEncoder::WriteHeader(ISequentialOutStream *outStream)
{
unsigned saltSize = _key.GetSaltSize();
g_RandomGenerator.Generate(_key.Salt, saltSize);
MY_RAND_GEN(_key.Salt, saltSize);
Init2();
RINOK(WriteStream(outStream, _key.Salt, saltSize));
return WriteStream(outStream, _key.PwdVerifComputed, kPwdVerifSize);

View File

@@ -49,7 +49,7 @@ HRESULT CEncoder::WriteHeader_Check16(ISequentialOutStream *outStream, UInt16 cr
PKZIP 2.0+ used 1 byte CRC check. It's more secure.
We also use 1 byte CRC. */
g_RandomGenerator.Generate(h, kHeaderSize - 1);
MY_RAND_GEN(h, kHeaderSize - 1);
// h[kHeaderSize - 2] = (Byte)(crc);
h[kHeaderSize - 1] = (Byte)(crc >> 8);

View File

@@ -85,13 +85,14 @@ HRESULT CDecoder::ReadHeader(ISequentialInStream *inStream, UInt32 crc, UInt64 u
return E_NOTIMPL;
RINOK(ReadStream_FALSE(inStream, temp, 4));
_remSize = GetUi32(temp);
const UInt32 kAlign = 16;
// const UInt32 kAlign = 16;
if (_remSize < 16 || _remSize > (1 << 18))
return E_NOTIMPL;
if (_remSize + kAlign > _buf.Size())
if (_remSize > _bufAligned.Size())
{
_buf.Alloc(_remSize + kAlign);
_bufAligned = (Byte *)((ptrdiff_t)((Byte *)_buf + kAlign - 1) & ~(ptrdiff_t)(kAlign - 1));
_bufAligned.AllocAtLeast(_remSize);
if (!(Byte *)_bufAligned)
return E_OUTOFMEMORY;
}
return ReadStream_FALSE(inStream, _bufAligned, _remSize);
}

View File

@@ -3,7 +3,7 @@
#ifndef __CRYPTO_ZIP_STRONG_H
#define __CRYPTO_ZIP_STRONG_H
#include "../../Common/MyBuffer.h"
#include "../../Common/MyBuffer2.h"
#include "../IPassword.h"
@@ -35,8 +35,7 @@ class CBaseCoder:
{
protected:
CKeyInfo _key;
CByteBuffer _buf;
Byte *_bufAligned;
CAlignedBuffer _bufAligned;
public:
STDMETHOD(Init)();
STDMETHOD(CryptoSetPassword)(const Byte *data, UInt32 size);

View File

@@ -131,7 +131,23 @@ namespace NCoderPropID
kBlockSize2, // VT_UI4 or VT_UI8
kCheckSize, // VT_UI4 : size of digest in bytes
kFilter, // VT_BSTR
kMemUse // VT_UI8
kMemUse, // VT_UI8
/* zstd props */
kStrategy, // VT_UI4 1=ZSTD_fast, 2=ZSTD_dfast, 3=ZSTD_greedy, 4=ZSTD_lazy, 5=ZSTD_lazy2, 6=ZSTD_btlazy2, 7=ZSTD_btopt, 8=ZSTD_btultra
kFast, // VT_UI4 The minimum fast is 1 and the maximum is 64 (default: unused)
kLong, // VT_UI4 The minimum long is 10 (1KiB) and the maximum is 30 (1GiB) on x32 and 31 (2GiB) on x64
kWindowLog, // VT_UI4 The minimum long is 10 (1KiB) and the maximum is 30 (1GiB) on x32 and 31 (2GiB) on x64
kHashLog, // VT_UI4 The minimum hlog is 6 (64 B) and the maximum is 26 (128 MiB).
kChainLog, // VT_UI4 The minimum clog is 6 (64 B) and the maximum is 28 (256 MiB)
kSearchLog, // VT_UI4 The minimum slog is 1 and the maximum is 26
kMinMatch, // VT_UI4 The minimum slen is 3 and the maximum is 7.
kTargetLen, // VT_UI4 The minimum tlen is 0 and the maximum is 999.
kOverlapLog, // VT_UI4 The minimum ovlog is 0 and the maximum is 9. (default: 6)
kLdmHashLog, // VT_UI4 The minimum ldmhlog is 6 and the maximum is 26 (default: 20).
kLdmSearchLength, // VT_UI4 The minimum ldmslen is 4 and the maximum is 4096 (default: 64).
kLdmBucketSizeLog, // VT_UI4 The minimum ldmblog is 0 and the maximum is 8 (default: 3).
kLdmHashRateLog // VT_UI4 The default value is wlog - ldmhlog.
};
}

View File

@@ -6,15 +6,10 @@
#include "../Common/MyUnknown.h"
#define k_7zip_GUID_Data1 0x23170F69
#ifdef NEED_7ZIP_GUID
#define k_7zip_GUID_Data2 0x40C1
#else
#define k_7zip_GUID_Data2 0x0803
#endif
#define k_7zip_GUID_Data2_ZS 0x20BB
#define k_7zip_GUID_Data3_Common 0x278A
#define k_7zip_GUID_Data3_Decoder 0x2790
#define k_7zip_GUID_Data3_Encoder 0x2791
#define k_7zip_GUID_Data3_Hasher 0x2792

View File

@@ -1,4 +1,4 @@
!IF "$(CPU)" == "AMD64"
!IF "$(PLATFORM)" == "x64"
CFLAGS_C_SPEC = -D_LZMA_DEC_OPT
ASM_OBJS = $(ASM_OBJS) \
$O\LzmaDecOpt.obj

View File

@@ -33,7 +33,7 @@ HINSTANCE g_hInstance = 0;
// Tou can find the list of all GUIDs in Guid.txt file.
// use another CLSIDs, if you want to support other formats (zip, rar, ...).
// {23170F69-0803-278A-1000-000110070000}
// {23170F69-40C1-278A-1000-000110070000}
DEFINE_GUID(CLSID_CFormat7z,
0x23170F69, 0x40C1, 0x278A, 0x10, 0x00, 0x00, 0x01, 0x10, 0x07, 0x00, 0x00);

View File

@@ -23,6 +23,7 @@
#include "../../../Common/StringConvert.h"
#include "../../../Common/StringToInt.h"
#include "../../../Windows/ErrorMsg.h"
#include "../../../Windows/FileDir.h"
#include "../../../Windows/FileName.h"
#ifdef _WIN32
@@ -39,7 +40,9 @@
extern bool g_CaseSensitive;
extern bool g_PathTrailReplaceMode;
#ifdef _7ZIP_LARGE_PAGES
bool g_LargePagesMode = false;
#endif
#ifdef UNDER_CE
@@ -410,8 +413,19 @@ static void AddToCensorFromListFile(
UStringVector names;
if (!NFind::DoesFileExist(us2fs(fileName)))
throw CArcCmdLineException(kCannotFindListFile, fileName);
if (!ReadNamesFromListFile(us2fs(fileName), names, codePage))
DWORD lastError = 0;
if (!ReadNamesFromListFile2(us2fs(fileName), names, codePage, lastError))
{
if (lastError != 0)
{
UString m;
m = "The file operation error for listfile";
m.Add_LF();
m += NError::MyFormatMessage(lastError);
throw CArcCmdLineException(m, fileName);
}
throw CArcCmdLineException(kIncorrectListFile, fileName);
}
if (renamePairs)
{
if ((names.Size() & 1) != 0)

View File

@@ -1182,7 +1182,9 @@ if (askExtractMode == NArchive::NExtract::NAskMode::kExtract && !_testMode)
bool needDelete = true;
if (needDelete)
{
if (NFind::DoesFileExist(fullProcessedPath))
if (!DeleteFileAlways(fullProcessedPath))
if (GetLastError() != ERROR_FILE_NOT_FOUND)
{
RINOK(SendMessageError_with_LastError(kCantDeleteOutputFile, fullProcessedPath));
return S_OK;
@@ -1368,13 +1370,35 @@ if (askExtractMode == NArchive::NExtract::NAskMode::kExtract && !_testMode)
// UInt64 ticks = GetCpuTicks();
bool res = _outFileStreamSpec->File.SetLength(_curSize);
_fileLengthWasSet = res;
_outFileStreamSpec->File.SeekToBegin();
// ticks = GetCpuTicks() - ticks;
// printf("\nticks = %10d\n", (unsigned)ticks);
if (!res)
{
RINOK(SendMessageError_with_LastError(kCantSetFileLen, fullProcessedPath));
}
/*
_outFileStreamSpec->File.Close();
ticks = GetCpuTicks() - ticks;
printf("\nticks = %10d\n", (unsigned)ticks);
return S_FALSE;
*/
/*
File.SetLength() on FAT (xp64): is fast, but then File.Close() can be slow,
if we don't write any data.
File.SetLength() for remote share file (exFAT) can be slow in some cases,
and the Windows can return "network error" after 1 minute,
while remote file still can grow.
We need some way to detect such bad cases and disable PreAllocateOutFile mode.
*/
res = _outFileStreamSpec->File.SeekToBegin();
if (!res)
{
RINOK(SendMessageError_with_LastError("Can not seek to begin of file", fullProcessedPath));
}
}
#ifdef SUPPORT_ALT_STREAMS

View File

@@ -2,6 +2,8 @@
#include "StdAfx.h"
#include "../../../Common/Wildcard.h"
#include "../../../Windows/FileDir.h"
#include "../../../Windows/FileName.h"
@@ -11,7 +13,7 @@
using namespace NWindows;
using namespace NFile;
UString CreateArchiveName(const NFind::CFileInfo &fi, bool keepName)
static UString CreateArchiveName(const NFind::CFileInfo &fi, bool keepName)
{
FString resultName = fi.Name;
if (!fi.IsDir() && !keepName)
@@ -72,7 +74,82 @@ static FString CreateArchiveName2(const FString &path, bool fromPrev, bool keepN
return resultName;
}
UString CreateArchiveName(const UString &path, bool fromPrev, bool keepName)
UString CreateArchiveName(const UStringVector &paths, const NFind::CFileInfo *fi)
{
return Get_Correct_FsFile_Name(fs2us(CreateArchiveName2(us2fs(path), fromPrev, keepName)));
bool keepName = false;
/*
if (paths.Size() == 1)
{
const UString &name = paths[0];
if (name.Len() > 4)
if (CompareFileNames(name.RightPtr(4), L".tar") == 0)
keepName = true;
}
*/
UString name;
if (fi)
name = CreateArchiveName(*fi, keepName);
else
{
if (paths.IsEmpty())
return L"archive";
bool fromPrev = (paths.Size() > 1);
name = Get_Correct_FsFile_Name(fs2us(CreateArchiveName2(us2fs(paths.Front()), fromPrev, keepName)));
}
UStringVector names;
{
FOR_VECTOR (i, paths)
{
NFind::CFileInfo fi2;
const NFind::CFileInfo *fp;
if (fi && paths.Size() == 1)
fp = fi;
else
{
if (!fi2.Find(us2fs(paths[i])))
continue;
fp = &fi2;
}
names.Add(fs2us(fp->Name));
}
}
UString postfix;
UInt32 index = 1;
for (;;)
{
// we don't want cases when we include archive to itself.
// so we find first available name for archive
const UString name2 = name + postfix;
const UString name2_zip = name2 + L".zip";
const UString name2_7z = name2 + L".7z";
const UString name2_tar = name2 + L".tar";
const UString name2_wim = name2 + L".wim";
unsigned i = 0;
for (i = 0; i < names.Size(); i++)
{
const UString &fname = names[i];
if ( 0 == CompareFileNames(fname, name2_zip)
|| 0 == CompareFileNames(fname, name2_7z)
|| 0 == CompareFileNames(fname, name2_tar)
|| 0 == CompareFileNames(fname, name2_wim))
break;
}
if (i == names.Size())
break;
index++;
postfix = "_";
postfix.Add_UInt32(index);
}
name += postfix;
return name;
}

View File

@@ -3,11 +3,8 @@
#ifndef __ARCHIVE_NAME_H
#define __ARCHIVE_NAME_H
#include "../../../Common/MyString.h"
#include "../../../Windows/FileFind.h"
UString CreateArchiveName(const UString &path, bool fromPrev, bool keepName);
UString CreateArchiveName(const NWindows::NFile::NFind::CFileInfo &fileInfo, bool keepName);
UString CreateArchiveName(const UStringVector &paths, const NWindows::NFile::NFind::CFileInfo *fi = NULL);
#endif

View File

@@ -102,7 +102,14 @@ STDMETHODIMP COpenCallbackImp::GetStream(const wchar_t *name, IInStream **inStre
// if (!allowAbsVolPaths)
if (!IsSafePath(name2))
return S_FALSE;
// #ifdef _WIN32
// we don't want to support wildcards in names here here
if (name2.Find(L'?') >= 0 ||
name2.Find(L'*') >= 0)
return S_FALSE;
// #endif
#endif

View File

@@ -29,7 +29,6 @@
#endif
#include "../../../../C/7zCrc.h"
#include "../../../../C/Alloc.h"
#include "../../../../C/CpuArch.h"
#ifndef _7ZIP_ST
@@ -47,6 +46,7 @@
#include "../../../Common/IntToString.h"
#include "../../../Common/MyBuffer2.h"
#include "../../../Common/StringConvert.h"
#include "../../../Common/StringToInt.h"
@@ -94,80 +94,33 @@ static const UInt32 kAdditionalSize = (1 << 16);
static const UInt32 kCompressedAdditionalSize = (1 << 10);
static const UInt32 kMaxLzmaPropSize = 5;
#define ALLOC_WITH_HRESULT(_buffer_, _size_) \
(_buffer_)->Alloc(_size_); \
if (!(_buffer_)->IsAllocated()) return E_OUTOFMEMORY;
class CBaseRandomGenerator
{
UInt32 A1;
UInt32 A2;
UInt32 Salt;
public:
CBaseRandomGenerator() { Init(); }
CBaseRandomGenerator(UInt32 salt = 0): Salt(salt) { Init(); }
void Init() { A1 = 362436069; A2 = 521288629;}
UInt32 GetRnd()
{
return
return Salt ^
(
((A1 = 36969 * (A1 & 0xffff) + (A1 >> 16)) << 16) +
((A2 = 18000 * (A2 & 0xffff) + (A2 >> 16)) );
((A2 = 18000 * (A2 & 0xffff) + (A2 >> 16)) )
);
}
};
static const unsigned kBufferAlignment = 1 << 4;
struct CBenchBuffer
{
size_t BufferSize;
#ifdef _WIN32
Byte *Buffer;
CBenchBuffer(): BufferSize(0), Buffer(NULL) {}
~CBenchBuffer() { ::MidFree(Buffer); }
void AllocAlignedMask(size_t size, size_t)
{
::MidFree(Buffer);
BufferSize = 0;
Buffer = (Byte *)::MidAlloc(size);
if (Buffer)
BufferSize = size;
}
#else
Byte *Buffer;
Byte *_bufBase;
CBenchBuffer(): BufferSize(0), Buffer(NULL), _bufBase(NULL){}
~CBenchBuffer() { ::MidFree(_bufBase); }
void AllocAlignedMask(size_t size, size_t alignMask)
{
::MidFree(_bufBase);
Buffer = NULL;
BufferSize = 0;
_bufBase = (Byte *)::MidAlloc(size + alignMask);
if (_bufBase)
{
// Buffer = (Byte *)(((uintptr_t)_bufBase + alignMask) & ~(uintptr_t)alignMask);
Buffer = (Byte *)(((ptrdiff_t)_bufBase + alignMask) & ~(ptrdiff_t)alignMask);
BufferSize = size;
}
}
#endif
bool Alloc(size_t size)
{
if (Buffer && BufferSize == size)
return true;
AllocAlignedMask(size, kBufferAlignment - 1);
return (Buffer != NULL || size == 0);
}
};
class CBenchRandomGenerator: public CBenchBuffer
class CBenchRandomGenerator: public CAlignedBuffer
{
static UInt32 GetVal(UInt32 &res, unsigned numBits)
{
@@ -184,23 +137,22 @@ class CBenchRandomGenerator: public CBenchBuffer
public:
void GenerateSimpleRandom(CBaseRandomGenerator *_RG_)
void GenerateSimpleRandom(UInt32 salt)
{
CBaseRandomGenerator rg = *_RG_;
const size_t bufSize = BufferSize;
Byte *buf = Buffer;
CBaseRandomGenerator rg(salt);
const size_t bufSize = Size();
Byte *buf = (Byte *)*this;
for (size_t i = 0; i < bufSize; i++)
buf[i] = (Byte)rg.GetRnd();
*_RG_ = rg;
}
void GenerateLz(unsigned dictBits, CBaseRandomGenerator *_RG_)
void GenerateLz(unsigned dictBits, UInt32 salt)
{
CBaseRandomGenerator rg = *_RG_;
CBaseRandomGenerator rg(salt);
UInt32 pos = 0;
UInt32 rep0 = 1;
const size_t bufSize = BufferSize;
Byte *buf = Buffer;
const size_t bufSize = Size();
Byte *buf = (Byte *)*this;
unsigned posBits = 1;
while (pos < bufSize)
@@ -255,8 +207,6 @@ public:
*dest++ = *src++;
}
}
*_RG_ = rg;
}
};
@@ -297,7 +247,7 @@ STDMETHODIMP CBenchmarkInStream::Read(void *data, UInt32 size, UInt32 *processed
class CBenchmarkOutStream:
public ISequentialOutStream,
public CBenchBuffer,
public CAlignedBuffer,
public CMyUnknownImp
{
// bool _overflow;
@@ -325,13 +275,13 @@ public:
STDMETHODIMP CBenchmarkOutStream::Write(const void *data, UInt32 size, UInt32 *processedSize)
{
size_t curSize = BufferSize - Pos;
size_t curSize = Size() - Pos;
if (curSize > size)
curSize = size;
if (curSize != 0)
{
if (RealCopy)
memcpy(Buffer + Pos, data, curSize);
memcpy(((Byte *)*this) + Pos, data, curSize);
if (CalcCrc)
Crc = CrcUpdate(Crc, data, curSize);
Pos += curSize;
@@ -522,10 +472,9 @@ class CBenchProgressInfo:
{
public:
CBenchProgressStatus *Status;
HRESULT Res;
IBenchCallback *Callback;
CBenchProgressInfo(): Callback(0) {}
CBenchProgressInfo(): Callback(NULL) {}
MY_UNKNOWN_IMP
STDMETHOD(SetRatioInfo)(const UInt64 *inSize, const UInt64 *outSize);
};
@@ -687,20 +636,39 @@ UInt64 GetDecompressRating(UInt64 elapsedTime, UInt64 freq, UInt64 outSize, UInt
return props.GetDecompressRating(elapsedTime, freq, outSize, inSize, numIterations);
}
#ifndef _7ZIP_ST
struct CBenchSyncCommon
{
bool ExitMode;
NSynchronization::CManualResetEvent StartEvent;
CBenchSyncCommon(): ExitMode(false) {}
};
#endif
struct CEncoderInfo;
struct CEncoderInfo
{
#ifndef _7ZIP_ST
NWindows::CThread thread[2];
NSynchronization::CManualResetEvent ReadyEvent;
UInt32 NumDecoderSubThreads;
CBenchSyncCommon *Common;
#endif
CMyComPtr<ICompressCoder> _encoder;
CMyComPtr<ICompressFilter> _encoderFilter;
CBenchProgressInfo *progressInfoSpec[2];
CMyComPtr<ICompressProgressInfo> progressInfo[2];
UInt64 NumIterations;
UInt32 Salt;
#ifdef USE_ALLOCA
size_t AllocaSize;
#endif
@@ -739,26 +707,29 @@ struct CEncoderInfo
const Byte *fileData;
CBenchRandomGenerator rg;
CBenchBuffer rgCopy; // it must be 16-byte aligned !!!
CAlignedBuffer rgCopy; // it must be 16-byte aligned !!!
CBenchmarkOutStream *propStreamSpec;
CMyComPtr<ISequentialOutStream> propStream;
// for decode
unsigned generateDictBits;
COneMethodInfo _method;
// for decode
size_t _uncompressedDataSize;
HRESULT Init(
const COneMethodInfo &method,
unsigned generateDictBits,
CBaseRandomGenerator *rg);
HRESULT Generate();
HRESULT Encode();
HRESULT Decode(UInt32 decoderIndex);
CEncoderInfo():
#ifndef _7ZIP_ST
Common(NULL),
#endif
Salt(0),
fileData(NULL),
CheckCrc_Enc(true),
CheckCrc_Dec(true),
outStreamSpec(0), callback(0), printCallback(0), propStreamSpec(0) {}
outStreamSpec(NULL), callback(NULL), printCallback(NULL), propStreamSpec(NULL) {}
#ifndef _7ZIP_ST
@@ -773,14 +744,15 @@ struct CEncoderInfo
#endif
res = encoder->Encode();
encoder->Results[0] = res;
}
catch(...)
{
res = E_FAIL;
}
encoder->Results[0] = res;
if (res != S_OK)
encoder->progressInfoSpec[0]->Status->SetResult(res);
encoder->ReadyEvent.Set();
return 0;
}
@@ -799,7 +771,12 @@ struct CEncoderInfo
HRESULT CreateEncoderThread()
{
return thread[0].Create(EncodeThreadFunction, this);
WRes res = 0;
if (!ReadyEvent.IsCreated())
res = ReadyEvent.Create();
if (res == 0)
res = thread[0].Create(EncodeThreadFunction, this);
return HRESULT_FROM_WIN32(res);
}
HRESULT CreateDecoderThread(unsigned index, bool callbackMode
@@ -824,11 +801,10 @@ struct CEncoderInfo
};
HRESULT CEncoderInfo::Init(
const COneMethodInfo &method,
unsigned generateDictBits,
CBaseRandomGenerator *rgLoc)
HRESULT CEncoderInfo::Generate()
{
const COneMethodInfo &method = _method;
// we need extra space, if input data is already compressed
const size_t kCompressedBufferSize =
kCompressedAdditionalSize +
@@ -842,40 +818,39 @@ HRESULT CEncoderInfo::Init(
if (!fileData)
{
if (!rg.Alloc(kBufferSize))
return E_OUTOFMEMORY;
ALLOC_WITH_HRESULT(&rg, kBufferSize);
// DWORD ttt = GetTickCount();
if (generateDictBits == 0)
rg.GenerateSimpleRandom(rgLoc);
rg.GenerateSimpleRandom(Salt);
else
rg.GenerateLz(generateDictBits, rgLoc);
rg.GenerateLz(generateDictBits, Salt);
// printf("\n%d\n ", GetTickCount() - ttt);
crc = CrcCalc(rg.Buffer, rg.BufferSize);
uncompressedDataPtr = rg.Buffer;
crc = CrcCalc((const Byte *)rg, rg.Size());
uncompressedDataPtr = (const Byte *)rg;
}
if (_encoderFilter)
{
if (!rgCopy.Alloc(kBufferSize))
return E_OUTOFMEMORY;
ALLOC_WITH_HRESULT(&rgCopy, kBufferSize);
}
outStreamSpec = new CBenchmarkOutStream;
outStream = outStreamSpec;
if (!outStreamSpec->Alloc(kCompressedBufferSize))
return E_OUTOFMEMORY;
if (!outStream)
{
outStreamSpec = new CBenchmarkOutStream;
outStream = outStreamSpec;
}
ALLOC_WITH_HRESULT(outStreamSpec, kCompressedBufferSize)
propStreamSpec = 0;
if (!propStream)
{
propStreamSpec = new CBenchmarkOutStream;
propStream = propStreamSpec;
}
if (!propStreamSpec->Alloc(kMaxLzmaPropSize))
return E_OUTOFMEMORY;
ALLOC_WITH_HRESULT(propStreamSpec, kMaxLzmaPropSize);
propStreamSpec->Init(true, false);
@@ -962,6 +937,28 @@ static void My_FilterBench(ICompressFilter *filter, Byte *data, size_t size)
HRESULT CEncoderInfo::Encode()
{
RINOK(Generate());
#ifndef _7ZIP_ST
if (Common)
{
Results[0] = S_OK;
WRes wres = ReadyEvent.Set();
if (wres == 0)
wres = Common->StartEvent.Lock();
if (wres != 0)
return HRESULT_FROM_WIN32(wres);
if (Common->ExitMode)
return S_OK;
}
else
#endif
{
CBenchProgressInfo *bpi = progressInfoSpec[0];
bpi->SetStartTime();
}
CBenchInfo &bi = progressInfoSpec[0]->BenchInfo;
bi.UnpackSize = 0;
bi.PackSize = 0;
@@ -998,10 +995,10 @@ HRESULT CEncoderInfo::Encode()
if (_encoderFilter)
{
memcpy(rgCopy.Buffer, uncompressedDataPtr, kBufferSize);
memcpy((Byte *)rgCopy, uncompressedDataPtr, kBufferSize);
_encoderFilter->Init();
My_FilterBench(_encoderFilter, rgCopy.Buffer, kBufferSize);
RINOK(WriteStream(outStream, rgCopy.Buffer, kBufferSize));
My_FilterBench(_encoderFilter, (Byte *)rgCopy, kBufferSize);
RINOK(WriteStream(outStream, (const Byte *)rgCopy, kBufferSize));
}
else
{
@@ -1079,7 +1076,7 @@ HRESULT CEncoderInfo::Decode(UInt32 decoderIndex)
if (setDecProps)
{
RINOK(setDecProps->SetDecoderProperties2(propStreamSpec->Buffer, (UInt32)propStreamSpec->Pos));
RINOK(setDecProps->SetDecoderProperties2((const Byte *)*propStreamSpec, (UInt32)propStreamSpec->Pos));
}
{
@@ -1107,7 +1104,7 @@ HRESULT CEncoderInfo::Decode(UInt32 decoderIndex)
prev = pi->BenchInfo.UnpackSize;
}
inStreamSpec->Init(outStreamSpec->Buffer, compressedSize);
inStreamSpec->Init((const Byte *)*outStreamSpec, compressedSize);
crcOutStreamSpec->Init();
UInt64 outSize = kBufferSize;
@@ -1115,12 +1112,12 @@ HRESULT CEncoderInfo::Decode(UInt32 decoderIndex)
if (_decoderFilter)
{
if (compressedSize > rgCopy.BufferSize)
if (compressedSize > rgCopy.Size())
return E_FAIL;
memcpy(rgCopy.Buffer, outStreamSpec->Buffer, compressedSize);
memcpy((Byte *)rgCopy, (const Byte *)*outStreamSpec, compressedSize);
_decoderFilter->Init();
My_FilterBench(_decoderFilter, rgCopy.Buffer, compressedSize);
RINOK(WriteStream(crcOutStream, rgCopy.Buffer, compressedSize));
My_FilterBench(_decoderFilter, (Byte *)rgCopy, compressedSize);
RINOK(WriteStream(crcOutStream, (const Byte *)rgCopy, compressedSize));
}
else
{
@@ -1144,7 +1141,7 @@ static const UInt32 kNumThreadsMax = (1 << 12);
struct CBenchEncoders
{
CEncoderInfo *encoders;
CBenchEncoders(UInt32 num): encoders(0) { encoders = new CEncoderInfo[num]; }
CBenchEncoders(UInt32 num): encoders(NULL) { encoders = new CEncoderInfo[num]; }
~CBenchEncoders() { delete []encoders; }
};
@@ -1158,6 +1155,57 @@ static UInt64 GetNumIterations(UInt64 numCommands, UInt64 complexInCommands)
}
#ifndef _7ZIP_ST
// ---------- CBenchThreadsFlusher ----------
struct CBenchThreadsFlusher
{
CBenchEncoders *EncodersSpec;
CBenchSyncCommon Common;
unsigned NumThreads;
bool NeedClose;
CBenchThreadsFlusher(): NumThreads(0), NeedClose(false) {}
~CBenchThreadsFlusher()
{
StartAndWait(true);
}
WRes StartAndWait(bool exitMode = false);
};
WRes CBenchThreadsFlusher::StartAndWait(bool exitMode)
{
if (!NeedClose)
return 0;
Common.ExitMode = exitMode;
WRes res = Common.StartEvent.Set();
for (unsigned i = 0; i < NumThreads; i++)
{
NWindows::CThread &t = EncodersSpec->encoders[i].thread[0];
if (t.IsCreated())
{
WRes res2 = t.Wait();
if (res2 == 0)
res2 = t.Close();
if (res == S_OK)
res = res2;
}
}
NeedClose = false;
return res;
}
#endif
static HRESULT MethodBench(
DECL_EXTERNAL_CODECS_LOC_VARS
UInt64 complexInCommands,
@@ -1209,6 +1257,8 @@ static HRESULT MethodBench(
numSubDecoderThreads = 2;
}
}
bool mtEncMode = (numEncoderThreads > 1);
#endif
CBenchEncoders encodersSpec(numEncoderThreads);
@@ -1248,9 +1298,6 @@ static HRESULT MethodBench(
}
}
CBaseRandomGenerator rg;
rg.Init();
UInt32 crc = 0;
if (fileData)
crc = CrcCalc(fileData, uncompressedDataSize);
@@ -1259,22 +1306,38 @@ static HRESULT MethodBench(
{
CEncoderInfo &encoder = encoders[i];
encoder._method = method;
encoder.generateDictBits = generateDictBits;
encoder._uncompressedDataSize = uncompressedDataSize;
encoder.kBufferSize = uncompressedDataSize;
encoder.fileData = fileData;
encoder.crc = crc;
RINOK(encoders[i].Init(method, generateDictBits, &rg));
}
CBenchProgressStatus status;
status.Res = S_OK;
status.EncodeMode = true;
#ifndef _7ZIP_ST
CBenchThreadsFlusher encoderFlusher;
if (mtEncMode)
{
WRes wres = encoderFlusher.Common.StartEvent.Create();
if (wres != 0)
return HRESULT_FROM_WIN32(wres);
encoderFlusher.NumThreads = numEncoderThreads;
encoderFlusher.EncodersSpec = &encodersSpec;
encoderFlusher.NeedClose = true;
}
#endif
for (i = 0; i < numEncoderThreads; i++)
{
CEncoderInfo &encoder = encoders[i];
encoder.NumIterations = GetNumIterations(benchProps->GeComprCommands(uncompressedDataSize), complexInCommands);
encoder.Salt = g_CrcTable[i & 0xFF];
encoder.Salt ^= (g_CrcTable[(i >> 8) & 0xFF] << 3);
// (g_CrcTable[0] == 0), and (encoder.Salt == 0) for first thread
// printf(" %8x", encoder.Salt);
for (int j = 0; j < 2; j++)
{
@@ -1289,30 +1352,50 @@ static HRESULT MethodBench(
CBenchProgressInfo *bpi = encoder.progressInfoSpec[0];
bpi->Callback = callback;
bpi->BenchInfo.NumIterations = numEncoderThreads;
bpi->SetStartTime();
}
#ifndef _7ZIP_ST
if (numEncoderThreads > 1)
if (mtEncMode)
{
#ifdef USE_ALLOCA
encoder.AllocaSize = (i * 16 * 21) & 0x7FF;
#endif
encoder.Common = &encoderFlusher.Common;
RINOK(encoder.CreateEncoderThread())
}
else
#endif
{
RINOK(encoder.Encode());
}
}
if (printCallback)
{
RINOK(printCallback->CheckBreak());
}
#ifndef _7ZIP_ST
if (numEncoderThreads > 1)
if (mtEncMode)
{
for (i = 0; i < numEncoderThreads; i++)
encoders[i].thread[0].Wait();
{
CEncoderInfo &encoder = encoders[i];
WRes wres = encoder.ReadyEvent.Lock();
if (wres != 0)
return HRESULT_FROM_WIN32(wres);
RINOK(encoder.Results[0]);
}
CBenchProgressInfo *bpi = encoders[0].progressInfoSpec[0];
bpi->SetStartTime();
WRes wres = encoderFlusher.StartAndWait();
if (status.Res == 0 && wres != 0)
return HRESULT_FROM_WIN32(wres);
}
else
#endif
{
RINOK(encoders[0].Encode());
}
RINOK(status.Res);
@@ -1328,11 +1411,16 @@ static HRESULT MethodBench(
CEncoderInfo &encoder = encoders[i];
info.UnpackSize += encoder.kBufferSize;
info.PackSize += encoder.compressedSize;
// printf("\n%7d\n", encoder.compressedSize);
}
RINOK(callback->SetEncodeResult(info, true));
// ---------- Decode ----------
status.Res = S_OK;
status.EncodeMode = false;
@@ -1545,7 +1633,7 @@ struct CFreqThreads
CFreqInfo *Items;
UInt32 NumThreads;
CFreqThreads(): Items(0), NumThreads(0) {}
CFreqThreads(): Items(NULL), NumThreads(0) {}
void WaitAll()
{
for (UInt32 i = 0; i < NumThreads; i++)
@@ -1603,7 +1691,7 @@ struct CCrcThreads
CCrcInfo *Items;
UInt32 NumThreads;
CCrcThreads(): Items(0), NumThreads(0) {}
CCrcThreads(): Items(NULL), NumThreads(0) {}
void WaitAll()
{
for (UInt32 i = 0; i < NumThreads; i++)
@@ -1619,21 +1707,21 @@ struct CCrcThreads
#endif
static UInt32 CrcCalc1(const Byte *buf, UInt32 size)
static UInt32 CrcCalc1(const Byte *buf, size_t size)
{
UInt32 crc = CRC_INIT_VAL;;
for (UInt32 i = 0; i < size; i++)
for (size_t i = 0; i < size; i++)
crc = CRC_UPDATE_BYTE(crc, buf[i]);
return CRC_GET_DIGEST(crc);
}
static void RandGen(Byte *buf, UInt32 size, CBaseRandomGenerator &RG)
static void RandGen(Byte *buf, size_t size, CBaseRandomGenerator &RG)
{
for (UInt32 i = 0; i < size; i++)
for (size_t i = 0; i < size; i++)
buf[i] = (Byte)RG.GetRnd();
}
static UInt32 RandGenCrc(Byte *buf, UInt32 size, CBaseRandomGenerator &RG)
static UInt32 RandGenCrc(Byte *buf, size_t size, CBaseRandomGenerator &RG)
{
RandGen(buf, size, RG);
return CrcCalc1(buf, size);
@@ -1641,14 +1729,15 @@ static UInt32 RandGenCrc(Byte *buf, UInt32 size, CBaseRandomGenerator &RG)
bool CrcInternalTest()
{
CBenchBuffer buffer;
const UInt32 kBufferSize0 = (1 << 8);
const UInt32 kBufferSize1 = (1 << 10);
const UInt32 kCheckSize = (1 << 5);
if (!buffer.Alloc(kBufferSize0 + kBufferSize1))
CAlignedBuffer buffer;
const size_t kBufferSize0 = (1 << 8);
const size_t kBufferSize1 = (1 << 10);
const unsigned kCheckSize = (1 << 5);
buffer.Alloc(kBufferSize0 + kBufferSize1);
if (!buffer.IsAllocated())
return false;
Byte *buf = buffer.Buffer;
UInt32 i;
Byte *buf = (Byte *)buffer;
size_t i;
for (i = 0; i < kBufferSize0; i++)
buf[i] = (Byte)i;
UInt32 crc1 = CrcCalc1(buf, kBufferSize0);
@@ -1657,7 +1746,7 @@ bool CrcInternalTest()
CBaseRandomGenerator RG;
RandGen(buf + kBufferSize0, kBufferSize1, RG);
for (i = 0; i < kBufferSize0 + kBufferSize1 - kCheckSize; i++)
for (UInt32 j = 0; j < kCheckSize; j++)
for (unsigned j = 0; j < kCheckSize; j++)
if (CrcCalc1(buf + i, j) != CrcCalc(buf + i, j))
return false;
return true;
@@ -1885,8 +1974,55 @@ AString GetProcessThreadsInfo(const NSystem::CProcessAffinity &ti)
}
static void PrintSize(AString &s, UInt64 v)
{
char c = 0;
if ((v & 0x3FF) == 0) { v >>= 10; c = 'K';
if ((v & 0x3FF) == 0) { v >>= 10; c = 'M';
if ((v & 0x3FF) == 0) { v >>= 10; c = 'G';
if ((v & 0x3FF) == 0) { v >>= 10; c = 'T';
}}}}
else
{
PrintHex(s, v);
return;
}
char temp[32];
ConvertUInt64ToString(v, temp);
s += temp;
if (c)
s += c;
}
#ifdef _7ZIP_LARGE_PAGES
extern bool g_LargePagesMode;
extern "C"
{
extern SIZE_T g_LargePageSize;
}
void Add_LargePages_String(AString &s)
{
if (g_LargePagesMode || g_LargePageSize != 0)
{
s += " (LP-";
PrintSize(s, g_LargePageSize);
#ifdef MY_CPU_X86_OR_AMD64
if (CPU_IsSupported_PageGB())
s += "-1G";
#endif
if (!g_LargePagesMode)
s += "-NA";
s += ")";
}
}
#endif
static void PrintRequirements(IBenchPrintCallback &f, const char *sizeString,
bool size_Defined, UInt64 size, const char *threadsString, UInt32 numThreads)
@@ -1898,8 +2034,15 @@ static void PrintRequirements(IBenchPrintCallback &f, const char *sizeString,
else
f.Print(" ?");
f.Print(" MB");
if (g_LargePagesMode)
f.Print(" LP");
#ifdef _7ZIP_LARGE_PAGES
{
AString s;
Add_LargePages_String(s);
f.Print(s);
}
#endif
f.Print(", # ");
f.Print(threadsString);
PrintNumber(f, numThreads, 3);
@@ -2189,14 +2332,13 @@ static HRESULT CrcBench(
methodName, hashID))
return E_NOTIMPL;
CBenchBuffer buffer;
CAlignedBuffer buffer;
size_t totalSize = (size_t)bufferSize * numThreads;
if (totalSize / numThreads != bufferSize)
return E_OUTOFMEMORY;
if (!buffer.Alloc(totalSize))
return E_OUTOFMEMORY;
ALLOC_WITH_HRESULT(&buffer, totalSize)
Byte *buf = buffer.Buffer;
Byte *buf = (Byte *)buffer;
CBaseRandomGenerator RG;
UInt32 bsize = (bufferSize == 0 ? 1 : bufferSize);
UInt64 numIterations = complexInCommands * 256 / complexity / bsize;
@@ -2539,26 +2681,7 @@ static const char * const k_PF[] =
#endif
static void PrintSize(AString &s, UInt64 v)
{
char c = 0;
if ((v & 0x3FF) == 0) { v >>= 10; c = 'K';
if ((v & 0x3FF) == 0) { v >>= 10; c = 'M';
if ((v & 0x3FF) == 0) { v >>= 10; c = 'G';
if ((v & 0x3FF) == 0) { v >>= 10; c = 'T';
}}}}
else
{
PrintHex(s, v);
return;
}
char temp[32];
ConvertUInt64ToString(v, temp);
s += temp;
if (c)
s += c;
}
static void PrintPage(AString &s, UInt32 v)
{
@@ -2707,8 +2830,9 @@ void GetCpuName(AString &s)
#endif
if (g_LargePagesMode)
s += " (LP)";
#ifdef _7ZIP_LARGE_PAGES
Add_LargePages_String(s);
#endif
}
@@ -2762,7 +2886,7 @@ HRESULT Bench(
bool multiDict)
{
if (!CrcInternalTest())
return S_FALSE;
return E_FAIL;
UInt32 numCPUs = 1;
UInt64 ramSize = (UInt64)(sizeof(size_t)) << 29;
@@ -2791,7 +2915,7 @@ HRESULT Bench(
COneMethodInfo method;
CBenchBuffer fileDataBuffer;
CAlignedBuffer fileDataBuffer;
{
unsigned i;
@@ -2816,10 +2940,9 @@ HRESULT Bench(
return E_FAIL;
if (len >= ((UInt32)1 << 31) || len == 0)
return E_INVALIDARG;
if (!fileDataBuffer.Alloc((size_t)len))
return E_OUTOFMEMORY;
ALLOC_WITH_HRESULT(&fileDataBuffer, (size_t)len);
UInt32 processedSize;
file.Read(fileDataBuffer.Buffer, (UInt32)len, processedSize);
file.Read((Byte *)fileDataBuffer, (UInt32)len, processedSize);
if (processedSize != len)
return E_FAIL;
if (printCallback)
@@ -2968,6 +3091,9 @@ HRESULT Bench(
UInt64 start = ::GetTimeCount();
UInt32 sum = (UInt32)start;
sum = CountCpuFreq(sum, (UInt32)(numMilCommands * 1000000 / kNumFreqCommands), g_BenchCpuFreqTemp);
if (sum == 0xF1541213)
if (printCallback)
printCallback->Print("");
const UInt64 realDelta = ::GetTimeCount() - start;
start = realDelta;
if (start == 0)
@@ -2984,7 +3110,7 @@ HRESULT Bench(
else
{
// PrintNumber(*printCallback, start, 0);
PrintNumber(*printCallback, mipsVal, 5 + ((sum == 0xF1541213) ? 1 : 0));
PrintNumber(*printCallback, mipsVal, 5);
}
}
/*
@@ -3032,7 +3158,7 @@ HRESULT Bench(
complexInCommands,
true, numThreadsSpecified,
method,
uncompressedDataSize, fileDataBuffer.Buffer,
uncompressedDataSize, (const Byte *)fileDataBuffer,
kOldLzmaDictBits, printCallback, benchCallback, &benchProps);
}
@@ -3344,9 +3470,9 @@ HRESULT Bench(
{
res = TotalBench(EXTERNAL_CODECS_LOC_VARS
complexInCommands, numThreads,
dictIsDefined || fileDataBuffer.Buffer, // forceUnpackSize
fileDataBuffer.Buffer ? fileDataBuffer.BufferSize : dict,
fileDataBuffer.Buffer,
dictIsDefined || fileDataBuffer.IsAllocated(), // forceUnpackSize
fileDataBuffer.IsAllocated() ? fileDataBuffer.Size() : dict,
(const Byte *)fileDataBuffer,
printCallback, &callback);
RINOK(res);
}
@@ -3436,9 +3562,9 @@ HRESULT Bench(
}
size_t uncompressedDataSize;
if (fileDataBuffer.Buffer)
if (fileDataBuffer.IsAllocated())
{
uncompressedDataSize = fileDataBuffer.BufferSize;
uncompressedDataSize = fileDataBuffer.Size();
}
else
{
@@ -3452,7 +3578,7 @@ HRESULT Bench(
complexInCommands,
true, numThreads,
method2,
uncompressedDataSize, fileDataBuffer.Buffer,
uncompressedDataSize, (const Byte *)fileDataBuffer,
kOldLzmaDictBits, printCallback, &callback, &callback.BenchProps);
f.NewLine();
RINOK(res);

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