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.
This commit is contained in:
Michael Lotz
2014-10-09 23:41:39 +02:00
parent d41ee54e6a
commit d98a3e026c
@@ -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);
}
}