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-05-10 03:00:00 +0300
committerKornel LesiƄski <kornel@geekhood.net>2016-05-28 02:16:59 +0300
commit66ac98bb02ac0fadd2a0e3266ea39279984580a3 (patch)
treec14c790212474e8b51df443d686b202cfe6b2315 /CPP/7zip/Archive/Cab
parentc20d013055085bf49b4c93b2c617030b10c1fb4d (diff)
16.0016.00
Diffstat (limited to 'CPP/7zip/Archive/Cab')
-rw-r--r--CPP/7zip/Archive/Cab/CabHandler.cpp24
1 files changed, 23 insertions, 1 deletions
diff --git a/CPP/7zip/Archive/Cab/CabHandler.cpp b/CPP/7zip/Archive/Cab/CabHandler.cpp
index 9c841545..31aa5e1d 100644
--- a/CPP/7zip/Archive/Cab/CabHandler.cpp
+++ b/CPP/7zip/Archive/Cab/CabHandler.cpp
@@ -348,15 +348,19 @@ STDMETHODIMP CHandler::Open(IInStream *inStream,
CMyComPtr<IInStream> nextStream = inStream;
bool prevChecked = false;
+ UString startVolName;
+ bool startVolName_was_Requested = false;
UInt64 numItems = 0;
unsigned numTempVolumes = 0;
// try
{
- while (nextStream != NULL)
+ while (nextStream)
{
CDatabaseEx db;
db.Stream = nextStream;
+
HRESULT res = archive.Open(db, maxCheckStartPosition);
+
_errorInHeaders |= archive.HeaderError;
_errorInHeaders |= archive.ErrorInNames;
_unexpectedEnd |= archive.UnexpectedEnd;
@@ -426,6 +430,7 @@ STDMETHODIMP CHandler::Open(IInStream *inStream,
for (;;)
{
const COtherArc *otherArc = NULL;
+
if (!prevChecked)
{
if (numTempVolumes == 0)
@@ -449,18 +454,35 @@ STDMETHODIMP CHandler::Open(IInStream *inStream,
}
}
}
+
if (!otherArc)
{
const CInArcInfo &ai = m_Database.Volumes.Back().ArcInfo;
if (ai.IsThereNext())
otherArc = &ai.NextArc;
}
+
if (!otherArc)
break;
if (!openVolumeCallback)
break;
// printf("\n%s", otherArc->FileName);
const UString fullName = MultiByteToUnicodeString(otherArc->FileName, CP_ACP);
+
+ if (!startVolName_was_Requested)
+ {
+ // some "bad" cab example can contain the link to itself.
+ startVolName_was_Requested = true;
+ {
+ NCOM::CPropVariant prop;
+ RINOK(openVolumeCallback->GetProperty(kpidName, &prop));
+ if (prop.vt == VT_BSTR)
+ startVolName = prop.bstrVal;
+ }
+ if (fullName == startVolName)
+ break;
+ }
+
HRESULT result = openVolumeCallback->GetStream(fullName, &nextStream);
if (result == S_OK)
break;