Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

FileStream memory leak in ZipArchive (ZipSubRStream) when extracting files from archive. #1389

Merged

Conversation

just-bank
Copy link
Contributor

Problem: FileStream memory leak in ZipArchive (ZipSubRStream) when extracting files from archive.

Reproduce:
Using following code to track FileStream objects':

@@ -22,6 +22,7 @@
 
 #include "platform/platform.h"
 #include "core/stream/fileStream.h"
+#include "console/console.h"
 
 
 //-----------------------------------------------------------------------------
@@ -31,6 +32,7 @@
 //-----------------------------------------------------------------------------
 FileStream::FileStream()
 {
+   Con::warnf("Created FileStream 0x%16p", (this));
    dMemset(mBuffer, 0, sizeof(mBuffer));
    // initialize the file stream
    init();
@@ -54,8 +56,11 @@ FileStream *FileStream::createAndOpen(const String &inFileName, Torque::FS::File
 //-----------------------------------------------------------------------------
 FileStream::~FileStream()
 {
+   String temp = mFile ? mFile->getName().getFullPath().c_str() : "none";
    // make sure the file stream is closed
    close();
+
+   Con::printf("Dropping FileStream 0x%16p on %s", (this), temp.c_str());
 }
 
 //-----------------------------------------------------------------------------
@@ -145,6 +150,7 @@ bool FileStream::open(const String &inFileName, Torque::FS::File::AccessMode inM
       Torque::FS::CreatePath(filePath);
 
    mFile = Torque::FS::OpenFile(filePath, inMode);
+   Con::warnf("Opened FileStream 0x%16p on %s", (this), mFile->getName().getFullPath().c_str());
 
    if (mFile != NULL)
    {
@@ -190,6 +196,7 @@ void FileStream::close()
       if (mDirty)
          flush();
 
+      Con::printf("Closing FileStream 0x%16p on %s", (this), mFile->getName().getFullPath().c_str());
       // and close the file
       mFile->close();

Using script:

   // Create archive
   new ZipObject(zo);
   zo.openArchive("data/test.zpp", "write");
   zo.addFile("data/file.txt", "file.txt");
   zo.closeArchive();
   zo.delete();
   // Extract file to catch mem-leak
   new ZipObject(zo);
   zo.openArchive("data/test.zpp", "read");
   zo.extractFile("file.txt", "data/fileOut.txt");
   zo.closeArchive();
   zo.delete();

.zpp ext used to prevent T3D to auto-load archive.

The extracting script gives this output:

Created FileStream 0x0000022596C625A0
Opened FileStream 0x0000022596C625A0 on game:/data/test.zpp
Created FileStream 0x000000E54BEF3A60
Opened FileStream 0x000000E54BEF3A60 on game:/data/file.txt
Created FileStream 0x0000022596C6A9C0                         // Created but never deleted
Opened FileStream 0x0000022596C6A9C0 on game:/data/test.zpp   // Opened but never closed
Closing FileStream 0x000000E54BEF3A60 on game:/data/file.txt
Dropping FileStream 0x000000E54BEF3A60 on none
Closing FileStream 0x0000022596C625A0 on game:/data/test.zpp
Dropping FileStream 0x0000022596C625A0 on none

This PR fixes the issue by passing new flag to closeFile() method in order to delete root stream from the chain (which is cloned/leaked FileStream on top of the ZipSubRStream).

Added safety check to prevent deleting mStream in case the bool ZipSubRStream::attachStream(Stream* io_pSlaveStream) method returns passed stream instead of cloned one.

Inside attachStream() method we may clone passed stream, but never delete it.
@Azaezel Azaezel merged commit a206746 into TorqueGameEngines:development Feb 19, 2025
3 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants