diff options
author | savilli <78875209+savilli@users.noreply.github.com> | 2022-06-17 00:53:23 +0300 |
---|---|---|
committer | GitHub <noreply@github.com> | 2022-06-16 23:53:23 +0200 |
commit | ae555465ba1c02d5fe6b409c50191ddc34d26d75 (patch) | |
tree | eee00673edc1e951849eb588eb31d436fc31f86a | |
parent | 622d857bed52404c7d54bcf7ff056d0c0250f2be (diff) | |
download | minetest-ae555465ba1c02d5fe6b409c50191ddc34d26d75.tar.gz minetest-ae555465ba1c02d5fe6b409c50191ddc34d26d75.tar.bz2 minetest-ae555465ba1c02d5fe6b409c50191ddc34d26d75.zip |
Fix zlib (de)compressor memory leaks
-rw-r--r-- | src/serialization.cpp | 21 |
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 { |