struct NAME
{
struct NAME * next;
char name[1];
};
puis :
strcpy(p->name, dp2->d_name);
Il me semble que strcpy copie jusqu'au premier \0 ? A moins que la
chaine soit vide, ce genre de truc va forcément "déborder", non et
corrompre la stack ?
Le 06-09-2008, à propos de strcpy sur un char[1] ???, Alain Montfranc écrivait dans fr.comp.lang.c :
Bonjour
Rebonjour ;-)
Dans un code source je trouve cela :
struct NAME { struct NAME * next; char name[1]; };
puis :
strcpy(p->name, dp2->d_name);
Des noms, des noms, des noms ! ;-)
Il me semble que strcpy copie jusqu'au premier ? A moins que la chaine soit vide, ce genre de truc va forcément "déborder", non et corrompre la stack ?
Oui. Je site :
La fonction strcpy() copie la chaîne pointée par src, y compris le car actère nul (« ») final dans la chaîne pointée par dest.
Ça déborde dès que la chaine source est de taille strictement supérieure à 0
JKB
-- Le cerveau, c'est un véritable scandale écologique. Il représente 2% de notre masse corporelle, mais disperse à lui seul 25% de l'énergie que nous consommons tous les jours.
Le 06-09-2008, à propos de
strcpy sur un char[1] ???,
Alain Montfranc écrivait dans fr.comp.lang.c :
Bonjour
Rebonjour ;-)
Dans un code source je trouve cela :
struct NAME
{
struct NAME * next;
char name[1];
};
puis :
strcpy(p->name, dp2->d_name);
Des noms, des noms, des noms ! ;-)
Il me semble que strcpy copie jusqu'au premier ? A moins que la
chaine soit vide, ce genre de truc va forcément "déborder", non et
corrompre la stack ?
Oui. Je site :
La fonction strcpy() copie la chaîne pointée par src, y compris le car
actère nul (« ») final dans la chaîne pointée par dest.
Ça déborde dès que la chaine source est de taille strictement supérieure
à 0
JKB
--
Le cerveau, c'est un véritable scandale écologique. Il représente 2% de notre
masse corporelle, mais disperse à lui seul 25% de l'énergie que nous
consommons tous les jours.
Le 06-09-2008, à propos de strcpy sur un char[1] ???, Alain Montfranc écrivait dans fr.comp.lang.c :
Bonjour
Rebonjour ;-)
Dans un code source je trouve cela :
struct NAME { struct NAME * next; char name[1]; };
puis :
strcpy(p->name, dp2->d_name);
Des noms, des noms, des noms ! ;-)
Il me semble que strcpy copie jusqu'au premier ? A moins que la chaine soit vide, ce genre de truc va forcément "déborder", non et corrompre la stack ?
Oui. Je site :
La fonction strcpy() copie la chaîne pointée par src, y compris le car actère nul (« ») final dans la chaîne pointée par dest.
Ça déborde dès que la chaine source est de taille strictement supérieure à 0
JKB
-- Le cerveau, c'est un véritable scandale écologique. Il représente 2% de notre masse corporelle, mais disperse à lui seul 25% de l'énergie que nous consommons tous les jours.
Erwan David
Alain Montfranc écrivait :
Bonjour
Dans un code source je trouve cela :
struct NAME { struct NAME * next; char name[1]; };
puis :
strcpy(p->name, dp2->d_name);
Il me semble que strcpy copie jusqu'au premier ? A moins que la chaine soit vide, ce genre de truc va forcément "déborder", non et corrompre la stack ?
Tout dépend de comment a été alloué p.
-- Le travail n'est pas une bonne chose. Si ça l'était, les riches l'auraient accaparé
Alain Montfranc <x@x.con> écrivait :
Bonjour
Dans un code source je trouve cela :
struct NAME
{
struct NAME * next;
char name[1];
};
puis :
strcpy(p->name, dp2->d_name);
Il me semble que strcpy copie jusqu'au premier ? A moins que la
chaine soit vide, ce genre de truc va forcément "déborder", non et
corrompre la stack ?
Tout dépend de comment a été alloué p.
--
Le travail n'est pas une bonne chose. Si ça l'était,
les riches l'auraient accaparé
struct NAME { struct NAME * next; char name[1]; };
puis :
strcpy(p->name, dp2->d_name);
Il me semble que strcpy copie jusqu'au premier ? A moins que la chaine soit vide, ce genre de truc va forcément "déborder", non et corrompre la stack ?
Tout dépend de comment a été alloué p.
-- Le travail n'est pas une bonne chose. Si ça l'était, les riches l'auraient accaparé
Alain Montfranc
Erwan David a écrit
Alain Montfranc écrivait :
Bonjour
Dans un code source je trouve cela :
struct NAME { struct NAME * next; char name[1]; };
puis :
strcpy(p->name, dp2->d_name);
Il me semble que strcpy copie jusqu'au premier ? A moins que la chaine soit vide, ce genre de truc va forcément "déborder", non et corrompre la stack ?
Tout dépend de comment a été alloué p.
Par un malloc. Ca change quoi ?
Erwan David a écrit
Alain Montfranc <x@x.con> écrivait :
Bonjour
Dans un code source je trouve cela :
struct NAME
{
struct NAME * next;
char name[1];
};
puis :
strcpy(p->name, dp2->d_name);
Il me semble que strcpy copie jusqu'au premier ? A moins que la
chaine soit vide, ce genre de truc va forcément "déborder", non et
corrompre la stack ?
struct NAME { struct NAME * next; char name[1]; };
puis :
strcpy(p->name, dp2->d_name);
Il me semble que strcpy copie jusqu'au premier ? A moins que la chaine soit vide, ce genre de truc va forcément "déborder", non et corrompre la stack ?
Tout dépend de comment a été alloué p.
Par un malloc. Ca change quoi ?
Alain Montfranc
JKB a écrit
Le 06-09-2008, à propos de strcpy sur un char[1] ???, Alain Montfranc écrivait dans fr.comp.lang.c :
Bonjour
Rebonjour ;-)
Dans un code source je trouve cela :
struct NAME { struct NAME * next; char name[1]; };
puis :
strcpy(p->name, dp2->d_name);
Des noms, des noms, des noms ! ;-)
openqm, version gpl
Il me semble que strcpy copie jusqu'au premier ? A moins que la chaine soit vide, ce genre de truc va forcément "déborder", non et corrompre la stack ?
Oui. Je site :
La fonction strcpy() copie la chaîne pointée par src, y compris le car actère nul (« ») final dans la chaîne pointée par dest.
Ça déborde dès que la chaine source est de taille strictement supérieure à 0
JKB
beurk quoi...
JKB a écrit
Le 06-09-2008, à propos de
strcpy sur un char[1] ???,
Alain Montfranc écrivait dans fr.comp.lang.c :
Bonjour
Rebonjour ;-)
Dans un code source je trouve cela :
struct NAME
{
struct NAME * next;
char name[1];
};
puis :
strcpy(p->name, dp2->d_name);
Des noms, des noms, des noms ! ;-)
openqm, version gpl
Il me semble que strcpy copie jusqu'au premier ? A moins que la
chaine soit vide, ce genre de truc va forcément "déborder", non et
corrompre la stack ?
Oui. Je site :
La fonction strcpy() copie la chaîne pointée par src, y compris le car
actère nul (« ») final dans la chaîne pointée par dest.
Ça déborde dès que la chaine source est de taille strictement supérieure
à 0
Le 06-09-2008, à propos de strcpy sur un char[1] ???, Alain Montfranc écrivait dans fr.comp.lang.c :
Bonjour
Rebonjour ;-)
Dans un code source je trouve cela :
struct NAME { struct NAME * next; char name[1]; };
puis :
strcpy(p->name, dp2->d_name);
Des noms, des noms, des noms ! ;-)
openqm, version gpl
Il me semble que strcpy copie jusqu'au premier ? A moins que la chaine soit vide, ce genre de truc va forcément "déborder", non et corrompre la stack ?
Oui. Je site :
La fonction strcpy() copie la chaîne pointée par src, y compris le car actère nul (« ») final dans la chaîne pointée par dest.
Ça déborde dès que la chaine source est de taille strictement supérieure à 0
JKB
beurk quoi...
Erwan David
Alain Montfranc écrivait :
Erwan David a écrit
Alain Montfranc écrivait :
Bonjour
Dans un code source je trouve cela :
struct NAME { struct NAME * next; char name[1]; };
puis :
strcpy(p->name, dp2->d_name);
Il me semble que strcpy copie jusqu'au premier ? A moins que la chaine soit vide, ce genre de truc va forcément "déborder", non et corrompre la stack ?
Tout dépend de comment a été alloué p.
Par un malloc. Ca change quoi ?
malloc avec quelle taille ? C'est une technique classique en C pré 99 d'avoir une structure qui déclare un dernier composant qui est un tableau de taille 1, mais la taille allouée est celle qu'il faut.
-- Le travail n'est pas une bonne chose. Si ça l'était, les riches l'auraient accaparé
Alain Montfranc <x@x.con> écrivait :
Erwan David a écrit
Alain Montfranc <x@x.con> écrivait :
Bonjour
Dans un code source je trouve cela :
struct NAME
{
struct NAME * next;
char name[1];
};
puis :
strcpy(p->name, dp2->d_name);
Il me semble que strcpy copie jusqu'au premier ? A moins que la
chaine soit vide, ce genre de truc va forcément "déborder", non et
corrompre la stack ?
Tout dépend de comment a été alloué p.
Par un malloc. Ca change quoi ?
malloc avec quelle taille ? C'est une technique classique en C pré 99
d'avoir une structure qui déclare un dernier composant qui est un
tableau de taille 1, mais la taille allouée est celle qu'il faut.
--
Le travail n'est pas une bonne chose. Si ça l'était,
les riches l'auraient accaparé
struct NAME { struct NAME * next; char name[1]; };
puis :
strcpy(p->name, dp2->d_name);
Il me semble que strcpy copie jusqu'au premier ? A moins que la chaine soit vide, ce genre de truc va forcément "déborder", non et corrompre la stack ?
Tout dépend de comment a été alloué p.
Par un malloc. Ca change quoi ?
malloc avec quelle taille ? C'est une technique classique en C pré 99 d'avoir une structure qui déclare un dernier composant qui est un tableau de taille 1, mais la taille allouée est celle qu'il faut.
-- Le travail n'est pas une bonne chose. Si ça l'était, les riches l'auraient accaparé
Alain Montfranc
Erwan David a écrit
Alain Montfranc écrivait :
Erwan David a écrit
Alain Montfranc écrivait :
Bonjour
Dans un code source je trouve cela :
struct NAME { struct NAME * next; char name[1]; };
puis :
strcpy(p->name, dp2->d_name);
Il me semble que strcpy copie jusqu'au premier ? A moins que la chaine soit vide, ce genre de truc va forcément "déborder", non et corrompre la stack ?
Tout dépend de comment a été alloué p.
Par un malloc. Ca change quoi ?
malloc avec quelle taille ? C'est une technique classique en C pré 99 d'avoir une structure qui déclare un dernier composant qui est un tableau de taille 1, mais la taille allouée est celle qu'il faut.
ok
Erwan David a écrit
Alain Montfranc <x@x.con> écrivait :
Erwan David a écrit
Alain Montfranc <x@x.con> écrivait :
Bonjour
Dans un code source je trouve cela :
struct NAME
{
struct NAME * next;
char name[1];
};
puis :
strcpy(p->name, dp2->d_name);
Il me semble que strcpy copie jusqu'au premier ? A moins que la
chaine soit vide, ce genre de truc va forcément "déborder", non et
corrompre la stack ?
Tout dépend de comment a été alloué p.
Par un malloc. Ca change quoi ?
malloc avec quelle taille ? C'est une technique classique en C pré 99
d'avoir une structure qui déclare un dernier composant qui est un
tableau de taille 1, mais la taille allouée est celle qu'il faut.
struct NAME { struct NAME * next; char name[1]; };
puis :
strcpy(p->name, dp2->d_name);
Il me semble que strcpy copie jusqu'au premier ? A moins que la chaine soit vide, ce genre de truc va forcément "déborder", non et corrompre la stack ?
Tout dépend de comment a été alloué p.
Par un malloc. Ca change quoi ?
malloc avec quelle taille ? C'est une technique classique en C pré 99 d'avoir une structure qui déclare un dernier composant qui est un tableau de taille 1, mais la taille allouée est celle qu'il faut.
ok
Antoine Leca
En news:, JKB va escriure:
Le 06-09-2008, à propos de strcpy sur un char[1] ???, Alain Montfranc écrivait dans fr.comp.lang.c :
struct NAME { struct NAME * next; char name[1]; }; strcpy(p->name, dp2->d_name); Il me semble que strcpy copie jusqu'au premier ?
Oui. Je site : La fonction strcpy() copie la chaîne pointée par src, y compris le car actère nul (« ») final dans la chaîne pointée par dest.
Et...
Ça déborde dès que la chaine source est de taille strictement supérieure à 0
Cela ne déborde que si la chaîne finale (la vraie, pas la déclaration) a une taille réservée inférieure à la taille réelle (strlen+1) de la chaîne origine.
Et en C, du fait de l'équivalence pointeur-tableau, la déclaration « visible » d'un tableau n'est pas forcément la déclaration réelle, en particulier en ce qui concerne la taille du tableau.
Antoine
En news:slrngc5jaf.mmh.knatschke@rayleigh.systella.fr, JKB va escriure:
Le 06-09-2008, à propos de strcpy sur un char[1] ???,
Alain Montfranc écrivait dans fr.comp.lang.c :
struct NAME { struct NAME * next; char name[1]; };
strcpy(p->name, dp2->d_name);
Il me semble que strcpy copie jusqu'au premier ?
Oui. Je site :
La fonction strcpy() copie la chaîne pointée par src, y
compris le car actère nul (« ») final dans la chaîne
pointée par dest.
Et...
Ça déborde dès que la chaine source est de taille strictement
supérieure à 0
Cela ne déborde que si la chaîne finale (la vraie, pas la déclaration) a une
taille réservée inférieure à la taille réelle (strlen+1) de la chaîne
origine.
Et en C, du fait de l'équivalence pointeur-tableau, la déclaration
« visible » d'un tableau n'est pas forcément la déclaration réelle, en
particulier en ce qui concerne la taille du tableau.
Le 06-09-2008, à propos de strcpy sur un char[1] ???, Alain Montfranc écrivait dans fr.comp.lang.c :
struct NAME { struct NAME * next; char name[1]; }; strcpy(p->name, dp2->d_name); Il me semble que strcpy copie jusqu'au premier ?
Oui. Je site : La fonction strcpy() copie la chaîne pointée par src, y compris le car actère nul (« ») final dans la chaîne pointée par dest.
Et...
Ça déborde dès que la chaine source est de taille strictement supérieure à 0
Cela ne déborde que si la chaîne finale (la vraie, pas la déclaration) a une taille réservée inférieure à la taille réelle (strlen+1) de la chaîne origine.
Et en C, du fait de l'équivalence pointeur-tableau, la déclaration « visible » d'un tableau n'est pas forcément la déclaration réelle, en particulier en ce qui concerne la taille du tableau.
Antoine
JKB
Le 09-09-2008, à propos de Re: strcpy sur un char[1] ???, Antoine Leca écrivait dans fr.comp.lang.c :
En news:, JKB va escriure:
Le 06-09-2008, à propos de strcpy sur un char[1] ???, Alain Montfranc écrivait dans fr.comp.lang.c :
struct NAME { struct NAME * next; char name[1]; }; strcpy(p->name, dp2->d_name); Il me semble que strcpy copie jusqu'au premier ?
Oui. Je site : La fonction strcpy() copie la chaîne pointée par src, y compris le car actère nul (« ») final dans la chaîne pointée par dest.
Et...
Ça déborde dès que la chaine source est de taille strictement supérieure à 0
Cela ne déborde que si la chaîne finale (la vraie, pas la déclaration) a une taille réservée inférieure à la taille réelle (strlen+1) de la chaîne origine.
Et en C, du fait de l'équivalence pointeur-tableau, la déclaration « visible » d'un tableau n'est pas forcément la déclaration réelle, en particulier en ce qui concerne la taille du tableau.
Nous sommes d'accord, mais je réagissais avec le source sous les yeux (ce fil est issu d'une discussion avec un psychopathe sur un autre forum). Dans le code en question, une structure est déclarée, et _jamais_ on ne contrôle que le strcpy ne va pas écraser quelque chose.
Cordialement,
JKB
-- Le cerveau, c'est un véritable scandale écologique. Il représente 2% de notre masse corporelle, mais disperse à lui seul 25% de l'énergie que nous consommons tous les jours.
Le 09-09-2008, à propos de
Re: strcpy sur un char[1] ???,
Antoine Leca écrivait dans fr.comp.lang.c :
En news:slrngc5jaf.mmh.knatschke@rayleigh.systella.fr, JKB va escriure:
Le 06-09-2008, à propos de strcpy sur un char[1] ???,
Alain Montfranc écrivait dans fr.comp.lang.c :
struct NAME { struct NAME * next; char name[1]; };
strcpy(p->name, dp2->d_name);
Il me semble que strcpy copie jusqu'au premier ?
Oui. Je site :
La fonction strcpy() copie la chaîne pointée par src, y
compris le car actère nul (« ») final dans la chaîne
pointée par dest.
Et...
Ça déborde dès que la chaine source est de taille strictement
supérieure à 0
Cela ne déborde que si la chaîne finale (la vraie, pas la déclaration) a une
taille réservée inférieure à la taille réelle (strlen+1) de la chaîne
origine.
Et en C, du fait de l'équivalence pointeur-tableau, la déclaration
« visible » d'un tableau n'est pas forcément la déclaration réelle, en
particulier en ce qui concerne la taille du tableau.
Nous sommes d'accord, mais je réagissais avec le source sous les
yeux (ce fil est issu d'une discussion avec un psychopathe sur un
autre forum). Dans le code en question, une structure est déclarée,
et _jamais_ on ne contrôle que le strcpy ne va pas écraser quelque
chose.
Cordialement,
JKB
--
Le cerveau, c'est un véritable scandale écologique. Il représente 2% de notre
masse corporelle, mais disperse à lui seul 25% de l'énergie que nous
consommons tous les jours.
Le 09-09-2008, à propos de Re: strcpy sur un char[1] ???, Antoine Leca écrivait dans fr.comp.lang.c :
En news:, JKB va escriure:
Le 06-09-2008, à propos de strcpy sur un char[1] ???, Alain Montfranc écrivait dans fr.comp.lang.c :
struct NAME { struct NAME * next; char name[1]; }; strcpy(p->name, dp2->d_name); Il me semble que strcpy copie jusqu'au premier ?
Oui. Je site : La fonction strcpy() copie la chaîne pointée par src, y compris le car actère nul (« ») final dans la chaîne pointée par dest.
Et...
Ça déborde dès que la chaine source est de taille strictement supérieure à 0
Cela ne déborde que si la chaîne finale (la vraie, pas la déclaration) a une taille réservée inférieure à la taille réelle (strlen+1) de la chaîne origine.
Et en C, du fait de l'équivalence pointeur-tableau, la déclaration « visible » d'un tableau n'est pas forcément la déclaration réelle, en particulier en ce qui concerne la taille du tableau.
Nous sommes d'accord, mais je réagissais avec le source sous les yeux (ce fil est issu d'une discussion avec un psychopathe sur un autre forum). Dans le code en question, une structure est déclarée, et _jamais_ on ne contrôle que le strcpy ne va pas écraser quelque chose.
Cordialement,
JKB
-- Le cerveau, c'est un véritable scandale écologique. Il représente 2% de notre masse corporelle, mais disperse à lui seul 25% de l'énergie que nous consommons tous les jours.
Antoine Leca
En news:, JKB va escriure:
Antoine Leca écrivait dans fr.comp.lang.c :
Et en C, du fait de l'équivalence pointeur-tableau, la déclaration « visible » d'un tableau n'est pas forcément la déclaration réelle, en particulier en ce qui concerne la taille du tableau.
Nous sommes d'accord, mais je réagissais avec le source sous les yeux [...]. Dans le code en question, une structure est déclarée, et _jamais_ on ne contrôle que le strcpy ne va pas écraser quelque chose.
Avec strcpy tout seul, il est virtuellement impossible de contrôler que tu ne vas pas écraser quelque chose.
Problème, la logique de nommage de la norme semble proposer strncpy quand tu veux contrôler, et pour des raisons historiques strncpy n'a pas cette fonction ; il faudrait utiliser strlcpy qui n'est pas normalisée, ou snprintf qui est d'une part C99 et d'autre part demande plus de ressources, ou sprintf(,"%.*s",) qui demande aussi beaucoup de ressources et n'est pas facile à relire car ce n'est pas « idiomatique »¹, ou strcpy_s qui est la réponse officielle du comité mais n'est pas très répandue, voire strncpy_s qui cumule tous les inconvénients : 4 arguments, sémantique différente à la fois de strncpy et de strlcpy, peu utilisée, possibilité de mettre en jeu un mécanisme d'exception à rebond multiple, fonction des implémentations et potentiellement différent à la fois de signal/raise et de setjmp/longjmp.
Par ailleurs, et c'était mon propos ci-dessus, lorsque tu utilises fct_qui_modifie_arg1(p->name, ...), la structure qui est déclarée pour &p importe peu, c'est la structure réellement utilisée pour l'allocation qui importe (le C a une règle spéciale pour permettre justement ce genre d'utilisation); note bien que dans le cas d'une allocation dynamique, même la déclaration utilisée pour l'allocation de la structure qui va être passée ensuite dans le pointeur p [ouf!] n'importe pas vraiment, c'est en fait le paramètre passé à malloc/calloc/realloc ou équivalent qui va déterminer indirectement la taille des éléments de la structure.
Antoine __________ ¹: Techniquement c'est-à-dire dans le respect strict de la norme, s[n]printf sont de plus limitées à des chaînes de 4095 caractères avec C99, voire 509 en C90.
En news:slrngcce7p.rul.knatschke@rayleigh.systella.fr, JKB va escriure:
Antoine Leca écrivait dans fr.comp.lang.c :
Et en C, du fait de l'équivalence pointeur-tableau, la déclaration
« visible » d'un tableau n'est pas forcément la déclaration réelle,
en particulier en ce qui concerne la taille du tableau.
Nous sommes d'accord, mais je réagissais avec le source sous les
yeux [...]. Dans le code en question, une structure est déclarée,
et _jamais_ on ne contrôle que le strcpy ne va pas écraser quelque
chose.
Avec strcpy tout seul, il est virtuellement impossible de contrôler que tu
ne vas pas écraser quelque chose.
Problème, la logique de nommage de la norme semble proposer strncpy quand tu
veux contrôler, et pour des raisons historiques strncpy n'a pas cette
fonction ; il faudrait utiliser strlcpy qui n'est pas normalisée, ou
snprintf qui est d'une part C99 et d'autre part demande plus de ressources,
ou sprintf(,"%.*s",) qui demande aussi beaucoup de ressources et n'est pas
facile à relire car ce n'est pas « idiomatique »¹, ou strcpy_s qui est la
réponse officielle du comité mais n'est pas très répandue, voire strncpy_s
qui cumule tous les inconvénients : 4 arguments, sémantique différente à la
fois de strncpy et de strlcpy, peu utilisée, possibilité de mettre en jeu un
mécanisme d'exception à rebond multiple, fonction des implémentations et
potentiellement différent à la fois de signal/raise et de setjmp/longjmp.
Par ailleurs, et c'était mon propos ci-dessus, lorsque tu utilises
fct_qui_modifie_arg1(p->name, ...), la structure qui est déclarée pour &p
importe peu, c'est la structure réellement utilisée pour l'allocation qui
importe (le C a une règle spéciale pour permettre justement ce genre
d'utilisation); note bien que dans le cas d'une allocation dynamique, même
la déclaration utilisée pour l'allocation de la structure qui va être passée
ensuite dans le pointeur p [ouf!] n'importe pas vraiment, c'est en fait le
paramètre passé à malloc/calloc/realloc ou équivalent qui va déterminer
indirectement la taille des éléments de la structure.
Antoine
__________
¹: Techniquement c'est-à-dire dans le respect strict de la norme, s[n]printf
sont de plus limitées à des chaînes de 4095 caractères avec C99, voire 509
en C90.
Et en C, du fait de l'équivalence pointeur-tableau, la déclaration « visible » d'un tableau n'est pas forcément la déclaration réelle, en particulier en ce qui concerne la taille du tableau.
Nous sommes d'accord, mais je réagissais avec le source sous les yeux [...]. Dans le code en question, une structure est déclarée, et _jamais_ on ne contrôle que le strcpy ne va pas écraser quelque chose.
Avec strcpy tout seul, il est virtuellement impossible de contrôler que tu ne vas pas écraser quelque chose.
Problème, la logique de nommage de la norme semble proposer strncpy quand tu veux contrôler, et pour des raisons historiques strncpy n'a pas cette fonction ; il faudrait utiliser strlcpy qui n'est pas normalisée, ou snprintf qui est d'une part C99 et d'autre part demande plus de ressources, ou sprintf(,"%.*s",) qui demande aussi beaucoup de ressources et n'est pas facile à relire car ce n'est pas « idiomatique »¹, ou strcpy_s qui est la réponse officielle du comité mais n'est pas très répandue, voire strncpy_s qui cumule tous les inconvénients : 4 arguments, sémantique différente à la fois de strncpy et de strlcpy, peu utilisée, possibilité de mettre en jeu un mécanisme d'exception à rebond multiple, fonction des implémentations et potentiellement différent à la fois de signal/raise et de setjmp/longjmp.
Par ailleurs, et c'était mon propos ci-dessus, lorsque tu utilises fct_qui_modifie_arg1(p->name, ...), la structure qui est déclarée pour &p importe peu, c'est la structure réellement utilisée pour l'allocation qui importe (le C a une règle spéciale pour permettre justement ce genre d'utilisation); note bien que dans le cas d'une allocation dynamique, même la déclaration utilisée pour l'allocation de la structure qui va être passée ensuite dans le pointeur p [ouf!] n'importe pas vraiment, c'est en fait le paramètre passé à malloc/calloc/realloc ou équivalent qui va déterminer indirectement la taille des éléments de la structure.
Antoine __________ ¹: Techniquement c'est-à-dire dans le respect strict de la norme, s[n]printf sont de plus limitées à des chaînes de 4095 caractères avec C99, voire 509 en C90.
JKB
Le 09-09-2008, à propos de Re: strcpy sur un char[1] ???, Antoine Leca écrivait dans fr.comp.lang.c :
En news:, JKB va escriure:
Antoine Leca écrivait dans fr.comp.lang.c :
Et en C, du fait de l'équivalence pointeur-tableau, la déclaration « visible » d'un tableau n'est pas forcément la déclaration réelle, en particulier en ce qui concerne la taille du tableau.
Nous sommes d'accord, mais je réagissais avec le source sous les yeux [...]. Dans le code en question, une structure est déclarée, et _jamais_ on ne contrôle que le strcpy ne va pas écraser quelque chose.
Avec strcpy tout seul, il est virtuellement impossible de contrôler que tu ne vas pas écraser quelque chose.
Je sais bien, on contrôle les longueurs _avant_ d'appliquer le strcpy. Ce qui n'est pas fait dans le code dont on parle.
Problème, la logique de nommage de la norme semble proposer strncpy quand tu veux contrôler, et pour des raisons historiques strncpy n'a pas cette fonction ; il faudrait utiliser strlcpy qui n'est pas normalisée, ou snprintf qui est d'une part C99 et d'autre part demande plus de ressources, ou sprintf(,"%.*s",) qui demande aussi beaucoup de ressources et n'est pas facile à relire car ce n'est pas « idiomatique »¹, ou strcpy_s qui est la réponse officielle du comité mais n'est pas très répandue, voire strncpy_s qui cumule tous les inconvénients : 4 arguments, sémantique différente à la fois de strncpy et de strlcpy, peu utilisée, possibilité de mettre en jeu un mécanisme d'exception à rebond multiple, fonction des implémentations et potentiellement différent à la fois de signal/raise et de setjmp/longjmp.
Par ailleurs, et c'était mon propos ci-dessus, lorsque tu utilises fct_qui_modifie_arg1(p->name, ...), la structure qui est déclarée pour &p importe peu, c'est la structure réellement utilisée pour l'allocation qui importe (le C a une règle spéciale pour permettre justement ce genre d'utilisation); note bien que dans le cas d'une allocation dynamique, même la déclaration utilisée pour l'allocation de la structure qui va être passée ensuite dans le pointeur p [ouf!] n'importe pas vraiment, c'est en fait le paramètre passé à malloc/calloc/realloc ou équivalent qui va déterminer indirectement la taille des éléments de la structure.
Nous sommes bien d'accord. Sauf que dans le cas présent, on alloue une structure d'une certaine taille et on écrit brutalement derrière. C'est assez casse-gueule comme manipulation. Note que je ne parle que du code en question et non de la programmation C en général.
Cordialement,
JKB
-- Le cerveau, c'est un véritable scandale écologique. Il représente 2% de notre masse corporelle, mais disperse à lui seul 25% de l'énergie que nous consommons tous les jours.
Le 09-09-2008, à propos de
Re: strcpy sur un char[1] ???,
Antoine Leca écrivait dans fr.comp.lang.c :
En news:slrngcce7p.rul.knatschke@rayleigh.systella.fr, JKB va escriure:
Antoine Leca écrivait dans fr.comp.lang.c :
Et en C, du fait de l'équivalence pointeur-tableau, la déclaration
« visible » d'un tableau n'est pas forcément la déclaration réelle,
en particulier en ce qui concerne la taille du tableau.
Nous sommes d'accord, mais je réagissais avec le source sous les
yeux [...]. Dans le code en question, une structure est déclarée,
et _jamais_ on ne contrôle que le strcpy ne va pas écraser quelque
chose.
Avec strcpy tout seul, il est virtuellement impossible de contrôler que tu
ne vas pas écraser quelque chose.
Je sais bien, on contrôle les longueurs _avant_ d'appliquer le
strcpy. Ce qui n'est pas fait dans le code dont on parle.
Problème, la logique de nommage de la norme semble proposer strncpy quand tu
veux contrôler, et pour des raisons historiques strncpy n'a pas cette
fonction ; il faudrait utiliser strlcpy qui n'est pas normalisée, ou
snprintf qui est d'une part C99 et d'autre part demande plus de ressources,
ou sprintf(,"%.*s",) qui demande aussi beaucoup de ressources et n'est pas
facile à relire car ce n'est pas « idiomatique »¹, ou strcpy_s qui est la
réponse officielle du comité mais n'est pas très répandue, voire strncpy_s
qui cumule tous les inconvénients : 4 arguments, sémantique différente à la
fois de strncpy et de strlcpy, peu utilisée, possibilité de mettre en jeu un
mécanisme d'exception à rebond multiple, fonction des implémentations et
potentiellement différent à la fois de signal/raise et de setjmp/longjmp.
Par ailleurs, et c'était mon propos ci-dessus, lorsque tu utilises
fct_qui_modifie_arg1(p->name, ...), la structure qui est déclarée pour &p
importe peu, c'est la structure réellement utilisée pour l'allocation qui
importe (le C a une règle spéciale pour permettre justement ce genre
d'utilisation); note bien que dans le cas d'une allocation dynamique, même
la déclaration utilisée pour l'allocation de la structure qui va être passée
ensuite dans le pointeur p [ouf!] n'importe pas vraiment, c'est en fait le
paramètre passé à malloc/calloc/realloc ou équivalent qui va déterminer
indirectement la taille des éléments de la structure.
Nous sommes bien d'accord. Sauf que dans le cas présent, on alloue
une structure d'une certaine taille et on écrit brutalement
derrière. C'est assez casse-gueule comme manipulation. Note que je
ne parle que du code en question et non de la programmation C en
général.
Cordialement,
JKB
--
Le cerveau, c'est un véritable scandale écologique. Il représente 2% de notre
masse corporelle, mais disperse à lui seul 25% de l'énergie que nous
consommons tous les jours.
Le 09-09-2008, à propos de Re: strcpy sur un char[1] ???, Antoine Leca écrivait dans fr.comp.lang.c :
En news:, JKB va escriure:
Antoine Leca écrivait dans fr.comp.lang.c :
Et en C, du fait de l'équivalence pointeur-tableau, la déclaration « visible » d'un tableau n'est pas forcément la déclaration réelle, en particulier en ce qui concerne la taille du tableau.
Nous sommes d'accord, mais je réagissais avec le source sous les yeux [...]. Dans le code en question, une structure est déclarée, et _jamais_ on ne contrôle que le strcpy ne va pas écraser quelque chose.
Avec strcpy tout seul, il est virtuellement impossible de contrôler que tu ne vas pas écraser quelque chose.
Je sais bien, on contrôle les longueurs _avant_ d'appliquer le strcpy. Ce qui n'est pas fait dans le code dont on parle.
Problème, la logique de nommage de la norme semble proposer strncpy quand tu veux contrôler, et pour des raisons historiques strncpy n'a pas cette fonction ; il faudrait utiliser strlcpy qui n'est pas normalisée, ou snprintf qui est d'une part C99 et d'autre part demande plus de ressources, ou sprintf(,"%.*s",) qui demande aussi beaucoup de ressources et n'est pas facile à relire car ce n'est pas « idiomatique »¹, ou strcpy_s qui est la réponse officielle du comité mais n'est pas très répandue, voire strncpy_s qui cumule tous les inconvénients : 4 arguments, sémantique différente à la fois de strncpy et de strlcpy, peu utilisée, possibilité de mettre en jeu un mécanisme d'exception à rebond multiple, fonction des implémentations et potentiellement différent à la fois de signal/raise et de setjmp/longjmp.
Par ailleurs, et c'était mon propos ci-dessus, lorsque tu utilises fct_qui_modifie_arg1(p->name, ...), la structure qui est déclarée pour &p importe peu, c'est la structure réellement utilisée pour l'allocation qui importe (le C a une règle spéciale pour permettre justement ce genre d'utilisation); note bien que dans le cas d'une allocation dynamique, même la déclaration utilisée pour l'allocation de la structure qui va être passée ensuite dans le pointeur p [ouf!] n'importe pas vraiment, c'est en fait le paramètre passé à malloc/calloc/realloc ou équivalent qui va déterminer indirectement la taille des éléments de la structure.
Nous sommes bien d'accord. Sauf que dans le cas présent, on alloue une structure d'une certaine taille et on écrit brutalement derrière. C'est assez casse-gueule comme manipulation. Note que je ne parle que du code en question et non de la programmation C en général.
Cordialement,
JKB
-- Le cerveau, c'est un véritable scandale écologique. Il représente 2% de notre masse corporelle, mais disperse à lui seul 25% de l'énergie que nous consommons tous les jours.