Repository navigation
FreePDF 7.4.0
FreePDF 7.4.0
FreePDF 7.4.0 saves documents as incremental updates, so a signed PDF can be
filled in or signed again without breaking the signatures already in it.
Packages
io7.FreePDFhttps://www.nuget.org/packages/io7.FreePDF/7.4.0io7.FreePDF.Layouthttps://www.nuget.org/packages/io7.FreePDF.Layout/7.4.0io7.FreePDF.Gdihttps://www.nuget.org/packages/io7.FreePDF.Gdi/7.4.0io7.FreePDF.Layout.Gdihttps://www.nuget.org/packages/io7.FreePDF.Layout.Gdi/7.4.0io7.FreePDF.Wpfhttps://www.nuget.org/packages/io7.FreePDF.Wpf/7.4.0io7.FreePDF.Layout.Wpfhttps://www.nuget.org/packages/io7.FreePDF.Layout.Wpf/7.4.0
dotnet add package io7.FreePDF --version 7.4.0
dotnet add package io7.FreePDF.Layout --version 7.4.0
New
-
Incremental save with
PdfDocumentOpenMode.Append. PDFsharp 6.2.4 always
writes a new file: saving a signed document after any change breaks its
signatures, and a signed document cannot be signed a second time. A document
opened inAppendmode is saved as the original file, byte for byte, followed
by one update that holds only the new and changed objects:using var document = PdfReader.Open("signed.pdf", PdfDocumentOpenMode.Append); ((PdfFormTextField)document.Catalog.GetAcroForm()!.Fields["name"]!).Text = "Ada Lovelace"; DigitalSignatureHandler.ForDocument(document, signer, options); // optional: sign it again document.Save("signed-filled.pdf");
- The signatures in the file stay valid. A new signature covers the whole
file, earlier signatures included. - The update ends with a cross-reference table, or a cross-reference stream
when the file uses one, and a trailer that points back to the previous one.
Object numbers, the first file identifier and the page tree stay as they are. - A document with no changes is saved exactly as it was. Otherwise the
document information gets a new modification date (unless you set one) and
FreePDF as its producer. - Pages can be added and removed when all pages hang directly under the page
tree's root, which is the common case. When the page tree is nested,
inserting, removing or moving pages throws before anything changes.
- The signatures in the file stay valid. A new signature covers the whole
Fixed
- Opening a form set a new modification date (
/M) on every field that is also
a widget. The date was written on the next save although the field had not
changed, and signature validators count it as an unexplained change. Fields
now keep their own date; only new widgets get one.
Upgrading from 7.3.x
Update all FreePDF packages to 7.4.0 together and rebuild; the assembly version
is now 7.4.0.0. PdfDocumentOpenMode.Append is new; documents opened in
Modify mode are saved as before, as a new file. Behaviour change to check:
- A form field that is also a widget keeps its modification date when a
document is opened and saved inModifymode. Up to 7.3.0 it got the time the
document was opened.
Limits of Append mode in 7.4.0:
- Encrypted documents cannot be opened in
Appendmode, nor can files whose
cross-reference table names the wrong objects; open those withModifyto
save a new file. A document opened inAppendmode cannot be given a password. - FreePDF does not check a certification signature's permissions (DocMDP); a
document certified with "no changes allowed" should not be changed at all. - Whether a validator accepts a change after a signature depends on the
signature's permissions and on the validator. Filling in fields and adding
signatures are permitted for an ordinary (approval) signature. Acrobat permits
added comments, but pyHanko reports any added comment. - Reading
page.Annotations,document.Outlinesordocument.ViewerPreferences
creates them when the file has none, and saving writes that as a change.
Validation
All 7.3.0 release gates apply, plus:
- regression tests for incremental saving: the original bytes are kept, only
changed objects are written, an unchanged document is saved byte for byte,
object numbers and the first identifier are kept, table and stream updates,
saving to the file it was opened from, page insertion in flat and nested page
trees, refusals, and a signature made before filling in a field or before a
second signature that still verifies (CMS over the byte range); 458
regression tests in all; - poppler's
pdfsigreported every signature valid in signed, filled,
annotated and countersigned files, and pyHanko 0.29.1's difference analysis
rated filling in and countersigning as "signing and form filling"; - a file signed by pyHanko, with cross-reference streams, was countersigned by
FreePDF, and both validators accept both signatures; - every readable file of a 2,950-file veraPDF and producer corpus (2,930) was
saved unchanged with identical bytes, and with one change writing only the
changed objects; the 13 encrypted files were refused; mutool parsed a sample
of 290 updated files, with one warning that comes from the original file; - an independent review of the incremental save code, whose findings were fixed
or documented before release.
See the migration guide's "Signed documents" section (https://github.com/io7/FreePDF/blob/8985eab0d57aa774b3771050b5222f09a7b898cd/docs/migrating-to-7.md#signed-documents)
and the support policy (https://github.com/io7/FreePDF/blob/8985eab0d57aa774b3771050b5222f09a7b898cd/docs/support-policy.md).
The attached packages are the verified CI artifacts from source revision 8985eab0d57aa774b3771050b5222f09a7b898cd, and the same files that were
uploaded to NuGet.org. SHA256SUMS and validation.json record their hashes and package-install evidence.
NuGet.org adds its repository signature, so a package downloaded from NuGet.org has a different hash from the attached file.
CI: https://github.com/io7/FreePDF/actions/runs/41789366099 (core),
https://github.com/io7/FreePDF/actions/runs/41789366102 (packages/API/independent checks),
https://github.com/io7/FreePDF/actions/runs/41789366178 (comparisons),
https://github.com/io7/FreePDF/actions/runs/41790809228 (NuGet publication).