Skip to content

FreePDF 7.5.2

Choose a tag to compare

@christianz christianz released this 04 Nov 18:34
a2d5d47

FreePDF 7.5.2

FreePDF 7.5.2 opens and reads encrypted documents whose metadata streams are
encrypted although the document leaves metadata unencrypted. Nothing else
changes from 7.5.1.

Packages

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

Fixed

  • Encrypted metadata in documents with EncryptMetadata false. ISO
    32000-1 exempts only the document's own metadata from encryption, so pyHanko,
    for example, encrypts a page's metadata stream. FreePDF decides from a
    metadata stream's content whether it is unencrypted, because some writers
    leave metadata unencrypted without marking it. It decompressed the encrypted
    data of a compressed stream, which threw InvalidDataException, so the
    document did not open: 199 of 200 such pyHanko files. It also took an
    uncompressed stream whose encrypted data starts with < (one in 256) for XML
    and did not decrypt it.

    The decision is now reliable:

    • A stream whose own bytes are empty or blank stays unencrypted.
    • A compressed stream without a zlib header, or one that does not decode,
      counts as encrypted.
    • Otherwise the text must start with <, and its first 16 characters must be
      printable ASCII, tabs, line breaks or UTF-8, as every XMP packet's
      <?xpacket begin= is.

Upgrading from 7.5.1

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

  • With EncryptMetadata false, unencrypted metadata that does not start like
    XML text counts as encrypted, both when FreePDF writes it and when it reads
    it. Examples are UTF-16 without a byte order mark, Latin-1 text or control
    characters in the first 16 characters, and compressed blank metadata from
    another writer. XMP must be Unicode, and UTF-16 with a byte order mark already
    counted as encrypted.
  • Files whose unencrypted metadata could not be decoded no longer fail to open;
    such a stream counts as encrypted. Examples are a mismatched predictor and an
    unsupported filter.

Validation

All 7.5.1 release gates apply, plus:

  • regression tests: encrypted compressed metadata with V4-RC4, AES-128 and
    AES-256; 2,000 encrypted metadata streams in one file, uncompressed and
    compressed, all decrypted; unencrypted metadata, ASCII or UTF-8, compressed or
    not, stays unencrypted and reads back; 606 regression tests in all;
  • pyHanko 0.29.1: 400 AES-256 files with EncryptMetadata false whose page
    metadata pyHanko encrypted, 200 of them compressed. 7.5.1 failed to open 199
    and misread 1; 7.5.2 reads all 400;
  • generated files: none of 50,000 compressed encrypted metadata streams is
    misread, and all of the 3,000 files from the 7.5.1 review read correctly
    (7.5.1 failed to open 1,496 and misread 6);
  • an independent review in two rounds, whose findings were fixed before release.
    On 100,000 random encrypted inputs per filter, at most 1 was taken for
    unencrypted metadata. Files that 7.5.1 wrote read the same, and ASCII and UTF-8
    metadata is written byte for byte as in 7.5.1.

The attached packages are the verified CI artifacts from source revision a2d5d477061c7c0449f41064b1ede2e4271f93d2, 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/41868952682 (core),
https://github.com/io7/FreePDF/actions/runs/41868952766 (packages/API/independent checks),
https://github.com/io7/FreePDF/actions/runs/41868953407 (comparisons),
https://github.com/io7/FreePDF/actions/runs/41878623607 (NuGet publication).