summaryrefslogtreecommitdiff
path: root/ext/zlib
diff options
context:
space:
mode:
authornagachika <nagachika@b2dd03c8-39d4-4d8f-98ff-823fe69b080e>2018-02-03 02:25:37 +0000
committernagachika <nagachika@b2dd03c8-39d4-4d8f-98ff-823fe69b080e>2018-02-03 02:25:37 +0000
commitce2bc45ae8679b40e97d6794e4e7a31b68444615 (patch)
treeb48256dafb55153e121aa5a8ae04e1711b373413 /ext/zlib
parent05ba99388d1133a99153044be67d7ae3b3dc4de5 (diff)
merge revision(s) 60042,60130,60131: [Backport #13982]
ext: adjust indent [ci skip] zlib.c: memory leak in gunzip * ext/zlib/zlib.c (zlib_gunzip): clear zstream to fix memory leak. [ruby-core:83162] [Bug #13982] zlib.c: ensure to free * ext/zlib/zlib.c (zlib_gunzip): gz0 is a structure variable on the stack, no longer valid after exit by an exception. ensure to free instead. [Bug #13982] git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/branches/ruby_2_4@62172 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
Diffstat (limited to 'ext/zlib')
-rw-r--r--ext/zlib/zlib.c58
1 files changed, 45 insertions, 13 deletions
diff --git a/ext/zlib/zlib.c b/ext/zlib/zlib.c
index 336cb2d095..fde85befab 100644
--- a/ext/zlib/zlib.c
+++ b/ext/zlib/zlib.c
@@ -451,7 +451,7 @@ rb_zlib_adler32(int argc, VALUE *argv, VALUE klass)
static VALUE
rb_zlib_adler32_combine(VALUE klass, VALUE adler1, VALUE adler2, VALUE len2)
{
- return ULONG2NUM(
+ return ULONG2NUM(
adler32_combine(NUM2ULONG(adler1), NUM2ULONG(adler2), NUM2LONG(len2)));
}
#else
@@ -489,7 +489,7 @@ rb_zlib_crc32(int argc, VALUE *argv, VALUE klass)
static VALUE
rb_zlib_crc32_combine(VALUE klass, VALUE crc1, VALUE crc2, VALUE len2)
{
- return ULONG2NUM(
+ return ULONG2NUM(
crc32_combine(NUM2ULONG(crc1), NUM2ULONG(crc2), NUM2LONG(len2)));
}
#else
@@ -644,7 +644,7 @@ zstream_expand_buffer(struct zstream *z)
}
else {
zstream_expand_buffer_into(z,
- ZSTREAM_AVAIL_OUT_STEP_MAX - buf_filled);
+ ZSTREAM_AVAIL_OUT_STEP_MAX - buf_filled);
}
}
else {
@@ -1381,7 +1381,7 @@ rb_zstream_data_type(VALUE obj)
static VALUE
rb_zstream_adler(VALUE obj)
{
- return rb_uint2inum(get_zstream(obj)->stream.adler);
+ return rb_uint2inum(get_zstream(obj)->stream.adler);
}
/*
@@ -2673,7 +2673,7 @@ gzfile_calc_crc(struct gzfile *gz, VALUE str)
}
else {
gz->crc = checksum_long(crc32, gz->crc, (Bytef*)RSTRING_PTR(str) + gz->ungetc,
- RSTRING_LEN(str) - gz->ungetc);
+ RSTRING_LEN(str) - gz->ungetc);
gz->ungetc = 0;
}
}
@@ -4245,6 +4245,14 @@ rb_gzreader_external_encoding(VALUE self)
return rb_enc_from_encoding(get_gzfile(self)->enc);
}
+static VALUE
+zlib_gzip_ensure(VALUE arg)
+{
+ struct gzfile *gz = (struct gzfile *)arg;
+ rb_rescue((VALUE(*)())gz->end, arg, NULL, Qnil);
+ return Qnil;
+}
+
static void
zlib_gzip_end(struct gzfile *gz)
{
@@ -4257,6 +4265,7 @@ zlib_gzip_end(struct gzfile *gz)
#define OPTHASH_GIVEN_P(opts) \
(argc > 0 && !NIL_P((opts) = rb_check_hash_type(argv[argc-1])) && (--argc, 1))
static ID id_level, id_strategy;
+static VALUE zlib_gzip_run(VALUE arg);
/*
* call-seq:
@@ -4285,9 +4294,8 @@ zlib_s_gzip(int argc, VALUE *argv, VALUE klass)
{
struct gzfile gz0;
struct gzfile *gz = &gz0;
- long len;
int err;
- VALUE src, opts, level=Qnil, strategy=Qnil;
+ VALUE src, opts, level=Qnil, strategy=Qnil, args[2];
if (OPTHASH_GIVEN_P(opts)) {
ID keyword_ids[2];
@@ -4309,9 +4317,23 @@ zlib_s_gzip(int argc, VALUE *argv, VALUE klass)
err = deflateInit2(&gz->z.stream, gz->level, Z_DEFLATED,
-MAX_WBITS, DEF_MEM_LEVEL, ARG_STRATEGY(strategy));
if (err != Z_OK) {
+ zlib_gzip_end(gz);
raise_zlib_error(err, gz->z.stream.msg);
}
ZSTREAM_READY(&gz->z);
+ args[0] = (VALUE)gz;
+ args[1] = src;
+ return rb_ensure(zlib_gzip_run, (VALUE)args, zlib_gzip_ensure, (VALUE)gz);
+}
+
+static VALUE
+zlib_gzip_run(VALUE arg)
+{
+ VALUE *args = (VALUE *)arg;
+ struct gzfile *gz = (struct gzfile *)args[0];
+ VALUE src = args[1];
+ long len;
+
gzfile_make_header(gz);
len = RSTRING_LEN(src);
if (len > 0) {
@@ -4327,10 +4349,11 @@ static void
zlib_gunzip_end(struct gzfile *gz)
{
gz->z.flags |= ZSTREAM_FLAG_CLOSING;
- gzfile_check_footer(gz);
zstream_end(&gz->z);
}
+static VALUE zlib_gunzip_run(VALUE arg);
+
/*
* call-seq:
* Zlib.gunzip(src) -> String
@@ -4355,7 +4378,6 @@ zlib_gunzip(VALUE klass, VALUE src)
struct gzfile gz0;
struct gzfile *gz = &gz0;
int err;
- VALUE dst;
StringValue(src);
@@ -4367,14 +4389,24 @@ zlib_gunzip(VALUE klass, VALUE src)
gz->io = Qundef;
gz->z.input = src;
ZSTREAM_READY(&gz->z);
+ return rb_ensure(zlib_gunzip_run, (VALUE)gz, zlib_gzip_ensure, (VALUE)gz);
+}
+
+static VALUE
+zlib_gunzip_run(VALUE arg)
+{
+ struct gzfile *gz = (struct gzfile *)arg;
+ VALUE dst;
+
gzfile_read_header(gz);
dst = zstream_detach_buffer(&gz->z);
gzfile_calc_crc(gz, dst);
- if (!ZSTREAM_IS_FINISHED(&gz->z)) {
- rb_raise(cGzError, "unexpected end of file");
- }
- if (NIL_P(gz->z.input))
+ if (!ZSTREAM_IS_FINISHED(&gz->z)) {
+ rb_raise(cGzError, "unexpected end of file");
+ }
+ if (NIL_P(gz->z.input)) {
rb_raise(cNoFooter, "footer is not found");
+ }
gzfile_check_footer(gz);
return dst;
}