Fonctions pour g=c3=a9rer des ent=c3=aates foireux (non-ASCII) en lecture

10 réponses
Avatar
Olivier Miakinen
Bonjour,

Les entêtes d'un message de courriel (e-mail) ou d'un article usenet
sont censés être en US-ASCII seul, quitte à ce qu'ils soient transformés
en ASCII par un encodage MIME selon le RFC 2047.

Mais il arrive que des logiciels mal configurés envoient des caractères
8-bits dans les entêtes, ce qui pose un problème parce qu'on ne peut
jamais savoir avec certitude dans quel charset on est censé les lire.

Pour les développeurs de logiciels devant recevoir et traiter de tels
messages et en faire quelque chose qui ne fiche pas la pagaille, je
propose trois fonctions, selon le degré de gentillesse qu'on veut
accorder à ces entêtes foireux. Dans chacune, je teste d'abord si
c'est de l'UTF-8 avant de me rabattre sur le CP1252 qui est le Latin1
de Windows (inclut tous les caractères de ISO-8859-1, plus quelques
autres).

=============================================================================
function want_utf8($cs, $str)
{
if (preg_match('//u', $str)) {
printf("%s (%s)\n", $str, $cs);
} else {
printf("%s (%s)\n", iconv("CP1252", "UTF-8", $str), $cs);
}
}
function want_translit($cs, $str)
{
if (preg_match('//u', $str)) {
printf("%s (%s)\n", iconv("UTF-8", "US-ASCII//TRANSLIT", $str), $cs);
} else {
printf("%s (%s)\n", iconv("CP1252", "US-ASCII//TRANSLIT", $str), $cs);
}
}
function want_ignore($cs, $str)
{
if (preg_match('//u', $str)) {
printf("%s (%s)\n", iconv("UTF-8", "US-ASCII//IGNORE", $str), $cs);
} else {
printf("%s (%s)\n", iconv("CP1252", "US-ASCII//IGNORE", $str), $cs);
}
}
=============================================================================

Voici un exemple de programme de test, suivi par le résultat de ce programme.

=============================================================================
$utf8 = "Dom Féranpière©® EUR=€ oe=œ OE=Œ";
$latin9 = iconv("UTF-8", "LATIN9//IGNORE", $utf8);
$cp1252 = iconv("UTF-8", "CP1252//IGNORE", $utf8);

printf("\nStarting string, either in UTF-8, LATIN9 or CP1252:\n");
printf("utf8 = %s\n", $utf8);
printf("latin9 = %s\n", iconv("LATIN9", "UTF-8", $latin9));
printf("cp1252 = %s\n", iconv("CP1252", "UTF-8", $cp1252));

printf("\nFunction want_utf8() if we want to obtain utf8:\n");
want_utf8("utf8", $utf8);
want_utf8("latin9", $latin9);
want_utf8("cp1252", $cp1252);

printf("\nFunction want_translit() to transliterate non ASCII:\n");
want_translit("utf8", $utf8);
want_translit("latin9", $latin9);
want_translit("cp1252", $cp1252);

printf("\nFunction want_ignore() to ignore non ASCII:\n");
want_ignore("utf8", $utf8);
want_ignore("latin9", $latin9);
want_ignore("cp1252", $cp1252);
=============================================================================
Starting string, either in UTF-8, LATIN9 or CP1252:
utf8 = Dom Féranpière©® EUR=€ oe=œ OE=Œ
latin9 = Dom Féranpière©® EUR=€ oe=œ OE=Œ
cp1252 = Dom Féranpière©® EUR=€ oe=œ OE=Œ

Function want_utf8() if we want to obtain utf8:
Dom Féranpière©® EUR=€ oe=œ OE=Œ (utf8)
Dom Féranpière©® EUR=¤ oe=½ OE=¼ (latin9)
Dom Féranpière©® EUR=€ oe=œ OE=Œ (cp1252)

Function want_translit() to transliterate non ASCII:
Dom Feranpiere(C)(R) EUR=EUR oe=oe OE=OE (utf8)
Dom Feranpiere(C)(R) EUR=? oe= 1/2 OE= 1/4 (latin9)
Dom Feranpiere(C)(R) EUR=EUR oe=oe OE=OE (cp1252)

Function want_ignore() to ignore non ASCII:
Dom Franpire EUR= oe= OE= (utf8)
Dom Franpire EUR= oe= OE= (latin9)
Dom Franpire EUR= oe= OE= (cp1252)
=============================================================================

Cordialement,
--
Olivier Miakinen

10 réponses

Avatar
Olivier Miakinen
Le 20/10/2020 23:51, j'écrivais :
============================================================================ > Dom Féranpière©® EUR=¤ oe=½ OE=¼ (latin9)
Dom Feranpiere(C)(R) EUR=? oe= 1/2 OE= 1/4 (latin9)
============================================================================

Je viens juste de comprendre pourquoi iconv rajoute des espaces autour
de « 1/2 » et « 1/4 » lors de la translittération de ½ et ¼ : c'est
pour éviter qu'une valeur telle que « 1½ » devienne « 11/2 ». ;-)
--
Olivier Miakinen
Avatar
yamo'
Olivier Miakinen a écrit :
Bonjour,
Les entêtes d'un message de courriel (e-mail) ou d'un article usenet
sont censés être en US-ASCII seul, quitte à ce qu'ils soient transformés
en ASCII par un encodage MIME selon le RFC 2047.
Mais il arrive que des logiciels mal configurés envoient des caractères
8-bits dans les entêtes, ce qui pose un problème parce qu'on ne peut
jamais savoir avec certitude dans quel charset on est censé les lire.
Pour les développeurs de logiciels devant recevoir et traiter de tels
messages et en faire quelque chose qui ne fiche pas la pagaille, je
propose trois fonctions, selon le degré de gentillesse qu'on veut
accorder à ces entêtes foireux. Dans chacune, je teste d'abord si
c'est de l'UTF-8 avant de me rabattre sur le CP1252 qui est le Latin1
de Windows (inclut tous les caractères de ISO-8859-1, plus quelques
autres).

J'ai adapté ton code en enlevant le printf, je ne sais pas si j'ai bien
fait mais au moins en répondant à
, je n'ai plus un message
vide.
<https://gitlab.com/yamo-nntp/newsportal/-/blob/master/newsportal.php>
Avatar
Olivier Miakinen
Le 21/10/2020 18:16, yamo' a écrit :
J'ai adapté ton code en enlevant le printf, je ne sais pas si j'ai bien
fait mais au moins en répondant à
, je n'ai plus un message
vide.

Je vois ça : <rmpm7a$84f$.
C'est rigolo qu'il ait réussi à translittérer © et ® mais pas é ni è. Quoi qu'il
en soit, l'essentiel c'est que ça donne quelque chose d'utilisable au lieu de
tout faire planter.
--
Olivier Miakinen
Avatar
yamo'
Olivier Miakinen a écrit :
Le 21/10/2020 18:16, yamo' a écrit :
J'ai adapté ton code en enlevant le printf, je ne sais pas si j'ai bien
fait mais au moins en répondant à
, je n'ai plus un message
vide.

Je vois ça : <rmpm7a$84f$.
C'est rigolo qu'il ait réussi à translittérer © et ® mais pas é ni è. Quoi qu'il
en soit, l'essentiel c'est que ça donne quelque chose d'utilisable au lieu de
tout faire planter.

J'ai je pense mis au bon endroit ton code :
https://gitlab.com/yamo-nntp/newsportal/-/blob/master/newsportal.php
lignes 509 à 512.
Et, pour les antislash manquants, je vois qu'il y a plusieurs fois la
fonction stripslashes.
Je regarde ce qu'il se passe en l'enlevant...
https://www.php.net/manual/fr/function.stripslashes.php
--
Stéphane
Avatar
yamo'
yamo' a écrit :
Olivier Miakinen a écrit :
Le 21/10/2020 18:16, yamo' a écrit :
J'ai adapté ton code en enlevant le printf, je ne sais pas si j'ai bien
fait mais au moins en répondant à
, je n'ai plus un message
vide.

Je vois ça : <rmpm7a$84f$.
C'est rigolo qu'il ait réussi à translittérer © et ® mais pas é ni è. Quoi qu'il
en soit, l'essentiel c'est que ça donne quelque chose d'utilisable au lieu de
tout faire planter.

J'ai je pense mis au bon endroit ton code :
https://gitlab.com/yamo-nntp/newsportal/-/blob/master/newsportal.php
lignes 509 à 512.
Et, pour les antislash manquants, je vois qu'il y a plusieurs fois la
fonction stripslashes.
Je regarde ce qu'il se passe en l'enlevant...
https://www.php.net/manual/fr/function.stripslashes.php

J'en ai laissé quelques uns. ????
Maintenant on peut écrire CRLF rn
J'ai mis à jour :
http://news2web.pasdenom.info
--
Stéphane
Le génie est fait d'un dixième d'inspiration... et de neuf dixième de
transpiration.
-+- Thomas Edison (1847-1931) -+-
Avatar
yamo'
Olivier Miakinen a écrit :
Le 21/10/2020 18:16, yamo' a écrit :
J'ai adapté ton code en enlevant le printf, je ne sais pas si j'ai bien
fait mais au moins en répondant à
, je n'ai plus un message
vide.

Je vois ça : <rmpm7a$84f$.
C'est rigolo qu'il ait réussi à translittérer © et ® mais pas é ni è. Quoi qu'il
en soit, l'essentiel c'est que ça donne quelque chose d'utilisable au lieu de
tout faire planter.

Un autre exemple :
Message-ID:
<http://al.howardknight.net/?ID0338413700>
<http://news2web.pasdenom.info/article.php?id82174&group=fr.soc.politique#1582174> (la version actuelle protégée par mot de passe ne fait pas mieux)
Nemo a aussi du mal mais affiche quelque chose :
<http://news2.nemoweb.net/?DataID=
Seamonkey, je ne sais pas ; je ne suis pas abonné à ce groupe.
Pan l'affiche correctement.
--
Stéphane
Avatar
Olivier Miakinen
Le 22/10/2020 à 18:34, yamo' a écrit :
Un autre exemple :
Message-ID:
<http://al.howardknight.net/?ID0338413700>
<http://news2web.pasdenom.info/article.php?id82174&group=fr.soc.politique#1582174> (la version actuelle protégée par mot de passe ne fait pas mieux)
Nemo a aussi du mal mais affiche quelque chose :
<http://news2.nemoweb.net/?DataID=

Très intéressant ! Je recopie le Subject (sous forme de citation pour
qu'il ne soit pas coupé) :
Subject: =?UTF-8?B?VG91dGVzIGxlcyDDqWxlY3Rpb25zIHByw6lzaWRlbnRpZWxsZXMgbm9y? > =?UTF-8?B?ZC1hbcOpcmljYWluZXMgZGVwdWlzIGxhIGd1ZXJyZSBk4oCZSXJhayBvbnQgcHLD? > =?UTF-8?B?qXNlbnTDqSBkZXMgY2FuZGlkYXRzIHF1aSBs4oCZb250IHNvdXRlbnVl?

Eh bien il va falloir faire un rapport de bug à MesNews/1.08.06.00 !
Ce qu'il ne respecte pas, c'est ceci :
<https://tools.ietf.org/html/rfc2047#section-5>
§
Each 'encoded-word' MUST represent an integral number of characters.
A multi-octet character may not be split across adjacent 'encoded-
word's.
§
Soit dit en passant, tous les logiciels que tu as testés sont incorrects
car ils devraient afficher les 'encoded-word's non décodés du fait que
ceux-ci sont incorrects.
Seamonkey, je ne sais pas ; je ne suis pas abonné à ce groupe.

Moi non plus.
Du coup, il va falloir demander à quelqu'un ayant un MesNews de faire
l'essai sur fr.test avec ce titre, à savoir (sans les guillemets) :
« Toutes les élections présidentielles nord-américaines depuis la guerre
d’Irak ont présenté des candidats qui l’ont soutenue »
Avatar
DV
Olivier Miakinen a écrit ceci :
Du coup, il va falloir demander à quelqu'un ayant un MesNews de faire
l'essai sur fr.test avec ce titre, à savoir (sans les guillemets) :
« Toutes les élections présidentielles nord-américaines depuis la guerre
d’Irak ont présenté des candidats qui l’ont soutenue »

Ceci fera-t-il l'affaire ?
<news:
--
Denis
Avatar
yamo'
DV a tapoté le 22/10/2020 19:43:
Olivier Miakinen a écrit ceci :
Du coup, il va falloir demander à quelqu'un ayant un MesNews de faire
l'essai sur fr.test avec ce titre, à savoir (sans les guillemets) :
« Toutes les élections présidentielles nord-américaines depuis la guerre
d’Irak ont présenté des candidats qui l’ont soutenue »

Ceci fera-t-il l'affaire ?
<news:

Il manque la deuxième ligne mais ça coince déjà dans la réponse.
Il me semble avoir un MN quelque part...
--
Stéphane
Avatar
yamo'
yamo' a écrit :
DV a tapoté le 22/10/2020 19:43:
Olivier Miakinen a écrit ceci :
Du coup, il va falloir demander à quelqu'un ayant un MesNews de faire
l'essai sur fr.test avec ce titre, à savoir (sans les guillemets) :
« Toutes les élections présidentielles nord-américaines depuis la guerre
d’Irak ont présenté des candidats qui l’ont soutenue »

Ceci fera-t-il l'affaire ?
<news:

Il manque la deuxième ligne mais ça coince déjà dans la réponse.

J'ai trouvé un deuxième bug qui lui est mineur.
S'il y a un espace au début du sujet NewsPortal, classe le message comme
une réponse.
<rmsjas$3u7$ <http://news2web.pasdenom.info/article.php?id0471&group=fr.test#30471> Mais le sujet est ok!
J'ai copié le texte entre les guillemets espaces compris.
--
Stéphane