Skip to content

Support opening PDFs larger than 2 GiB - #1293

Merged
BobLd merged 5 commits into
UglyToad:masterfrom
OrganizationUsername:master
Jun 6, 2026
Merged

BobLd merged 5 commits into
UglyToad:masterfrom
OrganizationUsername:master

Conversation

@OrganizationUsername

Copy link
Copy Markdown
Contributor

Fixes PdfDocument.Open(string) for PDFs larger than 2 GiB by opening the file as a seekable stream instead of reading the whole file into a byte array with File.ReadAllBytes.

Also widens FileHeaderOffset from int to long so header offsets are not narrowed during parsing.

Adds regression coverage using a sparse PDF with a logical size over 2 GiB, verifying that PdfPig can open it, read page 200, and extract text. A skipped local repro test is also included for generating and reading a real >2 GiB PDF.

Fixes #1259.

username added 2 commits May 14, 2026 19:31
- Introduced a new test in `LocalTests.cs` for creating and reading PDFs larger than two gigabytes using `LargePdfTestDocumentGenerator`.
- Updated `FileHeaderOffset.cs` to change the `Value` type from `int` to `long` for better handling of large values.
- Modified `PdfDocumentFactory.cs` to use `FileStream` for opening PDFs, enhancing memory efficiency.
- Added `PdfDocumentOpenTests` class to verify opening of large PDFs with a sparse XRef offset.
Introduced `RealBigFileTests` to test creation and reading of PDFs larger than 2 GiB. Updated `IntegrationDocumentTests` with a new test for opening large sparse documents and added utility methods for document creation. Removed `LocalTests` and `PdfDocumentOpenTests` to refactor the test structure, focusing on integration tests for large files.
@OrganizationUsername

Copy link
Copy Markdown
Contributor Author

Happy to drop the skipped real-file repro if it makes the PR easier to review. I included it because it’s pretty close to the kind of PDF I actually have to deal with at work.

…ugh Open(Stream)

The previous change to PdfDocumentFactory.Open(string) switched it from
File.ReadAllBytes to a FileStream wrapped in StreamInputBytes(shouldDispose: true),
so the document owned a live file handle for its lifetime. That is a silent
breaking change: Open(string) has never required disposal, and existing callers
(many of which don't wrap the document in a using block) would suddenly be
holding the file open and blocking re-open or delete until GC ran. Only
Open(Stream) is documented to require the caller to manage the stream.

This restores the pre-existing byte-array path for Open(string). Files larger
than 2 GiB cannot be loaded that way (byte[] is int.MaxValue-capped), which is
the same constraint that has always existed: callers with >2 GiB files must use
Open(Stream) with their own FileStream, and the two large-file tests are
updated to do exactly that. FileHeaderOffset.Value stays long since it's
internal-only and removes a lossy int cast.
@BobLd

BobLd commented May 16, 2026

Copy link
Copy Markdown
Collaborator

@OrganizationUsername yes, do you mind removing these optional test? the rest looks good to me. Thanks for that!

Per PR UglyToad#1293 reviewer feedback, removing RealBigFileTests and its
LargePdfTestDocumentGenerator helper. The actual regression coverage
lives in IntegrationDocumentTests.CanOpenLargeSparseDocumentAndReadPage,
which uses a sparse file with a >2 GiB xref offset.
@BobLd

BobLd commented May 16, 2026

Copy link
Copy Markdown
Collaborator

@OrganizationUsername can you also drop LocalTests?

@cremor

cremor commented May 17, 2026

Copy link
Copy Markdown

Fixes PdfDocument.Open(string) for PDFs larger than 2 GiB by opening the file as a seekable stream instead of reading the whole file into a byte array with File.ReadAllBytes.

Seems like this is no longer true. Please update the description of this PR.

@BobLd BobLd left a comment •

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

approving as-is and I'll remove the dead test

EDIT: Nothing to remove - misread github diffs

@BobLd
BobLd merged commit 6111c67 into UglyToad:master Jun 6, 2026
This was referenced Jun 25, 2026
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.

How to support files larger than 2GB ?

3 participants