fix: ASCII85 decoder drops 'z' zero-groups and never signals EOF at ~> marker - #84
Open
chappihappymeal wants to merge 1 commit into
Open
fix: ASCII85 decoder drops 'z' zero-groups and never signals EOF at ~> marker#84chappihappymeal wants to merge 1 commit into
chappihappymeal wants to merge 1 commit into
Conversation
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Fixes #83.
alphaReader(the sanitizing reader in front ofencoding/ascii85) had two bugs:z— the standard ASCII85 shorthand for an all-zero 4-byte group (PDF 32000-1:2008, §7.4.3), emitted by Ghostscript, Adobe tools, and Go's ownascii85.Encode. Everyzsilently dropped 4 bytes from the decoded stream: with[/ASCII85Decode /FlateDecode]this corrupted the flate stream (GetPlainText()→malformed PDF: unexpected EOF,Page.Content()→ panic escaping to the caller); with plain/ASCII85Decodethe corruption was silent.~>end-of-data marker it onlybreaked out of the sanitizing loop and returnedn, nil— it never signaledio.EOF, never truncated at the marker, and kept feeding post-marker bytes from laterReadchunks to the decoder.The rewritten
Readfilters in place (no per-call allocation), passeszthrough, and returns the sanitized byte count withio.EOFas soon as~is seen — per spec~can only start the EOD marker, which also handles a marker split across two reads for free. After that everyReadreturns0, io.EOFwithout touching the underlying reader.Tests: 6 unit tests for
alphaReader(zero-group, EOF at marker, marker split across reads, garbage after marker, line-wrapped input, reads after EOF) and 2 integration tests with minimal synthetic PDFs intestdata/— one with azgroup inside a text string (plain/ASCII85Decode), one with an Exstream-style[/ASCII85Decode /FlateDecode]chain. Both fixtures are read correctly by poppler'spdftotextand Python'sbase64.a85decode, and both failed on the old code.On a separate note: I noticed several open PRs fixing hangs/OOMs (#46, #58, #64, #76, #78, #79) have been waiting for review for a while. I understand maintaining this alone is a lot. I use this library in production for high-volume PDF processing (bank receipts, dozens of layouts) and have a large regression corpus for it — I'd be happy to help with triage and reviews as a co-maintainer if that's useful to you. If you'd rather keep it as is, no problem at all — feel free to just take the fix.