strcat Vs strncat – Quand utiliser quelle fonction?

Certains outils d’parsing de code statique suggèrent que toute utilisation de strcat devrait être remplacée par strncat à des fins de sécurité?

Dans un programme, si nous connaissons clairement la taille du tampon cible et des tampons source, est-il toujours recommandé de choisir strncat?

De plus, étant donné les suggestions des outils statiques, strcat devrait-il être utilisé?

Si vous êtes absolument certain de la taille du tampon source et que celui-ci contient un caractère NULL terminant la chaîne, vous pouvez utiliser strcat en toute sécurité lorsque le tampon de destination est suffisamment grand.

Je recommande quand même d’utiliser strncat et de lui donner la taille du tampon de destination – longueur de la chaîne de destination – 1

Note: J’ai édité ceci car les commentaires notaient que ma réponse précédente était horriblement fausse.

Concaténer deux chaînes en une seule chaîne.

Prototypes

#include  char * strcat(char *ressortingct s1, const char *ressortingct s2); char * strncat(char *ressortingct s1, const char *ressortingct s2, size_t n); 

LA DESCRIPTION

Les fonctions strcat() et strncat() ajoutent une copie de la chaîne s2 à terminaison null à la fin de la chaîne à terminaison null s1, puis ajoutent un \ 0 ‘final. La chaîne s1 doit avoir suffisamment d’espace pour contenir le résultat.

La fonction strncat () n’ajoute pas plus de n caractères à partir de s2, puis ajoute un \ 0 ‘final.

Les chaînes source et cible ne doivent pas se chevaucher car le comportement n’est pas défini.

VALEURS DE RETOUR

  The `strcat()` and `strncat()` functions return the pointer s1. 

CONSIDÉRATIONS DE SÉCURITÉ

La fonction strcat() est facilement utilisée de manière à permettre à des utilisateurs malveillants de modifier de manière arbitraire la fonctionnalité d’un programme en cours d’exécution via une attaque par débordement de mémoire tampon.

Évitez d’utiliser strcat() . A la place, utilisez strncat() ou strlcat() et assurez-vous que le nombre de caractères copiés dans la mémoire tampon de destination est supérieur à ce qu’il peut contenir.

Notez que strncat() peut également être problématique. Cela peut être un problème de sécurité pour une chaîne d’être tronquée. Étant donné que la chaîne tronquée ne sera pas aussi longue que la chaîne d’origine, elle peut faire référence à une ressource complètement différente et l’utilisation de la ressource tronquée peut entraîner un comportement très incorrect. Exemple:

 void foo(const char *arbitrary_ssortingng) { char onstack[8] = ""; #if defined(BAD) /* * This first strcat is bad behavior. Do not use strcat! */ (void)strcat(onstack, arbitrary_ssortingng); /* BAD! */ #elif defined(BETTER) /* * The following two lines demonstrate better use of * strncat(). */ (void)strncat(onstack, arbitrary_ssortingng, sizeof(onstack) - strlen(onstack) - 1); #elif defined(BEST) /* * These lines are even more robust due to testing for * truncation. */ if (strlen(arbitrary_ssortingng) + 1 > sizeof(onstack) - strlen(onstack)) err(1, "onstack would be truncated"); (void)strncat(onstack, arbitrary_ssortingng, sizeof(onstack) - strlen(onstack) - 1); #endif } 

Exemple

 char dest[20] = "Hello"; char *src = ", World!"; char numbers[] = "12345678"; printf("dest before strcat: \"%s\"\n", dest); // "Hello" strcat(dest, src); printf("dest after strcat: \"%s\"\n", dest); // "Hello, World!" strncat(dest, numbers, 3); // strcat first 3 chars of numbers printf("dest after strncat: \"%s\"\n", dest); // "Hello, World!123" 

Ils ne font pas la même chose, ils ne peuvent donc pas être substitués les uns aux autres. Les deux ont des modèles de données différents.

  • Une chaîne pour strcat est une chaîne terminée par un caractère nul pour laquelle vous (en tant que programmeur) garantissez qu’elle dispose de suffisamment d’espace.
  • Une chaîne pour strncat est une séquence de caractères qui se termine soit à la longueur que vous strncat soit par une terminaison null si elle est supposée être plus courte que cette longueur.

Ainsi, l’utilisation de ces fonctions dépend uniquement des hypothèses que vous pouvez (ou souhaitez) faire à propos de vos données.

Les outils statiques sont généralement mal à comprendre les circonstances entourant l’utilisation d’une fonction. Je parie que la plupart d’entre eux se contentent d’avertir chaque strcat rencontré au lieu de rechercher si les données transmises à la fonction sont déterministes ou non. Comme déjà mentionné, si vous avez le contrôle sur vos données d’entrée, aucune fonction n’est dangereuse.

Notez bien que strncat () est légèrement plus lent, car il doit vérifier par ‘\ 0’ une terminaison et un compteur, et l’append explicitement à la fin. strcat (), d’autre part, vérifie simplement ‘\ 0’, et ajoute le ‘\ 0’ final à la nouvelle chaîne en copiant le terminateur de la deuxième chaîne avec toutes les données.