From c9ed1ea292780eb14b2652974c2623cc7ed0574f Mon Sep 17 00:00:00 2001 From: Ingo Weinhold Date: Fri, 25 Oct 2013 22:46:41 +0200 Subject: [PATCH] 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. --- src/kits/package/hpkg/PackageWriterImpl.cpp | 22 +++++++++++++++------ 1 file changed, 16 insertions(+), 6 deletions(-) diff --git a/src/kits/package/hpkg/PackageWriterImpl.cpp b/src/kits/package/hpkg/PackageWriterImpl.cpp index 8985e5025d..cf2dd504ec 100644 --- a/src/kits/package/hpkg/PackageWriterImpl.cpp +++ b/src/kits/package/hpkg/PackageWriterImpl.cpp @@ -1,5 +1,5 @@ /* - * Copyright 2009-2011, Ingo Weinhold, ingo_weinhold@gmx.de. + * Copyright 2009-2013, Ingo Weinhold, ingo_weinhold@gmx.de. * Copyright 2011, Oliver Tappe * Distributed under the terms of the MIT License. */ @@ -457,6 +457,7 @@ PackageWriterImpl::PackageWriterImpl(BPackageWriterListener* listener) PackageWriterImpl::~PackageWriterImpl() { + delete fHeapRangesToRemove; delete fRootAttribute; delete fRootEntry; } @@ -561,9 +562,6 @@ status_t PackageWriterImpl::Finish() { try { - RangeArray heapRangesToRemove; - fHeapRangesToRemove = &heapRangesToRemove; - if ((Flags() & B_HPKG_WRITER_UPDATE_PACKAGE) != 0) { _UpdateCheckEntryCollisions(); @@ -590,8 +588,6 @@ PackageWriterImpl::Finish() if ((Flags() & B_HPKG_WRITER_UPDATE_PACKAGE) != 0) _CompactHeap(); - fHeapRangesToRemove = NULL; - return _Finish(); } catch (status_t error) { return error; @@ -622,6 +618,8 @@ PackageWriterImpl::_Init(const char* fileName, fHeapOffset = fHeaderSize = sizeof(hpkg_header); fTopAttribute = fRootAttribute; + fHeapRangesToRemove = new RangeArray; + // in update mode, parse the TOC if ((Flags() & B_HPKG_WRITER_UPDATE_PACKAGE) != 0) { PackageReaderImpl packageReader(fListener); @@ -638,6 +636,18 @@ PackageWriterImpl::_Init(const char* fileName, return result; 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;