summaryrefslogtreecommitdiff
path: root/test
diff options
context:
space:
mode:
authornagachika <nagachika@ruby-lang.org>2022-02-19 14:36:41 +0900
committernagachika <nagachika@ruby-lang.org>2022-02-19 14:36:41 +0900
commit49ed412060f48d3b9343b8b90d73e6fcb02b3354 (patch)
treef7397fbb5ef93d47e8170d7188c6952223d8cb37 /test
parentebbe2fc9233c929ebd5a243fb82aaa7c0115d39b (diff)
merge revision(s) b3d62a77d928eff01268ca7fa1c1c0966702926d: [Backport #17803]
[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 --- ext/zlib/zlib.c | 33 ++++++++++++++++++++++++++- test/zlib/test_zlib.rb | 61 ++++++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 93 insertions(+), 1 deletion(-)
Diffstat (limited to 'test')
-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 a51a00d329..a5fc9056c8 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