Skip to content

Guide

YAML 1.1 vs 1.2

Le bug YAML le plus coûteux qui soit a un code pays en son centre.

Par yamltojsonfree · Publié le · Mis à jour le

Ce qu’est le problème Norway

En YAML 1.1, les mots sans guillemets y, yes, on, n, no et off sont des booléens — en majuscules, en minuscules ou capitalisés. Une liste de codes pays contenant la Norvège — NO — devient donc silencieusement false. Rien n’échoue. Le document s’analyse, le déploiement réussit, et quelque part en aval un pays manque à une liste parce qu’un booléen ne peut pas être une clé de dictionnaire ni satisfaire une comparaison de chaînes.

YAML 1.2, publié en 2009, a supprimé cela : seuls true et false sont des booléens, et ces six mots sont des chaînes ordinaires. Il a aussi abandonné les autres conversions implicites de YAML 1.1 — 022 n’est plus un octal valant 18, et 12:30 n’est plus un nombre en base 60 valant 750.

Le hic, c’est que les deux versions restent largement utilisées, plus de quinze ans après. Le même fichier peut donc vouloir dire deux choses différentes selon l’outil qui l’ouvre — c’est exactement pourquoi le convertisseur YAML vers JSON de ce site utilise YAML 1.2 par défaut et signale chaque valeur de votre document qui serait lue différemment en 1.1.

Chaque valeur qui change de sens

La même source, lue par chaque version de la spécification.

Source YAMLLu en YAML 1.2Lu en YAML 1.1Forme sûre
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"

Notez la dernière ligne : 1.10 perd son zéro final dans les deux versions, parce qu’il est analysé comme un nombre. Les chaînes de version devraient toujours être entre guillemets.

Quels analyseurs lisent quelle version

On choisit rarement une version de YAML directement — on en hérite de la bibliothèque qu’utilise votre outillage. Voici, en gros, comment l’écosystème se répartit :

AnalyseurVersionNotes
PyYAML (Python)YAML 1.1Le défaut de la plupart des outils Python, Ansible compris.
ruamel.yaml (Python)YAML 1.2Le successeur maintenu de PyYAML ; 1.1 disponible en option.
js-yaml v5 (JavaScript)YAML 1.2Le moteur utilisé par ce site. Les versions antérieures lisaient 1.1.
go-yaml / sigs.k8s.io (Go)Surtout 1.2Ce qu’utilise Kubernetes ; conserve quelques comportements 1.1 par compatibilité.
SnakeYAML (Java)YAML 1.1Le défaut du chargement de configuration dans Spring Boot.
libyaml (C bindings)YAML 1.1La base de nombreux bindings de langages, PyYAML compris.

Conséquence pratique : un fichier écrit d’un côté de ce tableau et lu de l’autre peut changer des valeurs en silence. Si votre YAML est produit par Python et consommé par Kubernetes — un pipeline très courant — il franchit la frontière de version. Les détails au niveau du code sont dans le guide Convertir YAML en JSON dans du code.

Comment écrire du YAML sûr dans les deux versions

Trois habitudes éliminent toute cette classe de bugs. Mettez entre guillemets toute chaîne qui pourrait être prise pour autre chose — codes pays, numéros de version, valeurs avec des zéros en tête, et tout ce qui contient un deux-points. N’écrivez les booléens que comme true et false, jamais yes, on ou leurs cousins. Et avant qu’un fichier ne passe d’un outil à l’autre, faites-le passer par un convertisseur ou un validateur qui signale les valeurs dépendantes de la version — voir votre YAML en JSON explicite est le moyen le plus rapide de repérer un type que vous ne vouliez pas.

Références