Skip to content

Count only defined objects in an incremental save's /Size - #117

Open
KleiKodesh wants to merge 1 commit into
embedpdf:embedpdf/mainfrom
KleiKodesh:fix/incremental-save-size
Open

KleiKodesh wants to merge 1 commit into
embedpdf:embedpdf/mainfrom
KleiKodesh:fix/incremental-save-size

Conversation

@KleiKodesh

Copy link
Copy Markdown

An incremental save wrote /Size from the document's last object number. That number includes object numbers an editing session reserved with EPDFLayer_RaiseLastObjectNumber() and never used, so a save that only touched a few objects could claim a /Size dozens of numbers past the highest object in the file. qpdf reports that as an error (/Size larger than the highest object number + 1).

Now an incremental save (plain or a layer delta) takes its /Size, and the cross-reference stream's object number, from the highest object number the file actually defines:

  • the input's last object number and its trailer's /Size, so /Size never shrinks below the input's;
  • the objects this save wrote (including an inline encryption dictionary).

A layer delta is cumulative from its base, so it writes every object the base lacks and the rule holds there too. Full saves are unchanged: their single cross-reference subsection still lists reserved numbers as free entries (complete-xref).

The change sits under the existing save-traversal rule; the ledger entry says so.

Tests

  • New embedder test EPDFLayerEmbedderTest.SaveLayerDeltaSizeIgnoresUnusedReservedNumbers: a layer reserves 64 numbers, creates one annotation at the first, and the delta's /Size is that annotation's number + 1.
  • Not built or run locally (no emscripten/clang toolchain on the machine this was written on); CI hasn't run yet.

An incremental save wrote /Size from the document's last object number,
which includes numbers an editing session reserved with
EPDFLayer_RaiseLastObjectNumber() and never used. qpdf reports such a
/Size as larger than the highest object number plus one.

The /Size and the cross-reference stream's number now follow the
highest object number the file defines: the input's objects and /Size,
and the objects the save wrote.
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.

1 participant