The author is almost certainly abusing the strn*
functions. Unfortunately, there is almost never a good reason to use strn*
functions, since they don't actually do what you want.
Let's take a look at strcpy
and strncpy
:
char *strcpy(char *dest, const char *src);
char *strncpy(char *dest, const char *src, size_t n);
The strcpy
function copies src
into dest
, including a trailing \0
. It is only rarely useful:
Unless you know the source string fits in the destination buffer, you have a buffer overflow. Buffer overflows are security hazards, they can crash your program, and cause it to behave incorrectly.
If you do know the size of the source string and destination buffer, you might as well use memcpy
.
By comparison, the strncpy
copies at most n
bytes of src
into dest
and then pads the rest with \0
. It is only rarely useful:
Unless you know the source string is smaller than the destination buffer, you cannot be certain that the resulting buffer will be nul-terminated. This can cause errors elsewhere in the program, if you assume the result is nul-terminated.
If you do know the source string is smaller, again, you might as well use memcpy
.
You can simply terminate the string after you call strncpy
, but are you sure that you want to silently truncate the result? I'd imagine most of the time, you'd rather have an error message.
Why do these functions exist?
The strcpy
function is occasionally handy, but it is mostly a relic of an era where people did not care very much about validating input. Feeding a string that is too large to a program would crash it, and the advice was "don't do that".
The strncpy
function is useful when you want to transmit data in fixed-size fields, and you don't want to put garbage in the remainder of the field. This is mostly a relic of an era where people used fixed-size fields.
So you will rarely see strcat
or strncpy
in modern C software.
A worse problem
However, your example combines the worst of both worlds. Let's examine this piece of source code:
strncpy(dest, src, strlen(src));
This copies src
into dest
, without a \0
terminator and without bounds checking. It combines the worst aspect of strcpy
(no bounds checking) with the worst aspect of strncpy
(no terminator). If you see code like this, run away.
How to work with strings
Good C code typically uses one of a few options for working with strings:
Use fixed buffers and snprintf
, as long as you don't mind fixed buffers.
Use bounded string functions like strlcpy
and strlcat
. These are BSD extensions.
Use a custom string point which tracks string lengths, and write your own functions using memcpy
and malloc
.