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:
@@ -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;
|
||||||
|
|||||||
Reference in New Issue
Block a user