summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorsavilli <78875209+savilli@users.noreply.github.com>2022-06-17 00:53:23 +0300
committerGitHub <noreply@github.com>2022-06-16 23:53:23 +0200
commitae555465ba1c02d5fe6b409c50191ddc34d26d75 (patch)
treeeee00673edc1e951849eb588eb31d436fc31f86a
parent622d857bed52404c7d54bcf7ff056d0c0250f2be (diff)
downloadminetest-ae555465ba1c02d5fe6b409c50191ddc34d26d75.tar.gz
minetest-ae555465ba1c02d5fe6b409c50191ddc34d26d75.tar.bz2
minetest-ae555465ba1c02d5fe6b409c50191ddc34d26d75.zip
Fix zlib (de)compressor memory leaks
-rw-r--r--src/serialization.cpp21
1 files changed, 16 insertions, 5 deletions
diff --git a/src/serialization.cpp b/src/serialization.cpp
index 11164a0ed..dc34dd7b9 100644
--- a/src/serialization.cpp
+++ b/src/serialization.cpp
@@ -25,7 +25,7 @@ with this program; if not, write to the Free Software Foundation, Inc.,
#include <zstd.h>
/* report a zlib or i/o error */
-void zerr(int ret)
+static void zerr(int ret)
{
dstream<<"zerr: ";
switch (ret) {
@@ -52,6 +52,17 @@ void zerr(int ret)
}
}
+// Make sure that z is deleted in case of exception
+template <int (*F)(z_stream*)>
+class ZlibAutoDeleter {
+public:
+ ZlibAutoDeleter(z_stream *ptr) : ptr_(ptr) {}
+ ~ZlibAutoDeleter() { F(ptr_); }
+
+private:
+ z_stream *ptr_;
+};
+
void compressZlib(const u8 *data, size_t data_size, std::ostream &os, int level)
{
z_stream z;
@@ -68,6 +79,8 @@ void compressZlib(const u8 *data, size_t data_size, std::ostream &os, int level)
if(ret != Z_OK)
throw SerializationError("compressZlib: deflateInit failed");
+ ZlibAutoDeleter<deflateEnd> deleter(&z);
+
// Point zlib to our input buffer
z.next_in = (Bytef*)&data[0];
z.avail_in = data_size;
@@ -91,8 +104,6 @@ void compressZlib(const u8 *data, size_t data_size, std::ostream &os, int level)
if(status == Z_STREAM_END)
break;
}
-
- deflateEnd(&z);
}
void compressZlib(const std::string &data, std::ostream &os, int level)
@@ -119,6 +130,8 @@ void decompressZlib(std::istream &is, std::ostream &os, size_t limit)
if(ret != Z_OK)
throw SerializationError("dcompressZlib: inflateInit failed");
+ ZlibAutoDeleter<inflateEnd> deleter(&z);
+
z.avail_in = 0;
for(;;)
@@ -180,8 +193,6 @@ void decompressZlib(std::istream &is, std::ostream &os, size_t limit)
break;
}
}
-
- inflateEnd(&z);
}
struct ZSTD_Deleter {