Repository navigation
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.
A hybrid-reference file keeps a cross-reference table for readers that don't know cross-reference streams, and names a cross-reference stream with
/XRefStmin the trailer for those that do (PDF 32000-1:2008, 7.5.8.4). The objects in its object streams are only in that stream. The table leaves them out or lists them as free.readXrefTableignores/XRefStm, so none of those objects resolve, and anything that refers to them reads as null.Word, Acrobat Distiller, the Adobe PDF Library, LiveCycle Designer and Prince all write such files. In qpdf's
good17.pdf, for example,Outline()returns no entries, because the outline is in an object stream.readXrefTablenow reads the stream named by/XRefStmafter each table section, the newest first, as it does with/Prev. Its entries fill the numbers the table didn't set. If the stream can't be read, the table is used as it is.readXrefTableDatanow also checks whether an entry is already set by itsptrrather than itsoffset. A compressed entry for the first object in an object stream has offset 0, so an entry from an older table section would otherwise replace it.Test plan:
TestHybridReferenceFile: a file whose page tree is in an object stream, with free table entries for it. Onmaster,NumPageis 0; with this change it is 1.TestHybridReferenceFileWithUnreadableXRefStm, which checks that the table still works when/XRefStmpoints at something that isn't a cross-reference stream.go test ./...andgo build ./...pass.qpdf --json.good17.pdf,good18.pdfandhybrid-xref.pdf), and objects ofissue9418.pdf, a damaged file that qpdf reconstructs.Outline()ofgood17.pdfandhybrid-xref.pdfnow returns its 2 top-level entries. The text of the other hybrid files is unchanged.