"Fossies" - the Fresh Open Source Software Archive  

Source code changes of the file "CPP/7zip/Archive/PeHandler.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).

PeHandler.cpp  (p7zip_15.14.1_src_all):PeHandler.cpp  (p7zip_16.02_src_all)
skipping to change at line 245 skipping to change at line 245
UInt64 HeapCommit; UInt64 HeapCommit;
UInt32 NumDirItems; UInt32 NumDirItems;
CDirLink DirItems[kNumDirItemsMax]; CDirLink DirItems[kNumDirItemsMax];
bool Is64Bit() const { return Magic == PE_OptHeader_Magic_64; } bool Is64Bit() const { return Magic == PE_OptHeader_Magic_64; }
bool Parse(const Byte *p, UInt32 size); bool Parse(const Byte *p, UInt32 size);
int GetNumFileAlignBits() const int GetNumFileAlignBits() const
{ {
for (int i = 9; i <= 16; i++) for (unsigned i = 0; i <= 31; i++)
if (((UInt32)1 << i) == FileAlign) if (((UInt32)1 << i) == FileAlign)
return i; return i;
return -1; return -1;
} }
bool IsSybSystem_EFI() const bool IsSybSystem_EFI() const
{ {
return return
SubSystem >= k_SubSystems_EFI_First && SubSystem >= k_SubSystems_EFI_First &&
SubSystem <= k_SubSystems_EFI_Last; SubSystem <= k_SubSystems_EFI_Last;
skipping to change at line 350 skipping to change at line 350
UInt32 Pa; UInt32 Pa;
UInt32 Flags; UInt32 Flags;
UInt32 Time; UInt32 Time;
// UInt16 NumRelocs; // UInt16 NumRelocs;
bool IsRealSect; bool IsRealSect;
bool IsDebug; bool IsDebug;
bool IsAdditionalSection; bool IsAdditionalSection;
CSection(): IsRealSect(false), IsDebug(false), IsAdditionalSection(false) {} CSection(): IsRealSect(false), IsDebug(false), IsAdditionalSection(false) {}
// const UInt32 GetSize() const { return PSize; } const UInt32 GetSizeExtract() const { return PSize; }
const UInt32 GetSize() const { return MyMin(PSize, VSize); } const UInt32 GetSizeMin() const { return MyMin(PSize, VSize); }
void UpdateTotalSize(UInt32 &totalSize) const void UpdateTotalSize(UInt32 &totalSize) const
{ {
UInt32 t = Pa + PSize; UInt32 t = Pa + PSize;
if (totalSize < t) if (totalSize < t)
totalSize = t; totalSize = t;
} }
void Parse(const Byte *p); void Parse(const Byte *p);
int Compare(const CSection &s) const int Compare(const CSection &s) const
{ {
RINOZ(MyCompare(Pa, s.Pa)); RINOZ(MyCompare(Pa, s.Pa));
UInt32 size1 = GetSize(); UInt32 size1 = GetSizeExtract();
UInt32 size2 = s.GetSize(); UInt32 size2 = s.GetSizeExtract();
return MyCompare(size1, size2); return MyCompare(size1, size2);
} }
}; };
static const unsigned kNameSize = 8; static const unsigned kNameSize = 8;
static void GetName(const Byte *name, AString &res) static void GetName(const Byte *name, AString &res)
{ {
res.SetFrom_CalcLen((const char *)name, kNameSize); res.SetFrom_CalcLen((const char *)name, kNameSize);
} }
skipping to change at line 1044 skipping to change at line 1044
case kpidSize: prop = (UInt64)item.GetSize(); break; case kpidSize: prop = (UInt64)item.GetSize(); break;
case kpidPackSize: prop = (UInt64)item.Size; break; case kpidPackSize: prop = (UInt64)item.Size; break;
} }
} }
else else
{ {
const CSection &item = _sections[mixItem.SectionIndex]; const CSection &item = _sections[mixItem.SectionIndex];
switch (propID) switch (propID)
{ {
case kpidPath: prop = MultiByteToUnicodeString(item.Name); break; case kpidPath: prop = MultiByteToUnicodeString(item.Name); break;
case kpidSize: prop = (UInt64)item.GetSize(); break; case kpidSize: prop = (UInt64)item.PSize; break;
case kpidPackSize: prop = (UInt64)item.PSize; break; case kpidPackSize: prop = (UInt64)item.PSize; break;
case kpidVirtualSize: prop = (UInt64)item.VSize; break; case kpidVirtualSize: prop = (UInt64)item.VSize; break;
case kpidOffset: prop = item.Pa; break; case kpidOffset: prop = item.Pa; break;
case kpidVa: if (item.IsRealSect) prop = item.Va; break; case kpidVa: if (item.IsRealSect) prop = item.Va; break;
case kpidMTime: case kpidMTime:
case kpidCTime: case kpidCTime:
TimeToProp(item.IsDebug ? item.Time : _header.Time, prop); break; TimeToProp(item.IsDebug ? item.Time : _header.Time, prop); break;
case kpidCharacts: if (item.IsRealSect) FLAGS_TO_PROP(g_SectFlags, item.Fl ags, prop); break; case kpidCharacts: if (item.IsRealSect) FLAGS_TO_PROP(g_SectFlags, item.Fl ags, prop); break;
case kpidZerosTailIsAllowed: if (!item.IsRealSect) prop = true; break; case kpidZerosTailIsAllowed: if (!item.IsRealSect) prop = true; break;
} }
skipping to change at line 1153 skipping to change at line 1153
CTableItem item; CTableItem item;
item.ID = Get32(buf + 0); item.ID = Get32(buf + 0);
if ((bool)((item.ID & kFlag) != 0) != (bool)(i < numNameItems)) if ((bool)((item.ID & kFlag) != 0) != (bool)(i < numNameItems))
return S_FALSE; return S_FALSE;
item.Offset = Get32(buf + 4); item.Offset = Get32(buf + 4);
items.AddInReserved(item); items.AddInReserved(item);
} }
return S_OK; return S_OK;
} }
static const UInt32 kFileSizeMax = (UInt32)1 << 30; static const UInt32 kFileSizeMax = (UInt32)1 << 31;
static const unsigned kNumResItemsMax = (unsigned)1 << 23; static const unsigned kNumResItemsMax = (unsigned)1 << 23;
static const unsigned kNumStringLangsMax = 256; static const unsigned kNumStringLangsMax = 256;
// BITMAPINFOHEADER // BITMAPINFOHEADER
struct CBitmapInfoHeader struct CBitmapInfoHeader
{ {
// UInt32 HeaderSize; // UInt32 HeaderSize;
UInt32 XSize; UInt32 XSize;
Int32 YSize; Int32 YSize;
UInt16 Planes; UInt16 Planes;
skipping to change at line 1895 skipping to change at line 1895
f.CloseBlock(2); f.CloseBlock(2);
} }
f.CloseBlock(0); f.CloseBlock(0);
return true; return true;
} }
HRESULT CHandler::OpenResources(unsigned sectionIndex, IInStream *stream, IArchi veOpenCallback *callback) HRESULT CHandler::OpenResources(unsigned sectionIndex, IInStream *stream, IArchi veOpenCallback *callback)
{ {
const CSection &sect = _sections[sectionIndex]; const CSection &sect = _sections[sectionIndex];
const size_t fileSize = sect.GetSize(); size_t fileSize = sect.PSize;
if (fileSize > kFileSizeMax)
return S_FALSE;
{ {
UInt64 fileSize64 = fileSize; size_t fileSizeMin = sect.PSize;
if (callback)
RINOK(callback->SetTotal(NULL, &fileSize64)); if (sect.VSize < sect.PSize)
{
fileSize = fileSizeMin = sect.VSize;
const int numBits = _optHeader.GetNumFileAlignBits();
if (numBits > 0)
{
const UInt32 mask = ((UInt32)1 << numBits) - 1;
const size_t end = (size_t)((sect.VSize + mask) & (UInt32)~mask);
if (end > sect.VSize)
if (end <= sect.PSize)
fileSize = end;
else
fileSize = sect.PSize;
}
}
if (fileSize > kFileSizeMax)
return S_FALSE;
{
const UInt64 fileSize64 = fileSize;
if (callback)
RINOK(callback->SetTotal(NULL, &fileSize64));
}
RINOK(stream->Seek(sect.Pa, STREAM_SEEK_SET, NULL)); RINOK(stream->Seek(sect.Pa, STREAM_SEEK_SET, NULL));
_buf.Alloc(fileSize); _buf.Alloc(fileSize);
for (size_t pos = 0; pos < fileSize;)
size_t pos;
for (pos = 0; pos < fileSize;)
{ {
UInt64 offset64 = pos; {
if (callback) const UInt64 offset64 = pos;
RINOK(callback->SetCompleted(NULL, &offset64)) if (callback)
RINOK(callback->SetCompleted(NULL, &offset64))
}
size_t rem = MyMin(fileSize - pos, (size_t)(1 << 22)); size_t rem = MyMin(fileSize - pos, (size_t)(1 << 22));
RINOK(ReadStream_FALSE(stream, _buf + pos, rem)); RINOK(ReadStream(stream, _buf + pos, &rem));
if (rem == 0)
{
if (pos < fileSizeMin)
return S_FALSE;
break;
}
pos += rem; pos += rem;
} }
if (pos < fileSize)
memset(_buf + pos, 0, fileSize - pos);
} }
_usedRes.Alloc(fileSize); _usedRes.Alloc(fileSize);
CRecordVector<CTableItem> specItems; CRecordVector<CTableItem> specItems;
RINOK(ReadTable(0, specItems)); RINOK(ReadTable(0, specItems));
_oneLang = true; _oneLang = true;
bool stringsOk = true; bool stringsOk = true;
size_t maxOffset = 0; size_t maxOffset = 0;
FOR_VECTOR (i, specItems) FOR_VECTOR (i, specItems)
{ {
const CTableItem &item1 = specItems[i]; const CTableItem &item1 = specItems[i];
if ((item1.Offset & kFlag) == 0) if ((item1.Offset & kFlag) == 0)
return S_FALSE; return S_FALSE;
CRecordVector<CTableItem> specItems2; CRecordVector<CTableItem> specItems2;
RINOK(ReadTable(item1.Offset & kMask, specItems2)); RINOK(ReadTable(item1.Offset & kMask, specItems2));
FOR_VECTOR (j, specItems2) FOR_VECTOR (j, specItems2)
skipping to change at line 2004 skipping to change at line 2041
mixItem.VersionIndex = _versionFiles.Size(); mixItem.VersionIndex = _versionFiles.Size();
mixItem.SectionIndex = sectionIndex; // check it !!!! mixItem.SectionIndex = sectionIndex; // check it !!!!
CByteBuffer_WithLang &vf = _versionFiles.AddNew(); CByteBuffer_WithLang &vf = _versionFiles.AddNew();
vf.Lang = item.Lang; vf.Lang = item.Lang;
vf.CopyFrom(f.Buf, f.Buf.GetPos()); vf.CopyFrom(f.Buf, f.Buf.GetPos());
_mixItems.Add(mixItem); _mixItems.Add(mixItem);
continue; continue;
} }
// PrintError("ver.Parse error"); // PrintError("ver.Parse error");
} }
item.Enabled = true; item.Enabled = true;
_items.Add(item); _items.Add(item);
} }
} }
} }
if (stringsOk && !_strings.IsEmpty()) if (stringsOk && !_strings.IsEmpty())
{ {
unsigned i; unsigned i;
for (i = 0; i < _items.Size(); i++) for (i = 0; i < _items.Size(); i++)
skipping to change at line 2032 skipping to change at line 2070
continue; continue;
CMixItem mixItem; CMixItem mixItem;
mixItem.StringIndex = i; mixItem.StringIndex = i;
mixItem.SectionIndex = sectionIndex; mixItem.SectionIndex = sectionIndex;
_mixItems.Add(mixItem); _mixItems.Add(mixItem);
} }
} }
_usedRes.Free(); _usedRes.Free();
int numBits = _optHeader.GetNumFileAlignBits();
if (numBits >= 0)
{ {
UInt32 mask = (1 << numBits) - 1; // PSize can be much larger than VSize in some exe installers.
size_t end = ((maxOffset + mask) & ~mask); // it contains archive data after PE resources.
// So we need to use PSize here!
if (/* end < sect.VSize && */ end <= sect.GetSize()) if (maxOffset < sect.PSize)
{ {
CSection sect2; size_t end = fileSize;
sect2.Flags = 0;
// we skip Zeros to start of aligned block // we skip Zeros to start of aligned block
size_t i; size_t i;
for (i = maxOffset; i < end; i++) for (i = maxOffset; i < end; i++)
if (_buf[i] != 0) if (_buf[i] != 0)
break; break;
if (i == end) if (i == end)
maxOffset = end; maxOffset = end;
CSection sect2;
sect2.Flags = 0;
sect2.Pa = sect.Pa + (UInt32)maxOffset; sect2.Pa = sect.Pa + (UInt32)maxOffset;
sect2.Va = sect.Va + (UInt32)maxOffset; sect2.Va = sect.Va + (UInt32)maxOffset;
// 9.29: we use sect.PSize instead of sect.VSize to support some CAB-SFX // 9.29: we use sect.PSize instead of sect.VSize to support some CAB-SFX
// the code for .rsrc_2 is commented. // the code for .rsrc_2 is commented.
sect2.PSize = sect.GetSize() - (UInt32)maxOffset; sect2.PSize = sect.PSize - (UInt32)maxOffset;
if (sect2.PSize != 0) if (sect2.PSize != 0)
{ {
sect2.VSize = sect2.PSize; sect2.VSize = sect2.PSize;
sect2.Name = ".rsrc_1"; sect2.Name = ".rsrc_1";
sect2.Time = 0; sect2.Time = 0;
sect2.IsAdditionalSection = true; sect2.IsAdditionalSection = true;
_sections.Add(sect2); _sections.Add(sect2);
} }
} }
skipping to change at line 2203 skipping to change at line 2240
RINOK(ReadStream(stream, buf, &processed)); RINOK(ReadStream(stream, buf, &processed));
/* /*
if (processed != 0) if (processed != 0)
{ {
printf("\ndata after debug %d, %d \n", (int)size, (int)processed); printf("\ndata after debug %d, %d \n", (int)size, (int)processed);
fflush(stdout); fflush(stdout);
} }
*/ */
size_t i; size_t k;
for (i = 0; i < processed; i++) for (k = 0; k < processed; k++)
if (buf[i] != 0) if (buf[k] != 0)
break; break;
if (processed < size && processed < 100) if (processed < size && processed < 100)
_totalSize += (UInt32)processed; _totalSize += (UInt32)processed;
else if (((_totalSize + i) & 0x1FF) == 0 || processed < size) else if (((_totalSize + k) & 0x1FF) == 0 || processed < size)
_totalSize += (UInt32)i; _totalSize += (UInt32)k;
} }
} }
if (_header.NumSymbols > 0 && _header.PointerToSymbolTable >= 512) if (_header.NumSymbols > 0 && _header.PointerToSymbolTable >= 512)
{ {
if (_header.NumSymbols >= (1 << 24)) if (_header.NumSymbols >= (1 << 24))
return S_FALSE; return S_FALSE;
UInt32 size = _header.NumSymbols * 18; UInt32 size = _header.NumSymbols * 18;
RINOK(stream->Seek((UInt64)_header.PointerToSymbolTable + size, STREAM_SEEK_ SET, NULL)); RINOK(stream->Seek((UInt64)_header.PointerToSymbolTable + size, STREAM_SEEK_ SET, NULL));
Byte buf[4]; Byte buf[4];
skipping to change at line 2240 skipping to change at line 2277
sect.Pa = _header.PointerToSymbolTable; sect.Pa = _header.PointerToSymbolTable;
sect.PSize = sect.VSize = size; sect.PSize = sect.VSize = size;
sect.UpdateTotalSize(_totalSize); sect.UpdateTotalSize(_totalSize);
} }
{ {
CObjectVector<CSection> sections = _sections; CObjectVector<CSection> sections = _sections;
sections.Sort(); sections.Sort();
UInt32 limit = (1 << 12); UInt32 limit = (1 << 12);
unsigned num = 0; unsigned num = 0;
FOR_VECTOR (i, sections) FOR_VECTOR (k, sections)
{ {
const CSection &s = sections[i]; const CSection &s = sections[k];
if (s.Pa > limit) if (s.Pa > limit)
{ {
CSection &s2 = _sections.AddNew(); CSection &s2 = _sections.AddNew();
s2.Pa = s2.Va = limit; s2.Pa = s2.Va = limit;
s2.PSize = s2.VSize = s.Pa - limit; s2.PSize = s2.VSize = s.Pa - limit;
s2.IsAdditionalSection = true; s2.IsAdditionalSection = true;
s2.Name = '['; s2.Name = '[';
s2.Name += GetDecString(num++); s2.Name += GetDecString(num++);
s2.Name += ']'; s2.Name += ']';
limit = s.Pa; limit = s.Pa;
skipping to change at line 2468 skipping to change at line 2505
{ {
const CMixItem &mixItem = _mixItems[allFilesMode ? i : indices[i]]; const CMixItem &mixItem = _mixItems[allFilesMode ? i : indices[i]];
UInt64 size; UInt64 size;
if (mixItem.StringIndex >= 0) if (mixItem.StringIndex >= 0)
size = _strings[mixItem.StringIndex].FinalSize(); size = _strings[mixItem.StringIndex].FinalSize();
else if (mixItem.VersionIndex >= 0) else if (mixItem.VersionIndex >= 0)
size = _versionFiles[mixItem.VersionIndex].Size(); size = _versionFiles[mixItem.VersionIndex].Size();
else if (mixItem.ResourceIndex >= 0) else if (mixItem.ResourceIndex >= 0)
size = _items[mixItem.ResourceIndex].GetSize(); size = _items[mixItem.ResourceIndex].GetSize();
else else
size = _sections[mixItem.SectionIndex].GetSize(); size = _sections[mixItem.SectionIndex].GetSizeExtract();
totalSize += size; totalSize += size;
} }
extractCallback->SetTotal(totalSize); extractCallback->SetTotal(totalSize);
UInt64 currentTotalSize = 0; UInt64 currentTotalSize = 0;
UInt64 currentItemSize; UInt64 currentItemSize;
NCompress::CCopyCoder *copyCoderSpec = new NCompress::CCopyCoder(); NCompress::CCopyCoder *copyCoderSpec = new NCompress::CCopyCoder();
CMyComPtr<ICompressCoder> copyCoder = copyCoderSpec; CMyComPtr<ICompressCoder> copyCoder = copyCoderSpec;
skipping to change at line 2544 skipping to change at line 2581
isOk = false; isOk = false;
else if (outStream) else if (outStream)
{ {
if (item.HeaderSize != 0) if (item.HeaderSize != 0)
RINOK(WriteStream(outStream, item.Header, item.HeaderSize)); RINOK(WriteStream(outStream, item.Header, item.HeaderSize));
RINOK(WriteStream(outStream, _buf + offset, item.Size)); RINOK(WriteStream(outStream, _buf + offset, item.Size));
} }
} }
else else
{ {
currentItemSize = sect.GetSize(); currentItemSize = sect.GetSizeExtract();
if (!testMode && !outStream) if (!testMode && !outStream)
continue; continue;
RINOK(extractCallback->PrepareOperation(askMode)); RINOK(extractCallback->PrepareOperation(askMode));
RINOK(_stream->Seek(sect.Pa, STREAM_SEEK_SET, NULL)); RINOK(_stream->Seek(sect.Pa, STREAM_SEEK_SET, NULL));
streamSpec->Init(currentItemSize); streamSpec->Init(currentItemSize);
RINOK(copyCoder->Code(inStream, outStream, NULL, NULL, progress)); RINOK(copyCoder->Code(inStream, outStream, NULL, NULL, progress));
isOk = (copyCoderSpec->TotalSize == currentItemSize); isOk = (copyCoderSpec->TotalSize == currentItemSize);
} }
 End of changes. 25 change blocks. 
37 lines changed or deleted 74 lines changed or added

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