7 Maßnahmen

So umgehen Sie YAML-Probleme

02.04.2023
Von 
Serdar Yegulalp schreibt für unsere US-Schwesterpublikation Infoworld.
Die Auszeichnungssprache YAML ist flexibel und leicht verständlich, hält aber dennoch unerwartete Fallstricke bereit. So umgehen Sie diese.
Mit diesen sieben Maßnahmen bleiben Ihnen YAML-Unfälle erspart.
Mit diesen sieben Maßnahmen bleiben Ihnen YAML-Unfälle erspart.
Foto: Elena Pimukova - shutterstock.com

Die Konfigurationssprache YAML ("YAML Ain't Markup Language", ursprünglich "Yet Another Markup Language") bildet das Herzstück vieler moderner Anwendungen - etwa Kubernetes, Ansible, CircleCI und Salt. Dabei bietet YAML viele Vorteile, etwa Lesbarkeit, Flexibilität und die Möglichkeit, mit JSON-Dateien zu arbeiten. Allerdings hält die Markup Language für Ungeübte auch einige Fallstricke und Stolperfallen bereit.

Doch auch erfahrene YAML-Profis können von Problemen überrascht werden, wenn diese sich durch scheinbar harmloses Verhalten ankündigen. Die folgenden sieben Maßnahmen können Sie vor den lästigsten Problemen mit YAML bewahren.

1. Im Zweifel auf Strings setzen

Die wichtigste Defensivpraxis, die Sie anwenden können, wenn Sie in YAML schreiben: Zitieren Sie alles, was ein String sein soll. Eine der bekanntesten Eigenheiten von YAML ist es, dass man Strings auch ohne Quotes schreiben kann:

- movie:

title: Blade Runner

year: 1982

In diesem Beispiel werden die Keywords movie, title und year als Zeichenketten interpretiert, ebenso wie der Wert Blade Runner. Der Wert 1982 wird als Zahl geparst.

Aber was passiert hier:

- movie:

title: 1979

year: 2016

Der Filmtitel wird in diesem Fall als Zahl interpretiert. Doch es geht noch schlimmer:

- movie:

title: No

year: 2012

Die Wahrscheinlichkeit, dass dieser Titel als Boolescher Wert interpretiert wird, ist enorm hoch.

Wenn Sie absolut sichergehen wollen, dass Schlüssel und Werte als Zeichenketten interpretiert werden, und sich vor möglichen Mehrdeutigkeiten schützen wollen (und in YAML können sich viele Mehrdeutigkeiten einschleichen), dann quotieren Sie Ihre Zeichenketten:

- "movie":

"title": "Blade Runner"

"year": 1982

Wenn Sie Strings aus irgendeinem Grund nicht in Anführungszeichen setzen können, können Sie ein Präfix verwenden, um den Typ anzugeben. Das macht YAML zwar etwas unübersichtlicher, ist aber genauso eindeutig wie die Anführungszeichen:

2. Mehrzeilige Zeichenketten absichern

YAML bietet mehrere Möglichkeiten, mehrzeilige Zeichenketten darzustellen, je nachdem, wie diese formatiert sind. So können etwa Zeichenketten, die nicht in Anführungszeichen gesetzt sind, auf mehrere Zeilen aufgeteilt werden, indem ihnen ein > vorangestellt wird:

long string: >

This is a long string

Beachten Sie, dass bei Verwendung von > automatisch ein \n am Ende der Zeichenkette angehängt wird. Wenn Sie diesen Zeilenumbruch vermeiden wollen, verwenden Sie >- anstelle von >.

Wenn Sie Zeichenketten in Anführungszeichen setzen, müssen Sie jedem Zeilenumbruch einen Backslash voranstellen:

long string: "This is a long string \

that spans multiple lines."

Beachten Sie, dass Leerzeichen nach einem Zeilenumbruch als YAML-Formatierung und nicht als Teil des Strings interpretiert werden. Aus diesem Grund wird im obigen Beispiel das Leerzeichen vor dem Backslash eingefügt. Es stellt sicher, dass die Wörter string und that nicht zusammenlaufen.

3. Booleans explizit angeben

Wie bereits angedeutet, ist eine weitere große Schwierigkeit von YAML, boolesche Werte anzugeben. Dafür bietet YAML so viele Möglichkeiten, dass eine beabsichtigte Zeichenkette nur allzu leicht als Boolean interpretiert werden kann.

Ein vielzitiertes Beispiel hierfür ist das Problem mit Länderkennungen. Während US oder UK kein Problem darstellen, ist das beispielweise im Fall von NO anders - die Kennung wird nicht als Zeichenkette, sondern als Boolean ausgewertet.

Wenn immer möglich, sollten Sie deshalb sowohl Booleans, als auch kürzere Zeichenketten, die als solche fehlinterpretiert werden könnten, bewusst explizit angeben. Das YAML-Präfix für Booleans lautet !!bool.

4. Oktalausformungen beachten

Ein unscheinbarer aber möglicherweise lästiger Fehler: YAML 1.1 verwendet eine andere Notation für Oktalzahlen als YAML 1.2. In YAML 1.1 sehen diese wie 0777 aus. In YAML 1.2 wird aus der gleichen Oktalzahl 0o777 - was deutlich weniger zweideutig ist.

Kubernetes verwendet YAML 1.1. Wenn Sie YAML mit anderen Anwendungen verwenden, die die Version 1.2 nutzen, sollten Sie besonders darauf achten, nicht die falsche Schreibweise für Oktalzahlen zu verwenden. Da diese heute in der Regel nur noch für Dateirechte verwendet werden, handelt es sich im Vergleich zu anderen YAML-Problemen um ein Sonderfall.

5. Executables meiden

Viele YAML-Bibliotheken, etwa PyYAML für Python, ermöglichen es, bei der Deserialisierung von YAML beliebige Befehle auszuführen. Erstaunlicherweise handelt es sich dabei nicht um einen Bug, sondern um eine Fähigkeit, für die YAML konzipiert wurde.

Im Falle von PyYAML wurde das Standardverhalten für die Deserialisierung schließlich so geändert, dass nur noch eine sichere Teilmenge von YAML unterstützt wird. Das ursprüngliche Verhalten kann manuell wiederhergestellt werden, allerdings sollten Sie es nach Möglichkeit vermeiden, diese Funktion zu nutzen und sie standardmäßig deaktivieren.

6. Inkonsistenzen vermeiden

Ein weiteres mögliches Problem kann auftreten, wenn unterschiedliche YAML-Verarbeitungsbibliotheken in verschiedenen Programmiersprachen unterschiedliche Ergebnisse liefern.

Ein Beispiel: Wenn Sie eine YAML-Datei haben, die boolesche Werte enthält, die als true und false dargestellt werden und diese mit einer anderen Bibliothek, die boolesche Werte als y und n oder on und off darstellt, reserialisieren, kann es zu unerwarteten Ergebnissen kommen. Selbst wenn sich funktional nichts am Code verändert, kann dieser völlig anders aussehen.

7. Auf YAML verzichten

Die allgemein beste Möglichkeit, Probleme mit YAML zu vermeiden, besteht darin, es nicht zu verwenden. Oder zumindest nicht direkt.

Wenn Sie YAML als Teil eines Konfigurationsprozesses schreiben müssen, kann es sicherer sein, den Code in JSON oder nativem Code (z.B. Python Dictionaries) zu schreiben und diesen dann in YAML zu serialisieren. So haben Sie mehr Kontrolle über die Objekttypen und können eine Sprache verwenden, mit der Sie bereits arbeiten.

Anderenfalls können Sie einen Linter wie beispielsweise yamllint verwenden, um YAML auf gängige Probleme zu überprüfen. So können Sie zum Beispiel wahrheitsgemäße Werte wie YES oder off zugunsten von true und false verbieten oder String-Quoting erzwingen. (fm)

Dieser Beitrag basiert auf einem Artikel unserer US-Schwesterpublikation Infoworld.