strcpy(3)
Fonction de la bibliothèque C
Copie une chaîne, octet nul compris, dans un tampon que tu fournis. strcpy ignore la taille de la destination : c'est à toi de la garantir.
#include <string.h>
char *strcpy(char *restrict dst, const char *restrict src);Description
strcpy copie la chaîne src, octet nul final compris, dans le tableau dst. L'ordre des arguments est celui d'une affectation : la destination d'abord, dst = src. La fonction ne reçoit aucune taille : elle copie jusqu'au '\0' de la source, quelle que soit la place disponible. La destination doit donc offrir au moins strlen(src) + 1 octets, et c'est à l'appelant de le vérifier.
Valeur de retour
dst, le pointeur reçu. Il n'existe aucun cas d'erreur signalé : une destination trop petite ou un src non terminé ne sont pas détectés, ce sont des comportements indéfinis.
Pièges
Le débordement est silencieux. Dans l'exemple plus bas, 13 octets sont copiés dans un tableau de 8, le programme affiche le nom complet et se termine normalement. Les 5 octets en trop ont écrasé ce qui suivait nom sur la pile. Rien ne garantit que ça se passera aussi bien ailleurs.
En compilant avec -O2 -D_FORTIFY_SOURCE=2, la glibc remplace l'appel par une version qui connaît la taille de dst quand le compilateur la voit, et arrête le programme au lieu de déborder. Pratique pendant le développement, mais ce filet ne remplace pas la vérification.
Quand tu alloues la copie toi-même, n'oublie pas l'octet nul : malloc(strlen(src)) manque d'un octet, malloc(strlen(src) + 1) est juste. strdup(3) fait les deux étapes d'un coup.
Si src et dst se chevauchent, par exemple pour décaler une chaîne dans son propre tableau, le comportement est indéfini. Utilise memmove(3).
dst doit être modifiable : char *dst = "texte"; désigne une chaîne littérale en lecture seule, et la copie y plante en général. Déclare un tableau.
Pour une copie bornée, strncpy(3) n'est pas la bonne réponse, il peut laisser la destination sans octet nul. Vérifie la longueur avec strlen(3) avant de copier, ou utilise snprintf(dst, sizeof dst, "%s", src), qui tronque proprement quand dst est un tableau.
Exemple
#include <stdio.h>#include <string.h>
int main(int argc, char **argv){ char nom[8];
if (argc != 2) return 1; strcpy(nom, argv[1]); printf("Bonjour %s\n", nom); return 0;}$ gcc -Wall -Wextra bonjour.c -o bonjour$ ./bonjour AdaBonjour Ada$ ./bonjour "Ada Lovelace"Bonjour Ada Lovelace$ gcc -Wall -Wextra -O2 -D_FORTIFY_SOURCE=2 bonjour.c -o bonjour-fortify$ ./bonjour-fortify "Ada Lovelace"*** buffer overflow detected ***: terminatedAborted"Ada" occupe 4 octets avec son '\0', la copie tient. "Ada Lovelace" en occupe 13 pour 8 disponibles : la première version déborde sans rien dire, la version fortifiée s'arrête net sur buffer overflow detected.
strcpy
Écris gm_strcpy, qui copie src dans dst caractère par caractère, octet nul final compris, et renvoie dst.