From 81bb33b31befe6eeece9da51a56340b18bdd97bb Mon Sep 17 00:00:00 2001 From: Quentin Quadrat Date: Wed, 20 Mar 2019 19:35:10 +0100 Subject: [PATCH] Fix memory leaks (#25) --- zipper/unzipper.cpp | 53 ++++++++++++++++++++++++++++++++++------- zipper/unzipper.h | 3 ++- zipper/zipper.cpp | 57 +++++++++++++++++++++++++++++++++++++-------- zipper/zipper.h | 3 ++- 4 files changed, 96 insertions(+), 20 deletions(-) diff --git a/zipper/unzipper.cpp b/zipper/unzipper.cpp index 91a3435..6295644 100644 --- a/zipper/unzipper.cpp +++ b/zipper/unzipper.cpp @@ -329,17 +329,28 @@ namespace zipper { Impl(Unzipper& outer) : m_outer(outer), m_zipmem(), m_filefunc() { + m_zipmem.base = NULL; m_zf = NULL; } ~Impl() { + close(); } void close() { - if (m_zf) + if (m_zf != NULL) + { unzClose(m_zf); + m_zf = NULL; + } + + if (m_zipmem.base != NULL) + { + free(m_zipmem.base); + m_zipmem.base = NULL; + } } bool initFile(const std::string& filename) @@ -376,7 +387,8 @@ namespace zipper { { if (!buffer.empty()) { - m_zipmem.base = (char*)buffer.data(); + m_zipmem.base = (char*) malloc (buffer.size() * sizeof (char)); + memcpy(m_zipmem.base, (char*) buffer.data(), buffer.size()); m_zipmem.size = (uLong)buffer.size(); } @@ -467,7 +479,10 @@ namespace zipper { , m_impl(new Impl(*this)) { if (!m_impl->initWithStream(m_ibuffer)) - throw EXCEPTION_CLASS("Error loading zip in memory!"); + { + release(); + throw EXCEPTION_CLASS("Error loading zip in memory!"); + } m_open = true; } @@ -479,7 +494,10 @@ namespace zipper { , m_impl(new Impl(*this)) { if (!m_impl->initWithVector(m_vecbuffer)) - throw EXCEPTION_CLASS("Error loading zip in memory!"); + { + release(); + throw EXCEPTION_CLASS("Error loading zip in memory!"); + } m_open = true; } @@ -493,7 +511,10 @@ namespace zipper { , m_impl(new Impl(*this)) { if (!m_impl->initFile(zipname)) - throw EXCEPTION_CLASS("Error loading zip file!"); + { + release(); + throw EXCEPTION_CLASS("Error loading zip file!"); + } m_open = true; } @@ -508,14 +529,17 @@ namespace zipper { , m_impl(new Impl(*this)) { if (!m_impl->initFile(zipname)) - throw EXCEPTION_CLASS("Error loading zip file!"); - + { + release(); + throw EXCEPTION_CLASS("Error loading zip file!"); + } m_open = true; } - Unzipper::~Unzipper(void) + Unzipper::~Unzipper() { close(); + release(); } std::vector Unzipper::entries() @@ -550,6 +574,19 @@ namespace zipper { return m_impl->extractAll(destination, std::map()); } + void Unzipper::release() + { + if (!m_usingMemoryVector) + { + delete &m_vecbuffer; + } + if (!m_usingStream) + { + delete &m_ibuffer; + } + delete m_impl; + } + void Unzipper::close() { if (m_open) diff --git a/zipper/unzipper.h b/zipper/unzipper.h index e1e6556..1c837b7 100644 --- a/zipper/unzipper.h +++ b/zipper/unzipper.h @@ -20,7 +20,7 @@ namespace zipper { Unzipper(const std::string& zipname); Unzipper(const std::string& zipname, const std::string& password); - ~Unzipper(void); + ~Unzipper(); std::vector entries(); @@ -33,6 +33,7 @@ namespace zipper { void close(); private: + void release(); std::string m_password; std::string m_zipname; std::istream& m_ibuffer; diff --git a/zipper/zipper.cpp b/zipper/zipper.cpp index 84ce390..45542e3 100644 --- a/zipper/zipper.cpp +++ b/zipper/zipper.cpp @@ -18,9 +18,15 @@ namespace zipper { Impl(Zipper& outer) : m_outer(outer), m_zipmem(), m_filefunc() { m_zf = NULL; + m_zipmem.base = NULL; //m_filefunc = { 0 }; } + ~Impl() + { + close(); + } + bool initFile(const std::string& filename) { #ifdef USEWIN32IOAPI @@ -56,7 +62,8 @@ namespace zipper { if (size > 0) { - m_zipmem.base = new char[(size_t)size]; + if (m_zipmem.base != NULL) { free(m_zipmem.base); } + m_zipmem.base = (char*) malloc (size * sizeof (char)); stream.read(m_zipmem.base, size); } @@ -71,8 +78,9 @@ namespace zipper { if (!buffer.empty()) { - m_zipmem.base = new char[buffer.size()]; - memcpy(m_zipmem.base, (char*)buffer.data(), buffer.size()); + if (m_zipmem.base != NULL) { free(m_zipmem.base); } + m_zipmem.base = (char*) malloc (buffer.size() * sizeof (char)); + memcpy(m_zipmem.base, (char*) buffer.data(), buffer.size()); m_zipmem.size = (uLong)buffer.size(); } @@ -168,8 +176,11 @@ namespace zipper { void close() { - if (m_zf) + if (m_zf != NULL) + { zipClose(m_zf, NULL); + m_zf = NULL; + } if (m_zipmem.base && m_zipmem.limit > 0) { @@ -183,7 +194,11 @@ namespace zipper { m_outer.m_obuffer.write(m_zipmem.base, m_zipmem.limit); } - free(m_zipmem.base); + if (m_zipmem.base != NULL) + { + free(m_zipmem.base); + m_zipmem.base = NULL; + } } }; @@ -199,8 +214,10 @@ namespace zipper { , m_impl(new Impl(*this)) { if (!m_impl->initFile(zipname)) + { + release(); throw EXCEPTION_CLASS("Error creating zip in file!"); - + } m_open = true; } @@ -214,8 +231,10 @@ namespace zipper { , m_impl(new Impl(*this)) { if (!m_impl->initFile(zipname)) + { + release(); throw EXCEPTION_CLASS("Error creating zip in file!"); - + } m_open = true; } @@ -227,8 +246,10 @@ namespace zipper { , m_impl(new Impl(*this)) { if (!m_impl->initWithStream(m_obuffer)) + { + release(); throw EXCEPTION_CLASS("Error creating zip in memory!"); - + } m_open = true; } @@ -240,14 +261,30 @@ namespace zipper { , m_impl(new Impl(*this)) { if (!m_impl->initWithVector(m_vecbuffer)) + { + release(); throw EXCEPTION_CLASS("Error creating zip in memory!"); - + } m_open = true; } - Zipper::~Zipper(void) + Zipper::~Zipper() { close(); + release(); + } + + void Zipper::release() + { + if (!m_usingMemoryVector) + { + delete &m_vecbuffer; + } + if (!m_usingStream) + { + delete &m_obuffer; + } + delete m_impl; } bool Zipper::add(std::istream& source, const std::string& nameInZip, zipFlags flags) diff --git a/zipper/zipper.h b/zipper/zipper.h index 56fb5f2..d554cf3 100644 --- a/zipper/zipper.h +++ b/zipper/zipper.h @@ -20,7 +20,7 @@ namespace zipper { Zipper(const std::string& zipname); Zipper(const std::string& zipname, const std::string& password); - ~Zipper(void); + ~Zipper(); bool add(std::istream& source, const std::string& nameInZip = std::string(), zipFlags flags = Better); bool add(const std::string& fileOrFolderPath, zipFlags flags = Better); @@ -29,6 +29,7 @@ namespace zipper { void close(); private: + void release(); std::string m_password; std::string m_zipname; std::iostream& m_obuffer;