Author: | Yegor Samusev <yegor@samusev.pp.ru> |
---|---|
Modified: | 2010-12-08 |
The main problem in C programming is buffer overflow. To avoid it you must use correctly safe C functions instead unsafe ones. Unsafe functions exist only for compatibility with old sources.
Contents
Don't use gets()!
char * fgets(char * restrict str, int size, FILE * restrict stream);
The right usage:
fgets(str, sizeof (str), stdin);
Example:
char str[10]; printf("Name [%d]? ", sizeof (str)); fgets(str, sizeof (str), stdin); printf("Hello, %s!\n", str);
Don't use sprintf()!
int snprintf(char * restrict str, size_t size, const char * restrict format, ...);
The right usage:
snprintf(str, sizeof (str), format, ...);
Example:
char str[5]; char *format = "%02x%02x%02x"; snprintf(str, sizeof (str), format, 'B', 'S', 'D'); /* "4253\0" */
Use strncat() rather than strcat() and strncpy() rather than strcpy() but in BSD, Mac OS X, Solaris and IRIX you must use strlcat() and strlcpy() instead strncat() and strncpy() because they are more safe.
char * strncat(char * restrict s, const char * restrict append, size_t count);
The right usage:
strncat(s, append, sizeof (s) - strlen(s) - 1);
Example:
char s[] = {'F', 'r', 'e', 'e', '\0', '*', '*'}; char *append = "BSD"; strncat(s, append, sizeof (s) - strlen(s) - 1); /* "FreeBS\0" */
size_t strlcat(char *dst, const char *src, size_t size);
The right usage:
strlcat(dst, src, sizeof (dst));
Example:
char dst[] = {'F', 'r', 'e', 'e', '\0', '*', '*'}; char *src = "BSD"; strlcat(dst, src, sizeof (dst)); /* "FreeBS\0" */
char * strncpy(char * restrict dst, const char * restrict src, size_t len);
The right usage:
strncpy(dst, src, sizeof (dst) - 1); dst[sizeof (dst) - 1] = '\0';
Example:
char dst[] = {'*', '*', '*', '*', '*'}; char *src = "HELLO"; strncpy(dst, src, sizeof (dst) - 1); /* "HELL*" */ dst[sizeof (dst) - 1] = '\0'; /* "HELL\0" */
size_t strlcpy(char *dst, const char *src, size_t size);
The right usage:
strlcpy(dst, src, sizeof (dst));
Example:
char dst[] = {'*', '*', '*', '*', '*'}; char *src = "HELLO"; strlcpy(dst, src, sizeof (dst)); /* "HELL\0" */
The dst is:
char dst[5];
The dot symbol shows where data is unchanged.
Function | src | dst | Comment |
---|---|---|---|
strncpy(dst, src, sizeof (dst)) | HELLO\0 | HELLO | Unsafe. |
strlcpy(dst, src, sizeof (dst)) | HELLO\0 | HELL\0 | Safe! |
strncpy(dst, src, 1) | HELLO\0 | H.... | Unsafe but fast. |
strlcpy(dst, src, 1) | HELLO\0 | \0.... | Safe! |
strncpy(dst, src, sizeof (dst)) | X\0 | X\0\0\0\0 | Safe but slow. |
strlcpy(dst, src, sizeof (dst)) | X\0 | X\0... | Safe and fast! |