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>2015-11-19 03:00:00 +0300
committerKornel LesiƄski <kornel@geekhood.net>2016-05-28 02:16:57 +0300
commite24f7fba53cc8f28d74b5039f7279d9bf945ff25 (patch)
tree52cf49d97bf4436151ec824ec7fbbf9d567578ff /CPP/7zip/Archive
parent7c8a265a15125b64808e695882acd2a0298ebce4 (diff)
15.1115.11
Diffstat (limited to 'CPP/7zip/Archive')
-rw-r--r--CPP/7zip/Archive/7z/7zIn.h2
-rw-r--r--CPP/7zip/Archive/DllExports2.cpp2
-rw-r--r--CPP/7zip/Archive/Rar/Rar5Handler.cpp18
-rw-r--r--CPP/7zip/Archive/Rar/RarHandler.cpp23
-rw-r--r--CPP/7zip/Archive/Rar/RarHandler.h1
-rw-r--r--CPP/7zip/Archive/Udf/UdfHandler.cpp1
-rw-r--r--CPP/7zip/Archive/Udf/UdfIn.cpp58
-rw-r--r--CPP/7zip/Archive/Udf/UdfIn.h1
-rw-r--r--CPP/7zip/Archive/Zip/ZipIn.cpp34
9 files changed, 117 insertions, 23 deletions
diff --git a/CPP/7zip/Archive/7z/7zIn.h b/CPP/7zip/Archive/7z/7zIn.h
index ad8ceba5..3592e99b 100644
--- a/CPP/7zip/Archive/7z/7zIn.h
+++ b/CPP/7zip/Archive/7z/7zIn.h
@@ -87,6 +87,8 @@ struct CFolders
return PackPositions[index + 1] - PackPositions[index];
}
+ CFolders(): NumPackStreams(0), NumFolders(0) {}
+
void Clear()
{
NumPackStreams = 0;
diff --git a/CPP/7zip/Archive/DllExports2.cpp b/CPP/7zip/Archive/DllExports2.cpp
index 979b4bf9..10889e75 100644
--- a/CPP/7zip/Archive/DllExports2.cpp
+++ b/CPP/7zip/Archive/DllExports2.cpp
@@ -26,6 +26,7 @@ HINSTANCE g_hInstance;
#define NT_CHECK_FAIL_ACTION return FALSE;
+#ifdef _WIN32
extern "C"
BOOL WINAPI DllMain(
#ifdef UNDER_CE
@@ -49,6 +50,7 @@ BOOL WINAPI DllMain(
*/
return TRUE;
}
+#endif
DEFINE_GUID(CLSID_CArchiveHandler,
k_7zip_GUID_Data1,
diff --git a/CPP/7zip/Archive/Rar/Rar5Handler.cpp b/CPP/7zip/Archive/Rar/Rar5Handler.cpp
index dff327f2..131f2c9b 100644
--- a/CPP/7zip/Archive/Rar/Rar5Handler.cpp
+++ b/CPP/7zip/Archive/Rar/Rar5Handler.cpp
@@ -1825,6 +1825,8 @@ HRESULT CHandler::Open2(IInStream *stream,
int prevSplitFile = -1;
int prevMainFile = -1;
+ bool nextVol_is_Required = false;
+
CInArchive arch;
for (;;)
@@ -1861,7 +1863,8 @@ HRESULT CHandler::Open2(IInStream *stream,
if (!inStream || result != S_OK)
{
- _missingVolName = volName;
+ if (nextVol_is_Required)
+ _missingVolName = volName;
break;
}
}
@@ -2111,11 +2114,18 @@ HRESULT CHandler::Open2(IInStream *stream,
}
curBytes += endPos;
+
+ nextVol_is_Required = false;
+
if (!arcInfo.IsVolume())
break;
- if (arcInfo.EndOfArchive_was_Read
- && !arcInfo.AreMoreVolumes())
- break;
+
+ if (arcInfo.EndOfArchive_was_Read)
+ {
+ if (!arcInfo.AreMoreVolumes())
+ break;
+ nextVol_is_Required = true;
+ }
}
FillLinks();
diff --git a/CPP/7zip/Archive/Rar/RarHandler.cpp b/CPP/7zip/Archive/Rar/RarHandler.cpp
index 31c06d96..3b5924b4 100644
--- a/CPP/7zip/Archive/Rar/RarHandler.cpp
+++ b/CPP/7zip/Archive/Rar/RarHandler.cpp
@@ -640,6 +640,7 @@ HRESULT CInArchive::GetNextItem(CItem &item, ICryptoGetTextPassword *getTextPass
{
ArcInfo.EndFlags = m_BlockHeader.Flags;
UInt32 offset = 7;
+
if (m_BlockHeader.Flags & NHeader::NArchive::kEndOfArc_Flags_DataCRC)
{
if (processed < offset + 4)
@@ -648,6 +649,7 @@ HRESULT CInArchive::GetNextItem(CItem &item, ICryptoGetTextPassword *getTextPass
ArcInfo.DataCRC = Get32(m_FileHeaderData + offset);
offset += 4;
}
+
if (m_BlockHeader.Flags & NHeader::NArchive::kEndOfArc_Flags_VolNumber)
{
if (processed < offset + 2)
@@ -657,6 +659,7 @@ HRESULT CInArchive::GetNextItem(CItem &item, ICryptoGetTextPassword *getTextPass
ArcInfo.EndOfArchive_was_Read = true;
}
+
m_Position += processed;
FinishCryptoBlock();
ArcInfo.EndPos = m_Position;
@@ -699,11 +702,13 @@ HRESULT CInArchive::GetNextItem(CItem &item, ICryptoGetTextPassword *getTextPass
continue;
*/
}
+
if (m_CryptoMode && m_BlockHeader.HeadSize > (1 << 10))
{
error = k_ErrorType_DecryptionError;
return S_OK;
}
+
if ((m_BlockHeader.Flags & NHeader::NBlock::kLongBlock) != 0)
{
if (m_FileHeaderData.Size() < 7 + 4)
@@ -1032,7 +1037,10 @@ HRESULT CHandler::Open2(IInStream *stream,
openCallback->QueryInterface(IID_ICryptoGetTextPassword, (void **)&getTextPassword);
}
+ bool nextVol_is_Required = false;
+
CInArchive archive;
+
for (;;)
{
CMyComPtr<IInStream> inStream;
@@ -1072,7 +1080,8 @@ HRESULT CHandler::Open2(IInStream *stream,
if (!inStream || result != S_OK)
{
- _missingVolName = volName;
+ if (nextVol_is_Required)
+ _missingVolName = volName;
break;
}
}
@@ -1191,6 +1200,18 @@ HRESULT CHandler::Open2(IInStream *stream,
arc.PhySize = archive.ArcInfo.GetPhySize();
arc.Stream = inStream;
}
+
+ nextVol_is_Required = false;
+
+ if (!archive.ArcInfo.IsVolume())
+ break;
+
+ if (archive.ArcInfo.EndOfArchive_was_Read)
+ {
+ if (!archive.ArcInfo.AreMoreVolumes())
+ break;
+ nextVol_is_Required = true;
+ }
}
}
diff --git a/CPP/7zip/Archive/Rar/RarHandler.h b/CPP/7zip/Archive/Rar/RarHandler.h
index 9e6fb5cb..e280eb57 100644
--- a/CPP/7zip/Archive/Rar/RarHandler.h
+++ b/CPP/7zip/Archive/Rar/RarHandler.h
@@ -45,6 +45,7 @@ struct CInArcInfo
bool IsEncryptOld() const { return (!IsThereEncryptVer() || EncryptVersion < 36); }
+ bool AreMoreVolumes() const { return (EndFlags & NHeader::NArchive::kEndOfArc_Flags_NextVol) != 0; }
bool Is_VolNumber_Defined() const { return (EndFlags & NHeader::NArchive::kEndOfArc_Flags_VolNumber) != 0; }
bool Is_DataCRC_Defined() const { return (EndFlags & NHeader::NArchive::kEndOfArc_Flags_DataCRC) != 0; }
};
diff --git a/CPP/7zip/Archive/Udf/UdfHandler.cpp b/CPP/7zip/Archive/Udf/UdfHandler.cpp
index 876482d1..74ec0beb 100644
--- a/CPP/7zip/Archive/Udf/UdfHandler.cpp
+++ b/CPP/7zip/Archive/Udf/UdfHandler.cpp
@@ -98,6 +98,7 @@ STDMETHODIMP CHandler::GetArchiveProperty(PROPID propID, PROPVARIANT *value)
if (!_archive.IsArc) v |= kpv_ErrorFlags_IsNotArc;
if (_archive.Unsupported) v |= kpv_ErrorFlags_UnsupportedFeature;
if (_archive.UnexpectedEnd) v |= kpv_ErrorFlags_UnexpectedEnd;
+ if (_archive.NoEndAnchor) v |= kpv_ErrorFlags_HeadersError;
prop = v;
break;
}
diff --git a/CPP/7zip/Archive/Udf/UdfIn.cpp b/CPP/7zip/Archive/Udf/UdfIn.cpp
index 6be035cb..a051a271 100644
--- a/CPP/7zip/Archive/Udf/UdfIn.cpp
+++ b/CPP/7zip/Archive/Udf/UdfIn.cpp
@@ -610,6 +610,7 @@ API_FUNC_IsArc IsArc_Udf(const Byte *p, size_t size)
}
}
+
HRESULT CInArchive::Open2()
{
Clear();
@@ -644,8 +645,10 @@ HRESULT CInArchive::Open2()
CExtent extentVDS;
extentVDS.Parse(buf + i + 16);
*/
+
const size_t kBufSize = 1 << 11;
Byte buf[kBufSize];
+
for (SecLogSize = 11;; SecLogSize -= 3)
{
if (SecLogSize < 8)
@@ -665,6 +668,7 @@ HRESULT CInArchive::Open2()
break;
}
}
+
PhySize = (UInt32)(256 + 1) << SecLogSize;
IsArc = true;
@@ -946,28 +950,63 @@ HRESULT CInArchive::Open2()
}
{
- UInt32 secMask = ((UInt32)1 << SecLogSize) - 1;
+ const UInt32 secMask = ((UInt32)1 << SecLogSize) - 1;
PhySize = (PhySize + secMask) & ~(UInt64)secMask;
}
+
+ NoEndAnchor = true;
+
if (PhySize < fileSize)
{
+ UInt64 rem = fileSize - PhySize;
+ const size_t secSize = (size_t)1 << SecLogSize;
+
RINOK(_stream->Seek(PhySize, STREAM_SEEK_SET, NULL));
- size_t bufSize = (UInt32)1 << SecLogSize;
- size_t readSize = bufSize;
- RINOK(ReadStream(_stream, buf, &readSize));
- if (readSize == bufSize)
+
+ // some UDF images contain ZEROs before "Anchor Volume Descriptor Pointer" at the end
+
+ for (unsigned sec = 0; sec < 1024; sec++)
{
- CTag tag;
- if (tag.Parse(buf, readSize) == S_OK)
- if (tag.Id == DESC_TYPE_AnchorVolPtr)
+ if (rem == 0)
+ break;
+
+ size_t readSize = secSize;
+ if (readSize > rem)
+ readSize = (size_t)rem;
+
+ RINOK(ReadStream(_stream, buf, &readSize));
+
+ if (readSize == 0)
+ break;
+
+ if (readSize == secSize && NoEndAnchor)
+ {
+ CTag tag;
+ if (tag.Parse(buf, readSize) == S_OK &&
+ tag.Id == DESC_TYPE_AnchorVolPtr)
{
- PhySize += bufSize;
+ NoEndAnchor = false;
+ rem -= readSize;
+ PhySize = fileSize - rem;
+ continue;
}
+ }
+
+ size_t i;
+ for (i = 0; i < readSize && buf[i] == 0; i++);
+ if (i != readSize)
+ break;
+ rem -= readSize;
}
+
+ if (rem == 0)
+ PhySize = fileSize;
}
+
return S_OK;
}
+
HRESULT CInArchive::Open(IInStream *inStream, CProgressVirt *progress)
{
_progress = progress;
@@ -1000,6 +1039,7 @@ void CInArchive::Clear()
IsArc = false;
Unsupported = false;
UnexpectedEnd = false;
+ NoEndAnchor = false;
PhySize = 0;
FileSize = 0;
diff --git a/CPP/7zip/Archive/Udf/UdfIn.h b/CPP/7zip/Archive/Udf/UdfIn.h
index 3851062e..f7379401 100644
--- a/CPP/7zip/Archive/Udf/UdfIn.h
+++ b/CPP/7zip/Archive/Udf/UdfIn.h
@@ -370,6 +370,7 @@ public:
bool IsArc;
bool Unsupported;
bool UnexpectedEnd;
+ bool NoEndAnchor;
void UpdatePhySize(UInt64 val)
{
diff --git a/CPP/7zip/Archive/Zip/ZipIn.cpp b/CPP/7zip/Archive/Zip/ZipIn.cpp
index f72e7f8c..77ca89ea 100644
--- a/CPP/7zip/Archive/Zip/ZipIn.cpp
+++ b/CPP/7zip/Archive/Zip/ZipIn.cpp
@@ -188,9 +188,9 @@ API_FUNC_IsArc IsArc_Zip(const Byte *p, size_t size)
// Crc = Get32(p + 10);
// PackSize = Get32(p + 14);
// Size = Get32(p + 18);
- unsigned nameSize = Get16(p + 22);
+ const unsigned nameSize = Get16(p + 22);
unsigned extraSize = Get16(p + 24);
- UInt32 extraOffset = kLocalHeaderSize + (UInt32)nameSize;
+ const UInt32 extraOffset = kLocalHeaderSize + (UInt32)nameSize;
if (extraOffset + extraSize > (1 << 16))
return k_IsArc_Res_NO;
@@ -562,13 +562,21 @@ bool CInArchive::ReadLocalItem(CItemEx &item)
// return false;
}
}
+
if (!CheckDosTime(item.Time))
{
HeadersWarning = true;
// return false;
}
+
if (item.Name.Len() != nameSize)
- return false;
+ {
+ // we support "bad" archives with null-terminated name.
+ if (item.Name.Len() + 1 != nameSize)
+ return false;
+ HeadersWarning = true;
+ }
+
return item.LocalFullHeaderSize <= ((UInt32)1 << 16);
}
@@ -782,9 +790,9 @@ HRESULT CInArchive::ReadCdItem(CItemEx &item)
item.Crc = Get32(p + 12);
item.PackSize = Get32(p + 16);
item.Size = Get32(p + 20);
- unsigned nameSize = Get16(p + 24);
- UInt16 extraSize = Get16(p + 26);
- UInt16 commentSize = Get16(p + 28);
+ const unsigned nameSize = Get16(p + 24);
+ const unsigned extraSize = Get16(p + 26);
+ const unsigned commentSize = Get16(p + 28);
UInt32 diskNumberStart = Get16(p + 30);
item.InternalAttrib = Get16(p + 32);
item.ExternalAttrib = Get32(p + 34);
@@ -961,7 +969,7 @@ HRESULT CInArchive::TryReadCd(CObjectVector<CItemEx> &items, UInt64 cdOffset, UI
CItemEx cdItem;
RINOK(ReadCdItem(cdItem));
items.Add(cdItem);
- if (progress && items.Size() % 1 == 0)
+ if (progress && (items.Size() & 0xFFF) == 0)
RINOK(progress->SetCompletedCD(items.Size()));
}
return (m_Position - cdOffset == cdSize) ? S_OK : S_FALSE;
@@ -1009,6 +1017,7 @@ bool IsStrangeItem(const CItem &item)
return item.Name.Len() > (1 << 14) || item.Method > (1 << 8);
}
+
HRESULT CInArchive::ReadLocals(
CObjectVector<CItemEx> &items, CProgressVirt *progress)
{
@@ -1037,7 +1046,8 @@ HRESULT CInArchive::ReadLocals(
return S_FALSE;
throw;
}
- if (progress && items.Size() % 1 == 0)
+
+ if (progress && (items.Size() & 0xFF) == 0)
RINOK(progress->SetCompletedLocal(items.Size(), item.LocalHeaderPos));
}
@@ -1154,15 +1164,17 @@ HRESULT CInArchive::ReadHeaders2(CObjectVector<CItemEx> &items, CProgressVirt *p
HeadersError = true;
return S_OK;
}
+
_inBufMode = true;
_inBuffer.Init();
cdAbsOffset = m_Position - 4;
+
for (;;)
{
CItemEx cdItem;
RINOK(ReadCdItem(cdItem));
cdItems.Add(cdItem);
- if (progress && cdItems.Size() % 1 == 0)
+ if (progress && (cdItems.Size() & 0xFFF) == 0)
RINOK(progress->SetCompletedCD(items.Size()));
m_Signature = ReadUInt32();
if (m_Signature != NSignature::kCentralFileHeader)
@@ -1183,6 +1195,7 @@ HRESULT CInArchive::ReadHeaders2(CObjectVector<CItemEx> &items, CProgressVirt *p
CEcd64 ecd64;
bool isZip64 = false;
UInt64 ecd64AbsOffset = m_Position - 4;
+
if (m_Signature == NSignature::kEcd64)
{
IsZip64 = isZip64 = true;
@@ -1213,6 +1226,7 @@ HRESULT CInArchive::ReadHeaders2(CObjectVector<CItemEx> &items, CProgressVirt *p
(!items.IsEmpty())))
return S_FALSE;
}
+
if (m_Signature == NSignature::kEcd64Locator)
{
if (!isZip64)
@@ -1224,6 +1238,7 @@ HRESULT CInArchive::ReadHeaders2(CObjectVector<CItemEx> &items, CProgressVirt *p
return S_FALSE;
m_Signature = ReadUInt32();
}
+
if (m_Signature != NSignature::kEcd)
return S_FALSE;
@@ -1323,6 +1338,7 @@ HRESULT CInArchive::ReadHeaders2(CObjectVector<CItemEx> &items, CProgressVirt *p
return S_OK;
}
+
HRESULT CInArchive::ReadHeaders(CObjectVector<CItemEx> &items, CProgressVirt *progress)
{
HRESULT res;