Résumé
- RFC 5229 a introduit
set, l’expansion de chaînes et les variables de correspondance, mais seulement après la déclaration explicite de la capacitévariables. - Cette mémoire restait strictement bornée : les captures dépendaient du chemin d’exécution, les valeurs n’étaient visibles que dans le script en cours et un dépassement pouvait entraîner une troncature.
Un filtre avait besoin d’un peu de mémoire, pas d’une machine plus puissante
En janvier 2008, Sieve avait déjà une fonction précise : filtrer les messages au moment de leur remise finale. La spécification de base présentait un langage utile, mais volontairement limité. Il n’avait ni variables, ni boucles, ni possibilité d’appeler des commandes système. Ce n’étaient pas de simples fonctions oubliées que toute extension pouvait ajouter sans précaution ; ces absences délimitaient ce qu’un filtre écrit par un utilisateur pouvait demander au serveur de courrier.
RFC 5229 a ouvert une brèche très encadrée. Un script pouvait annoncer require "variables", affecter une chaîne à un nom avec set, puis réutiliser cette valeur dans une autre chaîne ou la tester. Une correspondance avec jokers pouvait rendre disponible le résultat entier sous ${0} et les morceaux capturés sous ${1}, ${2}, etc. Un filtre pouvait ainsi extraire le nom d’une liste depuis un en-tête, l’insérer dans le chemin d’une boîte ou éviter de recopier la même information dans plusieurs règles.
Cela ne signifie pas que le filtre acquérait une mémoire durable. La spécification dit que ces variables ne sont visibles que par le script alors en cours. Elle ne définit ni stockage commun à toute la boîte, ni registre des messages précédents, ni état partagé entre utilisateurs. Le mot « variable » paraît vaste ; l’objet normalisé est beaucoup plus modeste : un nom associé à du texte pendant l’exécution de ce script.
La déclaration faisait partie du modèle de sûreté
La capacité devait être demandée avant usage. Sans variables, les scripts ne recevaient pas silencieusement une nouvelle interprétation des chaînes. Dans un langage extensible, ce prérequis a du sens : une fonction suppose non seulement une opération, mais aussi un accord explicite entre le script et l’interpréteur sur son existence.
Lorsque le contrôle atteignait une instruction, les références étaient développées avec les valeurs alors courantes, en un seul passage. Une variable inconnue devenait une chaîne vide ; la casse des noms était indifférente. Le mécanisme était concis, mais certaines erreurs pouvaient passer inaperçues. Une faute de frappe pouvait supprimer un fragment au lieu de produire une erreur visible. Et si la valeur contenait elle-même une autre référence ${...}, celle-ci n’était pas réévaluée lors d’un second tour.
L’extension proposait quelques transformations limitées : changer la casse ASCII, modifier la première lettre, échapper les jokers ou calculer la longueur. Elle ajoutait aussi un test string. Mais pas de calcul arithmétique, pas de boucle, pas d’exécution de code arbitraire. Le langage gagnait en expressivité à l’intérieur d’un petit vocabulaire, non en puissance sans borne.
Une capture dépend du test qui a réellement été exécuté
Avec les variables de correspondance, le chemin suivi devient une partie des données. RFC 5229 impose l’évaluation de gauche à droite et l’arrêt dès qu’une réponse booléenne est déterminée. Dans anyof (true, header :matches ...), par exemple, le test d’en-tête n’est jamais atteint ; aucune capture n’en provient. Une correspondance réussie ultérieure peut remplacer la liste précédente. Une tentative infructueuse, elle, ne fournit pas de nouveaux fragments. Dans une règle complexe, il faut donc savoir quel test a effectivement tourné avant de faire confiance à ${1}.
Les captures ne s’appliquent pas automatiquement à chaque type de correspondance ajouté par une autre extension. Publié trois mois après RFC 5229, RFC 5173 établit une distinction instructive : si variables est activée, les références présentes dans les clés du test body peuvent être développées ; en revanche, les jokers utilisés par ce test ne doivent pas alimenter les variables de correspondance. Les standards autorisent donc certaines compositions tout en refusant d’assimiler deux opérations qui se ressemblent en surface.
Les limites minimales rendent ce choix concret. Une implémentation devait gérer au moins 128 variables, des noms d’au moins 32 caractères, des valeurs d’au moins 4 000 caractères et les captures ${1} à ${9}. Si une valeur dépassait la capacité réelle de l’implémentation, l’erreur devait si possible être détectée à la compilation ; si elle ne l’était qu’à l’exécution, la troncature était prévue et ne devait pas être considérée comme une erreur. La section de sécurité déconseille donc les structures volumineuses et sensibles, et rappelle qu’un expéditeur peut contrôler le texte capturé.
Une longue histoire de brouillons, pas une mesure d’adoption
L’historique du Datatracker remonte aux premières versions individuelles de mars 2003, puis aux versions du groupe de travail Sieve à partir de la fin de 2004, avec plusieurs révisions en 2005. Le compte rendu de l’IESG identifie le texte comme un travail du groupe Sieve. L’approbation en 2006 et la publication de RFC 5229 en janvier 2008 sont deux étapes consignées séparément. Cette chronologie ne révèle ni la cause du délai, ni le nombre de serveurs ayant ensuite adopté l’extension.
La note de Heng Lu sur la « spécification initiale minimale » offre ici un angle d’analyse : require laisse une base réduite coexister avec des choix futurs activés localement. « Running-Code Primacy » rappelle qu’une fonction publiée ne démontre pas qu’un serveur précis l’exécute. La note sur les couches de réalité aide à distinguer la déclaration du script, l’état de l’interpréteur, le comportement du serveur et l’expérience finale dans la boîte de réception. Ce sont des grilles d’analyse postérieures, pas des témoignages sur les intentions des auteurs du RFC.
Le filtre pouvait désormais retenir ce qu’une correspondance avait capturé et réemployer quelques chaînes nommées. Cela ne prouvait pas qu’il se souvenait d’échanges précédents, qu’il authentifiait l’expéditeur ou qu’il établissait la destination finale du message. La portée historique de RFC 5229 tient à une couture rendue plus utile, sans effacer la frontière de Sieve.
Sources
- RFC 5229 : extension Variables pour le filtrage Sieve
- Fiche RFC Editor de RFC 5229
- Notice de RFC 5229 dans l’IETF Datatracker
- Historique du brouillon Sieve Variables
- Compte rendu de l’IESG sur le brouillon Variables
- Brouillon 08 : Sieve Extension: Variables
- RFC 5228 : langage de filtrage Sieve
- Fiche RFC Editor de RFC 5228
- RFC 3028 : langage de filtrage Sieve
- Fiche RFC Editor de RFC 3028
- RFC 5173 : extension Body pour le filtrage Sieve
- Fiche RFC Editor de RFC 5173
- Heng Lu, « Running-Code Primacy »
- Heng Lu, « Minimum Initial Specification, Localized Future Decision, and Voluntary Adoption »
- Heng Lu, « On Reality Layers, Symbolic Power, and Why Clarity Feels So Hostile »
Briefing des membres
Contexte approfondi du profil
Connectez-vous avec le bon niveau d'adhésion pour débloquer le briefing complet et les notes de source.
Réservé à Strategic Circle
Strategic Circle
Ouvert à tous les lecteurs. Débloquez les briefings de profil après adhésion et connexion.
Rejoindre Strategic CircleRéservé aux membres de Leadership Alliance
Leadership Alliance
Réservé aux propriétaires et dirigeants qualifiés d'actifs IP ; connectez-vous pour débloquer les briefings Alliance.
Rejoindre Leadership Alliance
