Skip to content

FreePDF 7.6.1

Choose a tag to compare

@christianz christianz released this 05 Nov 07:14
90c50b5

FreePDF 7.6.1

FreePDF 7.6.1 reads list boxes with several selected options, decodes stream
filters in every form the standard allows, and writes metadata in encrypted
documents as ISO 32000-1 specifies. Nothing else changes from 7.6.0.

Packages

dotnet add package io7.FreePDF --version 7.6.1
dotnet add package io7.FreePDF.Layout --version 7.6.1

Fixed

  • List boxes with several selected options. A list box that allows multiple
    selection holds its value as an array (ISO 32000-1 Table 231).
    SelectedValue, SelectedIndex and Flatten() threw on it. All selected
    options are read now: SelectedValue and SelectedIndex report the first in
    option order, and the drawn list box highlights each one. A value held as an
    indirect string is read too.

  • Stream filters and their parameters. Decoding accepts every form ISO
    32000-1 7.3.8 allows:

    • a null /DecodeParms entry means no parameters;
    • a filter name or its parameters may be indirect objects;
    • a single filter may have its parameters in a one-element array, and the
      other way round.

    A /Crypt filter passes the data on, because it was decrypted when the file
    was read. Decoding threw "Filter not implemented: Crypt", for example for
    FreePDF's own document metadata when EncryptMetadata is false.

  • Crypt filter entries. When FreePDF marks a stream with a crypt filter, as it
    does for the document metadata when EncryptMetadata is false, /DecodeParms
    now has one entry per filter. It was a lone dictionary next to two filters,
    which ISO 32000-1 Table 5 does not allow and FreePDF could not decode. A stream
    whose parameters were a direct dictionary made the save throw ("A direct object
    can only be added once"). Streams that earlier versions wrote still decode.

  • Metadata encryption. With EncryptMetadata false, only the document's own
    metadata stream stays unencrypted, as ISO 32000-1 Table 20 specifies. FreePDF
    wrote every metadata stream that held XML unencrypted, and pyHanko could not
    read page metadata ("not a multiple of the block length"). Reading still
    accepts unencrypted metadata anywhere, as some writers leave it all
    unencrypted.

  • With EncryptMetadata false, saving a document without metadata added a
    /Metadata dictionary that held only the crypt filter and no stream, which
    ISO 32000-1 Table 28 does not allow. No such entry is added now.

Upgrading from 7.6.0

Update all FreePDF packages to 7.6.1 together and rebuild; the assembly version
is now 7.6.1.0. The public API is unchanged. Behaviour changes to check:

  • With EncryptMetadata false, metadata streams other than the document's own,
    such as page metadata, are now encrypted. FreePDF 7.5.1 and earlier cannot
    open such a file when that metadata is compressed (7.5.2 and later can).
  • Setting or resetting a crypt filter writes /Filter and /DecodeParms again,
    aligned; streams without a crypt filter are left as they are.

Validation

All 7.6.0 release gates apply, plus:

  • regression tests: a multi-select list box flattened with both options
    highlighted, indirect values and option order; null, indirect and one-element
    filter parameters, /Crypt alone and in front of another filter, the layout
    earlier versions wrote; document metadata compressed or not, with direct or
    indirect parameters and an indirect filter name; setting and resetting a crypt
    filter; other metadata encrypted, the document's not, also in Append mode;
    665 regression tests in all;
  • pyHanko 0.29.1 reads the document and page metadata of AES-128, AES-256 and
    V4-RC4 files that FreePDF wrote, also compressed, after Modify and Append
    saves, and all crypt filter layouts FreePDF now writes; mutool read the
    samples checked, including page metadata that it misread in 7.6.0 output;
  • an independent review in three rounds, whose findings were fixed before
    release. Every stream that decoded before decodes to the same bytes, streams
    without a crypt filter are written byte for byte as in 7.6.0, and resetting
    the encryption of a whole document no longer crashes on some parameter
    layouts.

The attached packages are the verified CI artifacts from source revision 90c50b5f5ef6b13f9673fe036609c22e19b0b585, 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/41924320872 (core),
https://github.com/io7/FreePDF/actions/runs/41924320762 (packages/API/independent checks),
https://github.com/io7/FreePDF/actions/runs/41924320747 (comparisons),
https://github.com/io7/FreePDF/actions/runs/41984593505 (NuGet publication).