summaryrefslogtreecommitdiff
path: root/ext/zlib
diff options
context:
space:
mode:
Diffstat (limited to 'ext/zlib')
-rw-r--r--ext/zlib/depend41
-rw-r--r--ext/zlib/extconf.rb15
-rw-r--r--ext/zlib/extlibs8
-rw-r--r--ext/zlib/win32/zlib-1.2.11-mswin.patch95
-rw-r--r--ext/zlib/zlib.c172
-rw-r--r--ext/zlib/zlib.gemspec2
6 files changed, 149 insertions, 184 deletions
diff --git a/ext/zlib/depend b/ext/zlib/depend
index 9e3443f5d7..bdce420264 100644
--- a/ext/zlib/depend
+++ b/ext/zlib/depend
@@ -2,6 +2,20 @@
zlib.o: $(RUBY_EXTCONF_H)
zlib.o: $(arch_hdrdir)/ruby/config.h
zlib.o: $(hdrdir)/ruby.h
+zlib.o: $(hdrdir)/ruby/assert.h
+zlib.o: $(hdrdir)/ruby/backward.h
+zlib.o: $(hdrdir)/ruby/backward/2/assume.h
+zlib.o: $(hdrdir)/ruby/backward/2/attributes.h
+zlib.o: $(hdrdir)/ruby/backward/2/bool.h
+zlib.o: $(hdrdir)/ruby/backward/2/inttypes.h
+zlib.o: $(hdrdir)/ruby/backward/2/limits.h
+zlib.o: $(hdrdir)/ruby/backward/2/long_long.h
+zlib.o: $(hdrdir)/ruby/backward/2/stdalign.h
+zlib.o: $(hdrdir)/ruby/backward/2/stdarg.h
+zlib.o: $(hdrdir)/ruby/defines.h
+zlib.o: $(hdrdir)/ruby/encoding.h
+zlib.o: $(hdrdir)/ruby/intern.h
+zlib.o: $(hdrdir)/ruby/internal/abi.h
zlib.o: $(hdrdir)/ruby/internal/anyargs.h
zlib.o: $(hdrdir)/ruby/internal/arithmetic.h
zlib.o: $(hdrdir)/ruby/internal/arithmetic/char.h
@@ -39,6 +53,7 @@ zlib.o: $(hdrdir)/ruby/internal/attr/noexcept.h
zlib.o: $(hdrdir)/ruby/internal/attr/noinline.h
zlib.o: $(hdrdir)/ruby/internal/attr/nonnull.h
zlib.o: $(hdrdir)/ruby/internal/attr/noreturn.h
+zlib.o: $(hdrdir)/ruby/internal/attr/packed_struct.h
zlib.o: $(hdrdir)/ruby/internal/attr/pure.h
zlib.o: $(hdrdir)/ruby/internal/attr/restrict.h
zlib.o: $(hdrdir)/ruby/internal/attr/returns_nonnull.h
@@ -71,6 +86,15 @@ zlib.o: $(hdrdir)/ruby/internal/core/rtypeddata.h
zlib.o: $(hdrdir)/ruby/internal/ctype.h
zlib.o: $(hdrdir)/ruby/internal/dllexport.h
zlib.o: $(hdrdir)/ruby/internal/dosish.h
+zlib.o: $(hdrdir)/ruby/internal/encoding/coderange.h
+zlib.o: $(hdrdir)/ruby/internal/encoding/ctype.h
+zlib.o: $(hdrdir)/ruby/internal/encoding/encoding.h
+zlib.o: $(hdrdir)/ruby/internal/encoding/pathname.h
+zlib.o: $(hdrdir)/ruby/internal/encoding/re.h
+zlib.o: $(hdrdir)/ruby/internal/encoding/sprintf.h
+zlib.o: $(hdrdir)/ruby/internal/encoding/string.h
+zlib.o: $(hdrdir)/ruby/internal/encoding/symbol.h
+zlib.o: $(hdrdir)/ruby/internal/encoding/transcode.h
zlib.o: $(hdrdir)/ruby/internal/error.h
zlib.o: $(hdrdir)/ruby/internal/eval.h
zlib.o: $(hdrdir)/ruby/internal/event.h
@@ -98,7 +122,6 @@ zlib.o: $(hdrdir)/ruby/internal/intern/enumerator.h
zlib.o: $(hdrdir)/ruby/internal/intern/error.h
zlib.o: $(hdrdir)/ruby/internal/intern/eval.h
zlib.o: $(hdrdir)/ruby/internal/intern/file.h
-zlib.o: $(hdrdir)/ruby/internal/intern/gc.h
zlib.o: $(hdrdir)/ruby/internal/intern/hash.h
zlib.o: $(hdrdir)/ruby/internal/intern/io.h
zlib.o: $(hdrdir)/ruby/internal/intern/load.h
@@ -129,32 +152,18 @@ zlib.o: $(hdrdir)/ruby/internal/memory.h
zlib.o: $(hdrdir)/ruby/internal/method.h
zlib.o: $(hdrdir)/ruby/internal/module.h
zlib.o: $(hdrdir)/ruby/internal/newobj.h
-zlib.o: $(hdrdir)/ruby/internal/rgengc.h
zlib.o: $(hdrdir)/ruby/internal/scan_args.h
zlib.o: $(hdrdir)/ruby/internal/special_consts.h
zlib.o: $(hdrdir)/ruby/internal/static_assert.h
zlib.o: $(hdrdir)/ruby/internal/stdalign.h
zlib.o: $(hdrdir)/ruby/internal/stdbool.h
+zlib.o: $(hdrdir)/ruby/internal/stdckdint.h
zlib.o: $(hdrdir)/ruby/internal/symbol.h
zlib.o: $(hdrdir)/ruby/internal/value.h
zlib.o: $(hdrdir)/ruby/internal/value_type.h
zlib.o: $(hdrdir)/ruby/internal/variable.h
zlib.o: $(hdrdir)/ruby/internal/warning_push.h
zlib.o: $(hdrdir)/ruby/internal/xmalloc.h
-zlib.o: $(hdrdir)/ruby/assert.h
-zlib.o: $(hdrdir)/ruby/backward.h
-zlib.o: $(hdrdir)/ruby/backward/2/assume.h
-zlib.o: $(hdrdir)/ruby/backward/2/attributes.h
-zlib.o: $(hdrdir)/ruby/backward/2/bool.h
-zlib.o: $(hdrdir)/ruby/backward/2/gcc_version_since.h
-zlib.o: $(hdrdir)/ruby/backward/2/inttypes.h
-zlib.o: $(hdrdir)/ruby/backward/2/limits.h
-zlib.o: $(hdrdir)/ruby/backward/2/long_long.h
-zlib.o: $(hdrdir)/ruby/backward/2/stdalign.h
-zlib.o: $(hdrdir)/ruby/backward/2/stdarg.h
-zlib.o: $(hdrdir)/ruby/defines.h
-zlib.o: $(hdrdir)/ruby/encoding.h
-zlib.o: $(hdrdir)/ruby/intern.h
zlib.o: $(hdrdir)/ruby/io.h
zlib.o: $(hdrdir)/ruby/missing.h
zlib.o: $(hdrdir)/ruby/onigmo.h
diff --git a/ext/zlib/extconf.rb b/ext/zlib/extconf.rb
index d674544f22..2b2dbb1a5b 100644
--- a/ext/zlib/extconf.rb
+++ b/ext/zlib/extconf.rb
@@ -11,10 +11,9 @@ require 'rbconfig'
dir_config 'zlib'
libs = $libs
-if %w'z libz zlib1 zlib zdll zlibwapi'.find {|z| have_library(z, 'deflateReset')} and
- have_header('zlib.h') then
- have_zlib = true
-else
+have_zlib = %w'z libz zlib1 zlib zdll zlibwapi'.any? {|z| have_library(z, 'deflateReset(NULL)', 'zlib.h')}
+
+unless have_zlib
$libs = libs
unless File.directory?(zsrc = "#{$srcdir}/zlib")
dirs = Dir.open($srcdir) {|z| z.grep(/\Azlib-\d+[.\d]*\z/) {|x|"#{$srcdir}/#{x}"}}
@@ -121,10 +120,18 @@ if have_zlib
$defs << "-DHAVE_CRC32_COMBINE"
$defs << "-DHAVE_ADLER32_COMBINE"
$defs << "-DHAVE_TYPE_Z_CRC_T"
+ $defs << "-DHAVE_CRC32_Z"
+ $defs << "-DHAVE_ADLER32_Z"
+ $defs << "-DHAVE_ZLIB_SIZE_T_FUNCS"
else
have_func('crc32_combine', 'zlib.h')
have_func('adler32_combine', 'zlib.h')
have_type('z_crc_t', 'zlib.h')
+ if (have_type('z_size_t', 'zlib.h') &&
+ have_func('crc32_z', 'zlib.h') &&
+ have_func('adler32_z', 'zlib.h'))
+ $defs << "-DHAVE_ZLIB_SIZE_T_FUNCS"
+ end
end
create_makefile('zlib') {|conf|
diff --git a/ext/zlib/extlibs b/ext/zlib/extlibs
deleted file mode 100644
index a64b37ba5f..0000000000
--- a/ext/zlib/extlibs
+++ /dev/null
@@ -1,8 +0,0 @@
-ver = 1.2.11
-pkg = zlib-$(ver)
-
-https://zlib.net/$(pkg).tar.gz \
- md5:1c9f62f0778697a09d36121ead88e08e \
- sha512:73fd3fff4adeccd4894084c15ddac89890cd10ef105dd5e1835e1e9bbb6a49ff229713bd197d203edfa17c2727700fce65a2a235f07568212d820dca88b528ae \
- #
- win32/$(pkg)-mswin.patch -p0
diff --git a/ext/zlib/win32/zlib-1.2.11-mswin.patch b/ext/zlib/win32/zlib-1.2.11-mswin.patch
deleted file mode 100644
index 8810b4403c..0000000000
--- a/ext/zlib/win32/zlib-1.2.11-mswin.patch
+++ /dev/null
@@ -1,95 +0,0 @@
-diff -ru zlib-1.2.11/gzread.c zlib-1.2.11/gzread.c
---- zlib-1.2.11/gzread.c 2016-12-31 23:37:10.000000000 +0900
-+++ zlib-1.2.11/gzread.c 2020-11-23 19:35:00.550987184 +0900
-@@ -316,7 +316,7 @@
- /* set n to the maximum amount of len that fits in an unsigned int */
- n = -1;
- if (n > len)
-- n = len;
-+ n = (unsigned)len;
-
- /* first just try copying data from the output buffer */
- if (state->x.have) {
-@@ -397,7 +397,7 @@
- }
-
- /* read len or fewer bytes to buf */
-- len = gz_read(state, buf, len);
-+ len = (unsigned)gz_read(state, buf, len);
-
- /* check for an error */
- if (len == 0 && state->err != Z_OK && state->err != Z_BUF_ERROR)
-@@ -469,7 +469,7 @@
- }
-
- /* nothing there -- try gz_read() */
-- ret = gz_read(state, buf, 1);
-+ ret = (int)gz_read(state, buf, 1);
- return ret < 1 ? -1 : buf[0];
- }
-
-diff -ru zlib-1.2.11/gzwrite.c zlib-1.2.11/gzwrite.c
---- zlib-1.2.11/gzwrite.c 2017-01-15 09:29:40.000000000 +0900
-+++ zlib-1.2.11/gzwrite.c 2020-11-23 19:35:41.530494030 +0900
-@@ -209,7 +209,7 @@
- state->in);
- copy = state->size - have;
- if (copy > len)
-- copy = len;
-+ copy = (unsigned)len;
- memcpy(state->in + have, buf, copy);
- state->strm.avail_in += copy;
- state->x.pos += copy;
-@@ -229,7 +229,7 @@
- do {
- unsigned n = (unsigned)-1;
- if (n > len)
-- n = len;
-+ n = (unsigned)len;
- state->strm.avail_in = n;
- state->x.pos += n;
- if (gz_comp(state, Z_NO_FLUSH) == -1)
-@@ -368,7 +368,7 @@
-
- /* write string */
- len = strlen(str);
-- ret = gz_write(state, str, len);
-+ ret = (int)gz_write(state, str, len);
- return ret == 0 && len != 0 ? -1 : ret;
- }
-
-diff -ru zlib-1.2.11/win32/Makefile.msc zlib-1.2.11/win32/Makefile.msc
---- zlib-1.2.11/win32/Makefile.msc 2017-01-15 09:07:08.000000000 +0900
-+++ zlib-1.2.11/win32/Makefile.msc 2020-11-23 22:37:19.746500208 +0900
-@@ -37,6 +37,22 @@
- gzwrite.obj infback.obj inflate.obj inftrees.obj inffast.obj trees.obj uncompr.obj zutil.obj
- OBJA =
-
-+!ifdef USE_ASM
-+LOC = -DASMV -DASMINF
-+!if "$(ARCH)" == "i386"
-+OBJA = inffas32.obj match686.obj
-+!else if "$(ARCH)" == "x64"
-+AS = ml64
-+LOC = $(LOC) -I.
-+OBJA = inffasx64.obj gvmat64.obj inffas8664.obj
-+!endif
-+!endif
-+
-+!if "$(ARCH)" == "x64"
-+ZBASE = 0x5A4C000000
-+!else
-+ZBASE = 0x5A4C0000
-+!endif
-
- # targets
- all: $(STATICLIB) $(SHAREDLIB) $(IMPLIB) \
-@@ -49,7 +65,7 @@
-
- $(SHAREDLIB): $(TOP)/win32/zlib.def $(OBJS) $(OBJA) zlib1.res
- $(LD) $(LDFLAGS) -def:$(TOP)/win32/zlib.def -dll -implib:$(IMPLIB) \
-- -out:$@ -base:0x5A4C0000 $(OBJS) $(OBJA) zlib1.res
-+ -out:$@ -base:$(ZBASE) $(OBJS) $(OBJA) zlib1.res
- if exist $@.manifest \
- mt -nologo -manifest $@.manifest -outputresource:$@;2
-
diff --git a/ext/zlib/zlib.c b/ext/zlib/zlib.c
index 794cf3b103..fe03072576 100644
--- a/ext/zlib/zlib.c
+++ b/ext/zlib/zlib.c
@@ -25,7 +25,7 @@
# define VALGRIND_MAKE_MEM_UNDEFINED(p, n) 0
#endif
-#define RUBY_ZLIB_VERSION "1.1.0"
+#define RUBY_ZLIB_VERSION "3.1.0"
#ifndef RB_PASS_CALLED_KEYWORDS
# define rb_class_new_instance_kw(argc, argv, klass, kw_splat) rb_class_new_instance(argc, argv, klass)
@@ -44,6 +44,14 @@
#endif
#endif
+#if defined(HAVE_ZLIB_SIZE_T_FUNCS)
+typedef uLong (*checksum_func)(uLong, const Bytef*, z_size_t);
+# define crc32 crc32_z
+# define adler32 adler32_z
+#else
+typedef uLong (*checksum_func)(uLong, const Bytef*, uInt);
+#endif
+
#if SIZEOF_LONG > SIZEOF_INT
static inline uInt
max_uint(long n)
@@ -65,7 +73,7 @@ static ID id_dictionaries, id_read, id_buffer;
static NORETURN(void raise_zlib_error(int, const char*));
static VALUE rb_zlib_version(VALUE);
-static VALUE do_checksum(int, VALUE*, uLong (*)(uLong, const Bytef*, uInt));
+static VALUE do_checksum(int, VALUE*, checksum_func);
static VALUE rb_zlib_adler32(int, VALUE*, VALUE);
static VALUE rb_zlib_crc32(int, VALUE*, VALUE);
static VALUE rb_zlib_crc_table(VALUE);
@@ -288,6 +296,7 @@ static VALUE rb_gzreader_readlines(int, VALUE*, VALUE);
* - Zlib::MemError
* - Zlib::BufError
* - Zlib::VersionError
+ * - Zlib::InProgressError
*
* (if you have GZIP_SUPPORT)
* - Zlib::GzipReader
@@ -304,7 +313,7 @@ void Init_zlib(void);
/*--------- Exceptions --------*/
static VALUE cZError, cStreamEnd, cNeedDict;
-static VALUE cStreamError, cDataError, cMemError, cBufError, cVersionError;
+static VALUE cStreamError, cDataError, cMemError, cBufError, cVersionError, cInProgressError;
static void
raise_zlib_error(int err, const char *msg)
@@ -354,7 +363,9 @@ raise_zlib_error(int err, const char *msg)
static void
finalizer_warn(const char *msg)
{
+#if 0
fprintf(stderr, "zlib(finalizer): %s\n", msg);
+#endif
}
@@ -371,26 +382,32 @@ rb_zlib_version(VALUE klass)
return rb_str_new2(zlibVersion());
}
-#if SIZEOF_LONG > SIZEOF_INT
+#if SIZEOF_LONG * CHAR_BIT > 32
+# define mask32(x) ((x) & 0xffffffff)
+#else
+# define mask32(x) (x)
+#endif
+
+#if SIZEOF_LONG > SIZEOF_INT && !defined(HAVE_ZLIB_SIZE_T_FUNCS)
static uLong
checksum_long(uLong (*func)(uLong, const Bytef*, uInt), uLong sum, const Bytef *ptr, long len)
{
if (len > UINT_MAX) {
do {
- sum = func(sum, ptr, UINT_MAX);
+ sum = func(mask32(sum), ptr, UINT_MAX);
ptr += UINT_MAX;
len -= UINT_MAX;
} while (len >= UINT_MAX);
}
- if (len > 0) sum = func(sum, ptr, (uInt)len);
+ if (len > 0) sum = func(mask32(sum), ptr, (uInt)len);
return sum;
}
#else
-#define checksum_long(func, sum, ptr, len) (func)((sum), (ptr), (len))
+#define checksum_long(func, sum, ptr, len) (func)(mask32(sum), (ptr), (len))
#endif
static VALUE
-do_checksum(int argc, VALUE *argv, uLong (*func)(uLong, const Bytef*, uInt))
+do_checksum(int argc, VALUE *argv, checksum_func func)
{
VALUE str, vsum;
unsigned long sum;
@@ -408,7 +425,7 @@ do_checksum(int argc, VALUE *argv, uLong (*func)(uLong, const Bytef*, uInt))
}
if (NIL_P(str)) {
- sum = func(sum, Z_NULL, 0);
+ sum = func(mask32(sum), Z_NULL, 0);
}
else if (rb_obj_is_kind_of(str, rb_cIO)) {
VALUE buf;
@@ -458,7 +475,7 @@ rb_zlib_adler32(int argc, VALUE *argv, VALUE klass)
*
* call-seq: Zlib.adler32_combine(adler1, adler2, len2)
*
- * Combine two Adler-32 check values in to one. +alder1+ is the first Adler-32
+ * Combine two Adler-32 check values in to one. +adler1+ is the first Adler-32
* value, +adler2+ is the second Adler-32 value. +len2+ is the length of the
* string used to generate +adler2+.
*
@@ -555,14 +572,15 @@ struct zstream {
} *func;
};
-#define ZSTREAM_FLAG_READY 0x1
-#define ZSTREAM_FLAG_IN_STREAM 0x2
-#define ZSTREAM_FLAG_FINISHED 0x4
-#define ZSTREAM_FLAG_CLOSING 0x8
-#define ZSTREAM_FLAG_GZFILE 0x10 /* disallows yield from expand_buffer for
+#define ZSTREAM_FLAG_READY (1 << 0)
+#define ZSTREAM_FLAG_IN_STREAM (1 << 1)
+#define ZSTREAM_FLAG_FINISHED (1 << 2)
+#define ZSTREAM_FLAG_CLOSING (1 << 3)
+#define ZSTREAM_FLAG_GZFILE (1 << 4) /* disallows yield from expand_buffer for
gzip*/
-#define ZSTREAM_REUSE_BUFFER 0x20
-#define ZSTREAM_FLAG_UNUSED 0x40
+#define ZSTREAM_REUSE_BUFFER (1 << 5)
+#define ZSTREAM_IN_PROGRESS (1 << 6)
+#define ZSTREAM_FLAG_UNUSED (1 << 7)
#define ZSTREAM_READY(z) ((z)->flags |= ZSTREAM_FLAG_READY)
#define ZSTREAM_IS_READY(z) ((z)->flags & ZSTREAM_FLAG_READY)
@@ -591,7 +609,9 @@ static const struct zstream_funcs inflate_funcs = {
};
struct zstream_run_args {
- struct zstream * z;
+ struct zstream *const z;
+ Bytef *src;
+ long len;
int flush; /* stream flush value for inflate() or deflate() */
int interrupt; /* stop processing the stream and return to ruby */
int jump_state; /* for buffer expansion block break or exception */
@@ -892,7 +912,6 @@ zstream_discard_input(struct zstream *z, long len)
}
rb_str_resize(z->input, newlen);
if (newlen == 0) {
- rb_gc_force_recycle(z->input);
z->input = Qnil;
}
else {
@@ -904,7 +923,7 @@ zstream_discard_input(struct zstream *z, long len)
z->input = Qnil;
}
else {
- z->input = rb_str_substr(z->input, len,
+ z->input = rb_str_subseq(z->input, len,
RSTRING_LEN(z->input) - len);
}
}
@@ -1057,19 +1076,18 @@ zstream_unblock_func(void *ptr)
args->interrupt = 1;
}
-static void
-zstream_run0(struct zstream *z, Bytef *src, long len, int flush)
+static VALUE
+zstream_run_try(VALUE value_arg)
{
- struct zstream_run_args args;
+ struct zstream_run_args *args = (struct zstream_run_args *)value_arg;
+ struct zstream *z = args->z;
+ Bytef *src = args->src;
+ long len = args->len;
+ int flush = args->flush;
+
int err;
VALUE old_input = Qnil;
- args.z = z;
- args.flush = flush;
- args.interrupt = 0;
- args.jump_state = 0;
- args.stream_output = !ZSTREAM_IS_GZFILE(z) && rb_block_given_p();
-
if (NIL_P(z->input) && len == 0) {
z->stream.next_in = (Bytef*)"";
z->stream.avail_in = 0;
@@ -1091,17 +1109,17 @@ zstream_run0(struct zstream *z, Bytef *src, long len, int flush)
loop:
#ifndef RB_NOGVL_UBF_ASYNC_SAFE
- err = (int)(VALUE)rb_thread_call_without_gvl(zstream_run_func, (void *)&args,
- zstream_unblock_func, (void *)&args);
+ err = (int)(VALUE)rb_thread_call_without_gvl(zstream_run_func, (void *)args,
+ zstream_unblock_func, (void *)args);
#else
- err = (int)(VALUE)rb_nogvl(zstream_run_func, (void *)&args,
- zstream_unblock_func, (void *)&args,
+ err = (int)(VALUE)rb_nogvl(zstream_run_func, (void *)args,
+ zstream_unblock_func, (void *)args,
RB_NOGVL_UBF_ASYNC_SAFE);
#endif
/* retry if no exception is thrown */
- if (err == Z_OK && args.interrupt) {
- args.interrupt = 0;
+ if (err == Z_OK && args->interrupt) {
+ args->interrupt = 0;
goto loop;
}
@@ -1135,37 +1153,54 @@ loop:
}
if (!NIL_P(old_input)) {
rb_str_resize(old_input, 0);
- rb_gc_force_recycle(old_input);
}
- if (args.jump_state)
- rb_jump_tag(args.jump_state);
+ if (args->jump_state)
+ rb_jump_tag(args->jump_state);
+
+ return Qnil;
}
-struct zstream_run_synchronized_args {
- struct zstream *z;
- Bytef *src;
- long len;
- int flush;
-};
+static VALUE
+zstream_run_ensure(VALUE value_arg)
+{
+ struct zstream_run_args *args = (struct zstream_run_args *)value_arg;
+
+ /* Remove ZSTREAM_IN_PROGRESS flag to signal that this zstream is not in use. */
+ args->z->flags &= ~ZSTREAM_IN_PROGRESS;
+
+ return Qnil;
+}
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);
+ struct zstream_run_args *args = (struct zstream_run_args *)value_arg;
+
+ /* Cannot start zstream while it is in progress. */
+ if (args->z->flags & ZSTREAM_IN_PROGRESS) {
+ rb_raise(cInProgressError, "zlib stream is in progress");
+ }
+ args->z->flags |= ZSTREAM_IN_PROGRESS;
+
+ rb_ensure(zstream_run_try, value_arg, zstream_run_ensure, value_arg);
+
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);
+ struct zstream_run_args args = {
+ .z = z,
+ .src = src,
+ .len = len,
+ .flush = flush,
+ .interrupt = 0,
+ .jump_state = 0,
+ .stream_output = !ZSTREAM_IS_GZFILE(z) && rb_block_given_p(),
+ };
+ rb_mutex_synchronize(z->mutex, zstream_run_synchronized, (VALUE)&args);
}
static VALUE
@@ -2904,8 +2939,6 @@ gzfile_readpartial(struct gzfile *gz, long len, VALUE outbuf)
if (!NIL_P(outbuf)) {
rb_str_resize(outbuf, RSTRING_LEN(dst));
memcpy(RSTRING_PTR(outbuf), RSTRING_PTR(dst), RSTRING_LEN(dst));
- rb_str_resize(dst, 0);
- rb_gc_force_recycle(dst);
dst = outbuf;
}
return dst;
@@ -3467,6 +3500,9 @@ static VALUE
rb_gzfile_eof_p(VALUE obj)
{
struct gzfile *gz = get_gzfile(obj);
+ while (!ZSTREAM_IS_FINISHED(&gz->z) && ZSTREAM_BUF_FILLED(&gz->z) == 0) {
+ gzfile_read_more(gz, Qnil);
+ }
return GZFILE_IS_FINISHED(gz) ? Qtrue : Qfalse;
}
@@ -4197,17 +4233,17 @@ gzreader_charboundary(struct gzfile *gz, long n)
{
char *s = RSTRING_PTR(gz->z.buf);
char *e = s + ZSTREAM_BUF_FILLED(&gz->z);
- char *p = rb_enc_left_char_head(s, s + n, e, gz->enc);
+ char *p = rb_enc_left_char_head(s, s + n - 1, e, gz->enc);
long l = p - s;
if (l < n) {
- n = rb_enc_precise_mbclen(p, e, gz->enc);
- if (MBCLEN_NEEDMORE_P(n)) {
- if ((l = gzfile_fill(gz, l + MBCLEN_NEEDMORE_LEN(n))) > 0) {
+ int n_bytes = rb_enc_precise_mbclen(p, e, gz->enc);
+ if (MBCLEN_NEEDMORE_P(n_bytes)) {
+ if ((l = gzfile_fill(gz, n + MBCLEN_NEEDMORE_LEN(n_bytes))) > 0) {
return l;
}
}
- else if (MBCLEN_CHARFOUND_P(n)) {
- return l + MBCLEN_CHARFOUND_LEN(n);
+ else if (MBCLEN_CHARFOUND_P(n_bytes)) {
+ return l + MBCLEN_CHARFOUND_LEN(n_bytes);
}
}
return n;
@@ -4617,6 +4653,7 @@ Init_zlib(void)
cMemError = rb_define_class_under(mZlib, "MemError", cZError);
cBufError = rb_define_class_under(mZlib, "BufError", cZError);
cVersionError = rb_define_class_under(mZlib, "VersionError", cZError);
+ cInProgressError = rb_define_class_under(mZlib, "InProgressError", cZError);
rb_define_module_function(mZlib, "zlib_version", rb_zlib_version, 0);
rb_define_module_function(mZlib, "adler32", rb_zlib_adler32, -1);
@@ -4924,6 +4961,7 @@ Init_zlib(void)
* - Zlib::MemError
* - Zlib::BufError
* - Zlib::VersionError
+ * - Zlib::InProgressError
*
*/
@@ -4999,6 +5037,20 @@ Init_zlib(void)
*/
/*
+ * Document-class: Zlib::InProgressError
+ *
+ * Subclass of Zlib::Error. This error is raised when the zlib
+ * stream is currently in progress.
+ *
+ * For example:
+ *
+ * inflater = Zlib::Inflate.new
+ * inflater.inflate(compressed) do
+ * inflater.inflate(compressed) # Raises Zlib::InProgressError
+ * end
+ */
+
+/*
* Document-class: Zlib::GzipFile::Error
*
* Base class of errors that occur when processing GZIP files.
diff --git a/ext/zlib/zlib.gemspec b/ext/zlib/zlib.gemspec
index 4a5f8f2ee8..bb67ea156c 100644
--- a/ext/zlib/zlib.gemspec
+++ b/ext/zlib/zlib.gemspec
@@ -27,5 +27,5 @@ Gem::Specification.new do |spec|
spec.executables = []
spec.require_paths = ["lib"]
spec.extensions = "ext/zlib/extconf.rb"
- spec.required_ruby_version = ">= 2.3.0"
+ spec.required_ruby_version = ">= 2.5.0"
end