Skip to content

Guard ParentTree allocation against pathological MCID - #94

Merged
Tim81 merged 1 commit into
mainfrom
v1.5.6-mcid-allocation-guard
Jun 16, 2026
Merged

Guard ParentTree allocation against pathological MCID#94
Tim81 merged 1 commit into
mainfrom
v1.5.6-mcid-allocation-guard

Conversation

@Tim81

@Tim81 Tim81 commented Jun 16, 2026

Copy link
Copy Markdown
Owner

Follow-up to a self-review of #93 (v1.5.5).

Problem

The v1.5.5 MCID ParentTree change sizes the per-page array by max(MCID) + 1. Since PdfStructElem.Mcid is a public setter, a hand-built structure tree with a very large MCID (or int.MaxValue) would attempt a multi-gigabyte allocation, or overflow max(MCID)+1 to a negative length — crashing mid-Save rather than failing cleanly. Documents tagged through the canvas are safe (their per-page MCIDs are dense and sequential); this only affected hand-built trees.

Fix

Cap the per-page MCID at 1_000_000 (per-page marked content is bounded by content-stream size, so this is ~100× beyond any real page) and throw a clear InvalidOperationException above it, before the array is sized — so neither the overflow nor the large allocation is reachable. It is a robustness guard, not a conformance limit.

Tests

  • New StructureTree_pathologicalMcid_throwsInsteadOfOom (asserts int.MaxValue throws InvalidOperationException, not OOM/overflow).
  • 633 Kernel + 187 Layout tests pass; dotnet format --verify-no-changes clean; AOT smoke passes.

Bumps version to 1.5.6.

A self-review of #93 (v1.5.5) found a regression: the per-page ParentTree
array is sized by (max MCID + 1), and PdfStructElem.Mcid is a public
setter, so a hand-built structure tree with a huge MCID (or int.MaxValue)
would attempt a multi-gigabyte allocation or overflow the length to a
negative value — crashing mid-Save instead of failing cleanly.

Cap the per-page MCID at 1,000,000 (far above any real page's
marked-content count, which is bounded by content-stream size) and throw
a clear InvalidOperationException above it, before the array is sized.
Documents tagged through the canvas are unaffected: their per-page MCIDs
are dense and sequential.

Bump to 1.5.6.
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