Skip to content

Guide

YAML 1.1 vs. 1.2

Der teuerste YAML-Bug überhaupt hat einen Ländercode im Zentrum.

Von yamltojsonfree · Veröffentlicht am · Aktualisiert am

Was das Norway-Problem ist

In YAML 1.1 sind die unzitierten Wörter y, yes, on, n, no und off Booleans — in Groß-, Klein- oder gemischter Schreibweise. Eine Liste von Ländercodes mit Norwegen — NO — wird also stillschweigend zu false. Nichts schlägt fehl. Das Dokument parst, das Deployment gelingt, und irgendwo weiter hinten fehlt ein Land in einer Liste, weil ein Boolean kein Dictionary-Schlüssel sein und keinem String-Vergleich standhalten kann.

YAML 1.2, veröffentlicht 2009, hat das abgeschafft: Nur true und false sind Booleans, und diese sechs Wörter sind gewöhnliche Strings. Auch die anderen impliziten Umwandlungen von YAML 1.1 sind weg — 022 ist keine Oktalzahl für 18 mehr, und 12:30 keine Zahl zur Basis 60 im Wert 750.

Der Haken: Beide Versionen sind mehr als fünfzehn Jahre später noch weit verbreitet. Dieselbe Datei kann also zwei verschiedene Dinge bedeuten, je nachdem, welches Werkzeug sie öffnet — genau deshalb verwendet der YAML-zu-JSON-Converter auf dieser Seite standardmäßig YAML 1.2 und markiert jeden Wert in deinem Dokument, der unter 1.1 anders gelesen würde.

Jeder Wert, der seine Bedeutung ändert

Dieselbe Quelle, gelesen von jeder Version der Spezifikation.

YAML-QuelleGelesen als YAML 1.2Gelesen als YAML 1.1Sichere Form
country: NO"NO"falsecountry: "NO"
enabled: yes"yes"trueenabled: true
debug: off"off"falsedebug: false
mode: 0222218mode: "022"
start: 12:30"12:30"750start: "12:30"
version: 1.101.11.1version: "1.10"

Beachte die letzte Zeile: 1.10 verliert in beiden Versionen seine Null am Ende, weil es als Zahl geparst wird. Versionsstrings sollten immer zitiert werden.

Welche Parser welche Version lesen

Man wählt eine YAML-Version selten direkt — man erbt sie von der Bibliothek, die das eigene Tooling zufällig verwendet. Ungefähr so teilt sich das Ökosystem:

ParserVersionHinweise
PyYAML (Python)YAML 1.1Der Standard für die meisten Python-Werkzeuge, einschließlich Ansible.
ruamel.yaml (Python)YAML 1.2Der gepflegte Nachfolger von PyYAML; 1.1 als Option verfügbar.
js-yaml v5 (JavaScript)YAML 1.2Die Engine dieser Seite. Frühere Versionen lasen 1.1.
go-yaml / sigs.k8s.io (Go)Überwiegend 1.2Was Kubernetes verwendet; behält aus Kompatibilitätsgründen einige 1.1-Verhalten.
SnakeYAML (Java)YAML 1.1Der Standard beim Laden von Spring-Boot-Konfiguration.
libyaml (C bindings)YAML 1.1Die Basis vieler Sprachbindungen, PyYAML eingeschlossen.

Die praktische Folge: Eine Datei, die auf der einen Seite dieser Tabelle geschrieben und auf der anderen gelesen wird, kann Werte stillschweigend verändern. Wenn dein YAML von Python erzeugt und von Kubernetes gelesen wird — eine sehr verbreitete Pipeline —, überquert es die Versionsgrenze. Die Details auf Code-Ebene stehen im Leitfaden YAML in Code zu JSON umwandeln.

So schreibst du YAML, das in beiden Versionen sicher ist

Drei Gewohnheiten beseitigen die gesamte Fehlerklasse. Zitiere jeden String, der mit etwas anderem verwechselt werden könnte — Ländercodes, Versionsnummern, Werte mit führender Null und alles, was einen Doppelpunkt enthält. Schreibe Booleans nur als true und false, nie als yes, on oder ihre Verwandten. Und bevor eine Datei zwischen Werkzeugen wechselt, schick sie durch einen Converter oder Validator, der versionsabhängige Werte meldet — dein YAML als explizites JSON zu sehen ist der schnellste Weg, einen ungewollten Typ zu erkennen.

Quellen

Prüfe dein eigenes YAML

Jeder Wert aus der Tabelle oben wird vom Converter und vom Validator auf dieser Seite markiert — mit dem Ergebnis, das jede Version liefern würde. Nichts wird hochgeladen.