From d98a3e026c2c8e81509ab5bd163d766f0389a6f5 Mon Sep 17 00:00:00 2001 From: Michael Lotz Date: Thu, 9 Oct 2014 23:15:48 +0200 Subject: [PATCH] package kit: Fix corruption of last package chunk on update. PackageFileHeapWriter::_UnwriteLastPartialChunk() used ReadData() to extract the last partial chunk into the pending buffer. This indirectly calls PackageFileHeapWriter::ReadAndDecompressChunk(), which assumes data past the last full chunk to come from the pending data buffer. Since the pending data buffer is not filled in at that point, the call to ReadAndDecompressChunk() simply did nothing, leaving the object with a correctly sized but completely nulled pending data buffer. The last partial chunk of a package would therefore always get corrupted when updating a package. Fixes #11306 that provided a reduced test case that happened to corrupt the only chunk of a package, nulling the .PackageInfo and therefore making the error more obvious as subsequent parsing of the info failed. --- src/kits/package/hpkg/PackageFileHeapWriter.cpp | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-) diff --git a/src/kits/package/hpkg/PackageFileHeapWriter.cpp b/src/kits/package/hpkg/PackageFileHeapWriter.cpp index 3a5800ccd8..9ca84dc735 100644 --- a/src/kits/package/hpkg/PackageFileHeapWriter.cpp +++ b/src/kits/package/hpkg/PackageFileHeapWriter.cpp @@ -642,13 +642,17 @@ PackageFileHeapWriter::_UnwriteLastPartialChunk() // If the last chunk is partial, read it in and remove it from the offsets. size_t lastChunkSize = fUncompressedHeapSize % kChunkSize; if (lastChunkSize != 0) { - status_t error = ReadData(fUncompressedHeapSize - lastChunkSize, - fPendingDataBuffer, lastChunkSize); + uint64 lastChunkOffset = fOffsets[fOffsets.Count() - 1]; + size_t compressedSize = fCompressedHeapSize - lastChunkOffset; + + status_t error = ReadAndDecompressChunkData(lastChunkOffset, + compressedSize, lastChunkSize, fCompressedDataBuffer, + fPendingDataBuffer);; if (error != B_OK) throw error; fPendingDataSize = lastChunkSize; - fCompressedHeapSize = fOffsets[fOffsets.Count() - 1]; + fCompressedHeapSize = lastChunkOffset; fOffsets.Remove(fOffsets.Count() - 1); } }