aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--ext/zlib/zlib.c32
-rw-r--r--test/zlib/test_zlib.rb56
-rw-r--r--version.h8
3 files changed, 91 insertions, 5 deletions
diff --git a/ext/zlib/zlib.c b/ext/zlib/zlib.c
index 3b8e097da9..bfd55ffe34 100644
--- a/ext/zlib/zlib.c
+++ b/ext/zlib/zlib.c
@@ -530,6 +530,7 @@ struct zstream {
unsigned long flags;
VALUE buf;
VALUE input;
+ VALUE mutex;
z_stream stream;
const struct zstream_funcs {
int (*reset)(z_streamp);
@@ -602,6 +603,7 @@ zstream_init(struct zstream *z, const struct zstream_funcs *func)
z->flags = 0;
z->buf = Qnil;
z->input = Qnil;
+ z->mutex = rb_mutex_new();
z->stream.zalloc = zlib_mem_alloc;
z->stream.zfree = zlib_mem_free;
z->stream.opaque = Z_NULL;
@@ -631,7 +633,9 @@ zstream_expand_buffer(struct zstream *z)
rb_obj_reveal(z->buf, rb_cString);
+ rb_mutex_unlock(z->mutex);
rb_protect(rb_yield, z->buf, &state);
+ rb_mutex_lock(z->mutex);
z->buf = Qnil;
zstream_expand_buffer_into(z, ZSTREAM_AVAIL_OUT_STEP_MAX);
@@ -1025,7 +1029,7 @@ zstream_unblock_func(void *ptr)
}
static void
-zstream_run(struct zstream *z, Bytef *src, long len, int flush)
+zstream_run0(struct zstream *z, Bytef *src, long len, int flush)
{
struct zstream_run_args args;
int err;
@@ -1109,6 +1113,31 @@ loop:
rb_jump_tag(args.jump_state);
}
+struct zstream_run_synchronized_args {
+ struct zstream *z;
+ Bytef *src;
+ long len;
+ int flush;
+};
+
+static VALUE
+zstream_run_synchronized(VALUE value_arg)
+{
+ struct zstream_run_synchronized_args *run_args = (struct zstream_run_synchronized_args *)value_arg;
+ zstream_run0(run_args->z, run_args->src, run_args->len, run_args->flush);
+ return Qnil;
+}
+
+static void
+zstream_run(struct zstream *z, Bytef *src, long len, int flush)
+{
+ struct zstream_run_synchronized_args run_args;
+ run_args.z = z;
+ run_args.src = src;
+ run_args.len = len;
+ run_args.flush = flush;
+ rb_mutex_synchronize(z->mutex, zstream_run_synchronized, (VALUE)&run_args);
+}
static VALUE
zstream_sync(struct zstream *z, Bytef *src, long len)
{
@@ -1154,6 +1183,7 @@ zstream_mark(void *p)
struct zstream *z = p;
rb_gc_mark(z->buf);
rb_gc_mark(z->input);
+ rb_gc_mark(z->mutex);
}
static void
diff --git a/test/zlib/test_zlib.rb b/test/zlib/test_zlib.rb
index 7d703d15e4..e4baa44ecb 100644
--- a/test/zlib/test_zlib.rb
+++ b/test/zlib/test_zlib.rb
@@ -3,6 +3,7 @@
require 'test/unit'
require 'stringio'
require 'tempfile'
+require 'securerandom'
begin
require 'zlib'
@@ -443,6 +444,61 @@ 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
diff --git a/version.h b/version.h
index 960bec511d..750dc066e5 100644
--- a/version.h
+++ b/version.h
@@ -2,11 +2,11 @@
# define RUBY_VERSION_MINOR RUBY_API_VERSION_MINOR
#define RUBY_VERSION_TEENY 6
#define RUBY_RELEASE_DATE RUBY_RELEASE_YEAR_STR"-"RUBY_RELEASE_MONTH_STR"-"RUBY_RELEASE_DAY_STR
-#define RUBY_PATCHLEVEL 209
+#define RUBY_PATCHLEVEL 210
-#define RUBY_RELEASE_YEAR 2021
-#define RUBY_RELEASE_MONTH 12
-#define RUBY_RELEASE_DAY 31
+#define RUBY_RELEASE_YEAR 2022
+#define RUBY_RELEASE_MONTH 3
+#define RUBY_RELEASE_DAY 5
#include "ruby/version.h"