"Fossies" - the Fresh Open Source Software Archive  

Source code changes of the file "CPP/7zip/Archive/Cab/CabHandler.cpp" between
p7zip_15.14.1_src_all.tar.gz and p7zip_16.02_src_all.tar.gz

About: p7zip is a command-line file archiver with a high compression ratio (a port of the Windows program 7za.exe).

CabHandler.cpp  (p7zip_15.14.1_src_all):CabHandler.cpp  (p7zip_16.02_src_all)
skipping to change at line 351 skipping to change at line 351
{ {
COM_TRY_BEGIN COM_TRY_BEGIN
Close(); Close();
CInArchive archive; CInArchive archive;
CMyComPtr<IArchiveOpenVolumeCallback> openVolumeCallback; CMyComPtr<IArchiveOpenVolumeCallback> openVolumeCallback;
callback->QueryInterface(IID_IArchiveOpenVolumeCallback, (void **)&openVolumeC allback); callback->QueryInterface(IID_IArchiveOpenVolumeCallback, (void **)&openVolumeC allback);
CMyComPtr<IInStream> nextStream = inStream; CMyComPtr<IInStream> nextStream = inStream;
bool prevChecked = false; bool prevChecked = false;
UString startVolName;
bool startVolName_was_Requested = false;
UInt64 numItems = 0; UInt64 numItems = 0;
unsigned numTempVolumes = 0; unsigned numTempVolumes = 0;
// try // try
{ {
while (nextStream != NULL) while (nextStream)
{ {
CDatabaseEx db; CDatabaseEx db;
db.Stream = nextStream; db.Stream = nextStream;
HRESULT res = archive.Open(db, maxCheckStartPosition); HRESULT res = archive.Open(db, maxCheckStartPosition);
_errorInHeaders |= archive.HeaderError; _errorInHeaders |= archive.HeaderError;
_errorInHeaders |= archive.ErrorInNames; _errorInHeaders |= archive.ErrorInNames;
_unexpectedEnd |= archive.UnexpectedEnd; _unexpectedEnd |= archive.UnexpectedEnd;
if (res == S_OK && !m_Database.Volumes.IsEmpty()) if (res == S_OK && !m_Database.Volumes.IsEmpty())
{ {
const CArchInfo &lastArc = m_Database.Volumes.Back().ArcInfo; const CArchInfo &lastArc = m_Database.Volumes.Back().ArcInfo;
unsigned cabNumber = db.ArcInfo.CabinetNumber; unsigned cabNumber = db.ArcInfo.CabinetNumber;
if (lastArc.SetID != db.ArcInfo.SetID) if (lastArc.SetID != db.ArcInfo.SetID)
res = S_FALSE; res = S_FALSE;
skipping to change at line 429 skipping to change at line 433
} }
} }
RINOK(callback->SetCompleted(&numItems, NULL)); RINOK(callback->SetCompleted(&numItems, NULL));
nextStream = NULL; nextStream = NULL;
for (;;) for (;;)
{ {
const COtherArc *otherArc = NULL; const COtherArc *otherArc = NULL;
if (!prevChecked) if (!prevChecked)
{ {
if (numTempVolumes == 0) if (numTempVolumes == 0)
{ {
const CInArcInfo &ai = m_Database.Volumes[0].ArcInfo; const CInArcInfo &ai = m_Database.Volumes[0].ArcInfo;
if (ai.IsTherePrev()) if (ai.IsTherePrev())
otherArc = &ai.PrevArc; otherArc = &ai.PrevArc;
else else
prevChecked = true; prevChecked = true;
} }
skipping to change at line 452 skipping to change at line 457
if (ai.IsThereNext()) if (ai.IsThereNext())
otherArc = &ai.NextArc; otherArc = &ai.NextArc;
else else
{ {
prevChecked = true; prevChecked = true;
m_Database.Volumes.DeleteFrontal(numTempVolumes); m_Database.Volumes.DeleteFrontal(numTempVolumes);
numTempVolumes = 0; numTempVolumes = 0;
} }
} }
} }
if (!otherArc) if (!otherArc)
{ {
const CInArcInfo &ai = m_Database.Volumes.Back().ArcInfo; const CInArcInfo &ai = m_Database.Volumes.Back().ArcInfo;
if (ai.IsThereNext()) if (ai.IsThereNext())
otherArc = &ai.NextArc; otherArc = &ai.NextArc;
} }
if (!otherArc) if (!otherArc)
break; break;
if (!openVolumeCallback) if (!openVolumeCallback)
break; break;
// printf("\n%s", otherArc->FileName); // printf("\n%s", otherArc->FileName);
const UString fullName = MultiByteToUnicodeString(otherArc->FileName, CP _ACP); 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); HRESULT result = openVolumeCallback->GetStream(fullName, &nextStream);
if (result == S_OK) if (result == S_OK)
break; break;
if (result != S_FALSE) if (result != S_FALSE)
return result; return result;
if (!_errorMessage.IsEmpty()) if (!_errorMessage.IsEmpty())
_errorMessage.Add_LF(); _errorMessage.Add_LF();
_errorMessage.AddAscii("Can't open volume: "); _errorMessage.AddAscii("Can't open volume: ");
_errorMessage += fullName; _errorMessage += fullName;
skipping to change at line 988 skipping to change at line 1010
extractStatuses.Clear(); extractStatuses.Clear();
for (; startIndex < index; startIndex++) for (; startIndex < index; startIndex++)
extractStatuses.Add(false); extractStatuses.Add(false);
extractStatuses.Add(true); extractStatuses.Add(true);
startIndex++; startIndex++;
UInt64 curUnpack = item.GetEndOffset(); UInt64 curUnpack = item.GetEndOffset();
for (; i < numItems; i++) for (; i < numItems; i++)
{ {
unsigned indexNext = allFilesMode ? i : indices[i]; unsigned indexNext = allFilesMode ? i : indices[i];
const CMvItem &mvItem = m_Database.Items[indexNext]; const CMvItem &mvItem2 = m_Database.Items[indexNext];
const CItem &item = m_Database.Volumes[mvItem.VolumeIndex].Items[mvItem.It const CItem &item2 = m_Database.Volumes[mvItem2.VolumeIndex].Items[mvItem2
emIndex]; .ItemIndex];
if (item.IsDir()) if (item2.IsDir())
continue; continue;
int newFolderIndex = m_Database.GetFolderIndex(&mvItem); int newFolderIndex = m_Database.GetFolderIndex(&mvItem2);
if (newFolderIndex != folderIndex) if (newFolderIndex != folderIndex)
break; break;
for (; startIndex < indexNext; startIndex++) for (; startIndex < indexNext; startIndex++)
extractStatuses.Add(false); extractStatuses.Add(false);
extractStatuses.Add(true); extractStatuses.Add(true);
startIndex++; startIndex++;
curUnpack = item.GetEndOffset(); curUnpack = item2.GetEndOffset();
} }
CFolderOutStream *cabFolderOutStream = new CFolderOutStream; CFolderOutStream *cabFolderOutStream = new CFolderOutStream;
CMyComPtr<ISequentialOutStream> outStream(cabFolderOutStream); CMyComPtr<ISequentialOutStream> outStream(cabFolderOutStream);
unsigned folderIndex2 = item.GetFolderIndex(db.Folders.Size()); unsigned folderIndex2 = item.GetFolderIndex(db.Folders.Size());
const CFolder &folder = db.Folders[folderIndex2]; const CFolder &folder = db.Folders[folderIndex2];
cabFolderOutStream->Init(&m_Database, &extractStatuses, startIndex2, cabFolderOutStream->Init(&m_Database, &extractStatuses, startIndex2,
curUnpack, extractCallback, testMode); curUnpack, extractCallback, testMode);
skipping to change at line 1075 skipping to change at line 1097
bool thereWasNotAlignedChunk = false; bool thereWasNotAlignedChunk = false;
for (UInt32 bl = 0; cabFolderOutStream->NeedMoreWrite();) for (UInt32 bl = 0; cabFolderOutStream->NeedMoreWrite();)
{ {
if (volIndex >= m_Database.Volumes.Size()) if (volIndex >= m_Database.Volumes.Size())
{ {
res = S_FALSE; res = S_FALSE;
break; break;
} }
const CDatabaseEx &db = m_Database.Volumes[volIndex]; const CDatabaseEx &db2 = m_Database.Volumes[volIndex];
const CFolder &folder = db.Folders[locFolderIndex]; const CFolder &folder2 = db2.Folders[locFolderIndex];
if (bl == 0) if (bl == 0)
{ {
cabBlockInStreamSpec->ReservedSize = db.ArcInfo.GetDataBlockReserveSiz cabBlockInStreamSpec->ReservedSize = db2.ArcInfo.GetDataBlockReserveSi
e(); ze();
RINOK(db.Stream->Seek(db.StartPosition + folder.DataStart, STREAM_SEEK RINOK(db2.Stream->Seek(db2.StartPosition + folder2.DataStart, STREAM_S
_SET, NULL)); EEK_SET, NULL));
} }
if (bl == folder.NumDataBlocks) if (bl == folder2.NumDataBlocks)
{ {
/* /*
CFolder::NumDataBlocks (CFFOLDER::cCFData in CAB specification) is 1 6-bit. CFolder::NumDataBlocks (CFFOLDER::cCFData in CAB specification) is 1 6-bit.
But there are some big CAB archives from MS that contain more But there are some big CAB archives from MS that contain more
than (0xFFFF) CFDATA blocks in folder. than (0xFFFF) CFDATA blocks in folder.
Old cab extracting software can show error (or ask next volume) Old cab extracting software can show error (or ask next volume)
but cab extracting library in new Windows ignores this error. but cab extracting library in new Windows ignores this error.
15.00 : We also try to ignore such error, if archive is not multi-vo lume. 15.00 : We also try to ignore such error, if archive is not multi-vo lume.
*/ */
if (m_Database.Volumes.Size() > 1) if (m_Database.Volumes.Size() > 1)
skipping to change at line 1109 skipping to change at line 1131
continue; continue;
} }
} }
bl++; bl++;
if (!keepInputBuffer) if (!keepInputBuffer)
cabBlockInStreamSpec->InitForNewBlock(); cabBlockInStreamSpec->InitForNewBlock();
UInt32 packSize, unpackSize; UInt32 packSize, unpackSize;
res = cabBlockInStreamSpec->PreRead(db.Stream, packSize, unpackSize); res = cabBlockInStreamSpec->PreRead(db2.Stream, packSize, unpackSize);
if (res == S_FALSE) if (res == S_FALSE)
break; break;
RINOK(res); RINOK(res);
keepInputBuffer = (unpackSize == 0); keepInputBuffer = (unpackSize == 0);
if (keepInputBuffer) if (keepInputBuffer)
continue; continue;
UInt64 totalUnPacked2 = totalUnPacked + cabFolderOutStream->GetPosInFold er(); UInt64 totalUnPacked2 = totalUnPacked + cabFolderOutStream->GetPosInFold er();
totalPacked += packSize; totalPacked += packSize;
skipping to change at line 1151 skipping to change at line 1173
{ {
res = S_FALSE; res = S_FALSE;
break; break;
} }
thereWasNotAlignedChunk = true; thereWasNotAlignedChunk = true;
} }
UInt64 unpackSize64 = unpackSize; UInt64 unpackSize64 = unpackSize;
UInt32 packSizeChunk = cabBlockInStreamSpec->GetPackSizeAvail(); UInt32 packSizeChunk = cabBlockInStreamSpec->GetPackSizeAvail();
switch (folder.GetMethod()) switch (folder2.GetMethod())
{ {
case NHeader::NMethod::kNone: case NHeader::NMethod::kNone:
res = copyCoder->Code(cabBlockInStream, outStream, NULL, &unpackSize 64, NULL); res = copyCoder->Code(cabBlockInStream, outStream, NULL, &unpackSize 64, NULL);
break; break;
case NHeader::NMethod::kMSZip: case NHeader::NMethod::kMSZip:
deflateDecoderSpec->Set_KeepHistory(keepHistory); deflateDecoderSpec->Set_KeepHistory(keepHistory);
/* v9.31: now we follow MSZIP specification that requires to finish deflate stream at the end of each block. /* v9.31: now we follow MSZIP specification that requires to finish deflate stream at the end of each block.
But PyCabArc can create CAB archives that doesn't have finish mar ker at the end of block. But PyCabArc can create CAB archives that doesn't have finish mar ker at the end of block.
Cabarc probably ignores such errors in cab archives. Cabarc probably ignores such errors in cab archives.
 End of changes. 16 change blocks. 
16 lines changed or deleted 38 lines changed or added

Home  |  About  |  All  |  Newest  |  Fossies Dox  |  Screenshots  |  Comments  |  Imprint  |  Privacy  |  HTTPS