Fix zlib (de)compressor memory leaks

This commit is contained in:
savilli 2022-06-17 00:53:23 +03:00 committed by GitHub
parent 622d857bed
commit ae555465ba
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23

@ -25,7 +25,7 @@ with this program; if not, write to the Free Software Foundation, Inc.,
#include <zstd.h> #include <zstd.h>
/* report a zlib or i/o error */ /* report a zlib or i/o error */
void zerr(int ret) static void zerr(int ret)
{ {
dstream<<"zerr: "; dstream<<"zerr: ";
switch (ret) { 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) void compressZlib(const u8 *data, size_t data_size, std::ostream &os, int level)
{ {
z_stream z; 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) if(ret != Z_OK)
throw SerializationError("compressZlib: deflateInit failed"); throw SerializationError("compressZlib: deflateInit failed");
ZlibAutoDeleter<deflateEnd> deleter(&z);
// Point zlib to our input buffer // Point zlib to our input buffer
z.next_in = (Bytef*)&data[0]; z.next_in = (Bytef*)&data[0];
z.avail_in = data_size; 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) if(status == Z_STREAM_END)
break; break;
} }
deflateEnd(&z);
} }
void compressZlib(const std::string &data, std::ostream &os, int level) 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) if(ret != Z_OK)
throw SerializationError("dcompressZlib: inflateInit failed"); throw SerializationError("dcompressZlib: inflateInit failed");
ZlibAutoDeleter<inflateEnd> deleter(&z);
z.avail_in = 0; z.avail_in = 0;
for(;;) for(;;)
@ -180,8 +193,6 @@ void decompressZlib(std::istream &is, std::ostream &os, size_t limit)
break; break;
} }
} }
inflateEnd(&z);
} }
struct ZSTD_Deleter { struct ZSTD_Deleter {