Quand les gens disent, " strcpy()
est dangereux, utilisez strncpy()
au lieu de" (ou des déclarations similaires sur strcat()
etc., mais je vais utiliser strcpy()
ici comme mon point de mire), ils signifient qu'il n'y a pas de vérification des limites dans strcpy()
. Ainsi, une chaîne trop longue entraînera un dépassement de la mémoire tampon. Ils sont corrects. Utilisation de strncpy()
dans ce cas, empêchera les dépassements de tampon.
J'ai l'impression que strncpy()
ne corrige pas vraiment les bugs : il résout un problème qui peut être facilement évité par un bon programmeur.
En tant que programmeur C, vous doit connaître la taille de la destination avant d'essayer de copier des chaînes de caractères. C'est l'hypothèse dans strncpy()
et strlcpy()
Vous pouvez également connaître les derniers paramètres de l'utilisateur : vous leur fournissez cette taille. Vous pouvez également connaître la taille de la source avant de copier les chaînes de caractères. Ensuite, si la destination n'est pas assez grande, n'appelez pas strcpy()
. Soit vous réallouez le tampon, soit vous faites autre chose.
Pourquoi je n'aime pas strncpy()
?
-
strncpy()
est une mauvaise solution dans la plupart des cas : votre chaîne de caractères va être tronquée sans que vous le sachiez. Je préfère écrire du code supplémentaire pour déterminer moi-même ce qu'il en est et ensuite prendre la décision que je souhaite prendre, plutôt que de laisser une fonction décider pour moi de ce qu'il faut faire.
-
strncpy()
est très inefficace. Il écrit sur chaque octet du tampon de destination. Vous n'avez pas besoin de ces milliers de '\0'
à la fin de votre destination.
- Il n'écrit pas une terminaison
'\0'
si la destination n'est pas assez grande. Vous devez donc de toute façon le faire vous-même. La complexité de cette opération n'en vaut pas la peine.
Maintenant, nous en arrivons à strlcpy()
. Les changements de strncpy()
l'améliorer, mais je ne suis pas sûr que le comportement spécifique des strl*
justifie leur existence : ils sont beaucoup trop spécifiques. Il faut toujours connaître la taille de la destination. C'est plus efficace que strncpy()
parce qu'il n'écrit pas nécessairement sur chaque octet de la destination. Mais il résout un problème qui peut être résolu en faisant : *((char *)mempcpy(dst, src, n)) = 0;
.
Je ne pense pas que quelqu'un dise que strlcpy()
ou strlcat()
peuvent entraîner des problèmes de sécurité, ce qu'ils (et moi) disent, c'est qu'ils peuvent entraîner des bogues, par exemple, lorsque vous vous attendez à ce que la chaîne complète soit écrite au lieu d'une partie de celle-ci.
La question principale ici est : combien d'octets faut-il copier ? Le programmeur doit le savoir, et s'il ne le sait pas.., strncpy()
ou strlcpy()
ne le sauvera pas.
strlcpy()
et strlcat()
ne sont pas standard, ni ISO C ni POSIX. Leur utilisation dans des programmes portables est donc impossible. En effet, strlcat()
a deux variantes différentes : l'implémentation de Solaris est différente des autres pour les cas limites impliquant la longueur 0. Cela le rend encore moins utile qu'autrement.