You need a 25 MB PDF to test an upload limit. Or a 105-page DOCX for pagination. Or a 1 GB binary to benchmark throughput.
The obvious answer is dd if=/dev/urandom of=test.pdf bs=1M count=25. You get exactly 25 MB. You also get a file that any format-sniffing validator rejects instantly, because it isn't a PDF — it's noise wearing a .pdf extension.
So you need real headers and an exact byte count. Those two requirements fight each other, and every format loses the fight differently.
A minimal PDF is a graph of objects and a cross-reference table of byte offsets. My first version emitted a content stream like this:
Browser viewers rendered it fine. Acrobat rejected it, and so did pypdf. A strict reader trusts /Length, reads 44 bytes, sails past endstream, and hits a parse error.
The second bug in the same object: /Resources > was empty while the content stream referenced /F1. A page that draws text with an undeclared font is invalid, even though lenient viewers substitute one silently.
The fix is to compute everything from the assembled bytes — stream lengths and xref offsets — rather than predicting them. Accumulate offsets as you append each object:
Padding then goes after %%EOF. That's the one region a conforming reader is required to ignore, which is what makes an exact byte count possible without corrupting the document.
An Office file is a ZIP containing word/document.xml. To hit a target size I padded the XML — by appending filler after the closing tag.
Which is the worst possible failure mode, because the entire audience for generated Office files is automated pipelines that parse them. A fixture that only opens in Word is useless to CI.
The fix is to put the padding somewhere the XML spec permits — inside a comment, before the closing tag:
PNG is a chunk stream. Padding goes in a tEXt ancillary chunk inserted before IEND, with a correct CRC-32. Decoders skip unknown ancillary chunks, so the image still decodes.
JPEG uses FFFE COM markers, each holding up to 65,533 bytes, chained for larger targets. Placement matters: put them immediately after SOI, not near EOI. Padding near the end decodes unreliably across libraries — I never fully root-caused why, and moving it made the problem disappear.
Ask for a 20-byte JSON file and there is no correct answer. The smallest valid JSON document with any structure is larger than that.
My generator quietly fell back to emitting whitespace — which produced a file of exactly the right size that failed JSON.parse(). Silent, and much worse than an error.
Below those, round up and tell the user. Don't emit something that satisfies the size check and violates the format.
PPTX needs presentation.xml, presProps.xml, a slide master, a slide layout, and a theme — and the master and layout reference each other. Get it slightly wrong and PowerPoint shows a repair prompt, which fails the whole "produces valid files" promise.
I stopped trying. Instead I ship a known-good minimal deck as a static asset, fetch it at runtime, clone its blank slide N times, and patch three files: [Content_Types].xml, presentation.xml.rels, and presentation.xml.
