From b1f182e98fd088cee3cf8bdb607dec3836fbb4c7 Mon Sep 17 00:00:00 2001 From: Sutou Kouhei Date: Tue, 5 Oct 2021 16:43:21 +0900 Subject: [PATCH] Fix a bug that GZipReader#gets may return incomplete line See also: https://github.com/ruby/csv/issues/117#issuecomment-933289373 How to reproduce with x.csv.gz in the issue comment: Zlib::GzipReader.open("x.csv.gz") do |rio| rio.gets(nil, 1024) while line = rio.gets(nil, 8192) raise line unless line.valid_encoding? end end Reported by Dimitrij Denissenko. Thanks!!! --- ext/zlib/zlib.c | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/ext/zlib/zlib.c b/ext/zlib/zlib.c index 147b734..fb7a5d5 100644 --- a/ext/zlib/zlib.c +++ b/ext/zlib/zlib.c @@ -4199,17 +4199,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;