Repository navigation
v0.4.1 — a 219-byte denial of service
Repairing a damaged file means listing its objects in order, and that was done by counting from nought to the highest object number and asking the cross-reference table about each one.
A file may name any object number it likes. mozilla/pdf.js's bug1980958.pdf is 219 bytes and declares object 2147483647 beside its three real ones. Counting up to that is two thousand million map lookups, done twice, for three objects.
| before | 219 bytes in, Open took 25.39s |
| after | 219 bytes in, Open took 0s |
No allocation either way — it was a loop, not a memory bomb, which is why nothing caught it. Any file a reader opens could do this.
The numbers that exist are collected, sorted and walked, which is what the order was wanted for in the first place.
Found by battle-testing go-pdfkit/forms against 1 046 files — 69 public forms plus the whole of mozilla/pdf.js's test corpus, which is adversarial by construction. 1 029 opened, 14 580 fields read and filled, no panics, and this one file took 12.87 of the run's 13.1 seconds.
100% statement coverage, go vet clean.