Skip to content

Do not match the line separator inside a multibyte character in GzipReader#gets - #180

Open
segiddins wants to merge 1 commit into
ruby:masterfrom
segiddins:segiddins/gzreader-gets-separator-char-boundary
Open

segiddins wants to merge 1 commit into
ruby:masterfrom
segiddins:segiddins/gzreader-gets-separator-char-boundary

Conversation

@segiddins

Copy link
Copy Markdown
Contributor

The separator was searched bytewise with memchr and memcmp, without checking that a match starts on a character boundary. In Shift_JIS the second byte of a character can be an ASCII byte such as "@", "a" or "|", so gets with such a separator cut the character in half. IO#gets only accepts a match on a boundary.

gz = Zlib.gzip("\x81\x40?\x81\x40@".b)
r = Zlib::GzipReader.new(StringIO.new(gz), external_encoding: "Shift_JIS")
r.gets("@")
# expected: "\x{8140}?\x{8140}@"
# actual:   "\x{8140}"

…eader#gets

The separator was searched bytewise with memchr and memcmp, without checking that a match starts on a character boundary. In Shift_JIS the second byte of a character can be an ASCII byte such as "@", "a" or "|", so gets with such a separator cut the character in half. IO#gets only accepts a match on a boundary.

```ruby
gz = Zlib.gzip("\x81\x40?\x81\x40@".b)
r = Zlib::GzipReader.new(StringIO.new(gz), external_encoding: "Shift_JIS")
r.gets("@")
# expected: "\x{8140}?\x{8140}@"
# actual:   "\x{8140}"
```

Co-Authored-By: Claude Mythos 5.1 <noreply@anthropic.com>
@segiddins
segiddins force-pushed the segiddins/gzreader-gets-separator-char-boundary branch from e4f661e to 92a8701 Compare October 26, 2026 19:43

This branch has not been deployed

No deployments
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant