Skip to content

Fix #1576: DO_NOT_ENCRYPT_METADATA no longer silently disables content encryption#1589

Open
andreasrosdalw wants to merge 1 commit into
LibrePDF:masterfrom
andreasrosdalw:fix-1576-do-not-encrypt-metadata
Open

Fix #1576: DO_NOT_ENCRYPT_METADATA no longer silently disables content encryption#1589
andreasrosdalw wants to merge 1 commit into
LibrePDF:masterfrom
andreasrosdalw:fix-1576-do-not-encrypt-metadata

Conversation

@andreasrosdalw

@andreasrosdalw andreasrosdalw commented Jul 21, 2026

Copy link
Copy Markdown
Contributor

Summary

Fixes #1576.

Passing PdfWriter.DO_NOT_ENCRYPT_METADATA to setEncryption(...) silently switched the output to embedded-files-only encryption mode: /StmF and /StrF were written as /Identity, so all stream and string content was left unencrypted, and Adobe Reader opens the resulting file without a password prompt — even though the caller asked for e.g. AES-128 encryption with only the metadata in plaintext.

Root cause

EMBEDDED_FILES_ONLY (24) is defined as the combination of DO_NOT_ENCRYPT_METADATA (bit 3, value 8) and a dedicated embedded-files-only bit (bit 4, value 16). The detection in PdfEncryption.setCryptoMode only tested for any of those bits:

embeddedFilesOnly = (mode & PdfWriter.EMBEDDED_FILES_ONLY) != 0; // true for DO_NOT_ENCRYPT_METADATA alone

Fix

Require both bits to be set:

embeddedFilesOnly = (mode & PdfWriter.EMBEDDED_FILES_ONLY) == PdfWriter.EMBEDDED_FILES_ONLY;

Resulting behavior:

Mode Before After
AES_128 everything encrypted unchanged
AES_128 | DO_NOT_ENCRYPT_METADATA content unencrypted (/StmF /Identity, /StrF /Identity, /EFF) content encrypted (/StmF /StdCF, /StrF /StdCF, /EncryptMetadata false)
AES_128 | EMBEDDED_FILES_ONLY embedded-files-only unchanged

Tests

New DoNotEncryptMetadataTest covers setCryptoMode flag handling for all three modes plus two end-to-end tests asserting the /Encrypt dictionary entries (/StmF, /StrF, /EFF, /AuthEvent, /EncryptMetadata) written by PdfStamper for DO_NOT_ENCRYPT_METADATA and EMBEDDED_FILES_ONLY. The two metadata-mode tests fail on current master and pass with the fix; the embedded-files-only tests guard against regressing that mode. Full openpdf-core suite passes: 2085 tests, 0 failures.

… embedded-files-only mode

EMBEDDED_FILES_ONLY (24) contains the DO_NOT_ENCRYPT_METADATA bit (8), so
detecting embedded-files-only mode with (mode & EMBEDDED_FILES_ONLY) != 0
also matched a mode that only sets DO_NOT_ENCRYPT_METADATA. As a result,
asking for e.g. ENCRYPTION_AES_128 | DO_NOT_ENCRYPT_METADATA wrote /StmF
and /StrF as /Identity, leaving all stream and string content unencrypted;
Adobe Reader opens such a file without asking for a password.

Require both bits of EMBEDDED_FILES_ONLY to be set instead, so
DO_NOT_ENCRYPT_METADATA keeps content encryption and only leaves the
/Metadata stream in plaintext, while EMBEDDED_FILES_ONLY (which implies
unencrypted metadata) behaves as before.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
@codacy-production

Copy link
Copy Markdown

Up to standards ✅

🟢 Issues 0 issues

Results:
0 new issues

View in Codacy

🟢 Metrics 154 complexity · 6 duplication

Metric Results
Complexity 154
Duplication 6

View in Codacy

NEW Get contextual insights on your PRs based on Codacy's metrics, along with PR and Jira context, without leaving GitHub. Enable AI reviewer
TIP This summary will be updated as you push new changes.

@sonarqubecloud

Copy link
Copy Markdown

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.

Setting DO_NOT_ENCRYPT_METADATA flag silently switches output to embedded-files-only mode, leaving stream/string content unencrypted

1 participant