strlcat(3) size-bounded string copying and concatenation

Other Alias

strlcpy

LIBRARY

Lb libbsd

SYNOPSIS

In bsd/string.h Ft size_t Fn strlcpy char *dst const char *src size_t size Ft size_t Fn strlcat char *dst const char *src size_t size

DESCRIPTION

The Fn strlcpy and Fn strlcat functions copy and concatenate strings respectively. They are designed to be safer, more consistent, and less error prone replacements for strncpy(3) and strncat(3). Unlike those functions, Fn strlcpy and Fn strlcat take the full size of the buffer (not just the length) and guarantee to NUL-terminate the result (as long as Fa size is larger than 0 or, in the case of Fn strlcat , as long as there is at least one byte free in Fa dst ) . Note that a byte for the NUL should be included in Fa size . Also note that Fn strlcpy and Fn strlcat only operate on true ``C'' strings. This means that for Fn strlcpy Fa src must be NUL-terminated and for Fn strlcat both Fa src and Fa dst must be NUL-terminated.

The Fn strlcpy function copies up to Fa size - 1 characters from the NUL-terminated string Fa src to Fa dst , NUL-terminating the result.

The Fn strlcat function appends the NUL-terminated string Fa src to the end of Fa dst . It will append at most Fa size - strlen(dst) - 1 bytes, NUL-terminating the result.

RETURN VALUES

The Fn strlcpy and Fn strlcat functions return the total length of the string they tried to create. For Fn strlcpy that means the length of Fa src . For Fn strlcat that means the initial length of Fa dst plus the length of Fa src . While this may seem somewhat confusing, it was done to make truncation detection simple.

Note, however, that if Fn strlcat traverses Fa size characters without finding a NUL, the length of the string is considered to be Fa size and the destination string will not be NUL-terminated (since there was no space for the NUL). This keeps Fn strlcat from running off the end of a string. In practice this should not happen (as it means that either Fa size is incorrect or that Fa dst is not a proper ``C'' string). The check exists to prevent potential security problems in incorrect code.

EXAMPLES

The following code fragment illustrates the simple case:
char *s, *p, buf[BUFSIZ];
...
(void)strlcpy(buf, s, sizeof(buf));
(void)strlcat(buf, p, sizeof(buf));

To detect truncation, perhaps while building a pathname, something like the following might be used:

char *dir, *file, pname[MAXPATHLEN];
...
if (strlcpy(pname, dir, sizeof(pname)) >= sizeof(pname))
        goto toolong;
if (strlcat(pname, file, sizeof(pname)) >= sizeof(pname))
        goto toolong;

Since it is known how many characters were copied the first time, things can be sped up a bit by using a copy instead of an append:

char *dir, *file, pname[MAXPATHLEN];
size_t n;
...
n = strlcpy(pname, dir, sizeof(pname));
if (n >= sizeof(pname))
        goto toolong;
if (strlcpy(pname + n, file, sizeof(pname) - n) >= sizeof(pname) - n)
        goto toolong;

However, one may question the validity of such optimizations, as they defeat the whole purpose of Fn strlcpy and Fn strlcat . As a matter of fact, the first version of this manual page got it wrong.

HISTORY

The Fn strlcpy and Fn strlcat functions first appeared in Ox 2.4 , and made their appearance in Fx 3.3 .