
UTF-8 Text (LF)
A UTF-8 text file with Unix (LF) line endings and no byte-order mark, containing accented and symbol characters — for testing charset detection.
- File
- TXT · Text Encodings · UTF-8 (no BOM)
- Use case
- Encoding detection
UTF-8, UTF-8-BOM, UTF-16, and Latin-1 files with documented encodings and line endings for testing charset detection.

A UTF-8 text file with Unix (LF) line endings and no byte-order mark, containing accented and symbol characters — for testing charset detection.

A UTF-8 text file that starts with a byte-order mark (EF BB BF) and uses Windows (CRLF) line endings — for testing BOM handling and line-ending detection.

A UTF-16 little-endian text file with a BOM (FF FE) and CRLF line endings — for testing wide-character decoding and encoding detection.

A UTF-16 big-endian text file with a BOM (FE FF) and CRLF line endings — for testing wide-character decoding and byte-order detection.

A UTF-32 little-endian text file with a BOM (FF FE 00 00) — four bytes per code point, for testing full-width Unicode decoders and byte-order handling.

A single-byte Latin-1 (ISO-8859-1) text file using high-range accented characters — for testing legacy 8-bit charset detection and transcoding to UTF-8.

A Windows-1252 text file using the 0x80–0x9F range (smart quotes, em dash, euro, bullet) that naive Latin-1 decoders get wrong — for testing codepage detection and transcoding.

A Shift-JIS encoded Japanese text file — a multi-byte East-Asian encoding, for testing CJK charset detection and Shift-JIS→UTF-8 conversion.

A UTF-8 text file that deliberately mixes LF, CRLF, and lone-CR line endings within one file — for testing newline normalisation and line-counting logic.

A UTF-8 file mixing left-to-right and right-to-left scripts (Arabic and Hebrew alongside English) — for testing bidirectional text handling, reordering, and rendering.

A UTF-8 file of emoji including zero-width-joiner sequences, regional-indicator flag pairs, and skin-tone modifiers — multi-code-point grapheme clusters for testing grapheme segmentation and display-width calculation.

A UTF-8 file with the same words in both NFC (precomposed) and NFD (decomposed combining marks) normalisation forms — for testing normalisation-aware comparison, search, and dedup.

A UTF-8 file consisting of a single very long line (~18,000 characters with no interior newline) — for testing editors, buffers, and line-oriented parsers against long-line handling.

CommonMark-leaning Markdown twin for “tasklist” — compare against the GFM variant.

CommonMark-leaning Markdown twin for “table” — compare against the GFM variant.

CommonMark-leaning Markdown twin for “strikethrough” — compare against the GFM variant.

CommonMark-leaning Markdown twin for “autolink” — compare against the GFM variant.

CommonMark-leaning Markdown twin for “fenced-lang” — compare against the GFM variant.

CommonMark-leaning Markdown twin for “emoji-ish” — compare against the GFM variant.

SAMPLE LaTeX article “On Sampling Rates” with abstract, equation, and \cite to a twin .bib.

SAMPLE LaTeX article “Notes on Information Entropy” with abstract, equation, and \cite to a twin .bib.

SAMPLE LaTeX article “Digital Filters Primer” with abstract, equation, and \cite to a twin .bib.

Short synthetic HL7 v2 ADT-A03 message — fictional SAMPLE demographics for parser tests.

Short synthetic HL7 v2 ORM-O01 message — fictional SAMPLE demographics for parser tests.

Short synthetic HL7 v2 ORU-R01 message — fictional SAMPLE demographics for parser tests.

Short synthetic HL7 v2 SIU-S12 message — fictional SAMPLE demographics for parser tests.

Short ANSI X12 855 SAMPLE transaction for EDI parser / translator tests.

Short ANSI X12 856 SAMPLE transaction for EDI parser / translator tests.

Short ANSI X12 997 SAMPLE transaction for EDI parser / translator tests.

Short ANSI X12 940 SAMPLE transaction for EDI parser / translator tests.

Short ANSI X12 204 SAMPLE transaction for EDI parser / translator tests.

Short ANSI X12 214 SAMPLE transaction for EDI parser / translator tests.

A CSV encoded in Latin-1 (ISO-8859-1) with accented names — for testing encoding detection and mis-decoding (it will look wrong if read as UTF-8).

A CSV prefixed with a UTF-8 BOM (EF BB BF) and accented / CJK cells — for testing BOM-aware importers.

The same three data rows as UTF-16 little-endian with a BOM — wide-character CSV decoding fixture.

UTF-16 big-endian CSV with BOM — for byte-order detection in tabular importers.

A CP1252 CSV using the 0x80–0x9F range (smart quotes, euro, bullet) that Latin-1 misreads.

A Shift-JIS encoded Japanese CSV — for CJK charset detection and Shift-JIS→UTF-8 conversion in importers.

A classic fixed-width text extract with documented column positions — for COBOL-style / mainframe importer tests.

A CSV that mixes CRLF and LF row endings within one file — newline normalisation fixture.

A Latin-1 CSV with high-bit accented characters — for legacy 8-bit charset detection.

Member names stored as UTF-8 with general-purpose bit 11 (the language-encoding flag) set, which is the modern, unambiguous way to carry a non-ASCII filename in a ZIP. Its CP437 twin encodes the same archive the legacy way, so a reader's encoding heuristic can be compared against a case where the answer is declared.

The legacy twin: names encoded in IBM CP437 with the language-encoding flag clear, which is what the ZIP spec says an un-flagged name means. Decoding these bytes as UTF-8 produces mojibake or an outright decode error, which is exactly the bug this file is for.

The third way a ZIP carries a non-ASCII name: an ASCII-safe name in the header plus an Info-ZIP Unicode Path extra field (0x7075) holding the real UTF-8 name and a CRC32 of the header name. A reader must prefer the extra field, but only while that CRC still matches the header name it was computed from.

PAX is the only tar variant that says what encoding its names are in: extended-header records are UTF-8 by definition. These three members carry accented Spanish and Japanese path components, so a reader that applies a locale-dependent guess instead of trusting the format produces mojibake on exactly this file.

A plain-text multi-chapter SAMPLE extract — for ebook converters that accept .txt sources.

A package document whose title and creator carry precomposed accents, a combining ring above a bare letter, and a typographic apostrophe. For testing normalisation, sorting and filename derivation - the combining mark is the one that breaks naive length and comparison code.

Every non-ASCII character in the metadata is written as a hexadecimal numeric character reference, so the package document is pure ASCII on disk while the title is Han and Cyrillic once parsed. For testing tools that read metadata with a regex instead of an XML parser.

The package document is encoded as UTF-16 little-endian with a byte order mark while the content documents stay UTF-8 - a combination EPUB permits and almost nothing tests. For finding the parser that opens the OPF as UTF-8 and sees a file full of null bytes.

A title containing two characters above the Basic Multilingual Plane - a blue book and a musical clef - plus a Japanese description. Anything that counts characters as UTF-16 code units, or truncates a title to a byte length, splits a surrogate pair here.

The package document, the navigation document and the chapter each begin with a UTF-8 byte order mark before the XML declaration. Legal, and the classic reason a strict parser reports content before the prolog on a file that looks perfectly fine in an editor.

A Cyrillic FictionBook stored in windows-1251 and declaring that encoding in its XML declaration - the single-byte legacy encoding a large share of real FB2 files still use. For testing importers that assume every XML file is UTF-8 and produce mojibake instead of an error.

An email whose Subject uses RFC 2047 UTF-8 encoded-words (café / crème) — for header decoding tests.

An attachment whose filename uses RFC 2231 UTF-8 encoding (résumé) — for MIME filename decoders.

A quoted-printable text/plain message in utf-8 whose body carries accented French text, guillemets, an em dash and a euro sign. It is the exact twin of the base64 message beside it: both decode to the same 247 octets, so a decoder can be diffed against a known-equal pair.

A base64 text/plain message in utf-8 carrying the identical body to the quoted-printable twin beside it. Base64 is opaque to whitespace and line-start characters, so it is the reference side of the pair when a QP decoder is suspect.

A quoted-printable text/plain message in utf-8 whose body ends lines with spaces and tabs that quoted-printable must encode as =20 and =09. It is the exact twin of the base64 message beside it: both decode to the same 193 octets, so a decoder can be diffed against a known-equal pair.

A base64 text/plain message in utf-8 carrying the identical body to the quoted-printable twin beside it. Base64 is opaque to whitespace and line-start characters, so it is the reference side of the pair when a QP decoder is suspect.

A quoted-printable text/plain message in utf-8 whose body holds a single line far past 76 columns, forcing quoted-printable soft breaks. It is the exact twin of the base64 message beside it: both decode to the same 451 octets, so a decoder can be diffed against a known-equal pair.

A base64 text/plain message in utf-8 carrying the identical body to the quoted-printable twin beside it. Base64 is opaque to whitespace and line-start characters, so it is the reference side of the pair when a QP decoder is suspect.

A quoted-printable text/plain message in iso-8859-1 whose body is single-byte ISO-8859-1 rather than UTF-8, so each umlaut is one octet. It is the exact twin of the base64 message beside it: both decode to the same 176 octets, so a decoder can be diffed against a known-equal pair.

A base64 text/plain message in iso-8859-1 carrying the identical body to the quoted-printable twin beside it. Base64 is opaque to whitespace and line-start characters, so it is the reference side of the pair when a QP decoder is suspect.

A quoted-printable text/plain message in utf-8 whose body starts a line with "From " and holds a lone "." line, which quoted-printable escapes as =46rom and =2E. It is the exact twin of the base64 message beside it: both decode to the same 219 octets, so a decoder can be diffed against a known-equal pair.

A base64 text/plain message in utf-8 carrying the identical body to the quoted-printable twin beside it. Base64 is opaque to whitespace and line-start characters, so it is the reference side of the pair when a QP decoder is suspect.

A Subject header carrying accented Latin text and an emoji as a single UTF-8 base64 encoded-word. Its Q-encoded twin decodes to the identical string, so the two together isolate the encoding from the charset.

The same Subject as the UTF-8 'B' twin, written with 'Q' encoding instead: underscores stand for spaces and every non-token octet is an =XX escape. A decoder that forgets the underscore rule produces visibly different text from its twin.

A German Subject encoded as ISO-8859-1 'Q', the shape most legacy mail actually uses. Each umlaut is one =XX escape, so a decoder that assumes UTF-8 produces mojibake rather than a clean error.

The ISO-8859-1 Subject again, base64-encoded instead of Q-encoded. Base64 hides the charset entirely, so this is the fixture that catches a decoder guessing the charset from the octets instead of reading the encoded-word's charset token.

A Japanese Subject as a Shift_JIS base64 encoded-word. Shift_JIS second bytes overlap ASCII punctuation values, so a decoder that scans the decoded octets for delimiters before converting the charset splits the string in the wrong place.

A Russian Subject as a KOI8-R base64 encoded-word. KOI8-R orders Cyrillic letters by Latin transliteration rather than alphabetically, so a decoder that substitutes any other Cyrillic codepage returns readable-looking but wrong text.

A single Subject built from three encoded-words in three charsets and two encodings. RFC 2047 allows this, and it is what happens when a subject is quoted through several mail systems, so each word has to be decoded on its own terms.

A Subject split mid-word across two adjacent encoded-words. RFC 2047 requires the linear whitespace between them to be discarded, so the correct result is one word; a decoder that keeps the space renders a split that reads as a typo.

A Subject folded across four physical lines, one encoded-word per line, which is the shape RFC 2047 prescribes for long international headers. Because the fold whitespace is discarded on decode, each continuation word carries its own leading space inside the encoded-word — omit that and the subject decodes run-together.

One unbroken encoded-word of 148 characters, well past the 75-character ceiling RFC 2047 sets. Real senders emit these, and a decoder should still recover the whole word rather than truncating it at 75 or rejecting the header.

Encoded-words used everywhere they turn up in practice: both display names, the Subject, and — against the spec but very common — inside the quoted filename parameter, where RFC 2231 is the conformant mechanism. A tolerant parser decodes all four.

The conformant answer to non-ASCII filenames: a filename split into three numbered RFC 2231 segments with a charset and a language tag, plus size and creation-date parameters. Parsers commonly handle filename*= but not the numbered continuation form.

One mailbox whose four messages each use a different charset and alternate between quoted-printable and base64, with RFC 2047 subjects to match. The file itself is LF-stored while the encoded payloads decode to CRLF text — the split every importer has to handle.

A French (fr) gettext PO catalog with seven UI strings — for i18n toolchain tests.

A German (de) gettext PO catalog with seven UI strings — for i18n toolchain tests.

A Portuguese (Brazil) (pt-BR) gettext PO catalog with seven UI strings — for i18n toolchain tests.

A Korean (ko) gettext PO catalog with seven UI strings — for i18n toolchain tests.

Mozilla Fluent SAMPLE catalog (English) with placeholders and plural select — for Fluent parsers and CAT tools.

Mozilla Fluent SAMPLE catalog (Spanish) with placeholders and plural select — for Fluent parsers and CAT tools.

Mozilla Fluent SAMPLE catalog (French) with placeholders and plural select — for Fluent parsers and CAT tools.

Mozilla Fluent SAMPLE catalog (Arabic RTL) with placeholders and plural select — for Fluent parsers and CAT tools.

Mozilla Fluent SAMPLE catalog (Hebrew RTL) with placeholders and plural select — for Fluent parsers and CAT tools.

Mozilla Fluent SAMPLE catalog (English US) with placeholders and plural select — for Fluent parsers and CAT tools.

ICU MessageFormat SAMPLE JSON (English) with plural/select patterns for i18n runtimes.

ICU MessageFormat SAMPLE JSON (Spanish) with plural/select patterns for i18n runtimes.

ICU MessageFormat SAMPLE JSON (French) with plural/select patterns for i18n runtimes.

ICU MessageFormat SAMPLE JSON (Arabic) with plural/select patterns for i18n runtimes.

ICU MessageFormat SAMPLE JSON (Hebrew) with plural/select patterns for i18n runtimes.

ICU MessageFormat SAMPLE JSON (German) with plural/select patterns for i18n runtimes.

ICU MessageFormat SAMPLE JSON (Japanese) with plural/select patterns for i18n runtimes.

ICU MessageFormat SAMPLE JSON (Chinese) with plural/select patterns for i18n runtimes.

English ICU plural and selectordinal SAMPLE catalogue for plural-rule engines.

Arabic RTL ICU plural SAMPLE covering zero/one/two/few/many/other categories.

ICU select SAMPLE for gender/status branching in message formatters.

Hebrew RTL ICU select SAMPLE for bidirectional UI string pipelines.

Arabic RTL UI string pack SAMPLE for bidirectional layout and font-fallback tests.

Hebrew RTL UI string pack SAMPLE for bidirectional layout and font-fallback tests.

Arabic Egypt RTL UI string pack SAMPLE for bidirectional layout and font-fallback tests.

Hebrew Israel RTL UI string pack SAMPLE for bidirectional layout and font-fallback tests.

Persian RTL UI string pack SAMPLE for bidirectional layout and font-fallback tests.

Urdu RTL UI string pack SAMPLE for bidirectional layout and font-fallback tests.

Crowdin-shaped SAMPLE bilingual export JSON for localization TMS importers.

Crowdin-shaped SAMPLE French bilingual export for TMS round-trip tests.

Bilingual EN→ES CSV SAMPLE for spreadsheet-based localization workflows.

Bilingual EN→AR RTL CSV SAMPLE for spreadsheet CAT and RTL review tools.

Four-locale multilingual CSV SAMPLE for bulk translation import tests.

Pseudolocalization SAMPLE (bracket-wrapped) for i18n layout overflow testing.

A English Java ResourceBundle with MessageFormat patterns, a ChoiceFormat plural, positional arguments, escaped braces and apostrophes, a backslash line continuation, and non-ASCII carried as \uXXXX escapes because .properties is defined as ISO-8859-1. The bytes on disk are pure ASCII.

A German Java ResourceBundle with MessageFormat patterns, a ChoiceFormat plural, positional arguments, escaped braces and apostrophes, a backslash line continuation, and non-ASCII carried as \uXXXX escapes because .properties is defined as ISO-8859-1. The bytes on disk are pure ASCII.

The encoding fixture the .strings format needs: a Japanese catalog written as UTF-16 Little Endian with a byte-order mark, which is what Xcode has historically produced and what a UTF-8-only reader turns into mojibake or a decode error. Also carries full-width punctuation and an ideographic space for width and line-breaking tests.

A reference sheet in which each of the ten shipped bidi control characters appears literally between ASCII guards, with its code point, UTF-8 bytes and the job it does. The two override characters are named but deliberately absent: a bidi rendering fixture does not need to ship the Trojan Source vector.

Six Arabic sentences containing a Latin filename, a phone number, a version range, a mixed-script path, a percentage and a bracketed insertion — each shown first as a translator usually delivers it and then with the one invisible character that makes it render correctly. The two forms differ by exactly one code point.

Mirroring is a rendering property of the bidi algorithm, not a transformation of the text: a U+0028 LEFT PARENTHESIS inside an RTL run is DRAWN as ')' while the stored byte never changes. These Hebrew and Arabic lines make that testable, and list the neutral characters that look like they should mirror but do not.

The same number, 1234567.89, rendered for twelve locales, with the group and decimal separator that produced each one named by code point and present literally in the cell. Four of the separators are not ASCII — U+00A0, U+202F, U+2019 and U+066C — and ar-EG additionally switches the digits themselves.

The structured twin of the number-format table, plus four documented traps: es-ES's minimumGroupingDigits=2 (which leaves a four-digit integer ungrouped), the four non-ASCII group separators, the arab numbering system's own digits, and the seven locales here whose decimal separator is a comma.

12345.60 in each locale's own currency, with the fraction-digit count and the symbol placement that produced it. JPY takes zero decimals and rounds; six rows separate the amount from the symbol with U+00A0 rather than a plain space; and ar-EG puts the amount in Arabic-Indic digits.

The structured currency table with the three traps spelled out: minor units belong to the CURRENCY not the locale (JPY 0, USD 2, KWD/BHD/JOD 3), the gap before a trailing symbol is U+00A0 in six of these locales, and CLDR's ar-EG pattern contains an invisible U+200F that breaks naive equality assertions.

Every separator, sign and digit set a locale-aware formatter has to survive, each present literally between ASCII guards: the no-break and narrow-no-break spaces, de-CH's U+2019 group separator, the Arabic decimal and thousands separators, the four numbering systems' digits, and CLDR's U+2212 MINUS SIGN, which is not the ASCII hyphen.

Test names containing &, <, >, quotes and an apostrophe, escaped as XML requires. Round-tripping this report through a converter is the fastest way to find double-escaping bugs that turn & into &amp; one hop at a time.

Test names in German, French, Japanese, Greek and Russian, stored as UTF-8 with no BOM and an explicit encoding declaration. A reporter that assumes the platform default encoding produces mojibake here rather than an error.

Durations written four different ways in one file: scientific notation, a comma decimal separator from a German-locale JVM, a bare integer, and a comma that could be either a decimal point or a thousands separator. A parser using a locale-sensitive number reader gets a different answer depending on where it runs.

A feature written entirely in French keywords, declared by the # language: fr header that must be the first line of the file. Parsers that hardcode English keywords read this as a feature with no scenarios rather than reporting an error, so it fails silently.

Byte-for-byte the same diff as its LF twin except that every line ends CR LF, which is what a diff produced or saved on Windows looks like. Readers that compare a hunk line against expected content without stripping the CR find that no line matches.

The LF half of the line-ending twin pair: identical text content to the CRLF fixture, differing only in the terminator bytes. Diff the two downloads to see nothing but line-ending changes, and use the pair to score end-of-line normalisation.

The file itself is LF-terminated, but every removed line carries a literal CR as its last character because the change under review is a CRLF-to-LF conversion. Renderers that do not show the CR display a hunk in which every removed and added line looks identical.

With git's default `core.quotepath`, a path containing non-ASCII bytes is wrapped in double quotes and each byte is written as a backslash-octal escape. A parser that takes the header text literally creates a directory called `caf\303\251` on disk.

The same change with `core.quotepath=false`, so the path is written as raw UTF-8 and the header is not quoted. Compare with the quoted twin to confirm a parser resolves both spellings to the same file.

Non-ASCII in the author name and the subject, so both are Q-encoded into `=?UTF-8?q?...?=` words and the subject is folded across two lines with a leading space. The body is left as raw UTF-8, which means one message needs two different decoders.

The whole patch file uses CRLF terminators, as it would after a round trip through a Windows editor or a mail client. `git am` needs `--keep-cr` to be told the CRs belong to the patch rather than to the content, and the `-- ` signature line now ends with space-CR-LF.

The LF half of the patch twin pair, identical in text content to the CRLF fixture. Diff the two downloads to get a change that is invisible in every renderer and fatal to a byte comparison.

The attribute file that decides what happens to line endings on checkout: `text=auto` as the default, explicit `eol=lf` and `eol=crlf` overrides, the `binary` macro that expands to `-text -diff`, and one `-text` entry that is still given a textconv driver. This is the file whose absence causes the CRLF twins elsewhere in this category.

Ten series whose label values contain the characters that break naive line splitting — escaped quotes and backslashes, an escaped newline, non-ASCII text, braces, commas, equals signs, a leading hash and significant whitespace. The exposition format defines exactly three escapes and this file uses all of them.

Dotted OpenTelemetry-style metric and label names written with the quoted-name syntax that Prometheus 3 accepts, mixed in one document with a legacy underscore-named family. The fixture for parsers that still assume every name matches [a-zA-Z_][a-zA-Z0-9_]*.

The same instant written ten ways — RFC 3339 at three precisions and with a non-UTC offset, epoch seconds as integer and float, epoch milliseconds and nanoseconds, Common Log Format and the log4j comma-decimal form. What a timestamp autodetector must resolve to one moment.

Log messages in Latin, Japanese and Arabic scripts, an emoji flag and a zero-width-joiner family, NFC and NFD forms of the same accented letter, and escaped tab, newline and carriage return. Everything that makes a log line's byte length and its display width disagree.

Two records containing unpaired \ud800 and \udfff escapes between three well-formed ones, plus a correct surrogate pair for comparison. Intentionally invalid: the escapes are syntactically legal JSON but cannot be encoded as UTF-8, which is where a re-serialising pipeline breaks.

A developer-mode log where the level and service are wrapped in ANSI colour codes, ending with one uncoloured line. Colour codes sit inside the field a parser wants to read, so level extraction fails unless the sequences are stripped first — the classic symptom of a container run without a TTY check.

One log file written by two agents, four lines ending CRLF and three LF, with one line carrying trailing spaces before its break. Splitting on \n alone leaves a stray carriage return at the end of four fields, which is how a level or status ends up with an invisible character attached.

Five log lines carrying a NUL byte, bell, backspace, vertical tab and form feed, plus one 0xFF byte that is not valid UTF-8 — the debris that arrives when binary data reaches a log field. Deliberately contains no terminal-escape sequences, only inert control bytes.

logfmt lines built to break naive splitting on spaces and equals signs: a value containing an equals sign, escaped quotes, a trailing backslash before the closing quote, a bare key with no value, duplicate keys, non-ASCII values and one unterminated quote followed by a clean line.

Demangled C++ templates, Rust trait impls, Java generics, lambdas and unresolved hex addresses in the folded format — including one symbol containing a semicolon, which the format has no way to escape. That line is genuinely ambiguous, and how a parser handles it is the point.

A CycloneDX SBOM whose author names and properties contain accented Latin, CJK, right-to-left Hebrew, emoji and a deliberately long property value — for testing encoding handling and field-width assumptions. Every package, version, hash and licence is fictional — the tree describes nothing real.

Four features whose labels are written in Latin with diacritics, katakana, right-to-left Arabic, and a decomposed combining sequence — all stored as raw UTF-8 rather than \u escapes. Shapefile DBF export is where these usually turn into question marks.

The same sentences terminated with a bare LF rather than the CR LF the standard mandates — what you get after a log passes through a text editor or a Unix pipeline. Parsers that strip only "\r\n" leave a stray character on every line and then fail the checksum.

A one-line sidecar naming the encoding of the .dbf. Without it a reader has to guess — usually cp1252 — and every non-ASCII attribute value comes back as mojibake, which is the single most common shapefile data-loss bug.

The same four accented attribute rows written in UTF-8. Both files are exactly the same size because DBF fields are fixed-width in bytes, not characters — so the UTF-8 table fits fewer characters per field, and a reader that guesses the encoding produces mojibake rather than an obvious failure.

The sidecar that declares `attributes-utf8.dbf` as UTF-8. Note that the DBF also carries a language-driver byte in its header, and the two can disagree — which is exactly the ambiguity a reader has to resolve and document.

The same four accented attribute rows written in CP1252. Both files are exactly the same size because DBF fields are fixed-width in bytes, not characters — so the UTF-8 table fits fewer characters per field, and a reader that guesses the encoding produces mojibake rather than an obvious failure.

The sidecar that declares `attributes-cp1252.dbf` as ISO-8859-1. Note that the DBF also carries a language-driver byte in its header, and the two can disagree — which is exactly the ambiguity a reader has to resolve and document.

The same point encoded both ways, plus a polygon, as uppercase hex — the form WKB takes when it travels through a text column or a SQL console. The byte-order flag is the first byte of each string, so the two point encodings differ everywhere after it.

Fixed-width byte strings, variable-length UTF-8 strings and UTF-8 attribute text in one file, including Greek, CJK and combining diacritics. HDF5 hands fixed-width strings back as padded bytes and variable-length ones as decoded text, and conflating the two is where string handling usually breaks.

A structured array whose field names use Greek and CJK characters, which is the only reason format version 3.0 exists: its header is UTF-8 where 1.0 and 2.0 are latin-1. A parser that decodes the header as latin-1 mangles all three names.

Eight measurements whose unit symbols use the codepoints that have Unicode look-alikes: MICRO SIGN against GREEK MU, OHM SIGN against GREEK OMEGA, ANGSTROM SIGN against A-with-ring. Each row also carries an ASCII fallback, so a normalisation bug shows up as a column mismatch rather than as an invisible change.

The workflow file that exposes the YAML 1.1 boolean resolver: a bare `on` key becomes True in PyYAML, SnakeYAML and Psych, so a round-trip through those loaders loses the trigger block. The env values repeat the trap with NO, yes and off alongside a quoted control.

The two GitLab inheritance mechanisms in one file: YAML anchors with merge keys, which the loader resolves before GitLab sees the document, and `extends`, which GitLab resolves afterwards with a deep merge. Hidden .job keys carry both.

GitLab's `!reference` custom YAML tag used three ways: inside a script list, as a whole after_script value, and as a whole rules value. A stock YAML 1.2 loader has no constructor for it and raises; GitLab's loader resolves each key path.

Compose with three x- extension fields carrying YAML anchors that are merged into services. The trap is ordering: a tool that strips x- keys before parsing the YAML destroys the anchors and the file stops resolving.

Anchors and aliases across mapping, sequence and scalar nodes, including an anchor nested inside another anchored node. The point most tooling misses: an alias is a reference to the same node, so a shallow-loading parser can share mutable state between jobs.

Merge keys with their full precedence rules: local keys beat merged ones, and in a merge sequence the earlier alias wins. The file publishes the expected merged values, and a strict YAML 1.2 loader produces none of them because 1.2 dropped << from the core schema.

Every block-scalar variation in one file: literal and folded styles, all three chomping indicators, an explicit indentation indicator, a folded block with a paragraph break, and an embedded shell-shaped script whose own indentation must survive.

The Norway problem in full: eleven bare words that a YAML 1.1 resolver turns into booleans, a matching quoted control group that survives, and a country-code list where position two silently becomes false. The definitive fixture for resolver-version behaviour.

Twenty-two unquoted values whose type depends entirely on the resolver. The worst is the leading zero: 0755 is 493 under YAML 1.1 and 755 under YAML 1.2, so both resolvers return a number and they return different ones. Also covers base-60 times, a version that loses its trailing zero, an integer past IEEE-754 precision, dates, and .inf / .nan.

Duplicate keys at three nesting levels, including a duplicated top-level sequence. The spec forbids them; most loaders keep the last silently, a few keep the first, and strict linters reject the document. The file publishes the last-wins answer.

A five-document stream with explicit end markers, a comment-only document that loads as null, and a bare sequence as a whole document. The single-document API returns only the first, which is how multi-object manifests silently lose objects.

Five spellings of null against the things routinely confused with it: empty strings, empty collections, and a key written with no value at all. Includes a sequence containing a hole, an empty string and two nulls in a row.

All three scalar quoting styles side by side: plain scalars and what they cannot contain, single quotes where backslashes stay literal and '' means one quote, and double quotes as the only style that processes \t, \n and \uXXXX escapes.

Flow (JSON-like) and block collections expressing the same structures, nested inside one another in both directions, plus a flow mapping wrapped across lines and a line of strict JSON — which is valid YAML, and a useful check on a parser's JSON-subset claim.

The indentation styles that all parse identically and that formatters fight over: sequences flush with their key versus indented under it, two-space against four-space maps, and deliberately irregular but legal nesting. For testing formatters and idempotency.

Non-ASCII keys and values across Latin, Cyrillic, Arabic, CJK and emoji, plus a key containing a zero-width space and a value distinguishing a combining acute from the precomposed character. Written as UTF-8 with no BOM.

A YAML file written with CRLF line endings, which the spec accepts as a line break. A parser that splits on \n alone leaves a stray carriage return at the end of every plain scalar, so "build" becomes "build\r" and equality checks quietly fail.

A YAML file beginning with a UTF-8 byte order mark, which the spec permits at the start of a stream. A parser that does not strip it reads the first key as \ufeffname, so the lookup misses and the document appears to be missing its name field.

Nested anchor reuse kept deliberately small: two anchors, six references, thirty-one expanded nodes. It is here to test alias resolution and expansion accounting on a safe input, and is explicitly not a billion-laughs expansion bomb.

Explicit tags across the standard set — !!str, !!float, !!int, !!bool, !!null, !!binary, !!timestamp, !!omap, !!set — alongside two application-local ! tags. CI dialects use local tags in the wild, so a pipeline parser has to decide whether to reject, ignore, or resolve them.

A two-document stream where each document declares its own %YAML directive and the second adds a %TAG handle used by a local tag. Comments appear in every position they are legal, and every one of them is lost by a non-round-tripping loader.
We use Google Analytics and show ads via Adsterra. Non-essential cookies and ad scripts run only after you allow the matching categories. See our cookie policy.