Edge-Case Test Files — Corrupt, Truncated, Empty and Mislabelled
21 files · direct links · no ads · free for any use
The rest of this library answers "give me a valid PNG". This page answers the harder question: what does your code do with a file that is truncated, empty, misnamed, lying about its type, or carrying data it should not? Those are the uploads that reach production, and they are tedious enough to construct by hand that most test suites simply never try them.
Every file here is safe. There are no zip bombs, no path-traversal entries, no executables and no malware test strings; the largest archive expands to under a megabyte. The failure modes are genuine, the payloads are not dangerous, and each file's SHA-256 is published so you can pin it as a fixture.
.jpg tells you whether an image upload can become stored cross-site scripting on your domain. The CSV with formula payloads tells you whether your exports arrive in a colleague's spreadsheet as live formulas. Those two find real bugs most often.Empty and near-empty files
A zero-byte upload is the single most common thing to forget. Validators that check a maximum size often forget the minimum, and code that reads the first byte before checking the length crashes here rather than returning a clean error.
| File | What it tests | Size | Get it |
|---|---|---|---|
zero-byte.txt | Completely empty. Tests minimum-size validation, division by length, and code that reads a first byte before checking there is one. | 0 B | Download |
one-byte.txt | A single character. Too small to contain a valid header in any format, so type sniffing must fail gracefully. | 1 B | Download |
empty-archive.zip | A structurally valid ZIP with no entries at all. Extraction should succeed and produce nothing, not throw. | 22 B | Download |
Truncated and corrupt files
These have a valid header and incomplete or damaged data, which is what an interrupted upload actually looks like. Code that trusts the header and streams the rest will fail here, and where it fails tells you whether your error handling is where you think it is.
| File | What it tests | Size | Get it |
|---|---|---|---|
truncated.png | Valid PNG signature and IHDR, cut off in the middle of the image data. Decoders raise an error here rather than returning a partial image. | 4 KB | Download |
corrupt-crc.png | Full length and correct structure, but a byte inside the image data was flipped and the stored CRC no longer matches. Strict decoders reject it; lenient ones return wrong pixels. | 9 KB | Download |
truncated.jpg | A JPEG cut off at 60 percent, with no end-of-image marker. Many decoders return a partially decoded image rather than failing, which is worth knowing about yours. | 603 B | Download |
truncated.zip | The central directory is cut off, which is what a half-finished upload of an archive looks like. This is the most common real-world corrupt ZIP. | 3 KB | Download |
malformed.json | A trailing comma, an unquoted key and an unclosed brace. Tests that your parser reports a useful position rather than a generic failure. | 136 B | Download |
Files that lie about their type
The extension says one thing, the bytes say another. If your upload handler trusts the extension or the browser-supplied Content-Type, these get through. The HTML file named .jpg is the one that matters: served back with an image content type it is harmless, served as HTML from your domain it is stored cross-site scripting.
| File | What it tests | Size | Get it |
|---|---|---|---|
actually-a-png.jpg | A genuine PNG with a .jpg extension. Anything that dispatches on extension will hand this to the wrong decoder. | 9 KB | Download |
actually-html.jpg | An HTML document with a .jpg extension. If your application stores this and serves it back with a guessed content type, you have stored cross-site scripting. | 335 B | Download |
Metadata and privacy
A photograph straight from a phone carries where it was taken and which way up it is. Strip the first or you leak your users' locations; ignore the second and every portrait appears sideways. This file carries both, so you can verify your pipeline handles each.
| File | What it tests | Size | Get it |
|---|---|---|---|
exif-gps-orientation.jpg | Carries GPS coordinates (the CN Tower, Toronto) and Orientation 6, meaning rotate 90 degrees clockwise to display upright. Use it to verify both that you strip location data and that you honour rotation. | 1 KB | Download |
Text, encoding and line endings
A byte-order mark that becomes a visible character in the first column, quoted fields containing commas and literal newlines, three different line terminators in one file, and no terminator at the end. Every one of these is ordinary in files real users send you.
| File | What it tests | Size | Get it |
|---|---|---|---|
bom-crlf-quoted.csv | A UTF-8 byte-order mark, CRLF terminators, quoted fields containing commas, escaped double quotes, a literal newline inside a field and non-ASCII names. If the BOM shows up in your first column header, that is the bug. | 180 B | Download |
unicode-torture.txt | Combining marks, a zero-width space, a right-to-left override, astral-plane characters and a six-codepoint flag emoji. Tests length counting, truncation and normalisation. | 565 B | Download |
mixed-line-endings.txt | LF, CRLF and a bare CR in one file, with no terminator on the last line. Line-counting code frequently disagrees with itself here. | 107 B | Download |
no-trailing-newline.txt | Ends without a newline. Appending to this file without checking produces two records joined into one. | 48 B | Download |
Difficult filenames
The name, not the contents, is the test. Long names overflow database columns and filesystem limits; non-ASCII names break Content-Disposition headers, URL escaping and the difference between composed and decomposed Unicode on macOS.
| File | What it tests | Size | Get it |
|---|---|---|---|
文件名-with spaces-🌲.txt | Chinese characters, spaces and an emoji in the filename. Tests Content-Disposition encoding, URL escaping and macOS decomposed-Unicode normalisation. | 194 B | Download |
Structural and resource limits
Valid files that are awkward rather than broken: an archive with ten thousand entries, JSON nested deeper than most parsers allow by default, and an encrypted archive. None of these is an attack — they are the shapes that make a naive implementation run out of something.
| File | What it tests | Size | Get it |
|---|---|---|---|
many-entries-10000.zip | Ten thousand small entries, under 1 MB uncompressed in total. Tests central-directory parsing and per-entry overhead. Deliberately not a zip bomb. | 1.6 MB | Download |
deeply-nested.json | 512 levels of nesting. Valid JSON, but deeper than many parsers permit by default, and deep enough to exhaust a recursive parser's stack. | 3 KB | Download |
encrypted-password-test.zip | Encrypted with ZipCrypto; the password is test. Extraction without a password must fail cleanly rather than producing garbage. | 292 B | Download |
Spreadsheet formula injection
A CSV cell beginning with =, +, - or @ is interpreted as a formula when the file is opened in Excel, Google Sheets or LibreOffice. If your application exports user-supplied text to CSV without escaping those prefixes, you are shipping their input as executable formulas. The payloads here compute harmless arithmetic.
| File | What it tests | Size | Get it |
|---|---|---|---|
formula-injection.csv | Cells beginning with =, +, - and @, which spreadsheet applications treat as formulas. The payloads compute harmless arithmetic and one builds a link to this site. Nothing runs a command. | 189 B | Download |
A short checklist for upload handling
- Check a minimum size as well as a maximum. Zero-byte uploads are the most commonly missed case.
- Determine the type from the bytes, never from the extension or the browser-supplied content type. Both are attacker-controlled.
- Serve user uploads from a separate domain, or with
Content-Disposition: attachmentandX-Content-Type-Options: nosniff, so a file that turns out to be HTML cannot execute in your origin. - Strip EXIF before publishing an image, and apply the orientation tag before you strip it.
- Escape leading
=,+,-and@when writing user text into CSV. - Set explicit limits on archive entry counts, total uncompressed size and parser recursion depth, and return a clear error when one is hit.
- Decide what a partially uploaded file should do, then test it with the truncated files here rather than assuming.
Frequently asked questions
Are these files dangerous?
No. There are no zip bombs, no path-traversal entries, no executables, no macros and no malware test strings. The largest file expands to under one megabyte. The failure modes are real — a truncated image really is truncated — but nothing here attacks the machine that opens it. The spreadsheet formula payloads compute harmless arithmetic rather than running a command.
What is the HTML file with a .jpg extension for?
It is the single most valuable file in the pack. If your application accepts it as an image, stores it, and later serves it back with a content type guessed from the contents, a browser renders it as a page on your domain. That is stored cross-site scripting delivered through an image upload. Accepting the file is fine; serving it back as HTML is not.
Why does the CSV have cells starting with an equals sign?
Because Excel, Google Sheets and LibreOffice interpret a cell beginning with =, +, - or @ as a formula. If your application exports user-supplied text to CSV without escaping those prefixes, whatever a user typed into a form arrives in a colleague's spreadsheet as a live formula. The fix is to prefix such cells with an apostrophe or wrap them in quotes on export.
Does the photo really contain GPS coordinates?
Yes — the CN Tower in Toronto, at 43.6426 north and 79.3871 west, plus an altitude. It also carries Orientation 6, meaning a viewer should rotate it 90 degrees clockwise to display it upright. Between them these cover the two things every image pipeline needs to get right: strip location data before publishing, and honour rotation so portraits are not sideways.
Can I use these in an automated test suite?
Yes, that is what they are for. Every file is deterministic, its SHA-256 is published here, and the direct links carry long cache lifetimes and open CORS headers. Pin the hash in your test and you will know immediately if a fixture ever changes.
Found a problem, or something that could be better? We read every message and we fix things quickly.
Need valid files instead?
Most testing needs a file that works. We publish those too — real images, video, audio, documents, archives, data and fonts, in exact sizes with published hashes.