Skip to content

fix(lex): bail readArray on io.EOF to avoid unbounded growth - #90

Closed
moberg wants to merge 1 commit into
ledongthuc:masterfrom
moberg:master
Closed

moberg wants to merge 1 commit into
ledongthuc:masterfrom
moberg:master

Conversation

@moberg

@moberg moberg commented Sep 18, 2026

Copy link
Copy Markdown

Malformed PDFs whose content stream never reaches a closing ']' previously drove (*buffer).readArray into an infinite loop: readToken returns io.EOF, the loop unreads it, calls readObject, which returns the same io.EOF, and the array slice grows by one element per iteration. On some inputs this allocates many GB before the process is OOM-killed.

readDict already has the same io.EOF guard. This change adds the matching guard to readArray.

Reproduced and validated with a content-stream-truncated PDF that previously hung at >30 GB resident memory; with the fix the parse returns cleanly within milliseconds.

Malformed PDFs whose content stream never reaches a closing ']'
previously drove (*buffer).readArray into an infinite loop:
readToken returns io.EOF, the loop unreads it, calls readObject,
which returns the same io.EOF, and the array slice grows by one
element per iteration. On some inputs this allocates many GB
before the process is OOM-killed.

readDict already has the same io.EOF guard. This change adds the
matching guard to readArray.

Reproduced and validated with a content-stream-truncated PDF
that previously hung at >30 GB resident memory; with the fix the
parse returns cleanly within milliseconds.
@ledongthuc

Copy link
Copy Markdown
Owner

@moberg The fix in this PR already exists in master. Commit 601f614 ("lex: stop readArray looping forever on io.EOF") adds the same check.

The condition in readArray is now:
if tok == nil || tok == io.EOF || tok == keyword("]") { break }

This means the new block in this PR is not run. The io.EOF check in this PR can never be true at that point.

So I will close this PR. But if you have any comment, feel free to add.

@ledongthuc ledongthuc closed this Oct 20, 2026
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.

2 participants