diff options
author | Sutou Kouhei <kou@clear-code.com> | 2021-10-05 16:43:21 +0900 |
---|---|---|
committer | git <svn-admin@ruby-lang.org> | 2021-10-15 15:31:15 +0900 |
commit | 027a3379d67922738d503511c2123989229f8d9b (patch) | |
tree | d9a04d8bd1ec1fb4c759905d2c064e21a4ee53a5 /ext/zlib/zlib.c | |
parent | 679054208e320d4e639aa3dc1f16ad1a4945ac72 (diff) |
[ruby/zlib] 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!!!
https://github.com/ruby/zlib/commit/b1f182e98f
Diffstat (limited to 'ext/zlib/zlib.c')
-rw-r--r-- | ext/zlib/zlib.c | 12 |
1 files changed, 6 insertions, 6 deletions
diff --git a/ext/zlib/zlib.c b/ext/zlib/zlib.c index 147b7344db..fb7a5d5ae3 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; |