#22895 - #12746 - Note : gniiiiii [RSS][WGet][GZip] - Le Hollandais Volant
Jadis, je m’étais mis à un lecteur RSS et je découvrais les joies des sites qui renvoyaient des données mal formatées, gzipés, avec des encodages à la con…
Bref, il faut tout tester, tout ce qu’on peut imaginer et même ce qu’on n’imagine même pas.
Voir là pour une petite liste : https://lehollandaisvolant.net/?mode=links&id=20200212181616
Aujourd’hui le moi se met à faire un client e-mail \o/.
… eh bah c’est autant le bordel.
Sans même parler du fait que le protocole IMAP utilise des éléments en UTF-7 — oui, 7, pas 8 – qui fout la merde, il faut faire à nouveau attention à tout.
Par exemple, comment transformer un e-mail HTML en texte simple ? Bon quelques régex et c’est bon : les tags sont virés, les espaces en trop aussi.
Sauf que j’ai passé 2 bonnes heures à comprendre pourquoi certains mails conservaient des tas d’espaces à la suite.
Il se trouve que certains singes avec des claviers n’utilisent pas des espaces ou des \n comme tout le monde, mais le caractère U+200C — généralement appelé ZWJN (zero-width non-joiner) — qui est vide et invisible, mais qui prend 3 octets, donc n’est pas filtré par strlen()===0.
Pour détecter ça, j’ai utilise urlencode() qui le met en évidence immédiatement.
C’est un caractère qui permet de faire des jointures entre les lettres (comme des ligatures), notamment dans le perse et l’arabe : https://en.wikipedia.org/wiki/Zero-width_non-joiner
C’est un caractère légitime, mais ici il est utilisé comme un <br/> forcé plus ou moins indétectable pour les agents utilisateurs.
J’espère qu’il y a un coin en enfer spécial pour les gens qui font ça.
ÉDIT : en fait y a tout un tas de caractères de ce genre :
$line = str_replace("\u{200C}", '', $line); // ZWNJ
$line = str_replace("\u{00AD}", '', $line); // soft hyphen
$line = str_replace("\u{200B}", '', $line); // zero-width space
$line = str_replace("\u{200D}", '', $line); // zero-width joiner
$line = str_replace("\u{FEFF}", '', $line); // BOM
$line = str_replace("\u{00A0}", ' ', $line); // non-breaking space
Notez que le le NBSP, je le remplace par le une espace. De toute façon, après je fais un trim(), comme ça les NBSP sur une ligne vide sont virés, mais ceux devant un signe de ponctuation subsitent en tant qu’espace simple. Les autres caractères sont invisibles. Et sont essentiellement facultatifs.