Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 6 additions & 0 deletions ext/zlib/zlib.c
Original file line number Diff line number Diff line change
Expand Up @@ -4496,6 +4496,12 @@ gzreader_gets(int argc, VALUE *argv, VALUE obj)
else {
n += (rb_len_t)(res - p);
p = res;
if (maxlen > 1 &&
rb_enc_left_char_head(RSTRING_PTR(gz->z.buf), p, RSTRING_PTR(gz->z.buf) + ZSTREAM_BUF_FILLED(&gz->z), enc) != p) {
/* the match starts inside a multibyte character: keep searching */
p++, n++;
continue;
}
if (rslen == 1 || memcmp(p, rsptr, rslen) == 0) break;
p++, n++;
}
Expand Down
14 changes: 14 additions & 0 deletions test/zlib/test_zlib.rb
Original file line number Diff line number Diff line change
Expand Up @@ -1367,6 +1367,20 @@ def test_reader_wrap
}
end

def test_gets_separator_inside_multibyte_char
pend "rb_io_extract_encoding_option ignores the encoding options on TruffleRuby" if RUBY_ENGINE == 'truffleruby'
# In Shift_JIS the second byte of a character can be an ASCII byte such
# as "@"; a separator must only match on a character boundary.
content = "\x81\x40?\x81\x40@".b
r = Zlib::GzipReader.new(StringIO.new(Zlib.gzip(content)), external_encoding: "Shift_JIS")
assert_equal(content.dup.force_encoding("Shift_JIS"), r.gets("@"))
assert_nil(r.gets("@"))
r = Zlib::GzipReader.new(StringIO.new(Zlib.gzip(content)), external_encoding: "Shift_JIS")
assert_equal("\x81\x40?".b.force_encoding("Shift_JIS"), r.gets("?"))
assert_equal("\x81\x40@".b.force_encoding("Shift_JIS"), r.gets("?"))
assert_nil(r.gets("?"))
end

def test_corrupted_header
gz = Zlib::GzipWriter.new(StringIO.new(s = "".dup))
gz.orig_name = "X"
Expand Down
Loading