Skip to content

pdftopdf: don't abort on annotations that have no appearance stream - #255

Open
dreed47 wants to merge 1 commit into
OpenPrinting:masterfrom
dreed47:fix-246-pdftopdf-annotation-name
Open

dreed47 wants to merge 1 commit into
OpenPrinting:masterfrom
dreed47:fix-246-pdftopdf-annotation-name

Conversation

@dreed47

@dreed47 dreed47 commented Sep 22, 2026

Copy link
Copy Markdown

pdftopdf exits 1 on PDFs whose annotations have no appearance stream. Chrome's direct-to-CUPS print path builds one /Link annotation per hyperlink and does not give those annotations an /AP /N stream, so printing a normal web page fails inside the universal filter. A saved PDF of the same page, which has no such annotations, prints.

The no-appearance branch of flatten_pdf() still created a Form XObject and registered it with pdfioDictSetObj() under a malloc'd name, then freed that name. pdfioDictSetObj() keeps the caller's key pointer. After the name was freed, every /XObject key in the flattened page was a dangling pointer, the flattened file could not be reopened, and cfFilterPDFToPDF() returned 1 with no further error. One link is enough for this to happen intermittently. A page with more links fails every time. The log still said "special case ignore annotation with no appearance" while doing the opposite.

Annotations with nothing to paint (links, and form fields that have no value) are now skipped. Text and choice fields that still carry a value are synthesized, and the XObject name is a PDFio-owned string so it stays valid until the file is closed. annotation_contents is allocated with calloc, so a skipped slot cannot be a garbage pointer.

cupsfilters/test-pdftopdf-no-appearance.sh runs a one-page PDF with 16 appearance-less link annotations through pdftopdf and checks that the output opens and has a page. On current master that fixture produces an empty file and exit status 1.

Fixes #246

Flattening a link or a form field that has no /N appearance registered
a Form XObject under a heap-allocated name and then freed that name.
pdfioDictSetObj() keeps the key pointer, so the page /XObject dictionary
was corrupt by the time the flattened file was written.  Reopening it
failed and cfFilterPDFToPDF() exited 1.  Chrome's direct-to-CUPS PDF
hits this for every hyperlink.

Skip annotations that have nothing to paint.  Text and choice fields
that still carry a value are synthesized under a PDFio-owned name.

Fixes OpenPrinting#246
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.

pdftopdf exits with status 1 (no error message) on PDFs with form fields lacking /N and /BBox

1 participant