diff options
author | Igor Pavlov <ipavlov@users.sourceforge.net> | 2016-05-10 03:00:00 +0300 |
---|---|---|
committer | Kornel LesiĆski <kornel@geekhood.net> | 2016-05-28 02:16:59 +0300 |
commit | 66ac98bb02ac0fadd2a0e3266ea39279984580a3 (patch) | |
tree | c14c790212474e8b51df443d686b202cfe6b2315 /CPP/7zip/Archive/Cab | |
parent | c20d013055085bf49b4c93b2c617030b10c1fb4d (diff) |
16.0016.00
Diffstat (limited to 'CPP/7zip/Archive/Cab')
-rw-r--r-- | CPP/7zip/Archive/Cab/CabHandler.cpp | 24 |
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; |