Use OpenBSD's revamped description of strlcpy and strlcat.

This explanation is supposed to be simpler and better.  In particular
"comparing it to the snprintf API provides lots of value, since it raises the
bar on understanding, so that programmers/auditors will a better job calling
all 3 of these functions."

Requested by:	deraadt@cvs.openbsd.org
Obtained From:	OpenBSD
Reviewed by:	cperciva
This commit is contained in:
Eitan Adler 2013-11-04 19:05:31 +00:00
parent 023fc3804d
commit fc81a90261

View File

@ -1,4 +1,4 @@
.\" $OpenBSD: strlcpy.3,v 1.19 2007/05/31 19:19:32 jmc Exp $
.\" $OpenBSD: strlcpy.3,v 1.26 2013/09/30 12:02:35 millert Exp $
.\"
.\" Copyright (c) 1998, 2000 Todd C. Miller <Todd.Miller@courtesan.com>
.\"
@ -27,7 +27,7 @@
.\"
.\" $FreeBSD$
.\"
.Dd June 22, 1998
.Dd November 10, 2013
.Dt STRLCPY 3
.Os
.Sh NAME
@ -47,69 +47,81 @@ 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
functions copy and concatenate strings with the
same input parameters and output result as
.Xr snprintf 3 .
They are designed to be safer, more consistent, and less error
prone replacements for the easily misused functions
.Xr strncpy 3
and
.Xr 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
.Dq 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.
.Pp
The
.Fn strlcpy
function copies up to
.Fa size
- 1 characters from the NUL-terminated string
and
.Fn strlcat
take the full size of the destination buffer and guarantee
NUL-termination if there is room.
Note that room for the NUL should be included in
.Fa dstsize .
.Pp
.Fn strlcpy
copies up to
.Fa dstsize
\- 1 characters from the string
.Fa src
to
.Fa dst ,
NUL-terminating the result.
NUL-terminating the result if
.Fa dstsize
is not 0.
.Pp
The
.Fn strlcat
function appends the NUL-terminated string
appends string
.Fa src
to the end of
.Fa dst .
It will append at most
.Fa size
- strlen(dst) - 1 bytes, NUL-terminating the result.
.Fa dstsize
\- strlen(dst) \- 1 characters.
It will then NUL-terminate, unless
.Fa dstsize
is 0 or the original
.Fa dst
string was longer than
.Fa dstsize
(in practice this should not happen
as it means that either
.Fa dstsize
is incorrect or that
.Fa dst
is not a proper string).
.Pp
If the
.Fa src
and
.Fa dst
strings overlap, the behavior is undefined.
.Sh RETURN VALUES
The
Besides quibbles over the return type
.Pf ( Va size_t
versus
.Va int )
and signal handler safety
.Pf ( Xr snprintf 3
is not entirely safe on some systems), the
following two are equivalent:
.Bd -literal -offset indent
n = strlcpy(dst, src, len);
n = snprintf(dst, len, "%s", src);
.Ed
.Pp
Like
.Xr snprintf 3 ,
the
.Fn strlcpy
and
.Fn strlcat
functions return the total length of the string they tried to
create.
functions return the total length of the string they tried to create.
For
.Fn strlcpy
that means the length of
@ -121,29 +133,12 @@ that means the initial length of
plus
the length of
.Fa src .
While this may seem somewhat confusing, it was done to make
truncation detection simple.
.Pp
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
.Dq C
string).
The check exists to prevent potential security problems in incorrect code.
If the return value is
.Cm >=
.Va dstsize ,
the output string has been truncated.
It is the caller's responsibility to handle this.
.Sh EXAMPLES
The following code fragment illustrates the simple case:
.Bd -literal -offset indent
@ -169,7 +164,7 @@ if (strlcat(pname, file, sizeof(pname)) >= sizeof(pname))
.Ed
.Pp
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.
can be sped up a bit by using a copy instead of an append:
.Bd -literal -offset indent
char *dir, *file, pname[MAXPATHLEN];
size_t n;
@ -201,5 +196,5 @@ and
.Fn strlcat
functions first appeared in
.Ox 2.4 ,
and made their appearance in
and
.Fx 3.3 .