ruby-changes:54049
From: normal <ko1@a...>
Date: Fri, 7 Dec 2018 16:09:37 +0900 (JST)
Subject: [ruby-changes:54049] normal:r66268 (trunk): zlib (gzfile_write_raw): do not resize string after .write call
normal 2018-12-07 16:09:31 +0900 (Fri, 07 Dec 2018) New Revision: 66268 https://svn.ruby-lang.org/cgi-bin/viewvc.cgi?view=revision&revision=66268 Log: zlib (gzfile_write_raw): do not resize string after .write call Apparently, a component of Rails implements a buffering .write method which keeps the String buffer around and makes it unsafe for us to clear it after calling .write. This caused Rack::Deflater to give empty results when enabled. Fortunately, per r61631 / a55abcc0ca6f628fc05304f81e5a044d65ab4a68, this misguided optimization was only worth a small (0.5MB) savings and we still benefit from the majority of the memory savings in that change. Thanks to zunda for the bug report. [ruby-core:90133] [Bug #15356] Fixes: r61631 (commit a55abcc0ca6f628fc05304f81e5a044d65ab4a68) ("zlib: reduce garbage on gzip writes (deflate)") Modified files: trunk/ext/zlib/zlib.c trunk/test/zlib/test_zlib.rb Index: test/zlib/test_zlib.rb =================================================================== --- test/zlib/test_zlib.rb (revision 66267) +++ test/zlib/test_zlib.rb (revision 66268) @@ -1081,6 +1081,23 @@ if defined? Zlib https://github.com/ruby/ruby/blob/trunk/test/zlib/test_zlib.rb#L1081 assert_nothing_raised { w.close } } end + + def test_zlib_writer_buffered_write + bug15356 = '[ruby-core:90346] [Bug #15356]'.freeze + fixes = 'r61631 (commit a55abcc0ca6f628fc05304f81e5a044d65ab4a68)'.freeze + ary = [] + def ary.write(*args) + self.concat(args) + end + gz = Zlib::GzipWriter.new(ary) + gz.write(bug15356) + gz.write("\n") + gz.write(fixes) + gz.close + assert_not_predicate ary, :empty? + exp = [ bug15356, fixes ] + assert_equal exp, Zlib.gunzip(ary.join('')).split("\n") + end end class TestZlib < Test::Unit::TestCase Index: ext/zlib/zlib.c =================================================================== --- ext/zlib/zlib.c (revision 66267) +++ ext/zlib/zlib.c (revision 66268) @@ -2364,7 +2364,6 @@ gzfile_write_raw(struct gzfile *gz) https://github.com/ruby/ruby/blob/trunk/ext/zlib/zlib.c#L2364 str = zstream_detach_buffer(&gz->z); OBJ_TAINT(str); /* for safe */ rb_funcall(gz->io, id_write, 1, str); - rb_str_resize(str, 0); if ((gz->z.flags & GZFILE_FLAG_SYNC) && rb_respond_to(gz->io, id_flush)) rb_funcall(gz->io, id_flush, 0); -- ML: ruby-changes@q... Info: http://www.atdot.net/~ko1/quickml/