From strcat(3), 'SECURITY CONSIDERATIONS' section:
Avoid using strcat(). Instead, use strncat() or strlcat() ...
... Note that strncat() can also be problematic.
So use strncat(3) if your priority is portability...
#include<stdio.h>#include<string.h>/* Compile: cc -g -ansi -pedantic -Wall -O2 -o concat-strings concat-strings.c *//* Run: ./concat-strings */#defineMAX_LEN_FULL_NAME 20
#defineERR_MSG"Error: the string '%s%s' would be too long to fit into the variable of %d chars (terminating NULL included)."intmain(intargc, char *argv[])
{
charfull_name[MAX_LEN_FULL_NAME];
/* Command line argument check. */if (argc != 3)
{
printf("Usage: %s <first_name> <last_name>\n", argv[0]);
return 1;
}
/* Check strings before copy. *//* Length of first name can be at most MAX_LEN_FULL_NAME - 1 (don't forget the NULL char!). */if (strlen(argv[1]) > MAX_LEN_FULL_NAME - 1)
{
fprintf(stderr, ERR_MSG, "", argv[1], MAX_LEN_FULL_NAME);
return 1;
}
/* Copy first name to full_name. */
(void)strncpy(full_name, argv[1], MAX_LEN_FULL_NAME - 1);
/* Check strings before concatenate. *//* Length of first name plus length of " " can be at most MAX_LEN_FULL_NAME - 1. */if (strlen(full_name) + strlen(" ") > MAX_LEN_FULL_NAME - 1)
{
fprintf(stderr, ERR_MSG, argv[1], " ", MAX_LEN_FULL_NAME);
return 1;
}
/* Concat first name and space. */
(void)strncat(full_name, " ", MAX_LEN_FULL_NAME - strlen(full_name) - 1);
/* Check strings before concatenate. *//* Length of first name plus length of " " plus length of last name can be at most MAX_LEN_FULL_NAME - 1. */if (strlen(full_name) + strlen(argv[2]) > MAX_LEN_FULL_NAME - 1)
{
fprintf(stderr, ERR_MSG, full_name, argv[2], MAX_LEN_FULL_NAME);
return 1;
}
/* Concat last name to first name, separated by a space. */
(void)strncat(full_name, argv[2], MAX_LEN_FULL_NAME - strlen(full_name) - 1);
/* NULL-terminate string. */
full_name[MAX_LEN_FULL_NAME - 1] = '\0';
printf("Your name is '%s'.\n", full_name);
return 0;
}
...or use strlcat(3) if your priority is security:
#include<stdio.h>#include<string.h>/* Compile: cc -g -ansi -pedantic -Wall -O2 -o concat-strings concat-strings.c *//* Run: ./concat-strings */#defineMAX_LEN_FULL_NAME 20
/* Protoype */voiderrmsg(int);
intmain(intargc, char *argv[])
{
charfull_name[MAX_LEN_FULL_NAME];
if (argc != 3)
{
printf("Usage: %s <first_name> <last_name>\n", argv[0]);
return 1;
}
/* Copy first name to full_name. */if (strlcpy(full_name, argv[1], sizeof(full_name)) >= sizeof(full_name))
{
/* Error: destination string 'full_name' was truncated. */
errmsg(MAX_LEN_FULL_NAME);
return 1;
}
/* Concat a space char to first name. */if (strlcat(full_name, " ", sizeof(full_name)) >= sizeof(full_name))
{
/* Error: destination string 'full_name' was truncated. */
errmsg(MAX_LEN_FULL_NAME);
return 1;
}
/* Concat last name to first name, separated by a space. */if (strlcat(full_name, argv[2], sizeof(full_name)) >= sizeof(full_name))
{
/* Error: destination string 'full_name' was truncated. */
errmsg(MAX_LEN_FULL_NAME);
return 1;
}
printf("Your name is '%s'.\n", full_name);
return 0;
}
voiderrmsg(intmaxlen)
{
/* Error: destination string was truncated. */
printf("Sorry, this program only accepts full names shorter than %i characters\n \
(including 1 space character as a separator).\n", maxlen);
}