Skip to content

Commit

Permalink
Fix ahnyQuab ogg decompression crashes.
Browse files Browse the repository at this point in the history
This issue was introduced when `hsStream::Close()` was removed in favor
of RAII. Unfortunately, the patcher is handing off files before it
deletes the patcher stream, which causes race conditions around zlib
decompression not being complete. We need to explicitly close the
underlying stream before performing any handoffs to prevent crashes.
  • Loading branch information
Hoikas committed Oct 17, 2023
1 parent df3a346 commit fff8316
Showing 1 changed file with 15 additions and 0 deletions.
15 changes: 15 additions & 0 deletions Sources/Plasma/FeatureLib/pfPatcher/pfPatcher.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -264,6 +264,13 @@ class pfPatcherStream : public plZlibStream
return retVal;
}

void Close()
{
if (hsCheckBits(fFlags, kFlagZipped))
plZlibStream::Close();
fOutput.reset();
}

uint32_t Write(uint32_t count, const void* buf) override
{
// tick whatever progress bar we have
Expand Down Expand Up @@ -383,6 +390,14 @@ static void IFileThingDownloadCB(ENetError result, void* param, const plFileName
pfPatcherWorker* patcher = static_cast<pfPatcherWorker*>(param);
pfPatcherStream* stream = static_cast<pfPatcherStream*>(writer);

// We need to explicitly close any underlying streams NOW because we
// might be about to signal the client that this file needs to be acted
// on, eg installed, decompressed from ogg to wave, etc. We can't wait
// for hsStream's RAII to close the stream at the end of this function or
// the callback code may crash due to either a permissions error or the
// zlib decompression not being complete.
stream->Close();

if (IS_NET_SUCCESS(result)) {
PatcherLogGreen("\tDownloaded File '{}'", stream->GetFileName());
patcher->WhitelistFile(stream->GetFileName(), true);
Expand Down

0 comments on commit fff8316

Please sign in to comment.