diff --git a/ext/zlib/zlib.c b/ext/zlib/zlib.c index f13ef4d..0a8f5e8 100644 --- a/ext/zlib/zlib.c +++ b/ext/zlib/zlib.c @@ -1368,6 +1368,14 @@ get_zstream(VALUE obj) return z; } +static void +zstream_check_reinitialize(VALUE obj, struct zstream *z) +{ + if (ZSTREAM_IS_READY(z)) { + rb_raise(rb_eRuntimeError, "reinitializing %"PRIsVALUE, rb_obj_class(obj)); + } +} + /* ------------------------------------------------------------------------- */ @@ -1714,6 +1722,7 @@ rb_deflate_initialize(int argc, VALUE *argv, VALUE obj) rb_scan_args(argc, argv, "04", &level, &wbits, &memlevel, &strategy); TypedData_Get_Struct(obj, struct zstream, &zstream_data_type, z); + zstream_check_reinitialize(obj, z); err = deflateInit2(&z->stream, ARG_LEVEL(level), Z_DEFLATED, ARG_WBITS(wbits), ARG_MEMLEVEL(memlevel), @@ -2070,6 +2079,7 @@ rb_inflate_initialize(int argc, VALUE *argv, VALUE obj) rb_scan_args(argc, argv, "01", &wbits); TypedData_Get_Struct(obj, struct zstream, &zstream_data_type, z); + zstream_check_reinitialize(obj, z); err = inflateInit2(&z->stream, ARG_WBITS(wbits)); if (err != Z_OK) { @@ -3805,6 +3815,7 @@ rb_gzwriter_initialize(int argc, VALUE *argv, VALUE obj) rb_scan_args(argc, argv, "12", &io, &level, &strategy); TypedData_Get_Struct(obj, struct gzfile, &gzfile_data_type, gz); + zstream_check_reinitialize(obj, &gz->z); /* this is undocumented feature of zlib */ gz->level = ARG_LEVEL(level); @@ -4067,6 +4078,7 @@ rb_gzreader_initialize(int argc, VALUE *argv, VALUE obj) int err; TypedData_Get_Struct(obj, struct gzfile, &gzfile_data_type, gz); + zstream_check_reinitialize(obj, &gz->z); rb_scan_args(argc, argv, "1:", &io, &opt); /* this is undocumented feature of zlib */ diff --git a/test/zlib/test_zlib.rb b/test/zlib/test_zlib.rb index e1ecbf8..693bbce 100644 --- a/test/zlib/test_zlib.rb +++ b/test/zlib/test_zlib.rb @@ -1558,6 +1558,21 @@ def ary.write(*args) end class TestZlib < Test::Unit::TestCase + def test_reinitialize + z = Zlib::Deflate.new + assert_raise(RuntimeError) { z.send(:initialize) } + z.close + z = Zlib::Inflate.new + assert_raise(RuntimeError) { z.send(:initialize) } + z.close + gz = Zlib::GzipWriter.new(StringIO.new(+"")) + assert_raise(RuntimeError) { gz.send(:initialize, StringIO.new(+"")) } + gz.close + gz = Zlib::GzipReader.new(StringIO.new(Zlib.gzip("foo"))) + assert_raise(RuntimeError) { gz.send(:initialize, StringIO.new(Zlib.gzip("foo"))) } + gz.close + end + def test_version assert_instance_of(String, Zlib.zlib_version) end