Skip to content

fix(forms): pass resolver for indirect refs in dicts and name trees#56

Merged
Mythie merged 1 commit intomainfrom
issue/55
Mar 21, 2026
Merged

fix(forms): pass resolver for indirect refs in dicts and name trees#56
Mythie merged 1 commit intomainfrom
issue/55

Conversation

@Mythie
Copy link
Contributor

@Mythie Mythie commented Mar 20, 2026

PdfDict.getArray(), getDict(), and get() return undefined when the
value is an indirect PdfRef and no resolver is provided. This caused
silent failures for PDFs that store /Fields, /Kids, /AP, /BS, /Opt,
/I, /Contents, and name-tree /Kids and /Names as indirect references.

Fixes 24 call sites across acro-form, field base, widget-annotation,
choice-fields, form-flattener, and name-tree. Also fixes a latent
listbox bug where stale /I entries weren't cleared on single-select
setValue().

Closes #55

PdfDict.getArray(), getDict(), and get() return undefined when the
value is an indirect PdfRef and no resolver is provided. This caused
silent failures for PDFs that store /Fields, /Kids, /AP, /BS, /Opt,
/I, /Contents, and name-tree /Kids and /Names as indirect references.

Fixes 24 call sites across acro-form, field base, widget-annotation,
choice-fields, form-flattener, and name-tree. Also fixes a latent
listbox bug where stale /I entries weren't cleared on single-select
setValue().

Closes #55
@vercel
Copy link
Contributor

vercel bot commented Mar 20, 2026

The latest updates on your projects. Learn more about Vercel for GitHub.

Project Deployment Actions Updated (UTC)
core Ready Ready Preview, Comment Mar 20, 2026 0:20am

@github-actions
Copy link
Contributor

Benchmark Results

Comparison

Load PDF

Benchmark Mean p99 RME Samples
libpdf 2.37ms 3.20ms ±1.2% 212
pdf-lib 41.06ms 51.07ms ±5.7% 13
@cantoo/pdf-lib 40.37ms 44.79ms ±2.8% 13

Create blank PDF

Benchmark Mean p99 RME Samples
libpdf 63μs 142μs ±1.8% 7998
pdf-lib 440μs 1.68ms ±2.7% 1137
@cantoo/pdf-lib 521μs 2.14ms ±3.3% 961

Add 10 pages

Benchmark Mean p99 RME Samples
libpdf 106μs 193μs ±1.8% 4721
pdf-lib 587μs 2.45ms ±3.5% 852
@cantoo/pdf-lib 524μs 2.77ms ±3.9% 955

Draw 50 rectangles

Benchmark Mean p99 RME Samples
libpdf 346μs 1.04ms ±2.0% 1444
pdf-lib 1.89ms 7.99ms ±8.0% 264
@cantoo/pdf-lib 2.14ms 6.07ms ±6.6% 234

Load and save PDF

Benchmark Mean p99 RME Samples
libpdf 2.44ms 3.60ms ±1.5% 205
pdf-lib 95.13ms 108.08ms ±5.1% 10
@cantoo/pdf-lib 161.06ms 170.63ms ±2.5% 10

Load, modify, and save PDF

Benchmark Mean p99 RME Samples
libpdf 47.54ms 61.49ms ±7.6% 11
pdf-lib 92.36ms 111.16ms ±7.4% 10
@cantoo/pdf-lib 161.62ms 172.28ms ±3.0% 10

Extract single page from 100-page PDF

Benchmark Mean p99 RME Samples
libpdf 4.18ms 6.42ms ±2.2% 120
pdf-lib 10.25ms 17.50ms ±4.7% 49
@cantoo/pdf-lib 11.06ms 15.08ms ±3.8% 46

Split 100-page PDF into single-page PDFs

Benchmark Mean p99 RME Samples
libpdf 36.24ms 43.43ms ±3.9% 14
pdf-lib 92.61ms 96.36ms ±3.1% 6
@cantoo/pdf-lib 102.95ms 111.29ms ±6.1% 5

Split 2000-page PDF into single-page PDFs (0.9MB)

Benchmark Mean p99 RME Samples
libpdf 662.68ms 662.68ms ±0.0% 1
pdf-lib 1.70s 1.70s ±0.0% 1
@cantoo/pdf-lib 1.81s 1.81s ±0.0% 1

Copy 10 pages between documents

Benchmark Mean p99 RME Samples
libpdf 5.12ms 6.14ms ±1.3% 98
pdf-lib 13.52ms 18.46ms ±3.1% 37
@cantoo/pdf-lib 14.91ms 17.70ms ±2.6% 34

Merge 2 x 100-page PDFs

Benchmark Mean p99 RME Samples
libpdf 16.78ms 19.61ms ±2.7% 30
pdf-lib 60.52ms 78.96ms ±9.6% 9
@cantoo/pdf-lib 68.14ms 77.31ms ±5.8% 8

Fill FINTRAC form fields

Benchmark Mean p99 RME Samples
libpdf 24.69ms 44.40ms ±9.8% 21
pdf-lib 34.95ms 40.36ms ±3.5% 15
@cantoo/pdf-lib 36.76ms 51.18ms ±7.4% 14

Fill and flatten FINTRAC form

Benchmark Mean p99 RME Samples
libpdf 19.29ms 25.29ms ±4.9% 26
pdf-lib FAILED - - 0
@cantoo/pdf-lib 39.37ms 45.73ms ±4.2% 13
Copying

Copy pages between documents

Benchmark Mean p99 RME Samples
copy 1 page 1.09ms 2.14ms ±2.6% 459
copy 10 pages from 100-page PDF 5.16ms 11.76ms ±3.1% 97
copy all 100 pages 8.26ms 8.96ms ±1.0% 61

Duplicate pages within same document

Benchmark Mean p99 RME Samples
duplicate page 0 976μs 1.79ms ±1.6% 513
duplicate all pages (double the document) 977μs 1.58ms ±1.0% 512

Merge PDFs

Benchmark Mean p99 RME Samples
merge 2 small PDFs 1.54ms 2.36ms ±1.3% 325
merge 10 small PDFs 8.78ms 10.56ms ±1.9% 58
merge 2 x 100-page PDFs 16.02ms 23.45ms ±4.1% 32
Drawing

benchmarks/drawing.bench.ts

Benchmark Mean p99 RME Samples
draw 100 rectangles 616μs 1.85ms ±2.9% 812
draw 100 circles 1.40ms 3.77ms ±3.7% 358
draw 100 lines 537μs 1.30ms ±2.0% 931
draw 100 text lines (standard font) 1.62ms 2.59ms ±1.7% 308
create 10 pages with mixed content 1.41ms 2.66ms ±2.3% 355
Forms

benchmarks/forms.bench.ts

Benchmark Mean p99 RME Samples
get form fields 3.61ms 8.55ms ±5.6% 139
fill text fields 12.84ms 18.26ms ±4.6% 39
read field values 3.05ms 4.81ms ±1.5% 164
flatten form 8.73ms 12.39ms ±2.5% 58
Loading

benchmarks/loading.bench.ts

Benchmark Mean p99 RME Samples
load small PDF (888B) 58μs 140μs ±0.8% 8561
load medium PDF (19KB) 91μs 131μs ±0.7% 5521
load form PDF (116KB) 1.42ms 2.60ms ±1.6% 353
load heavy PDF (9.9MB) 2.26ms 2.95ms ±0.9% 221
Saving

benchmarks/saving.bench.ts

Benchmark Mean p99 RME Samples
save unmodified (19KB) 109μs 249μs ±1.1% 4568
save with modifications (19KB) 793μs 1.43ms ±1.6% 631
incremental save (19KB) 182μs 445μs ±1.4% 2754
save heavy PDF (9.9MB) 2.28ms 2.94ms ±0.9% 219
incremental save heavy PDF (9.9MB) 7.20ms 15.86ms ±8.7% 70
Splitting

Extract single page

Benchmark Mean p99 RME Samples
extractPages (1 page from small PDF) 1.02ms 2.23ms ±2.6% 493
extractPages (1 page from 100-page PDF) 3.73ms 6.78ms ±2.5% 135
extractPages (1 page from 2000-page PDF) 57.88ms 58.71ms ±1.0% 10

Split into single-page PDFs

Benchmark Mean p99 RME Samples
split 100-page PDF (0.1MB) 32.47ms 35.20ms ±2.3% 16
split 2000-page PDF (0.9MB) 599.66ms 599.66ms ±0.0% 1

Batch page extraction

Benchmark Mean p99 RME Samples
extract first 10 pages from 2000-page PDF 61.00ms 62.56ms ±1.0% 9
extract first 100 pages from 2000-page PDF 64.22ms 65.97ms ±1.6% 8
extract every 10th page from 2000-page PDF (200 pages) 69.00ms 69.87ms ±1.6% 8
Environment
  • Runner: Linux (X64)
  • Runtime: Bun 1.3.11

Results are machine-dependent.

@Mythie Mythie merged commit a7b42d4 into main Mar 21, 2026
6 checks passed
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.

Bug: Missing resolver when reading indirect /Fields and /Contents references

1 participant