diff options
author | normal <normal@b2dd03c8-39d4-4d8f-98ff-823fe69b080e> | 2018-12-07 07:09:31 +0000 |
---|---|---|
committer | normal <normal@b2dd03c8-39d4-4d8f-98ff-823fe69b080e> | 2018-12-07 07:09:31 +0000 |
commit | cc9b57a2b4b6ddcf52502b3b1e827fcc0173ff7a (patch) | |
tree | fe802bf03c4447162eec7b6685d59a79d1977b03 | |
parent | 7780553c3082124591343bb9fb54820cbcaf7931 (diff) |
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)")
git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@66268 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
-rw-r--r-- | ext/zlib/zlib.c | 1 | ||||
-rw-r--r-- | test/zlib/test_zlib.rb | 17 |
2 files changed, 17 insertions, 1 deletions
diff --git a/ext/zlib/zlib.c b/ext/zlib/zlib.c index 7753cc67e1..1b48bb2677 100644 --- a/ext/zlib/zlib.c +++ b/ext/zlib/zlib.c @@ -2364,7 +2364,6 @@ gzfile_write_raw(struct gzfile *gz) 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); diff --git a/test/zlib/test_zlib.rb b/test/zlib/test_zlib.rb index 6a90c6782c..fc2ab5073f 100644 --- a/test/zlib/test_zlib.rb +++ b/test/zlib/test_zlib.rb @@ -1081,6 +1081,23 @@ if defined? Zlib 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 |