Twitter iPhone pliant OnePlus 11 PS5 Disney+ Orange Livebox Windows 11

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

8 réponses
Avatar
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 ?

8 réponses

Avatar
Jean-Marc Bourguet
Stephane Tougard writes:

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
Avatar
Stephane Tougard
On 2016-01-22, Jean-Marc Bourguet wrote:
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.
Avatar
Lucas Levrel
Le 23 janvier 2016, Stephane Tougard a écrit :

On 2016-01-22, Jean-Marc Bourguet wrote:

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
Ἕν οἶδα ὅτι οὐδὲν οἶδα (Σωκράτης)
Avatar
cLx
On 23/01/2016 11:44, Lucas Levrel wrote:
Le 23 janvier 2016, Stephane Tougard a écrit :

On 2016-01-22, Jean-Marc Bourguet wrote:

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);
Avatar
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.

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.
Avatar
Stephane Tougard
On 2016-01-23, cLx 'aimail.com.almost.invalid> wrote:

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.
Avatar
espie
In article <n7vrh6$sme$,
Samuel DEVULDER wrote:
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.
Avatar
Olivier Miakinen
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