summaryrefslogtreecommitdiff
path: root/ext/zlib
diff options
context:
space:
mode:
authornobu <nobu@b2dd03c8-39d4-4d8f-98ff-823fe69b080e>2017-10-06 13:41:37 +0000
committernobu <nobu@b2dd03c8-39d4-4d8f-98ff-823fe69b080e>2017-10-06 13:41:37 +0000
commitb268da23d2be376057b6184f2bddf50841f58728 (patch)
treef8d1a86cebff6c5c12f4adbd4fb2add1485777f6 /ext/zlib
parent4f966c0a680becf29d2174c2e9d53c16a18bf936 (diff)
zlib.c: memory leak in gunzip
* ext/zlib/zlib.c (zlib_gunzip): clear zstream to fix memory leak. [ruby-core:83162] [Bug #13982] git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@60130 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
Diffstat (limited to 'ext/zlib')
-rw-r--r--ext/zlib/zlib.c25
1 files changed, 21 insertions, 4 deletions
diff --git a/ext/zlib/zlib.c b/ext/zlib/zlib.c
index 84df3a5c9a..780b1bd8c6 100644
--- a/ext/zlib/zlib.c
+++ b/ext/zlib/zlib.c
@@ -4287,7 +4287,7 @@ zlib_s_gzip(int argc, VALUE *argv, VALUE klass)
struct gzfile *gz = &gz0;
long len;
int err;
- VALUE src, opts, level=Qnil, strategy=Qnil;
+ VALUE src, opts, level=Qnil, strategy=Qnil, guard, ret;
if (OPTHASH_GIVEN_P(opts)) {
ID keyword_ids[2];
@@ -4311,6 +4311,7 @@ zlib_s_gzip(int argc, VALUE *argv, VALUE klass)
if (err != Z_OK) {
raise_zlib_error(err, gz->z.stream.msg);
}
+ guard = TypedData_Wrap_Struct(0, &gzfile_data_type, gz);
ZSTREAM_READY(&gz->z);
gzfile_make_header(gz);
len = RSTRING_LEN(src);
@@ -4320,7 +4321,10 @@ zlib_s_gzip(int argc, VALUE *argv, VALUE klass)
zstream_run(&gz->z, ptr, len, Z_NO_FLUSH);
}
gzfile_close(gz, 0);
- return zstream_detach_buffer(&gz->z);
+ ret = zstream_detach_buffer(&gz->z);
+ zstream_end(&gz->z);
+ DATA_PTR(guard) = 0;
+ return ret;
}
static void
@@ -4331,6 +4335,14 @@ zlib_gunzip_end(struct gzfile *gz)
zstream_end(&gz->z);
}
+static void
+zlib_gunzip_guard_end(VALUE guard)
+{
+ struct gzfile *gz = DATA_PTR(guard);
+ DATA_PTR(guard) = 0;
+ gz->end(gz);
+}
+
/*
* call-seq:
* Zlib.gunzip(src) -> String
@@ -4356,6 +4368,7 @@ zlib_gunzip(VALUE klass, VALUE src)
struct gzfile *gz = &gz0;
int err;
VALUE dst;
+ VALUE guard;
StringValue(src);
@@ -4364,6 +4377,7 @@ zlib_gunzip(VALUE klass, VALUE src)
if (err != Z_OK) {
raise_zlib_error(err, gz->z.stream.msg);
}
+ guard = TypedData_Wrap_Struct(0, &gzfile_data_type, gz);
gz->io = Qundef;
gz->z.input = src;
ZSTREAM_READY(&gz->z);
@@ -4371,11 +4385,14 @@ zlib_gunzip(VALUE klass, VALUE src)
dst = zstream_detach_buffer(&gz->z);
gzfile_calc_crc(gz, dst);
if (!ZSTREAM_IS_FINISHED(&gz->z)) {
+ zlib_gunzip_guard_end(guard);
rb_raise(cGzError, "unexpected end of file");
}
- if (NIL_P(gz->z.input))
+ if (NIL_P(gz->z.input)) {
+ zlib_gunzip_guard_end(guard);
rb_raise(cNoFooter, "footer is not found");
- gzfile_check_footer(gz);
+ }
+ zlib_gunzip_guard_end(guard);
return dst;
}