Skip to content

Fix readuntil missing a terminator that spans two reads - #66

Merged
hsbt merged 3 commits into
masterfrom
readuntil-chunk-boundary
Aug 25, 2026
Merged

Fix readuntil missing a terminator that spans two reads#66
hsbt merged 3 commits into
masterfrom
readuntil-chunk-boundary

Conversation

@hsbt

@hsbt hsbt commented Aug 25, 2026

Copy link
Copy Markdown
Member

Net::BufferedIO#readuntil resumes searching from the previous buffer end after each refill, so a multi-byte terminator split across two reads, such as "\r" at the end of one chunk and "\n" at the start of the next, is never matched and readuntil returns data past the terminator. This can corrupt response parsing in net/http and other clients when a CRLF straddles a packet boundary. Rewind the search offset by terminator.bytesize - 1 before refilling. A regression test reads "abc\r" and "\ndef\r\n" from a fake IO and expects "abc\r\n".

hsbt and others added 3 commits August 25, 2026 18:37
BufferedIO#readuntil resumed searching at the previous buffer end, so a
multi-byte terminator split across two fills, such as "\r" ending one
chunk and "\n" starting the next, was never matched and readuntil
returned data past the terminator. Rewind the search by
terminator.bytesize - 1 before refilling, floored at @rbuf_offset.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Cover a terminator split across two reads and across more than two, the
negative rewind the floor clamps, the floor keeping the search out of
consumed bytes, and the ignore_eof branch that returns data without a
terminator. FakeReadPartialIO now signals EOF instead of raising
TypeError, and hands out binary chunks so @rbuf stays binary the way a
real IO leaves it.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Running the tests leaves one behind, and a prior branch committed it by
accident. Anchored to the root like every other entry.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
@hsbt
hsbt force-pushed the readuntil-chunk-boundary branch from 14f7784 to 0dbbaea Compare August 25, 2026 09:37
@hsbt
hsbt merged commit 716719e into master Aug 25, 2026
72 checks passed
@hsbt
hsbt deleted the readuntil-chunk-boundary branch August 25, 2026 09:40
hsbt added a commit that referenced this pull request Aug 25, 2026
The rewind added in #66 makes the search resume before the end of the
previous read, and every limit test so far used a single-byte terminator
where that rewind never moves. This is the combination the limit has to
measure the result rather than how far the search looked back.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
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