Les fonctions de string.h sur de l'arabe ou du chinois
8 réponses
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 ?
Cette action est irreversible, confirmez la suppression du commentaire ?
Signaler le commentaire
Veuillez sélectionner un problème
Nudité
Violence
Harcèlement
Fraude
Vente illégale
Discours haineux
Terrorisme
Autre
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.
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
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.
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.
On 2016-01-22, Jean-Marc Bourguet <jm@bourguet.org> 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.
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 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 Ἕν οἶδα ὅτι οὐδὲν οἶδα (Σωκράτης)
Le 23 janvier 2016, Stephane Tougard a écrit :
On 2016-01-22, Jean-Marc Bourguet <jm@bourguet.org> 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.
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.
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.
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.
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.
In article <n7vrh6$sme$1@gioia.aioe.org>,
Samuel DEVULDER <samuel-dot-devulder@laposte-dot-net.invalid> wrote:
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.
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.
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
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.
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.