PackageWriterImpl: Fix package file heap leak on update

_Init(): In update mode remove the package attributes section and the
TOC section from the package file's heap. We write the updated sections
in Finish(); previously the space for the old sections would be leaked.
This was also the reason why updating haiku_loader would result in a
non-bootable image.
This commit is contained in:
Ingo Weinhold
2013-10-25 22:54:44 +02:00
parent b8f713e904
commit c9ed1ea292
+16 -6
View File
@@ -1,5 +1,5 @@
/* /*
* Copyright 2009-2011, Ingo Weinhold, [email protected]. * Copyright 2009-2013, Ingo Weinhold, [email protected].
* Copyright 2011, Oliver Tappe <[email protected]> * Copyright 2011, Oliver Tappe <[email protected]>
* Distributed under the terms of the MIT License. * Distributed under the terms of the MIT License.
*/ */
@@ -457,6 +457,7 @@ PackageWriterImpl::PackageWriterImpl(BPackageWriterListener* listener)
PackageWriterImpl::~PackageWriterImpl() PackageWriterImpl::~PackageWriterImpl()
{ {
delete fHeapRangesToRemove;
delete fRootAttribute; delete fRootAttribute;
delete fRootEntry; delete fRootEntry;
} }
@@ -561,9 +562,6 @@ status_t
PackageWriterImpl::Finish() PackageWriterImpl::Finish()
{ {
try { try {
RangeArray<uint64> heapRangesToRemove;
fHeapRangesToRemove = &heapRangesToRemove;
if ((Flags() & B_HPKG_WRITER_UPDATE_PACKAGE) != 0) { if ((Flags() & B_HPKG_WRITER_UPDATE_PACKAGE) != 0) {
_UpdateCheckEntryCollisions(); _UpdateCheckEntryCollisions();
@@ -590,8 +588,6 @@ PackageWriterImpl::Finish()
if ((Flags() & B_HPKG_WRITER_UPDATE_PACKAGE) != 0) if ((Flags() & B_HPKG_WRITER_UPDATE_PACKAGE) != 0)
_CompactHeap(); _CompactHeap();
fHeapRangesToRemove = NULL;
return _Finish(); return _Finish();
} catch (status_t error) { } catch (status_t error) {
return error; return error;
@@ -622,6 +618,8 @@ PackageWriterImpl::_Init(const char* fileName,
fHeapOffset = fHeaderSize = sizeof(hpkg_header); fHeapOffset = fHeaderSize = sizeof(hpkg_header);
fTopAttribute = fRootAttribute; fTopAttribute = fRootAttribute;
fHeapRangesToRemove = new RangeArray<uint64>;
// in update mode, parse the TOC // in update mode, parse the TOC
if ((Flags() & B_HPKG_WRITER_UPDATE_PACKAGE) != 0) { if ((Flags() & B_HPKG_WRITER_UPDATE_PACKAGE) != 0) {
PackageReaderImpl packageReader(fListener); PackageReaderImpl packageReader(fListener);
@@ -638,6 +636,18 @@ PackageWriterImpl::_Init(const char* fileName,
return result; return result;
fHeapWriter->Reinit(packageReader.RawHeapReader()); fHeapWriter->Reinit(packageReader.RawHeapReader());
// Remove the old packages attributes and TOC section from the heap.
// We'll write new ones later.
const PackageFileSection& attributesSection
= packageReader.PackageAttributesSection();
const PackageFileSection& tocSection = packageReader.TOCSection();
if (!fHeapRangesToRemove->AddRange(attributesSection.offset,
attributesSection.uncompressedLength)
|| !fHeapRangesToRemove->AddRange(tocSection.offset,
tocSection.uncompressedLength)) {
throw std::bad_alloc();
}
} }
return B_OK; return B_OK;