utf-8

Le
tth
Bonsoir.

Voilà, j'ai du vieux code bien cracra (20 ans d'age) à qui il arrive
de traiter du texte. Avec des casts de goret dedans. Et maintenant,
je voudrais que ce machin comprenne l'utf-8 de manière propre.

Voici donc deux questions :

- Où trouver un guide des bonnes pratiques dans ce domaine ?
- Vers quoi me tourner pour une conversion utf-8 -> CP437 ?


tTh, angoissé

--
http://my.smeuh.org/
Vidéos High-Tech et Jeu Vidéo
Téléchargements
Vos réponses Page 1 / 2
Gagnez chaque mois un abonnement Premium avec GNT : Inscrivez-vous !
Trier par : date / pertinence
Sébastien Kirche
Le #26337375
Le 4 February 2015 à 18:11, tth a dit :

Bonsoir.

Voilà, j'ai du vieux code bien cracra (20 ans d'age) à qui il arrive
de traiter du texte. Avec des casts de goret dedans. Et maintenant,
je voudrais que ce machin comprenne l'utf-8 de manière propre.

Voici donc deux questions :

- Où trouver un guide des bonnes pratiques dans ce domaine ?
- Vers quoi me tourner pour une conversion utf-8 -> CP437 ?



À tout hasard, libiconv pourrait te convenir ? J'ai utilisé pour
ressusciter un vieux code (début des années 90) qui ne causait qu'ascii
pour lui faire comprendre les encodages modernes. C'est même visible en
ligne sur gougeule code[¹].

tTh, angoissé...



Meuh non, ça va bien se passer :o)


[¹] https://code.google.com/p/patrocle/source/browse/trunk/bot/
--
Sébastien Kirche
Damien Wyart
Le #26337393
* tth
Voilà, j'ai du vieux code bien cracra (20 ans d'age) à qui il arrive
de traiter du texte. Avec des casts de goret dedans. Et maintenant,
je voudrais que ce machin comprenne l'utf-8 de manière propre.

Voici donc deux questions :
- Où trouver un guide des bonnes pratiques dans ce domaine ?
- Vers quoi me tourner pour une conversion utf-8 -> CP437 ?



Les deux « classiques » du domaine sont iconv (et libiconv) et recode
(et librecode) :

https://www.gnu.org/software/libiconv/
https://github.com/pinard/Recode

Il y a également ICU d'IBM, beaucoup utilisé fin 90/début 2000 mais qui
me semble en perte de vitesse et qui est assez usine à gaz :
http://site.icu-project.org/

Pour de la lecture, il y a par exemple ceci :
http://www.cl.cam.ac.uk/~mgk25/unicode.html
http://unicodebook.readthedocs.org/ (non joignable pour le moment mais dans le cache Google)
http://www.joelonsoftware.com/articles/Unicode.html
http://unicode.org/faq/programming.html
http://linuxgazette.net/147/pfeiffer.html

--
DW
tth
Le #26337425
On 02/04/2015 07:46 PM, Sébastien Kirche a dit:

Voici donc deux questions :

- Où trouver un guide des bonnes pratiques "utf8" ?
- Vers quoi me tourner pour une conversion utf-8 -> CP437 ?



À tout hasard, libiconv pourrait te convenir ? J'ai utilisé pour
ressusciter un vieux code (début des années 90) qui ne causait qu'ascii



Oui, je regarde iconv(3) et je pense que c'est bon pour ce que
je veux faire. Mais ça ne répond pas à ma première question.

Des incertitudes àlc genre "que retourne strlen sur un argv[2]
qui vient d'un shell en utf8 ?" ce genre de chose qui peut
conduire à un *poke* dans la pile, voire même pire.



--
--- http://my.smeuh.org/ ---
Xavier Roche
Le #26337447
On 02/04/2015 11:32 PM, tth wrote:
Des incertitudes àlc genre "que retourne strlen sur un argv[2]
qui vient d'un shell en utf8 ?" ce genre de chose qui peut
conduire à un *poke* dans la pile, voire même pire.



strlen() et ses amis renverront toujours le nombre d'octets, mais pas nécessairement le nombre de caractères.

donc en utf-8,
strlen("e") == 1
strlen("é") == 2
strlen("ₑ") == 3

Du coup il n'est plus possible d'accéder en temps constant au Nième *caractère*, mais c'est toujours bon pour le Nième *octet* :)

Mais pas mal de propriétés restent vraies: l'ascii est préservé (tout l'ascii 7-bit), le tri fonctionne toujours (le tri standard d'une chaîne utf-8 va également trier selon le code unicode), etc.

Selon le programme, cela peut ou non être gênant (typiquement si on traite les arguments comme des chaines opaques pour open(), cela ne pose aucun souci)
Antoine Leca
Le #26337682
Le 04/02/2015 22:32Z, tth écrivit :
- Où trouver un guide des bonnes pratiques "utf8" ?







UTF-8 est un encodage de caractères à longueur variable, ce qui est un
peu plus complexe que les encodages à longueur fixe (ASCII, iso-8859,
UTF-32, ou l'Unicode original UCS-2) ; mais en dehors de cela, c'est un
encodage très facile à manipuler: il n'est pas ambigu, il est
déterministe (pas d'état), il se resynchronise en 6 octets au maximum.

Tous les guides sur les encodages à longueur variable peuvent donc
convenir. Par exemple, ceux écrit par Apple, Microsoft ou IBM dans les
années 1980 (à l'époque du Shift-JIS).


Des incertitudes àlc genre "que retourne strlen sur un argv[2]
qui vient d'un shell en utf8 ?"



Le nombre de "bytes" (multiplet en français du livre).
Ce qu'il faut comprendre avec les encodages à longueur variable, c'est
que les chaînes (char*) représentent une suite de caractères, et qu'il
faut les manipuler comme telles. En particulier, un caractère est une
chaîne (qui a entre 1 et 6 bytes, plus le '' final).
Autrement dit, les manipulations de str* ou de char* sont normalement
sans problème ; ce à quoi il faut s'intéresser, c'est aux manipulations
sur les caractères individuels. Surtout quand ce ne sont _pas_ des
chiffres ou des lettres du code US-ASCII.

ce genre de chose qui peut conduire à un *poke* dans la pile, voire


même pire.

Uniquement avec des manipulations douteuses. Et avec UTF-8, c'est
difficile, parce qu'il faut avoir de mauvaises intentions pour se
tromper à ce point. Par exemple, un truc horrible du genre
for (char*p; *p; p++) {
/* . . . */
if (*p == 'è') *p ='e'; // supprime les accents

va peut-être susciter un avertissement du compilateur (parce que 'è' est
une constante caractère multi-byte, un truc louche et pas portable) mais
à par cela, il n'y aura pas d'effet (et le è va garder son accent).


Pour moi, la conséquence la plus visible de l'UTF-8, c'est que les
déclarations de chaînes doivent être agrandies.


Antoine
espie
Le #26337683
In article Antoine Leca
Le 04/02/2015 22:32Z, tth écrivit :
- Où trouver un guide des bonnes pratiques "utf8" ?







UTF-8 est un encodage de caractères à longueur variable, ce qui est un
peu plus complexe que les encodages à longueur fixe (ASCII, iso-8859,
UTF-32, ou l'Unicode original UCS-2) ; mais en dehors de cela, c'est un
encodage très facile à manipuler: il n'est pas ambigu, il est
déterministe (pas d'état), il se resynchronise en 6 octets au maximum.

Tous les guides sur les encodages à longueur variable peuvent donc
convenir. Par exemple, ceux écrit par Apple, Microsoft ou IBM dans les
années 1980 (à l'époque du Shift-JIS).



Attention aux buffer overflow. Il y a eu des tonnes de bug dans la
plupart des bibliotheques de gestion d'UTF8. Il ne faut *pas* faire
confiance aveuglement a une chaine "en instance de decodage" mais bien
bloquer a 6 octets, meme si on ne voit pas d'octet de fin.

Une autre difficulte d'utf8 est liee aux diacritiques (les accents): il y a
plusieurs facons d'encoder le meme caractere + accent, et il faut se
renseigner sur les formes normales. C'est necessaire pour faire des
recherches de texte qui ressemblent a quelques choses.

Le dernier ecueil est purement fonctionnel: il y a des caracteres dont
la graphie est tres proche qui sont fondamentalement differents. C'est un
vecteur d'attaque pour les sites web internationaux (depuis qu'on peut
mettre de l'unicode dans les noms de site): l'analogue de se faire passer
pour microsoft en s'appelant micro$oft, mais en plus subtil et de facon
invisible avec une police usuelle...
Tous les navigateurs modernes decents ont un mecanisme ou deux pour empecher
ce genre de choses, en mettant dans une couleur differente un caractere
"louche" au milieu d'un nom de site.
Antoine Leca
Le #26337712
Le 06/02/2015 11:43, Marc Espie écrivit :
Attention aux buffer overflow.



Oui, bien sûr.

Il y a eu des tonnes de bug dans la
plupart des bibliotheques de gestion d'UTF8.



Ce qui me fait penser à un autre problème de UTF-8 (qui a été beaucoup
«exploité»), qui sont les faux encodages : exemple (utilisé par Java),
"xC0x80" «représente» la même chose que "", mais bien sûr n'a pas
les mêmes propriétés ; autres exemples, "xC0xAExC0xAExC0xAF"
représente "../", ce qui permet de passer à travers les répertoires,
avec des effets dévastateurs en terme de sécurité (la variante
"xC0xAExC0xAExC1x9C" pour ".." pourrait s'appeler CodeRed, et fut
responsable en 2001 d'un des plus gros bogues de Microsoft).

Il est indispensable d'être strict dans le décodage des éléments UTF-8
(et d'abord, décoder uniquement lorsque c'est nécessaire) : en dehors de
CESU-8 (qui ne devrait pas être un problème en pratique pour la
translittération en UTF-8 par nous autres Français d'un programme
pré-existant) et hors Java, les faux encodages sont *toujours* des
erreurs. Cela a pour corolaire de prévoir un mécanisme de rejet, pour
avoir un comportement globalement sain en présence d'une entrée erronée.


Antoine
Olivier Miakinen
Le #26337804
Le 06/02/2015 11:29, Antoine Leca a écrit :

UTF-8 [...] se resynchronise en 6 octets au maximum.



En 4 octets au maximum dans la version actuelle de la norme.

[...] En particulier, un caractère est une
chaîne (qui a entre 1 et 6 bytes, plus le '' final).



Entre 1 et 4 bytes maintenant, et ça ne devrait plus changer.
tth
Le #26337815
On 02/06/2015 01:56 PM, Antoine Leca a dit:

Ce qui me fait penser à un autre problème de UTF-8 (qui a été beaucoup
«exploité»), qui sont les faux encodages : exemple (utilisé par Java),
"xC0x80" «représente» la même chose que "", mais bien sûr n'a pas
les mêmes propriétés ; autres exemples, "xC0xAExC0xAExC0xAF"
représente "../", ce qui permet de passer à travers les répertoires,



Voilà, c'est à ce genre de piège que je pensais quand je parlais
d'un guide des bonnes manières.

--
--- http://my.smeuh.org/ ---
espie
Le #26337858
In article
On 02/06/2015 01:56 PM, Antoine Leca a dit:

Ce qui me fait penser à un autre problème de UTF-8 (qui a été beaucoup
«exploité»), qui sont les faux encodages : exemple (utilisé par Java),
"xC0x80" «représente» la même chose que "", mais bien sûr n'a pas
les mêmes propriétés ; autres exemples, "xC0xAExC0xAExC0xAF"
représente "../", ce qui permet de passer à travers les répertoires,



Voilà, c'est à ce genre de piège que je pensais quand je parlais
d'un guide des bonnes manières.



Ben je pense que du coup, tu as largement de quoi faire et te faire peur...
Publicité
Poster une réponse
Anonyme