Les fonctions de string.h sur de l'arabe ou du chinois

Le
Stephane Tougard
J'ai un programme en C qui utilise un certain nombre de fonctions de
stdio.h ou string.h comme printf, getline, strstr, strncmp sur des
tableau de characteres dans un pointeur de structures.

Tout ce petit monde fonctionne très bien tant qu'on travaille sur notre
bon vieil alphabet. Mais dès que j'essaye avec une entrée en chinois ou
en arabe, je me prends un

traps: hello[25000] general protection ip:45dae0 sp:7ffdb3304c90 error:0 in hello[400000+bf000]

Donc je présume que lorsqu'on a en entrée d'un programme en C un fichier
en UTF-8 qui contient de l'arabe ou du chinois sur le quel on va
appliquer des traitements divers et variés. Il faut avant opérer à une
conversion quelconque dans un format interne au C.

Une piste sur la méthode standard pour résoudre ce petit problème ?
Vidéos High-Tech et Jeu Vidéo
Téléchargements
Vos réponses
Gagnez chaque mois un abonnement Premium avec GNT : Inscrivez-vous !
Trier par : date / pertinence
Jean-Marc Bourguet
Le #26385690
Stephane Tougard
J'ai un programme en C qui utilise un certain nombre de fonctions de
stdio.h ou string.h comme printf, getline, strstr, strncmp sur des
tableau de characteres dans un pointeur de structures.

Tout ce petit monde fonctionne très bien tant qu'on travaille sur notre
bon vieil alphabet. Mais dès que j'essaye avec une entrée en chinois ou
en arabe, je me prends un

traps: hello[25000] general protection ip:45dae0 sp:7ffdb3304c90 error:0 in hello[400000+bf000]

Donc je présume que lorsqu'on a en entrée d'un programme en C un fichier
en UTF-8 qui contient de l'arabe ou du chinois sur le quel on va
appliquer des traitements divers et variés. Il faut avant opérer à une
conversion quelconque dans un format interne au C.

Une piste sur la méthode standard pour résoudre ce petit problème ?



Le sujet est complexe... En restant dans le cadre de la norme, et en
supposant le reste de l'environnement correctement configuré (ce qui est
une grosse hypothèse; en particulier dans le cas de l'arabe qui s'écrit
avec moultes ligatures et de gauche à droite), le plus simple est de faire:

setlocale(LC_ALL, "");

arpès on a le choix entre utiliser les char et savoir qu'on peut avoir plus
d'un char par caractère (il y a une série de fonctions mbXXX -- multi byte
-- qui aident) et utiliser les wchar_t et les formes w des fonctions d'IO
et de gestion de strings en ayant un wchar_t par caractère. Et il faut
être conscient que les caractères c'est les codepoint d'Unicode, donc qu'il
peut y en avoir plusieurs pour un glyphe.

A+

--
Jean-Marc
FAQ de fclc: http://www.levenez.com/lang/c/faq
Site de usenet-fr: http://www.usenet-fr.news.eu.org
Stephane Tougard
Le #26385723
On 2016-01-22, Jean-Marc Bourguet
J'ai un programme en C qui utilise un certain nombre de fonctions de
stdio.h ou string.h comme printf, getline, strstr, strncmp sur des
tableau de characteres dans un pointeur de structures.

Tout ce petit monde fonctionne très bien tant qu'on travaille sur notre
bon vieil alphabet. Mais dès que j'essaye avec une entrée en chinois ou
en arabe, je me prends un

traps: hello[25000] general protection ip:45dae0 sp:7ffdb3304c90 error:0 in hello[400000+bf000]

Donc je présume que lorsqu'on a en entrée d'un programme en C un fichier
en UTF-8 qui contient de l'arabe ou du chinois sur le quel on va
appliquer des traitements divers et variés. Il faut avant opérer à une
conversion quelconque dans un format interne au C.

Une piste sur la méthode standard pour résoudre ce petit problème ?



Le sujet est complexe... En restant dans le cadre de la norme, et en
supposant le reste de l'environnement correctement configuré (ce qui est
une grosse hypothèse; en particulier dans le cas de l'arabe qui s'écrit
avec moultes ligatures et de gauche à droite), le plus simple est de faire:

setlocale(LC_ALL, "");



Rajouté, mais ça ne change rien au problème, j'ai un général protection
ip au premier printf.

Le système est un Debian standard.

arpès on a le choix entre utiliser les char et savoir qu'on peut avoir plus
d'un char par caractère (il y a une série de fonctions mbXXX -- multi byte
-- qui aident) et utiliser les wchar_t et les formes w des fonctions d'IO
et de gestion de strings en ayant un wchar_t par caractère. Et il faut
être conscient que les caractères c'est les codepoint d'Unicode, donc qu'il
peut y en avoir plusieurs pour un glyphe.



Le simple fait de détecter que c'est de l'Arabe et d'ignorer cette
entrée serait déjà un pas en avant.
Lucas Levrel
Le #26385737
Le 23 janvier 2016, Stephane Tougard a écrit :

On 2016-01-22, Jean-Marc Bourguet

traps: hello[25000] general protection ip:45dae0 sp:7ffdb3304c90 error:0 in hello[400000+bf000]



setlocale(LC_ALL, "");



Rajouté, mais ça ne change rien au problème, j'ai un général protection
ip au premier printf.



Sans ECM ça va être dur de t'aider...

--
LL
Ἕν οἶδα ὅτι οὐδὲν οἶδα (Σωκράτης)
cLx
Le #26385745
On 23/01/2016 11:44, Lucas Levrel wrote:
Le 23 janvier 2016, Stephane Tougard a écrit :

On 2016-01-22, Jean-Marc Bourguet

traps: hello[25000] general protection ip:45dae0 sp:7ffdb3304c90 error:0
in hello[400000+bf000]



setlocale(LC_ALL, "");



Rajouté, mais ça ne change rien au problème, j'ai un général protection
ip au premier printf.



Sans ECM ça va être dur de t'aider...




C'est bizarre que ça puisse planter comme ça... Appliquer des traitements non
appropriés sur la chaîne, ok, mais carrément planter ?

Est-ce que printf() est utilisé comme ceci ?
printf("%s", null_terminated_input_string);

(et pas comme cela ?)
printf(null_terminated_input_string);
Samuel DEVULDER
Le #26385752
Le 23/01/2016 12:50, cLx a écrit :

C'est bizarre que ça puisse planter comme ça... Appliquer des
traitements non appropriés sur la chaîne, ok, mais carrément planter ?

Est-ce que printf() est utilisé comme ceci ?
printf("%s", null_terminated_input_string);

(et pas comme cela ?)
printf(null_terminated_input_string);



Il est indiqué ici:
https://en.wikipedia.org/wiki/Null-terminated_string#Character_encodings
que toutes les chaines utf-8 ne peuvent pas forcément être représenté en
chaine se terminant par un nul.

Si ca se trouve c'est le cas ici, la chaine utf-8 contient un nul
plus-tot que la la fin. Du coup strlen (ne détectant pas l’échappement
utf-8) conduit à l'allocation d'un buffer trop petit résultant dans un
débordement de mémoire.

Un truc à savoir: d'habitude quand on supprime une lettre à une chaine,
le strlen() diminue... Mais pas forcément avec l'arabe et l'UTF8 (où
l'unicode). En relation avec les ligatures, une lettre de moins peut
résulter en une chaine plus longue. C'est probablement cela qui a
conduit à un bug dans les iPhones sur les chaines arabes raccourcie dans
la zone de notification.

http://www.lefigaro.fr/secteur/high-tech/2015/05/27/32001-20150527ARTFIG00402-recevoir-ce-texo-fera-planter-a-coup-sur-votre-iphone.php

https://www.youtube.com/watch?v=hJLMSllzoLA

a+

sam.
Stephane Tougard
Le #26385787
On 2016-01-23, cLx
C'est bizarre que ça puisse planter comme ça... Appliquer des traitements non
appropriés sur la chaîne, ok, mais carrément planter ?



Bon, honte à moi, le problème n'était pas du à l'UTF8, mais à la place
que prend une chaine de characteres en UTF8. Un simple dépassement de
tableau.

Désolé, ça aurait pu être un problème intéressant à résoudre, mais même
pas, c'est une simplement une erreur de débutant.
espie
Le #26385795
In article Samuel DEVULDER
Le 23/01/2016 12:50, cLx a écrit :

C'est bizarre que ça puisse planter comme ça... Appliquer des
traitements non appropriés sur la chaîne, ok, mais carrément planter ?

Est-ce que printf() est utilisé comme ceci ?
printf("%s", null_terminated_input_string);

(et pas comme cela ?)
printf(null_terminated_input_string);



Il est indiqué ici:
https://en.wikipedia.org/wiki/Null-terminated_string#Character_encodings
que toutes les chaines utf-8 ne peuvent pas forcément être représenté en
chaine se terminant par un nul.



La j'ai des doutes. Ca suppose qu'on considere NUL comme caractere
valide dans la chaine (ce que dit la page wikipedia). On sort quand meme
fortement des conditions usuelles d'utilisation du C.
Olivier Miakinen
Le #26385840
Le 23/01/2016 13:26, Samuel DEVULDER a écrit :

Il est indiqué ici:
https://en.wikipedia.org/wiki/Null-terminated_string#Character_encodings
que toutes les chaines utf-8 ne peuvent pas forcément être représenté en
chaine se terminant par un nul.



Non, ce n'est pas ça qui est indiqué, c'est plutôt le contraire.

Sachant que le caractère nul est représenté par un octet nul, il n'est
pas possible de coder une chaîne US-ASCII ou UTF-8 *contenant* un nul
en utilisant la convention du langage C selon laquelle le nul termine
la chaîne.

Si donc on a *besoin* d'envoyer un texte pouvant *contenir* un nul,
on ne peut pas utiliser l'UTF-8 standard et il faut utiliser un UTF-8
modifié dans lequel le nul est représenté par C0 80 (encodage interdit
en UTF-8 et dûment contrôlé).

Si ca se trouve c'est le cas ici, la chaine utf-8 contient un nul
plus-tot que la la fin. Du coup strlen (ne détectant pas l’échappement
utf-8) conduit à l'allocation d'un buffer trop petit résultant dans un
débordement de mémoire.



C'est doublement impossible, d'abord parce que cette chaîne aurait été
rejetée comme n'étant pas de l'UTF-8, et aussi parce que le strlen ne
prendra pas le C0 80 pour une fin de chaîne.

Cordialement,
--
Olivier Miakinen
Publicité
Poster une réponse
Anonyme