blobforge

Adversarial fixtures

break your yaml parser

13 YAML documents engineered to fail. The Norway problem, colons read as base-60, leading zeros read as octal, anchor expansion, tabs in indentation, and six different spellings of null — each with the correct behaviour documented next to it.

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

0Passed
0Failed
13Untested

The Norway problem

coercion-norway-problem.yaml

What this tests

Unquoted country codes and answers: NO, ON, OFF, YES, Y, N, TRUE.

What a correct parser should do

These should be strings. Under YAML 1.1 — which PyYAML and many others still default to — `NO` resolves to the boolean false, so the country code for Norway silently becomes false in a list of country codes. YAML 1.2 narrowed the boolean set to true/false only, which is why the same file behaves differently across libraries.

Bytes · 131 B
00000000636F756E74726965733A0A20202D204Ecountries:. - N
000000104F0A20202D2053450A20202D20444B0AO. - SE. - DK.
00000020616E73776572733A0A20207965735F76answers:. yes_v
00000030616C75653A205945530A20206E6F5F76alue: YES. no_v
00000040616C75653A204E4F0A20206F6E5F7661alue: NO. on_va
000000506C75653A204F4E0A20206F66665F7661lue: ON. off_va
000000606C75653A204F46460A2020795F76616Clue: OFF. y_val
0000007075653A20590A20206E5F76616C75653Aue: Y. n_value:
00000080204E0A N.
Hover a byte to see why it matters.
  • Line feed

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 YAML 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 YAML parsers fail

YAML's failure modes are almost the opposite of JSON's. The syntax rarely breaks; the types do. YAML 1.1 resolves unquoted scalars implicitly, so NO becomes the boolean false, 22:22 becomes the integer 1342, and 0755 becomes 493. YAML 1.2 changed all three, and most libraries still default to 1.1 — so the spec version your parser implements silently changes your data.

That is what makes these dangerous rather than annoying. Almost nothing here raises an error. The file loads, the config looks right, and a port number is a string or a country code is a boolean. The fixtures that do fail loudly — tabs in indentation, invalid UTF-8 — are the easy ones.

Questions

What is the Norway problem?
Under YAML 1.1, the unquoted scalar NO resolves to the boolean false — so in a list of ISO country codes, Norway silently becomes false. YES, ON, OFF, Y and N behave the same way. YAML 1.2 narrowed booleans to true and false only, but many widely used libraries still default to 1.1, which is why the same file behaves differently depending on what is reading it.
Most of these parse without errors — is that not the point of a test file?
That is exactly the point. YAML's syntax rarely breaks; its implicit typing does. Almost every fixture here loads successfully and produces a value that is simply not what was written. A parser that raises an error is the good case — the dangerous one is the config that loads cleanly with a port number that became a string, or a country code that became false.
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.