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

github.com/kornelski/7z.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorIgor Pavlov <ipavlov@users.sourceforge.net>2016-09-29 03:00:00 +0300
committerKornel Lesiński <kornel@geekhood.net>2016-12-08 15:12:54 +0300
commit232ce7957441b06193c4cbdc1bc9e71436fadfdb (patch)
treecbfba61cb993434ebb38be4e058a977d91a8676a /CPP/7zip/Archive
parent1eddf527cacc149016ec987d554d3dfb52b69131 (diff)
16.0316.03
Diffstat (limited to 'CPP/7zip/Archive')
-rw-r--r--CPP/7zip/Archive/7z/7zIn.cpp5
-rw-r--r--CPP/7zip/Archive/7z/7zUpdate.cpp4
-rw-r--r--CPP/7zip/Archive/Cab/CabHandler.cpp2
-rw-r--r--CPP/7zip/Archive/ElfHandler.cpp49
-rw-r--r--CPP/7zip/Archive/FlvHandler.cpp6
-rw-r--r--CPP/7zip/Archive/GptHandler.cpp28
-rw-r--r--CPP/7zip/Archive/HfsHandler.cpp26
-rw-r--r--CPP/7zip/Archive/Iso/IsoHandler.cpp85
-rw-r--r--CPP/7zip/Archive/Iso/IsoIn.cpp2
-rw-r--r--CPP/7zip/Archive/Iso/IsoItem.h184
-rw-r--r--CPP/7zip/Archive/MachoHandler.cpp6
-rw-r--r--CPP/7zip/Archive/Nsis/NsisDecode.cpp45
-rw-r--r--CPP/7zip/Archive/Nsis/NsisDecode.h9
-rw-r--r--CPP/7zip/Archive/Nsis/NsisIn.cpp22
-rw-r--r--CPP/7zip/Archive/NtfsHandler.cpp3
-rw-r--r--CPP/7zip/Archive/PeHandler.cpp2
-rw-r--r--CPP/7zip/Archive/SquashfsHandler.cpp26
-rw-r--r--CPP/7zip/Archive/SwfHandler.cpp2
-rw-r--r--CPP/7zip/Archive/Tar/TarHandler.cpp16
-rw-r--r--CPP/7zip/Archive/Tar/TarHandler.h1
-rw-r--r--CPP/7zip/Archive/Tar/TarHandlerOut.cpp2
-rw-r--r--CPP/7zip/Archive/Tar/TarIn.cpp83
-rw-r--r--CPP/7zip/Archive/Tar/TarIn.h1
-rw-r--r--CPP/7zip/Archive/UefiHandler.cpp2
-rw-r--r--CPP/7zip/Archive/Wim/WimHandler.cpp3
-rw-r--r--CPP/7zip/Archive/XarHandler.cpp12
-rw-r--r--CPP/7zip/Archive/Zip/ZipHandlerOut.cpp2
-rw-r--r--CPP/7zip/Archive/Zip/ZipIn.cpp9
-rw-r--r--CPP/7zip/Archive/Zip/ZipIn.h2
-rw-r--r--CPP/7zip/Archive/Zip/ZipUpdate.cpp32
-rw-r--r--CPP/7zip/Archive/Zip/ZipUpdate.h2
31 files changed, 565 insertions, 108 deletions
diff --git a/CPP/7zip/Archive/7z/7zIn.cpp b/CPP/7zip/Archive/7z/7zIn.cpp
index b0c6b98c..d8c27175 100644
--- a/CPP/7zip/Archive/7z/7zIn.cpp
+++ b/CPP/7zip/Archive/7z/7zIn.cpp
@@ -1097,7 +1097,10 @@ HRESULT CInArchive::ReadAndDecodePackedStreams(
if (CrcCalc(data, unpackSize) != folders.FolderCRCs.Vals[i])
ThrowIncorrect();
}
- HeadersSize += folders.PackPositions[folders.NumPackStreams];
+
+ if (folders.PackPositions)
+ HeadersSize += folders.PackPositions[folders.NumPackStreams];
+
return S_OK;
}
diff --git a/CPP/7zip/Archive/7z/7zUpdate.cpp b/CPP/7zip/Archive/7z/7zUpdate.cpp
index 4e74fa33..68e57f09 100644
--- a/CPP/7zip/Archive/7z/7zUpdate.cpp
+++ b/CPP/7zip/Archive/7z/7zUpdate.cpp
@@ -38,7 +38,7 @@ struct CFilterMode
{
if (Id == k_IA64)
Delta = 16;
- else if (Id == k_ARM || Id == k_PPC || Id == k_PPC)
+ else if (Id == k_ARM || Id == k_PPC || Id == k_SPARC)
Delta = 4;
else if (Id == k_ARMT)
Delta = 2;
@@ -779,7 +779,7 @@ struct CSolidGroup
CRecordVector<CFolderRepack> folderRefs;
};
-static const char *g_ExeExts[] =
+static const char * const g_ExeExts[] =
{
"dll"
, "exe"
diff --git a/CPP/7zip/Archive/Cab/CabHandler.cpp b/CPP/7zip/Archive/Cab/CabHandler.cpp
index 5f145739..18f58b3d 100644
--- a/CPP/7zip/Archive/Cab/CabHandler.cpp
+++ b/CPP/7zip/Archive/Cab/CabHandler.cpp
@@ -168,7 +168,7 @@ STDMETHODIMP CHandler::GetArchiveProperty(PROPID propID, PROPVARIANT *value)
case kpidVolumeIndex:
{
- if (m_Database.Volumes.Size() == 1)
+ if (!m_Database.Volumes.IsEmpty())
{
const CDatabaseEx &db = m_Database.Volumes[0];
const CInArcInfo &ai = db.ArcInfo;
diff --git a/CPP/7zip/Archive/ElfHandler.cpp b/CPP/7zip/Archive/ElfHandler.cpp
index 1c3c7c45..4543b067 100644
--- a/CPP/7zip/Archive/ElfHandler.cpp
+++ b/CPP/7zip/Archive/ElfHandler.cpp
@@ -156,7 +156,7 @@ bool CHeader::Parse(const Byte *p)
#define PT_PHDR 6
-static const char *g_SegnmentTypes[] =
+static const char * const g_SegnmentTypes[] =
{
"Unused",
"Loadable segment",
@@ -554,13 +554,31 @@ static const CUInt32PCharPair g_OS[] =
{ 255, "Standalone" }
};
+#define k_Machine_ARM 40
+
+/*
+#define EF_ARM_ABIMASK 0xFF000000
+#define EF_ARM_BE8 0x00800000
+#define EF_ARM_GCCMASK 0x00400FFF
+#define EF_ARM_ABI_FLOAT_SOFT 0x00000200
+#define EF_ARM_ABI_FLOAT_HARD 0x00000400
+*/
+
+static const CUInt32PCharPair g_ARM_Flags[] =
+{
+ { 9, "SF" },
+ { 10, "HF" },
+ { 23, "BE8" }
+};
+
+
#define ET_NONE 0
#define ET_REL 1
#define ET_EXEC 2
#define ET_DYN 3
#define ET_CORE 4
-static const char *g_Types[] =
+static const char * const g_Types[] =
{
"None",
"Relocatable file",
@@ -569,6 +587,9 @@ static const char *g_Types[] =
"Core file"
};
+
+
+
class CHandler:
public IInArchive,
public IArchiveAllowTail,
@@ -659,7 +680,29 @@ STDMETHODIMP CHandler::GetArchiveProperty(PROPID propID, PROPVARIANT *value)
case kpidBit64: if (_header.Mode64) prop = _header.Mode64; break;
case kpidBigEndian: if (_header.Be) prop = _header.Be; break;
case kpidShortComment:
- case kpidCpu: PAIR_TO_PROP(g_Machines, _header.Machine, prop); break;
+
+ case kpidCpu:
+ {
+ AString s = TypePairToString(g_Machines, ARRAY_SIZE(g_Machines), _header.Machine);
+ UInt32 flags = _header.Flags;
+ if (flags != 0)
+ {
+ char sz[16];
+ s.Add_Space();
+ if (_header.Machine == k_Machine_ARM)
+ {
+ s += FlagsToString(g_ARM_Flags, ARRAY_SIZE(g_ARM_Flags), flags & (((UInt32)1 << 24) - 1));
+ s += " ABI:";
+ ConvertUInt32ToString(flags >> 24, sz);
+ }
+ else
+ ConvertUInt32ToHex(flags, sz);
+ s += sz;
+ }
+ prop = s;
+ break;
+ }
+
case kpidHostOS: PAIR_TO_PROP(g_OS, _header.Os, prop); break;
case kpidCharacts: TYPE_TO_PROP(g_Types, _header.Type, prop); break;
case kpidExtension:
diff --git a/CPP/7zip/Archive/FlvHandler.cpp b/CPP/7zip/Archive/FlvHandler.cpp
index 72ccd993..1f52f60b 100644
--- a/CPP/7zip/Archive/FlvHandler.cpp
+++ b/CPP/7zip/Archive/FlvHandler.cpp
@@ -93,7 +93,7 @@ static const Byte kProps[] =
IMP_IInArchive_Props
IMP_IInArchive_ArcProps_NO_Table
-static const char *g_AudioTypes[16] =
+static const char * const g_AudioTypes[16] =
{
"pcm"
, "adpcm"
@@ -113,7 +113,7 @@ static const char *g_AudioTypes[16] =
, "audio15"
};
-static const char *g_VideoTypes[16] =
+static const char * const g_VideoTypes[16] =
{
"video0"
, "jpeg"
@@ -133,7 +133,7 @@ static const char *g_VideoTypes[16] =
, "video15"
};
-static const char *g_Rates[4] =
+static const char * const g_Rates[4] =
{
"5.5 kHz"
, "11 kHz"
diff --git a/CPP/7zip/Archive/GptHandler.cpp b/CPP/7zip/Archive/GptHandler.cpp
index 53e941c7..52c7aab9 100644
--- a/CPP/7zip/Archive/GptHandler.cpp
+++ b/CPP/7zip/Archive/GptHandler.cpp
@@ -244,9 +244,31 @@ HRESULT CHandler::Open2(IInStream *stream)
_items.Add(item);
}
- UInt64 end = (backupLba + 1) * kSectorSize;
- if (_totalSize < end)
- _totalSize = end;
+ {
+ const UInt64 end = (backupLba + 1) * kSectorSize;
+ if (_totalSize < end)
+ _totalSize = end;
+ }
+
+ {
+ UInt64 fileEnd;
+ RINOK(stream->Seek(0, STREAM_SEEK_END, &fileEnd));
+
+ if (_totalSize < fileEnd)
+ {
+ const UInt64 rem = fileEnd - _totalSize;
+ const UInt64 kRemMax = 1 << 22;
+ if (rem <= kRemMax)
+ {
+ RINOK(stream->Seek(_totalSize, STREAM_SEEK_SET, NULL));
+ bool areThereNonZeros = false;
+ UInt64 numZeros = 0;
+ if (ReadZeroTail(stream, areThereNonZeros, numZeros, kRemMax) == S_OK)
+ if (!areThereNonZeros)
+ _totalSize += numZeros;
+ }
+ }
+ }
return S_OK;
}
diff --git a/CPP/7zip/Archive/HfsHandler.cpp b/CPP/7zip/Archive/HfsHandler.cpp
index abf8bef6..185df7f0 100644
--- a/CPP/7zip/Archive/HfsHandler.cpp
+++ b/CPP/7zip/Archive/HfsHandler.cpp
@@ -507,7 +507,7 @@ HRESULT CHeaderRec::Parse(const Byte *p)
// LeafRecords = Get32(p + 6);
FirstLeafNode = Get32(p + 0xA);
// LastLeafNode = Get32(p + 0xE);
- UInt32 nodeSize = Get16(p + 0x12);
+ const UInt32 nodeSize = Get16(p + 0x12);
unsigned i;
for (i = 9; ((UInt32)1 << i) != nodeSize; i++)
@@ -583,9 +583,9 @@ HRESULT CDatabase::LoadExtentFile(const CFork &fork, IInStream *inStream, CObjec
for (unsigned i = 0; i < desc.NumRecords; i++)
{
- UInt32 nodeSize = (UInt32)1 << hr.NodeSizeLog;
- UInt32 offs = Get16(p + nodeOffset + nodeSize - (i + 1) * 2);
- UInt32 offsNext = Get16(p + nodeOffset + nodeSize - (i + 2) * 2);
+ const UInt32 nodeSize = (UInt32)1 << hr.NodeSizeLog;
+ const UInt32 offs = Get16(p + nodeOffset + nodeSize - (i + 1) * 2);
+ const UInt32 offsNext = Get16(p + nodeOffset + nodeSize - (i + 2) * 2);
if (offs > nodeSize || offsNext > nodeSize)
return S_FALSE;
UInt32 recSize = offsNext - offs;
@@ -727,12 +727,12 @@ HRESULT CDatabase::LoadAttrs(const CFork &fork, IInStream *inStream, IArchiveOpe
for (unsigned i = 0; i < desc.NumRecords; i++)
{
- UInt32 nodeSize = (1 << hr.NodeSizeLog);
- UInt32 offs = Get16(p + nodeOffset + nodeSize - (i + 1) * 2);
- UInt32 offsNext = Get16(p + nodeOffset + nodeSize - (i + 2) * 2);
+ const UInt32 nodeSize = (1 << hr.NodeSizeLog);
+ const UInt32 offs = Get16(p + nodeOffset + nodeSize - (i + 1) * 2);
+ const UInt32 offsNext = Get16(p + nodeOffset + nodeSize - (i + 2) * 2);
UInt32 recSize = offsNext - offs;
if (offs >= nodeSize
- || offsNext >= nodeSize
+ || offsNext > nodeSize
|| offsNext < offs)
return S_FALSE;
@@ -898,7 +898,7 @@ HRESULT CDatabase::LoadCatalog(const CFork &fork, const CObjectVector<CIdExtents
return S_FALSE;
usedBuf[node] = 1;
- size_t nodeOffset = (size_t)node << hr.NodeSizeLog;
+ const size_t nodeOffset = (size_t)node << hr.NodeSizeLog;
CNodeDescriptor desc;
desc.Parse(p + nodeOffset);
if (!desc.CheckNumRecords(hr.NodeSizeLog))
@@ -908,12 +908,12 @@ HRESULT CDatabase::LoadCatalog(const CFork &fork, const CObjectVector<CIdExtents
for (unsigned i = 0; i < desc.NumRecords; i++)
{
- UInt32 nodeSize = (1 << hr.NodeSizeLog);
- UInt32 offs = Get16(p + nodeOffset + nodeSize - (i + 1) * 2);
- UInt32 offsNext = Get16(p + nodeOffset + nodeSize - (i + 2) * 2);
+ const UInt32 nodeSize = (1 << hr.NodeSizeLog);
+ const UInt32 offs = Get16(p + nodeOffset + nodeSize - (i + 1) * 2);
+ const UInt32 offsNext = Get16(p + nodeOffset + nodeSize - (i + 2) * 2);
UInt32 recSize = offsNext - offs;
if (offs >= nodeSize
- || offs >= nodeSize
+ || offsNext > nodeSize
|| offsNext < offs
|| recSize < 6)
return S_FALSE;
diff --git a/CPP/7zip/Archive/Iso/IsoHandler.cpp b/CPP/7zip/Archive/Iso/IsoHandler.cpp
index 14aec498..5a19516c 100644
--- a/CPP/7zip/Archive/Iso/IsoHandler.cpp
+++ b/CPP/7zip/Archive/Iso/IsoHandler.cpp
@@ -30,7 +30,14 @@ static const Byte kProps[] =
kpidIsDir,
kpidSize,
kpidPackSize,
- kpidMTime
+ kpidMTime,
+ // kpidCTime,
+ // kpidATime,
+ kpidPosixAttrib,
+ // kpidUser,
+ // kpidGroup,
+ // kpidLinks,
+ kpidSymLink
};
static const Byte kArcProps[] =
@@ -213,17 +220,87 @@ STDMETHODIMP CHandler::GetProperty(UInt32 index, PROPID propID, PROPVARIANT *val
prop = s;
}
break;
+
+ case kpidSymLink:
+ if (_archive.IsSusp)
+ {
+ UString s;
+ UInt32 mode;
+ if (item.GetPx(_archive.SuspSkipSize, k_Px_Mode, mode))
+ {
+ if (((mode >> 12) & 0xF) == 10)
+ {
+ AString s8;
+ if (item.GetSymLink(_archive.SuspSkipSize, s8))
+ {
+ s = MultiByteToUnicodeString(s8, CP_OEMCP);
+ prop = s;
+ }
+ }
+ }
+ }
+ break;
+
+
+ case kpidPosixAttrib:
+ /*
+ case kpidLinks:
+ case kpidUser:
+ case kpidGroup:
+ */
+ {
+ if (_archive.IsSusp)
+ {
+ UInt32 t = 0;
+ switch (propID)
+ {
+ case kpidPosixAttrib: t = k_Px_Mode; break;
+ /*
+ case kpidLinks: t = k_Px_Links; break;
+ case kpidUser: t = k_Px_User; break;
+ case kpidGroup: t = k_Px_Group; break;
+ */
+ }
+ UInt32 v;
+ if (item.GetPx(_archive.SuspSkipSize, t, v))
+ prop = v;
+ }
+ break;
+ }
+
case kpidIsDir: prop = item.IsDir(); break;
case kpidSize:
case kpidPackSize:
if (!item.IsDir())
prop = (UInt64)ref.TotalSize;
break;
+
case kpidMTime:
+ // case kpidCTime:
+ // case kpidATime:
{
FILETIME utc;
- if (item.DateTime.GetFileTime(utc))
+ if (/* propID == kpidMTime && */ item.DateTime.GetFileTime(utc))
prop = utc;
+ /*
+ else
+ {
+ UInt32 t = 0;
+ switch (propID)
+ {
+ case kpidMTime: t = k_Tf_MTime; break;
+ case kpidCTime: t = k_Tf_CTime; break;
+ case kpidATime: t = k_Tf_ATime; break;
+ }
+ CRecordingDateTime dt;
+ if (item.GetTf(_archive.SuspSkipSize, t, dt))
+ {
+ FILETIME utc;
+ if (dt.GetFileTime(utc))
+ prop = utc;
+ }
+ }
+ */
break;
}
}
@@ -321,8 +398,10 @@ STDMETHODIMP CHandler::Extract(const UInt32 *indices, UInt32 numItems,
UInt64 offset = 0;
for (UInt32 e = 0; e < ref.NumExtents; e++)
{
- lps->InSize = lps->OutSize = currentTotalSize + offset;
const CDir &item2 = ref.Dir->_subItems[ref.Index + e];
+ if (item2.Size == 0)
+ continue;
+ lps->InSize = lps->OutSize = currentTotalSize + offset;
RINOK(_stream->Seek((UInt64)item2.ExtentLocation * kBlockSize, STREAM_SEEK_SET, NULL));
streamSpec->Init(item2.Size);
RINOK(copyCoder->Code(inStream, realOutStream, NULL, NULL, progress));
diff --git a/CPP/7zip/Archive/Iso/IsoIn.cpp b/CPP/7zip/Archive/Iso/IsoIn.cpp
index 1ebc15e8..8530a25e 100644
--- a/CPP/7zip/Archive/Iso/IsoIn.cpp
+++ b/CPP/7zip/Archive/Iso/IsoIn.cpp
@@ -608,7 +608,7 @@ HRESULT CInArchive::Open2()
for (UInt32 j = 0; j < ref.NumExtents; j++)
{
const CDir &item = ref.Dir->_subItems[ref.Index + j];
- if (!item.IsDir())
+ if (!item.IsDir() && item.Size != 0)
UpdatePhySize(item.ExtentLocation, item.Size);
}
}
diff --git a/CPP/7zip/Archive/Iso/IsoItem.h b/CPP/7zip/Archive/Iso/IsoItem.h
index ce154264..c4950e60 100644
--- a/CPP/7zip/Archive/Iso/IsoItem.h
+++ b/CPP/7zip/Archive/Iso/IsoItem.h
@@ -3,6 +3,8 @@
#ifndef __ARCHIVE_ISO_ITEM_H
#define __ARCHIVE_ISO_ITEM_H
+#include "../../../../C/CpuArch.h"
+
#include "../../../Common/MyString.h"
#include "../../../Common/MyBuffer.h"
@@ -38,6 +40,32 @@ struct CRecordingDateTime
}
};
+enum EPx
+{
+ k_Px_Mode,
+ k_Px_Links,
+ k_Px_User,
+ k_Px_Group,
+ k_Px_SerialNumber
+
+ // k_Px_Num
+};
+
+/*
+enum ETf
+{
+ k_Tf_CTime,
+ k_Tf_MTime,
+ k_Tf_ATime,
+ k_Tf_Attrib,
+ k_Tf_Backup,
+ k_Tf_Expiration,
+ k_Tf_Effective
+
+ // k_Tf_Num
+};
+*/
+
struct CDirRecord
{
UInt32 ExtentLocation;
@@ -69,7 +97,8 @@ struct CDirRecord
return (b == 0 || b == 1);
}
- const Byte* FindSuspName(unsigned skipSize, unsigned &lenRes) const
+
+ const Byte* FindSuspRecord(unsigned skipSize, Byte id0, Byte id1, unsigned &lenRes) const
{
lenRes = 0;
if (SystemUse.Size() < skipSize)
@@ -81,12 +110,12 @@ struct CDirRecord
unsigned len = p[2];
if (len < 3 || len > rem)
return 0;
- if (p[0] == 'N' && p[1] == 'M' && p[3] == 1)
+ if (p[0] == id0 && p[1] == id1 && p[3] == 1)
{
- if (len < 5)
+ if (len < 4)
return 0; // Check it
- lenRes = len - 5;
- return p + 5;
+ lenRes = len - 4;
+ return p + 4;
}
p += len;
rem -= len;
@@ -94,17 +123,23 @@ struct CDirRecord
return 0;
}
+
const Byte* GetNameCur(bool checkSusp, int skipSize, unsigned &nameLenRes) const
{
const Byte *res = NULL;
unsigned len = 0;
if (checkSusp)
- res = FindSuspName(skipSize, len);
- if (!res)
+ res = FindSuspRecord(skipSize, 'N', 'M', len);
+ if (!res || len < 1)
{
res = (const Byte *)FileId;
len = (unsigned)FileId.Size();
}
+ else
+ {
+ res++;
+ len--;
+ }
unsigned i;
for (i = 0; i < len; i++)
if (res[i] == 0)
@@ -114,6 +149,141 @@ struct CDirRecord
}
+ const bool GetSymLink(int skipSize, AString &link) const
+ {
+ link.Empty();
+ const Byte *p = NULL;
+ unsigned len = 0;
+ p = FindSuspRecord(skipSize, 'S', 'L', len);
+ if (!p || len < 1)
+ return false;
+
+ if (*p != 0)
+ return false;
+
+ p++;
+ len--;
+
+ while (len != 0)
+ {
+ if (len < 2)
+ return false;
+ unsigned flags = p[0];
+ unsigned cl = p[1];
+ p += 2;
+ len -= 2;
+
+ if (cl > len)
+ return false;
+
+ bool needSlash = false;
+
+ if (flags & (1 << 1)) link += "./";
+ else if (flags & (1 << 2)) link += "../";
+ else if (flags & (1 << 3)) link += '/';
+ else
+ needSlash = true;
+
+ for (unsigned i = 0; i < cl; i++)
+ {
+ char c = p[i];
+ if (c == 0)
+ {
+ break;
+ // return false;
+ }
+ link += c;
+ }
+
+ p += cl;
+ len -= cl;
+
+ if (len == 0)
+ break;
+
+ if (needSlash)
+ link += '/';
+ }
+
+ return true;
+ }
+
+ static const bool GetLe32Be32(const Byte *p, UInt32 &dest)
+ {
+ UInt32 v1 = GetUi32(p);
+ UInt32 v2 = GetBe32(p + 4);
+ if (v1 == v2)
+ {
+ dest = v1;
+ return true;
+ }
+ return false;
+ }
+
+
+ const bool GetPx(int skipSize, unsigned pxType, UInt32 &val) const
+ {
+ const Byte *p = NULL;
+ unsigned len = 0;
+ p = FindSuspRecord(skipSize, 'P', 'X', len);
+ if (!p)
+ return false;
+ // px.Clear();
+ if (len < ((unsigned)pxType + 1) * 8)
+ return false;
+
+ return GetLe32Be32(p + pxType * 8, val);
+ }
+
+ /*
+ const bool GetTf(int skipSize, unsigned pxType, CRecordingDateTime &t) const
+ {
+ const Byte *p = NULL;
+ unsigned len = 0;
+ p = FindSuspRecord(skipSize, 'T', 'F', len);
+ if (!p)
+ return false;
+ if (len < 1)
+ return false;
+ Byte flags = *p++;
+ len--;
+
+ unsigned step = 7;
+ if (flags & 0x80)
+ {
+ step = 17;
+ return false;
+ }
+
+ if ((flags & (1 << pxType)) == 0)
+ return false;
+
+ for (unsigned i = 0; i < pxType; i++)
+ {
+ if (len < step)
+ return false;
+ if (flags & (1 << i))
+ {
+ p += step;
+ len -= step;
+ }
+ }
+
+ if (len < step)
+ return false;
+
+ t.Year = p[0];
+ t.Month = p[1];
+ t.Day = p[2];
+ t.Hour = p[3];
+ t.Minute = p[4];
+ t.Second = p[5];
+ t.GmtOffset = (signed char)p[6];
+
+ return true;
+ }
+ */
+
bool CheckSusp(const Byte *p, unsigned &startPos) const
{
if (p[0] == 'S' &&
diff --git a/CPP/7zip/Archive/MachoHandler.cpp b/CPP/7zip/Archive/MachoHandler.cpp
index 9dae1e70..26260686 100644
--- a/CPP/7zip/Archive/MachoHandler.cpp
+++ b/CPP/7zip/Archive/MachoHandler.cpp
@@ -75,7 +75,7 @@ static const CUInt32PCharPair g_CpuPairs[] =
#define SECT_ATTR_ZEROFILL 1
-static const char *g_SectTypes[] =
+static const char * const g_SectTypes[] =
{
"REGULAR"
, "ZEROFILL"
@@ -108,7 +108,7 @@ enum EFileType
kType_DSYM
};
-static const char *g_FileTypes[] =
+static const char * const g_FileTypes[] =
{
"0"
, "OBJECT"
@@ -124,7 +124,7 @@ static const char *g_FileTypes[] =
};
-static const char *g_ArcFlags[] =
+static const char * const g_ArcFlags[] =
{
"NOUNDEFS"
, "INCRLINK"
diff --git a/CPP/7zip/Archive/Nsis/NsisDecode.cpp b/CPP/7zip/Archive/Nsis/NsisDecode.cpp
index 0bbf6094..daf3df6e 100644
--- a/CPP/7zip/Archive/Nsis/NsisDecode.cpp
+++ b/CPP/7zip/Archive/Nsis/NsisDecode.cpp
@@ -12,7 +12,6 @@
#include "../../Compress/BcjCoder.h"
#include "../../Compress/BZip2Decoder.h"
-#include "../../Compress/DeflateDecoder.h"
#define Get32(p) GetUi32(p)
@@ -27,12 +26,16 @@ HRESULT CDecoder::Init(ISequentialInStream *inStream, bool &useFilter)
if (Method != _curMethod)
Release();
_curMethod = Method;
+
if (!_codecInStream)
{
switch (Method)
{
// case NMethodType::kCopy: return E_NOTIMPL;
- case NMethodType::kDeflate: _codecInStream = new NCompress::NDeflate::NDecoder::CNsisCOMCoder(); break;
+ case NMethodType::kDeflate:
+ _deflateDecoder = new NCompress::NDeflate::NDecoder::CCOMCoder();
+ _codecInStream = _deflateDecoder;
+ break;
case NMethodType::kBZip2: _codecInStream = new NCompress::NBZip2::CNsisDecoder(); break;
case NMethodType::kLZMA:
_lzmaDecoder = new NCompress::NLzma::CDecoder();
@@ -42,6 +45,9 @@ HRESULT CDecoder::Init(ISequentialInStream *inStream, bool &useFilter)
}
}
+ if (Method == NMethodType::kDeflate)
+ _deflateDecoder->SetNsisMode(IsNsisDeflate);
+
if (FilterFlag)
{
Byte flag;
@@ -199,9 +205,8 @@ HRESULT CDecoder::Decode(CByteBuffer *outBuf, bool unpackSizeDefined, UInt32 unp
if (outBuf)
{
- if (!unpackSizeDefined)
- return S_FALSE;
- outBuf->Alloc(unpackSize);
+ if (unpackSizeDefined)
+ outBuf->Alloc(unpackSize);
}
UInt64 inSizeStart = 0;
@@ -213,6 +218,8 @@ HRESULT CDecoder::Decode(CByteBuffer *outBuf, bool unpackSizeDefined, UInt32 unp
unpackSize = 0xFFFFFFFF;
UInt32 offset = 0;
+ HRESULT res = S_OK;
+
for (;;)
{
size_t rem = unpackSize - offset;
@@ -225,11 +232,25 @@ HRESULT CDecoder::Decode(CByteBuffer *outBuf, bool unpackSizeDefined, UInt32 unp
if (size == 0)
{
if (unpackSizeDefined)
- return S_FALSE;
+ res = S_FALSE;
break;
}
+
if (outBuf)
+ {
+ size_t nextSize = offset + size;
+ if (outBuf->Size() < nextSize)
+ {
+ {
+ const size_t nextSize2 = outBuf->Size() * 2;
+ if (nextSize < nextSize2)
+ nextSize = nextSize2;
+ }
+ outBuf->ChangeSize_KeepData(nextSize, offset);
+ }
memcpy((Byte *)*outBuf + (size_t)offset, Buffer, size);
+ }
+
StreamPos += size;
offset += (UInt32)size;
@@ -243,9 +264,17 @@ HRESULT CDecoder::Decode(CByteBuffer *outBuf, bool unpackSizeDefined, UInt32 unp
UInt64 outSize = offset;
RINOK(progress->SetRatioInfo(&inSize, &outSize));
if (realOutStream)
- RINOK(WriteStream(realOutStream, Buffer, size));
+ {
+ res = WriteStream(realOutStream, Buffer, size);
+ if (res != S_OK)
+ break;
+ }
}
- return S_OK;
+
+ if (outBuf && offset != outBuf->Size())
+ outBuf->ChangeSize_KeepData(offset, offset);
+
+ return res;
}
}}
diff --git a/CPP/7zip/Archive/Nsis/NsisDecode.h b/CPP/7zip/Archive/Nsis/NsisDecode.h
index 7b22181e..ec713d05 100644
--- a/CPP/7zip/Archive/Nsis/NsisDecode.h
+++ b/CPP/7zip/Archive/Nsis/NsisDecode.h
@@ -8,6 +8,7 @@
#include "../../Common/FilterCoder.h"
#include "../../Common/StreamUtils.h"
+#include "../../Compress/DeflateDecoder.h"
#include "../../Compress/LzmaDecoder.h"
namespace NArchive {
@@ -37,6 +38,7 @@ class CDecoder
CMyComPtr<ISequentialInStream> _codecInStream;
CMyComPtr<ISequentialInStream> _decoderInStream;
+ NCompress::NDeflate::NDecoder::CCOMCoder *_deflateDecoder;
NCompress::NLzma::CDecoder *_lzmaDecoder;
public:
@@ -46,9 +48,16 @@ public:
NMethodType::EEnum Method;
bool FilterFlag;
bool Solid;
+ bool IsNsisDeflate;
CByteBuffer Buffer; // temp buf.
+ CDecoder():
+ FilterFlag(false),
+ Solid(true),
+ IsNsisDeflate(true)
+ {}
+
void Release()
{
_filterInStream.Release();
diff --git a/CPP/7zip/Archive/Nsis/NsisIn.cpp b/CPP/7zip/Archive/Nsis/NsisIn.cpp
index e04a97a8..a3bfcaec 100644
--- a/CPP/7zip/Archive/Nsis/NsisIn.cpp
+++ b/CPP/7zip/Archive/Nsis/NsisIn.cpp
@@ -175,7 +175,7 @@ static const CCommandInfo k_Commands[kNumCmds] =
{ 0 }, // "BringToFront" },
{ 2 }, // "SetDetailsView" },
{ 2 }, // "SetFileAttributes" },
- { 2 }, // CreateDirectory, SetOutPath
+ { 3 }, // CreateDirectory, SetOutPath
{ 3 }, // "IfFileExists" },
{ 3 }, // SetRebootFlag, ...
{ 4 }, // "If" }, // IfAbort, IfSilent, IfErrors, IfRebootFlag
@@ -1395,7 +1395,7 @@ void CInArchive::AddRegRoot(UInt32 val)
Script += s;
}
-static const char *g_WinAttrib[] =
+static const char * const g_WinAttrib[] =
{
"READONLY"
, "HIDDEN"
@@ -3362,6 +3362,11 @@ HRESULT CInArchive::ReadEntries(const CBlockHeader &bh)
#ifdef NSIS_SCRIPT
s += isSetOutPath ? "SetOutPath" : "CreateDirectory";
AddParam(params[0]);
+ if (params[2] != 0)
+ {
+ SmallSpaceComment();
+ s += "CreateRestrictedDirectory";
+ }
#endif
break;
@@ -3378,11 +3383,8 @@ HRESULT CInArchive::ReadEntries(const CBlockHeader &bh)
params[2] == 0 &&
params[3] == 0)
{
- if (IsVarStr(params[1], kVar_OUTDIR))
- {
- spec_outdir_U = UPrefixes.Back(); // outdir_U;
- spec_outdir_A = APrefixes.Back();// outdir_A;
- }
+ spec_outdir_U = UPrefixes.Back(); // outdir_U;
+ spec_outdir_A = APrefixes.Back(); // outdir_A;
}
}
@@ -5045,6 +5047,9 @@ HRESULT CInArchive::Parse()
DetectNsisType(bhEntries, _data + bhEntries.Offset);
+ Decoder.IsNsisDeflate = (NsisType != k_NsisType_Nsis3);
+
+
#ifdef NSIS_SCRIPT
{
@@ -5606,6 +5611,9 @@ HRESULT CInArchive::Open2(const Byte *sig, size_t size)
Decoder.Method = Method;
Decoder.FilterFlag = FilterFlag;
Decoder.Solid = IsSolid;
+
+ Decoder.IsNsisDeflate = true; // we need some smart check that NSIS is not NSIS3 here.
+
Decoder.InputStream = _stream;
Decoder.Buffer.Alloc(kInputBufSize);
Decoder.StreamPos = 0;
diff --git a/CPP/7zip/Archive/NtfsHandler.cpp b/CPP/7zip/Archive/NtfsHandler.cpp
index 93e9f88f..a6350944 100644
--- a/CPP/7zip/Archive/NtfsHandler.cpp
+++ b/CPP/7zip/Archive/NtfsHandler.cpp
@@ -2157,7 +2157,7 @@ STDMETHODIMP CHandler::GetRawProp(UInt32 index, PROPID propID, const void **data
return S_OK;
const CItem &item = Items[index];
const CMftRec &rec = Recs[item.RecIndex];
- if (rec.SiAttr.SecurityId >= 0)
+ if (rec.SiAttr.SecurityId > 0)
{
UInt64 offset;
UInt32 size;
@@ -2169,6 +2169,7 @@ STDMETHODIMP CHandler::GetRawProp(UInt32 index, PROPID propID, const void **data
}
}
}
+
return S_OK;
}
diff --git a/CPP/7zip/Archive/PeHandler.cpp b/CPP/7zip/Archive/PeHandler.cpp
index 51087166..7175cef3 100644
--- a/CPP/7zip/Archive/PeHandler.cpp
+++ b/CPP/7zip/Archive/PeHandler.cpp
@@ -321,7 +321,7 @@ bool COptHeader::Parse(const Byte *p, UInt32 size)
if (NumDirItems > (1 << 16))
return false;
pos += 4;
- if (pos + 8 * NumDirItems != size)
+ if (pos + 8 * NumDirItems > size)
return false;
for (UInt32 i = 0; i < NumDirItems && i < kNumDirItemsMax; i++)
DirItems[i].Parse(p + pos + i * 8);
diff --git a/CPP/7zip/Archive/SquashfsHandler.cpp b/CPP/7zip/Archive/SquashfsHandler.cpp
index 5ddfae3f..3bcb2862 100644
--- a/CPP/7zip/Archive/SquashfsHandler.cpp
+++ b/CPP/7zip/Archive/SquashfsHandler.cpp
@@ -959,7 +959,7 @@ static HRESULT LzoDecode(Byte *dest, SizeT *destLen, const Byte *src, SizeT *src
*srcLen = 0;
const Byte *destStart = dest;
const Byte *srcStart = src;
- unsigned mode = 2;
+ unsigned mode = 0;
{
if (srcRem == 0)
@@ -970,7 +970,7 @@ static HRESULT LzoDecode(Byte *dest, SizeT *destLen, const Byte *src, SizeT *src
src++;
srcRem--;
b -= 17;
- mode = (b < 4 ? 0 : 1);
+ mode = (b < 4 ? 1 : 4);
if (b > srcRem || b > destRem)
return S_FALSE;
srcRem -= b;
@@ -988,6 +988,7 @@ static HRESULT LzoDecode(Byte *dest, SizeT *destLen, const Byte *src, SizeT *src
UInt32 b = *src++;
srcRem--;
UInt32 len, back;
+
if (b >= 64)
{
srcRem--;
@@ -996,7 +997,7 @@ static HRESULT LzoDecode(Byte *dest, SizeT *destLen, const Byte *src, SizeT *src
}
else if (b < 16)
{
- if (mode == 2)
+ if (mode == 0)
{
if (b == 0)
{
@@ -1013,21 +1014,23 @@ static HRESULT LzoDecode(Byte *dest, SizeT *destLen, const Byte *src, SizeT *src
}
}
}
+
b += 3;
if (b > srcRem || b > destRem)
return S_FALSE;
srcRem -= b;
destRem -= b;
- mode = 1;
+ mode = 4;
do
*dest++ = *src++;
while (--b);
continue;
}
+
srcRem--;
back = (b >> 2) + (*src++ << 2);
len = 2;
- if (mode == 1)
+ if (mode == 4)
{
back += (1 << 11);
len = 3;
@@ -1038,6 +1041,7 @@ static HRESULT LzoDecode(Byte *dest, SizeT *destLen, const Byte *src, SizeT *src
UInt32 bOld = b;
b = (b < 32 ? 7 : 31);
len = bOld & b;
+
if (len == 0)
{
for (len = b;; len += 255)
@@ -1053,6 +1057,7 @@ static HRESULT LzoDecode(Byte *dest, SizeT *destLen, const Byte *src, SizeT *src
}
}
}
+
len += 2;
if (srcRem < 2)
return S_FALSE;
@@ -1062,38 +1067,39 @@ static HRESULT LzoDecode(Byte *dest, SizeT *destLen, const Byte *src, SizeT *src
srcRem -= 2;
if (bOld < 32)
{
+ back += ((bOld & 8) << 11);
if (back == 0)
{
*destLen = dest - destStart;
*srcLen = src - srcStart;
return S_OK;
}
- back += ((bOld & 8) << 11) + (1 << 14) - 1;
+ back += (1 << 14) - 1;
}
}
+
back++;
if (len > destRem || (size_t)(dest - destStart) < back)
return S_FALSE;
destRem -= len;
Byte *destTemp = dest - back;
dest += len;
+
do
{
*(destTemp + back) = *destTemp;
destTemp++;
}
while (--len);
+
b &= 3;
+ mode = b;
if (b == 0)
- {
- mode = 2;
continue;
- }
if (b > srcRem || b > destRem)
return S_FALSE;
srcRem -= b;
destRem -= b;
- mode = 0;
*dest++ = *src++;
if (b > 1)
{
diff --git a/CPP/7zip/Archive/SwfHandler.cpp b/CPP/7zip/Archive/SwfHandler.cpp
index 77d2ad7d..06ed2106 100644
--- a/CPP/7zip/Archive/SwfHandler.cpp
+++ b/CPP/7zip/Archive/SwfHandler.cpp
@@ -646,7 +646,7 @@ STDMETHODIMP CHandler::GetNumberOfItems(UInt32 *numItems)
return S_OK;
}
-static const char *g_TagDesc[92] =
+static const char * const g_TagDesc[92] =
{
"End"
, "ShowFrame"
diff --git a/CPP/7zip/Archive/Tar/TarHandler.cpp b/CPP/7zip/Archive/Tar/TarHandler.cpp
index 14cf3e59..baa43c79 100644
--- a/CPP/7zip/Archive/Tar/TarHandler.cpp
+++ b/CPP/7zip/Archive/Tar/TarHandler.cpp
@@ -72,6 +72,13 @@ STDMETHODIMP CHandler::GetArchiveProperty(PROPID propID, PROPVARIANT *value)
break;
}
+ case kpidWarningFlags:
+ {
+ if (_warning)
+ prop = kpv_ErrorFlags_HeadersError;
+ break;
+ }
+
case kpidCodePage:
{
const char *name = NULL;
@@ -98,7 +105,13 @@ STDMETHODIMP CHandler::GetArchiveProperty(PROPID propID, PROPVARIANT *value)
HRESULT CHandler::ReadItem2(ISequentialInStream *stream, bool &filled, CItemEx &item)
{
item.HeaderPos = _phySize;
- RINOK(ReadItem(stream, filled, item, _error));
+ EErrorType error;
+ HRESULT res = ReadItem(stream, filled, item, error);
+ if (error == k_ErrorType_Warning)
+ _warning = true;
+ else if (error != k_ErrorType_OK)
+ _error = error;
+ RINOK(res);
if (filled)
{
/*
@@ -233,6 +246,7 @@ STDMETHODIMP CHandler::OpenSeq(ISequentialInStream *stream)
STDMETHODIMP CHandler::Close()
{
_isArc = false;
+ _warning = false;
_error = k_ErrorType_OK;
_phySizeDefined = false;
diff --git a/CPP/7zip/Archive/Tar/TarHandler.h b/CPP/7zip/Archive/Tar/TarHandler.h
index 42d57d45..eb9c049e 100644
--- a/CPP/7zip/Archive/Tar/TarHandler.h
+++ b/CPP/7zip/Archive/Tar/TarHandler.h
@@ -37,6 +37,7 @@ private:
UInt64 _headersSize;
bool _phySizeDefined;
EErrorType _error;
+ bool _warning;
bool _isArc;
// bool _isSparse;
diff --git a/CPP/7zip/Archive/Tar/TarHandlerOut.cpp b/CPP/7zip/Archive/Tar/TarHandlerOut.cpp
index 429a8afe..0b67a285 100644
--- a/CPP/7zip/Archive/Tar/TarHandlerOut.cpp
+++ b/CPP/7zip/Archive/Tar/TarHandlerOut.cpp
@@ -75,7 +75,7 @@ STDMETHODIMP CHandler::UpdateItems(ISequentialOutStream *outStream, UInt32 numIt
{
COM_TRY_BEGIN
- if ((_stream && (_error != k_ErrorType_OK /* || _isSparse */)) || _seqStream)
+ if ((_stream && (_error != k_ErrorType_OK || _warning /* || _isSparse */)) || _seqStream)
return E_NOTIMPL;
CObjectVector<CUpdateItem> updateItems;
UINT codePage = (_forceCodePage ? _specifiedCodePage : _openCodePage);
diff --git a/CPP/7zip/Archive/Tar/TarIn.cpp b/CPP/7zip/Archive/Tar/TarIn.cpp
index 80200c3b..57e18ac0 100644
--- a/CPP/7zip/Archive/Tar/TarIn.cpp
+++ b/CPP/7zip/Archive/Tar/TarIn.cpp
@@ -328,13 +328,63 @@ static HRESULT GetNextItemReal(ISequentialInStream *stream, bool &filled, CItemE
return S_OK;
}
+
+static HRESULT ReadDataToString(ISequentialInStream *stream, CItemEx &item, AString &s, EErrorType &error)
+{
+ const unsigned packSize = (unsigned)item.GetPackSizeAligned();
+ size_t processedSize = packSize;
+ HRESULT res = ReadStream(stream, s.GetBuf(packSize), &processedSize);
+ item.HeaderSize += (unsigned)processedSize;
+ s.ReleaseBuf_CalcLen((unsigned)item.PackSize);
+ RINOK(res);
+ if (processedSize != packSize)
+ error = k_ErrorType_UnexpectedEnd;
+ return S_OK;
+}
+
+static bool ParsePaxLongName(const AString &src, AString &dest)
+{
+ dest.Empty();
+ for (unsigned pos = 0;;)
+ {
+ if (pos >= src.Len())
+ return false;
+ const char *start = src.Ptr(pos);
+ const char *end;
+ const UInt32 lineLen = ConvertStringToUInt32(start, &end);
+ if (end == start)
+ return false;
+ if (*end != ' ')
+ return false;
+ if (lineLen > src.Len() - pos)
+ return false;
+ unsigned offset = (unsigned)(end - start) + 1;
+ if (lineLen < offset)
+ return false;
+ if (IsString1PrefixedByString2(src.Ptr(pos + offset), "path="))
+ {
+ offset += 5; // "path="
+ dest = src.Mid(pos + offset, lineLen - offset);
+ if (dest.IsEmpty())
+ return false;
+ if (dest.Back() != '\n')
+ return false;
+ dest.DeleteBack();
+ return true;
+ }
+ pos += lineLen;
+ }
+}
+
HRESULT ReadItem(ISequentialInStream *stream, bool &filled, CItemEx &item, EErrorType &error)
{
item.HeaderSize = 0;
+
bool flagL = false;
bool flagK = false;
AString nameL;
AString nameK;
+ AString pax;
for (;;)
{
@@ -363,18 +413,11 @@ HRESULT ReadItem(ISequentialInStream *stream, bool &filled, CItemEx &item, EErro
return S_OK;
if (item.PackSize > (1 << 14))
return S_OK;
- unsigned packSize = (unsigned)item.GetPackSizeAligned();
- char *buf = name->GetBuf(packSize);
- size_t processedSize = packSize;
- HRESULT res = ReadStream(stream, buf, &processedSize);
- item.HeaderSize += (unsigned)processedSize;
- name->ReleaseBuf_CalcLen((unsigned)item.PackSize);
- RINOK(res);
- if (processedSize != packSize)
- {
- error = k_ErrorType_UnexpectedEnd;
+
+ RINOK(ReadDataToString(stream, item, *name, error));
+ if (error != k_ErrorType_OK)
return S_OK;
- }
+
continue;
}
@@ -385,6 +428,14 @@ HRESULT ReadItem(ISequentialInStream *stream, bool &filled, CItemEx &item, EErro
case 'X':
{
// pax Extended Header
+ if (item.Name.IsPrefixedBy("PaxHeader/"))
+ {
+ RINOK(ReadDataToString(stream, item, pax, error));
+ if (error != k_ErrorType_OK)
+ return S_OK;
+ continue;
+ }
+
break;
}
case NFileHeader::NLinkFlag::kDumpDir:
@@ -415,6 +466,16 @@ HRESULT ReadItem(ISequentialInStream *stream, bool &filled, CItemEx &item, EErro
}
error = k_ErrorType_OK;
+
+ if (!pax.IsEmpty())
+ {
+ AString name;
+ if (ParsePaxLongName(pax, name))
+ item.Name = name;
+ else
+ error = k_ErrorType_Warning;
+ }
+
return S_OK;
}
}
diff --git a/CPP/7zip/Archive/Tar/TarIn.h b/CPP/7zip/Archive/Tar/TarIn.h
index a67b1dbd..1c508bcc 100644
--- a/CPP/7zip/Archive/Tar/TarIn.h
+++ b/CPP/7zip/Archive/Tar/TarIn.h
@@ -15,6 +15,7 @@ enum EErrorType
k_ErrorType_OK,
k_ErrorType_Corrupted,
k_ErrorType_UnexpectedEnd,
+ k_ErrorType_Warning
};
HRESULT ReadItem(ISequentialInStream *stream, bool &filled, CItemEx &itemInfo, EErrorType &error);
diff --git a/CPP/7zip/Archive/UefiHandler.cpp b/CPP/7zip/Archive/UefiHandler.cpp
index 80692493..ff0737a0 100644
--- a/CPP/7zip/Archive/UefiHandler.cpp
+++ b/CPP/7zip/Archive/UefiHandler.cpp
@@ -225,7 +225,7 @@ enum
FV_FILETYPE_FFS_PAD = 0xF0
};
-static const char *g_FileTypes[] =
+static const char * const g_FileTypes[] =
{
"ALL"
, "RAW"
diff --git a/CPP/7zip/Archive/Wim/WimHandler.cpp b/CPP/7zip/Archive/Wim/WimHandler.cpp
index 27d3298a..234780dd 100644
--- a/CPP/7zip/Archive/Wim/WimHandler.cpp
+++ b/CPP/7zip/Archive/Wim/WimHandler.cpp
@@ -298,7 +298,8 @@ STDMETHODIMP CHandler::GetArchiveProperty(PROPID propID, PROPVARIANT *value)
AString res;
- bool numMethods = 0;
+ unsigned numMethods = 0;
+
for (unsigned i = 0; i < ARRAY_SIZE(k_Methods); i++)
{
if (methodMask & ((UInt32)1 << i))
diff --git a/CPP/7zip/Archive/XarHandler.cpp b/CPP/7zip/Archive/XarHandler.cpp
index 59196b18..96386809 100644
--- a/CPP/7zip/Archive/XarHandler.cpp
+++ b/CPP/7zip/Archive/XarHandler.cpp
@@ -255,13 +255,13 @@ static bool AddItem(const CXmlItem &item, CObjectVector<CFile> &files, int paren
if (encodingItem.IsTag)
{
AString s = encodingItem.GetPropVal("style");
- if (s.Len() >= 0)
+ if (!s.IsEmpty())
{
- AString appl = "application/";
+ const AString appl = "application/";
if (s.IsPrefixedBy(appl))
{
s.DeleteFrontal(appl.Len());
- AString xx = "x-";
+ const AString xx = "x-";
if (s.IsPrefixedBy(xx))
{
s.DeleteFrontal(xx.Len());
@@ -365,12 +365,12 @@ HRESULT CHandler::Open2(IInStream *stream)
{
const CFile &file = _files[i];
file.UpdateTotalPackSize(totalPackSize);
- if (file.Name == "Payload")
+ if (file.Name == "Payload" || file.Name == "Content")
{
_mainSubfile = i;
numMainFiles++;
}
- if (file.Name == "PackageInfo")
+ else if (file.Name == "PackageInfo")
_is_pkg = true;
}
@@ -723,7 +723,7 @@ STDMETHODIMP CHandler::GetStream(UInt32 index, ISequentialInStream **stream)
static const Byte k_Signature[] = { 'x', 'a', 'r', '!', 0, 0x1C };
REGISTER_ARC_I(
- "Xar", "xar pkg", 0, 0xE1,
+ "Xar", "xar pkg xip", 0, 0xE1,
k_Signature,
0,
0,
diff --git a/CPP/7zip/Archive/Zip/ZipHandlerOut.cpp b/CPP/7zip/Archive/Zip/ZipHandlerOut.cpp
index aa06c4f8..8a8de511 100644
--- a/CPP/7zip/Archive/Zip/ZipHandlerOut.cpp
+++ b/CPP/7zip/Archive/Zip/ZipHandlerOut.cpp
@@ -276,7 +276,7 @@ STDMETHODIMP CHandler::UpdateItems(ISequentialOutStream *outStream, UInt32 numIt
EXTERNAL_CODECS_VARS
m_Items, updateItems, outStream,
m_Archive.IsOpen() ? &m_Archive : NULL, _removeSfxBlock,
- &options, callback);
+ options, callback);
COM_TRY_END2
}
diff --git a/CPP/7zip/Archive/Zip/ZipIn.cpp b/CPP/7zip/Archive/Zip/ZipIn.cpp
index c71c40fd..6361dc5c 100644
--- a/CPP/7zip/Archive/Zip/ZipIn.cpp
+++ b/CPP/7zip/Archive/Zip/ZipIn.cpp
@@ -1454,7 +1454,10 @@ HRESULT CVols::ParseArcName(IArchiveOpenVolumeCallback *volCallback)
if (result == S_FALSE || !ZipStream)
{
if (MissingName.IsEmpty())
+ {
+ MissingZip = true;
MissingName = volName;
+ }
return S_OK;
}
@@ -1988,6 +1991,12 @@ HRESULT CInArchive::ReadHeaders2(CObjectVector<CItemEx> &items)
if (!IsMultiVol)
{
+ if (EcdVolIndex == 0 && Vols.MissingZip && Vols.StartIsExe)
+ {
+ Vols.MissingName.Empty();
+ Vols.MissingZip = false;
+ }
+
UseDisk_in_SingleVol = true;
if (localsWereRead)
diff --git a/CPP/7zip/Archive/Zip/ZipIn.h b/CPP/7zip/Archive/Zip/ZipIn.h
index 9b10905e..9b0afe28 100644
--- a/CPP/7zip/Archive/Zip/ZipIn.h
+++ b/CPP/7zip/Archive/Zip/ZipIn.h
@@ -139,6 +139,7 @@ public:
bool StartIsZ; // is .zip or .zNN
bool StartIsZip; // is .zip
bool IsUpperCase;
+ bool MissingZip;
Int32 StartVolIndex; // = (NN - 1), if StartStream is .zNN
Int32 StartParsingVol; // if we need local parsing, we must use that stream
@@ -173,6 +174,7 @@ public:
BaseName.Empty();
MissingName.Empty();
+ MissingZip = false;
ecd_wasRead = false;
Streams.Clear();
diff --git a/CPP/7zip/Archive/Zip/ZipUpdate.cpp b/CPP/7zip/Archive/Zip/ZipUpdate.cpp
index 8cb123e6..bc50c1d7 100644
--- a/CPP/7zip/Archive/Zip/ZipUpdate.cpp
+++ b/CPP/7zip/Archive/Zip/ZipUpdate.cpp
@@ -584,7 +584,7 @@ static HRESULT Update2(
CInArchive *inArchive,
const CObjectVector<CItemEx> &inputItems,
CObjectVector<CUpdateItem> &updateItems,
- const CCompressionMethodMode *options,
+ const CCompressionMethodMode &options,
const CByteBuffer *comment,
IArchiveUpdateCallback *updateCallback)
{
@@ -629,17 +629,15 @@ static HRESULT Update2(
UInt64 totalComplexity = complexity;
- CAddCommon compressor(*options);
+ CAddCommon compressor(options);
complexity = 0;
- CCompressionMethodMode options2;
- if (options != 0)
- options2 = *options;
+ CCompressionMethodMode options2 = options;
#ifndef _7ZIP_ST
- UInt32 numThreads = options->NumThreads;
+ UInt32 numThreads = options.NumThreads;
const UInt32 kNumMaxThreads = 64;
if (numThreads > kNumMaxThreads)
numThreads = kNumMaxThreads;
@@ -652,12 +650,12 @@ static HRESULT Update2(
const size_t kMemPerThread = (1 << 25);
const size_t kBlockSize = 1 << 16;
- bool mtMode = ((options != 0) && (numThreads > 1));
+ bool mtMode = (numThreads > 1);
if (numFilesToCompress <= 1)
mtMode = false;
- Byte method = options->MethodSequence.Front();
+ Byte method = options.MethodSequence.Front();
if (!mtMode)
{
@@ -670,7 +668,7 @@ static HRESULT Update2(
}
else
{
- if (method == NFileHeader::NCompressionMethod::kStored && !options->PasswordIsDefined)
+ if (method == NFileHeader::NCompressionMethod::kStored && !options.PasswordIsDefined)
numThreads = 1;
if (method == NFileHeader::NCompressionMethod::kBZip2)
{
@@ -855,16 +853,16 @@ static HRESULT Update2(
if (isDir)
{
- WriteDirHeader(archive, options, ui, item);
+ WriteDirHeader(archive, &options, ui, item);
}
else
{
if (lastRealStreamItemIndex < (int)itemIndex)
{
lastRealStreamItemIndex = itemIndex;
- SetFileHeader(archive, *options, ui, item);
+ SetFileHeader(archive, options, ui, item);
// file Size can be 64-bit !!!
- archive.PrepareWriteCompressedData(item.Name.Len(), ui.Size, options->IsRealAesMode());
+ archive.PrepareWriteCompressedData(item.Name.Len(), ui.Size, options.IsRealAesMode());
}
CMemBlocks2 &memRef = refs.Refs[itemIndex];
@@ -874,12 +872,12 @@ static HRESULT Update2(
CMyComPtr<IOutStream> outStream;
archive.CreateStreamForCompressing(&outStream);
memRef.WriteToStream(memManager.GetBlockSize(), outStream);
- SetFileHeader(archive, *options, ui, item);
+ SetFileHeader(archive, options, ui, item);
// the BUG was fixed in 9.26:
// SetItemInfoFromCompressingResult must be after SetFileHeader
// to write correct Size.
SetItemInfoFromCompressingResult(memRef.CompressingResult,
- options->IsRealAesMode(), options->AesKeyMode, item);
+ options.IsRealAesMode(), options.AesKeyMode, item);
archive.WriteLocalHeader_And_SeekToNextFile(item);
// RINOK(updateCallback->SetOperationResult(NArchive::NUpdate::NOperationResult::kOK));
memRef.FreeOpt(&memManager);
@@ -920,9 +918,9 @@ static HRESULT Update2(
{
RINOK(threadInfo.OutStreamSpec->WriteToRealStream());
threadInfo.OutStreamSpec->ReleaseOutStream();
- SetFileHeader(archive, *options, ui, item);
+ SetFileHeader(archive, options, ui, item);
SetItemInfoFromCompressingResult(threadInfo.CompressingResult,
- options->IsRealAesMode(), options->AesKeyMode, item);
+ options.IsRealAesMode(), options.AesKeyMode, item);
archive.WriteLocalHeader_And_SeekToNextFile(item);
}
else
@@ -1173,7 +1171,7 @@ HRESULT Update(
CObjectVector<CUpdateItem> &updateItems,
ISequentialOutStream *seqOutStream,
CInArchive *inArchive, bool removeSfx,
- CCompressionMethodMode *compressionMethodMode,
+ const CCompressionMethodMode &compressionMethodMode,
IArchiveUpdateCallback *updateCallback)
{
if (inArchive)
diff --git a/CPP/7zip/Archive/Zip/ZipUpdate.h b/CPP/7zip/Archive/Zip/ZipUpdate.h
index 054db668..15cbf69d 100644
--- a/CPP/7zip/Archive/Zip/ZipUpdate.h
+++ b/CPP/7zip/Archive/Zip/ZipUpdate.h
@@ -51,7 +51,7 @@ HRESULT Update(
CObjectVector<CUpdateItem> &updateItems,
ISequentialOutStream *seqOutStream,
CInArchive *inArchive, bool removeSfx,
- CCompressionMethodMode *compressionMethodMode,
+ const CCompressionMethodMode &compressionMethodMode,
IArchiveUpdateCallback *updateCallback);
}}