C’est quoi, tous ces signes égal (=), au juste ?
(lars.ingebrigtsen.no)- Récemment, d’anciennes citations d’e-mails ont circulé sur Twitter, suscitant des questions sur la présence de signes égal (=) en fin de phrase
- Ces signes apparaissent lors du processus d’encodage « quoted-printable », où ils servent à indiquer qu’une ligne longue a été coupée et qu’elle continue à la ligne suivante
- Lors de l’envoi d’e-mails, le saut de ligne standard est CRLF (retour chariot + saut de ligne), mais lorsqu’il est converti en NL d’Unix, un mauvais fonctionnement de l’algorithme de décodage peut laisser des signes égal ou faire disparaître des caractères
- Le signe égal sert aussi à représenter des caractères non ASCII (ex. : =C2=A0), et un décodeur défectueux peut provoquer des erreurs en les remplaçant de manière simpliste
- À l’origine du problème : une logique de décodage boguée et un traitement de conversion inadapté, ce qui montre que la personne ayant transformé l’e-mail maîtrisait mal l’aspect technique
L’origine des signes égal (=) dans les citations d’e-mails
-
Ces derniers jours, de nombreuses anciennes citations d’e-mails ont été partagées sur Twitter, avec un phénomène frappant : des signes égal visibles en fin de phrase
- L’auteur réfute les hypothèses selon lesquelles il s’agirait d’une erreur de code ou d’OCR (reconnaissance optique de caractères)
- En réalité, il s’agit d’une erreur de traitement d’encodage survenue lors de la conversion de l’e-mail dans un format plus lisible
-
À l’origine, les e-mails étaient du simple texte, mais pour gérer les lignes longues et les caractères spéciaux, l’encodage « quoted-printable » a été introduit
- Lorsqu’une ligne longue est coupée, un signe égal (=) est ajouté en fin de ligne pour indiquer que « cette ligne continue »
- Après ce signe égal vient alors CRLF (retour chariot + saut de ligne)
Erreurs d’encodage et de décodage des sauts de ligne
-
Les serveurs de messagerie utilisent CRLF comme saut de ligne standard, alors que les systèmes Unix n’utilisent que NL
- Pendant la conversion, un octet disparaît, et si le décodeur le gère mal, le signe égal peut rester ou des caractères peuvent manquer
- Par exemple, si « non- =CRLF cloven » est mal traité, on peut obtenir « non- loven », avec disparition du
c
-
Certaines implémentations traitent le signe égal en fin de ligne en supprimant simplement deux caractères
- Cet algorithme dysfonctionne sur les fichiers au format Unix, ce qui laisse le signe égal tel quel
Un autre usage du signe égal : l’encodage des caractères non ASCII
-
Le signe égal est aussi utilisé pour l’encodage des caractères non ASCII, en plus des sauts de ligne
- Exemple :
=C2=A0signifie non-breaking space (espace insécable) - On le rencontre souvent dans le corps des e-mails pour l’indentation ou l’expression de caractères spéciaux
- Exemple :
-
L’auteur suppose que certains convertisseurs se sont contentés d’un simple search-replace sur
=C2,=A0, etc., sans utiliser de décodeur correct
Contexte technique et standard
-
La norme RFC 2045 définit l’encodage quoted-printable comme un mécanisme de transport
- Après réception, il doit en principe être décodé puis stocké sous forme de texte propre
- Mais dans les implémentations réelles, cette étape est parfois omise, d’où des erreurs fréquentes dans le traitement des sauts de ligne
-
Dans l’exemple de code,
(quoted-printable-decode-string "he=\nllo")est correctement restauré en"hello"- Cela vient du fait qu’un algorithme supposant le contexte CRLF des serveurs SMTP a été réutilisé
- Il fonctionne correctement sur les fichiers Windows, mais échoue sur Unix
Conclusion
- Les signes égal dans les citations d’e-mails sont des résidus de l’encodage quoted-printable et le résultat combiné de défauts dans le traitement des sauts de ligne et le décodage des caractères non ASCII
- La cause profonde du problème est une implémentation imprécise du décodeur et des erreurs de conversion d’encodage
- L’auteur résume cela comme un problème technique et le résultat d’un mauvais traitement, et souligne la nécessité de respecter scrupuleusement les standards lors de la conversion des e-mails
1 commentaires
Avis Hacker News
Le protagoniste de cet article est Lars Ingebrigtsen, la personne qui a rédigé le manuel de Gnus, le paquet lecteur d’e-mails/Usenet d’Emacs
Son manuel est spirituel et instructif, et il a une compréhension du parsing d’e-mails bien plus profonde que la plupart des gens
Le manuel est consultable ici, et une autre version se trouve à ce lien
Je me souviens de l’époque où il créait Gnus pour la première fois à l’université d’Oslo (UiO)
C’était une petite star du développement parmi les étudiants en informatique, et tout le monde utilisait Emacs et Gnus
Cette affaire est un cas typique de « quelqu’un qui en sait juste assez pour être dangereux »
Je savais que l’e-mail n’était pas du simple texte, mais je ne savais pas qu’on ne pouvait pas traiter le décodage quoted-printable avec un simple remplacement
C’est le même genre de bug que parser du HTML directement avec des expressions régulières : au début ça marche, puis plus tard on se retrouve avec des tas de signes ‘=’ restés dans une pièce à conviction au Congrès
Une question a été posée : « pourquoi les serveurs mail détestent-ils les longues lignes ? »
Le serveur doit parser les en-têtes, donc il ne peut pas traiter cela comme un simple blob binaire
IMAP exige que le serveur fasse un parsing complet, et POP3, pensé pour un seul appareil, n’est plus vraiment adapté aujourd’hui
La RFC 821 limitait la longueur des lignes à 1000 octets maximum, et, pour des raisons de compatibilité, il était courant de couper à moins de 80 caractères
C’est pour cela que l’encodage Base64 insère aussi un retour à la ligne tous les 76 caractères
Par exemple, un PDP-11 avait environ 512 KB, un VAX-11 environ 2 MB, et les programmeurs comptaient la mémoire octet par octet
HELO,MAIL FROM,RCPT TO,DATA, etc.La documentation correspondante est disponible dans la documentation officielle IBM et sur Wikipedia
Au départ, je pensais que cet article parlerait de la signification d’opérateurs comme
= == === .=. <== ==> <<== ==>> (==) => =~=Personnellement, j’ai moi-même développé un logiciel d’archivage d’e-mails
Le plus difficile a été de gérer les cas limites dans des fichiers .eml accumulés sur plus de 20 ans
Le concept est simple, mais l’e-mail est étonnamment complexe
Même la validation d’une adresse e-mail est en pratique presque impossible
Il a eu quelques utilisateurs pendant plusieurs années, mais la gestion du MIME a été de loin la plus grande souffrance
Ce qui m’a paru intéressant n’était pas tant le signe ‘=’ lui-même, mais le phénomène de disparition des caractères autour de lui
Comme un bug off-by-one : au lieu de supprimer le ‘=’, on dirait qu’une partie du texte réel a disparu
Une conversion CRLF/LF est peut-être liée au problème
Je me demandais pourquoi ce problème apparaissait maintenant
Ces derniers jours, des gens publient de vieux e-mails sur Twitter, et je me demandais pourquoi
Une personne a avancé que la cause du problème pourrait ne pas être Gmail, mais une transformation sur un serveur intermédiaire
Au-delà de la conversion CRLF→LF, un double traitement du quoted-printable peut aussi laisser des signes ‘=’, donc il est possible que deux serveurs mail aient été impliqués
En pratique, c’est souvent un stagiaire non spécialisé qui récupère les données avec des outils rudimentaires, puis plusieurs conversions successives finissent par abîmer le format
Les originaux ont déjà été détruits, et il ne reste plus que des fragments de données dont seule la forme subsiste
L’article sur archive.today montre lui aussi le même problème de quoted-printable cassé
Les liens associés sont pastes.io/correspond et ce fil HN
Quelqu’un dit qu’en consultant des e-mails téléchargés depuis Outlook, il serait pratique d’avoir un visualiseur .eml qui décode automatiquement le quoted-printable