blobforge

Adversarial fixtures

break your xml parser

13 XML documents engineered to fail. Entity expansion, external entity probes, undeclared namespace prefixes, duplicate attributes, CDATA that terminates itself, and control characters XML 1.0 forbids outright — each with the correct behaviour documented next to it.

Built in your browser. Nothing is uploaded, and no signup is required.

0Passed
0Failed
13Untested

BOM before the XML declaration

encoding-bom-and-declaration.xml

What this tests

A UTF-8 BOM sits before `<?xml version="1.0"?>`.

What a correct parser should do

Strip the BOM and parse normally — a BOM before the declaration is explicitly legal in XML. Parsers that match on the literal bytes `<?xml` at offset 0 report 'content is not allowed in prolog', which is one of the most misleading error messages in the ecosystem because the content it objects to is invisible.

Bytes · 79 B
00000000EFBBBF3C3F786D6C2076657273696F6E...<?xml version
000000103D22312E302220656E636F64696E673D="1.0" encoding=
00000020225554462D38223F3E0A3C726F6F743E"UTF-8"?>.<root>
000000303C6974656D2069643D2231223E416461<item id="1">Ada
000000403C2F6974656D3E3C2F726F6F743E0A</item></root>.
Hover a byte to see why it matters.
  • Byte order mark
  • Line feed
  • Double quote

How to use these fixtures

  1. Download a single file, or take all 13 as a ZIP — the archive includes a README explaining every file.
  2. Run each one through your own XML import path.
  3. Come back and record whether your parser handled it. Results are kept in your browser, so leaving the page is expected.
  4. Copy the damage report as Markdown and paste it into a pull request or an issue.

Why XML parsers fail

XML is rigorously specified, which makes its failure modes the opposite of CSV's. The spec is clear; the bugs come from parsers being too accommodating. Entity expansion and external entity resolution are both conformant features, enabled by default in several widely used parsers, and wanted by almost no application.

The rest are the cases where a tolerant parser silently restructures your document. XML has no error recovery by design — unlike HTML, where leniency is correct. A parser that repairs a mismatched tag or picks a winner from duplicate attributes is inventing your data for you, and it does so without raising anything.

Questions

Why do the entity fixtures matter?
Entity expansion and external entity resolution are both conformant XML features that almost no application actually wants enabled. If your parser resolves them, any XML upload becomes a denial-of-service vector or a file-disclosure vector. Checking that they are disabled is the standard hardening step for every XML parser, and these two fixtures are how you check.
Will the entity expansion fixture hang my machine?
No. The classic billion-laughs file uses nine levels of nesting and expands to billions of nodes. This one uses four levels and expands to roughly ten thousand, which demonstrates the behaviour without being a real denial of service against the machine you are testing from. If your parser expands this one, the full-size version would take your service down.
Does the external entity fixture read a real file?
No. The canonical version of that test points at /etc/passwd. This one points at a path that does not exist, which proves the same thing — if your parser attempts resolution at all, the error it raises will name that path — without the fixture reading anything sensitive.
Are these files dangerous?
No. They are inert test files for checking your own import pipeline. Nothing here executes on its own — the fixtures that model injection or traversal exist so you can verify your own code rejects them, and the resource-exhaustion ones are deliberately scaled down so they demonstrate the behaviour without taking down the machine you are testing from.
Why does the page show raw bytes?
Because most of these cases are invisible in a text preview. A byte order mark renders as nothing, a bare carriage return looks identical to a CRLF, and a NUL looks like the end of the string. The hex view highlights exactly which bytes matter and explains each one when you hover it.
Does my pass/fail progress get saved?
Yes, in your own browser only, and separately for each format. The workflow expects you to leave the page, run a fixture through your parser, and come back — so results persist locally. Nothing is uploaded, and clearing site data clears them.
Is this free?
Yes. Every fixture is generated in your browser, with no signup and no upload.