summaryrefslogtreecommitdiff
path: root/test/zlib
diff options
context:
space:
mode:
authorJeremy Evans <code@jeremyevans.net>2021-06-15 15:27:57 -0700
committerHiroshi SHIBATA <hsbt@ruby-lang.org>2021-07-28 13:40:03 +0900
commitb3d62a77d928eff01268ca7fa1c1c0966702926d (patch)
treed2232838c62a4e81b4a880113b501c381e78d5dd /test/zlib
parent218c3b25480d7de904a24d4508e7135c160eb871 (diff)
downloadruby-b3d62a77d928eff01268ca7fa1c1c0966702926d.tar.gz
[ruby/zlib] Synchronize access to zstream to prevent segfault in multithreaded use
I'm not sure whether this handles all multithreaded use cases, but this handles the example that crashes almost immediately and does 10,000,000 total deflates using 100 separate threads. To prevent the tests from taking forever, the committed test for this uses only 10,000 deflates across 10 separate threads, which still causes a segfault in the previous implementation almost immediately. Fixes [Bug #17803] https://github.com/ruby/zlib/commit/4b1023b3f2
Diffstat (limited to 'test/zlib')
-rw-r--r--test/zlib/test_zlib.rb61
1 files changed, 61 insertions, 0 deletions
diff --git a/test/zlib/test_zlib.rb b/test/zlib/test_zlib.rb
index be0570165e..4780bc077b 100644
--- a/test/zlib/test_zlib.rb
+++ b/test/zlib/test_zlib.rb
@@ -4,6 +4,7 @@ require 'test/unit'
require 'stringio'
require 'tempfile'
require 'tmpdir'
+require 'securerandom'
begin
require 'zlib'
@@ -503,6 +504,66 @@ if defined? Zlib
assert_raise(Zlib::StreamError) { z.set_dictionary("foo") }
z.close
end
+
+ def test_multithread_deflate
+ zd = Zlib::Deflate.new
+
+ s = "x" * 10000
+ (0...10).map do |x|
+ Thread.new do
+ 1000.times { zd.deflate(s) }
+ end
+ end.each do |th|
+ th.join
+ end
+ ensure
+ zd&.finish
+ zd&.close
+ end
+
+ def test_multithread_inflate
+ zi = Zlib::Inflate.new
+
+ s = Zlib.deflate("x" * 10000)
+ (0...10).map do |x|
+ Thread.new do
+ 1000.times { zi.inflate(s) }
+ end
+ end.each do |th|
+ th.join
+ end
+ ensure
+ zi&.finish
+ zi&.close
+ end
+
+ def test_recursive_deflate
+ zd = Zlib::Deflate.new
+
+ s = SecureRandom.random_bytes(1024**2)
+ assert_raise(Zlib::BufError) do
+ zd.deflate(s) do
+ zd.deflate(s)
+ end
+ end
+ ensure
+ zd&.finish
+ zd&.close
+ end
+
+ def test_recursive_inflate
+ zi = Zlib::Inflate.new
+
+ s = Zlib.deflate(SecureRandom.random_bytes(1024**2))
+
+ assert_raise(Zlib::DataError) do
+ zi.inflate(s) do
+ zi.inflate(s)
+ end
+ end
+ ensure
+ zi&.close
+ end
end
class TestZlibGzipFile < Test::Unit::TestCase