Skip to content

feat: Incrementing handling of attachments - #119

Open
RianKoja wants to merge 2 commits into
sambitdash:masterfrom
RianKoja:master
Open

RianKoja wants to merge 2 commits into
sambitdash:masterfrom
RianKoja:master

Conversation

@RianKoja

Copy link
Copy Markdown

Hi, thanks for all the good work! I'm using PDFIO.jl and would really apreciate a feature, to downlaod attachments from a pdf file. I'd be happy to contribute and iterate on revisions.

PR Content:

Adds a PD-layer API for files embedded in a PDF (implements #6):

  • pdDocGetAttachments, pdDocExtractAttachments (takes a PDDoc or a file path), PDAttachment, pdAttachmentGetName/GetData/Extract.
  • Finds files in the /EmbeddedFiles name tree (including indirect /Names and /Kids) and in FileAttachment annotations, deduplicated by stream. Legacy /EF keys (/Unix, /Mac, /DOS) are read too.

pdDocExtractAttachments("file.pdf") writes every attachment to the current directory.

Safety Measures

Names come from the PDF, so they are sanitized to a plain file name. Files are created with O_EXCL, so nothing is overwritten or followed through a symlink; a numeric suffix is used instead. Streams pointing at a local file via /F are ignored.
One small change in shared code: attach_object (src/CosDoc.jl) registered any stream's /F path for deletion on close, so a crafted PDF could make closing the document delete a local file. Only files inside the parser's own temp directory are registered now.

Tests

New tests in test/runtests.jl with two small fixtures in test/files/: byte-exact round trip (bytes cross-checked with pypdf), name sanitizing, malformed UTF-16/UTF-8 names, collision suffixes, symlink safety, external-file rejection, a crafted PDF proving the referenced file survives pdDocClose (fails without the fix), legacy /EF keys, and no leaked file handles. Run standalone on Julia 1.10.4: 49/49 pass. The full suite needs the external PDTest data, so it is left to CI.

Limitations

Encrypted documents are not supported. Extraction buffers each decoded stream in memory, like the existing COS decoders.

RianKoja and others added 2 commits September 30, 2026 02:35
Adds PD-layer pdDocGetAttachments and pdDocExtractAttachments, discovering
files in the EmbeddedFiles name tree and FileAttachment annotations.
Attachment names are sanitized, files are created exclusively and never
overwritten, and streams referring to external local files are rejected.

Closing a document no longer deletes files that a stream names in /F; only
the parser's own temporary files are removed.
Add extraction of embedded file attachments
@sambitdash

Copy link
Copy Markdown
Owner

@RianKoja, thanks for the submission. I need a few days to review the submission. I will work on it mid-next week. Hope, you are ok with it.

This branch has not been deployed

No deployments
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