]>
Commit | Line | Data |
---|---|---|
1 | .\" $OpenBSD: strlcpy.3,v 1.5 1999/06/06 15:17:32 aaron Exp $ | |
2 | .\" | |
3 | .\" Copyright (c) 1998 Todd C. Miller <Todd.Miller@courtesan.com> | |
4 | .\" All rights reserved. | |
5 | .\" | |
6 | .\" Redistribution and use in source and binary forms, with or without | |
7 | .\" modification, are permitted provided that the following conditions | |
8 | .\" are met: | |
9 | .\" 1. Redistributions of source code must retain the above copyright | |
10 | .\" notice, this list of conditions and the following disclaimer. | |
11 | .\" 2. Redistributions in binary form must reproduce the above copyright | |
12 | .\" notice, this list of conditions and the following disclaimer in the | |
13 | .\" documentation and/or other materials provided with the distribution. | |
14 | .\" 3. The name of the author may not be used to endorse or promote products | |
15 | .\" derived from this software without specific prior written permission. | |
16 | .\" | |
17 | .\" THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, | |
18 | .\" INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY | |
19 | .\" AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL | |
20 | .\" THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, | |
21 | .\" EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, | |
22 | .\" PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; | |
23 | .\" OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, | |
24 | .\" WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR | |
25 | .\" OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF | |
26 | .\" ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. | |
27 | .\" | |
28 | .\" $FreeBSD: src/lib/libc/string/strlcpy.3,v 1.13 2004/07/02 23:52:13 ru Exp $ | |
29 | .\" | |
30 | .Dd June 22, 1998 | |
31 | .Dt STRLCPY 3 | |
32 | .Os | |
33 | .Sh NAME | |
34 | .Nm strlcpy , | |
35 | .Nm strlcat | |
36 | .Nd size-bounded string copying and concatenation | |
37 | .Sh LIBRARY | |
38 | .Lb libc | |
39 | .Sh SYNOPSIS | |
40 | .In string.h | |
41 | .Ft size_t | |
42 | .Fn strlcpy "char *dst" "const char *src" "size_t size" | |
43 | .Ft size_t | |
44 | .Fn strlcat "char *dst" "const char *src" "size_t size" | |
45 | .Sh DESCRIPTION | |
46 | The | |
47 | .Fn strlcpy | |
48 | and | |
49 | .Fn strlcat | |
50 | functions copy and concatenate strings respectively. | |
51 | They are designed | |
52 | to be safer, more consistent, and less error prone replacements for | |
53 | .Xr strncpy 3 | |
54 | and | |
55 | .Xr strncat 3 . | |
56 | Unlike those functions, | |
57 | .Fn strlcpy | |
58 | and | |
59 | .Fn strlcat | |
60 | take the full size of the buffer (not just the length) and guarantee to | |
61 | NUL-terminate the result (as long as | |
62 | .Fa size | |
63 | is larger than 0 or, in the case of | |
64 | .Fn strlcat , | |
65 | as long as there is at least one byte free in | |
66 | .Fa dst ) . | |
67 | Note that you should include a byte for the NUL in | |
68 | .Fa size . | |
69 | Also note that | |
70 | .Fn strlcpy | |
71 | and | |
72 | .Fn strlcat | |
73 | only operate on true | |
74 | .Dq C | |
75 | strings. | |
76 | This means that for | |
77 | .Fn strlcpy | |
78 | .Fa src | |
79 | must be NUL-terminated and for | |
80 | .Fn strlcat | |
81 | both | |
82 | .Fa src | |
83 | and | |
84 | .Fa dst | |
85 | must be NUL-terminated. | |
86 | .Pp | |
87 | The | |
88 | .Fn strlcpy | |
89 | function copies up to | |
90 | .Fa size | |
91 | - 1 characters from the NUL-terminated string | |
92 | .Fa src | |
93 | to | |
94 | .Fa dst , | |
95 | NUL-terminating the result. | |
96 | .Pp | |
97 | The | |
98 | .Fn strlcat | |
99 | function appends the NUL-terminated string | |
100 | .Fa src | |
101 | to the end of | |
102 | .Fa dst . | |
103 | It will append at most | |
104 | .Fa size | |
105 | - strlen(dst) - 1 bytes, NUL-terminating the result. | |
106 | .Sh RETURN VALUES | |
107 | The | |
108 | .Fn strlcpy | |
109 | and | |
110 | .Fn strlcat | |
111 | functions return the total length of the string they tried to | |
112 | create. | |
113 | For | |
114 | .Fn strlcpy | |
115 | that means the length of | |
116 | .Fa src . | |
117 | For | |
118 | .Fn strlcat | |
119 | that means the initial length of | |
120 | .Fa dst | |
121 | plus | |
122 | the length of | |
123 | .Fa src . | |
124 | While this may seem somewhat confusing it was done to make | |
125 | truncation detection simple. | |
126 | .Pp | |
127 | Note however, that if | |
128 | .Fn strlcat | |
129 | traverses | |
130 | .Fa size | |
131 | characters without finding a NUL, the length of the string is considered | |
132 | to be | |
133 | .Fa size | |
134 | and the destination string will not be NUL-terminated (since there was | |
135 | no space for the NUL). | |
136 | This keeps | |
137 | .Fn strlcat | |
138 | from running off the end of a string. | |
139 | In practice this should not happen (as it means that either | |
140 | .Fa size | |
141 | is incorrect or that | |
142 | .Fa dst | |
143 | is not a proper | |
144 | .Dq C | |
145 | string). | |
146 | The check exists to prevent potential security problems in incorrect code. | |
147 | .Sh EXAMPLES | |
148 | The following code fragment illustrates the simple case: | |
149 | .Bd -literal -offset indent | |
150 | char *s, *p, buf[BUFSIZ]; | |
151 | ||
152 | \&... | |
153 | ||
154 | (void)strlcpy(buf, s, sizeof(buf)); | |
155 | (void)strlcat(buf, p, sizeof(buf)); | |
156 | .Ed | |
157 | .Pp | |
158 | To detect truncation, perhaps while building a pathname, something | |
159 | like the following might be used: | |
160 | .Bd -literal -offset indent | |
161 | char *dir, *file, pname[MAXPATHLEN]; | |
162 | ||
163 | \&... | |
164 | ||
165 | if (strlcpy(pname, dir, sizeof(pname)) >= sizeof(pname)) | |
166 | goto toolong; | |
167 | if (strlcat(pname, file, sizeof(pname)) >= sizeof(pname)) | |
168 | goto toolong; | |
169 | .Ed | |
170 | .Pp | |
171 | Since we know how many characters we copied the first time, we can | |
172 | speed things up a bit by using a copy instead of an append: | |
173 | .Bd -literal -offset indent | |
174 | char *dir, *file, pname[MAXPATHLEN]; | |
175 | size_t n; | |
176 | ||
177 | \&... | |
178 | ||
179 | n = strlcpy(pname, dir, sizeof(pname)); | |
180 | if (n >= sizeof(pname)) | |
181 | goto toolong; | |
182 | if (strlcpy(pname + n, file, sizeof(pname) - n) >= sizeof(pname) - n) | |
183 | goto toolong; | |
184 | .Ed | |
185 | .Pp | |
186 | However, one may question the validity of such optimizations, as they | |
187 | defeat the whole purpose of | |
188 | .Fn strlcpy | |
189 | and | |
190 | .Fn strlcat . | |
191 | As a matter of fact, the first version of this manual page got it wrong. | |
192 | .Sh SEE ALSO | |
193 | .Xr snprintf 3 , | |
194 | .Xr strncat 3 , | |
195 | .Xr strncpy 3 | |
196 | .Sh HISTORY | |
197 | The | |
198 | .Fn strlcpy | |
199 | and | |
200 | .Fn strlcat | |
201 | functions first appeared in | |
202 | .Ox 2.4 , | |
203 | and made their appearance in | |
204 | .Fx 3.3 . |