diff options
author | millert <> | 2013-09-25 21:50:18 +0000 |
---|---|---|
committer | millert <> | 2013-09-25 21:50:18 +0000 |
commit | d2c4b95c0364ddb27d57c0d976621efe6b37c36f (patch) | |
tree | 627b496b34a429489f8e4d1b211a90cd74e6c400 | |
parent | d43fbdbe15661679852f61d404fabacd5aa30b48 (diff) | |
download | openbsd-d2c4b95c0364ddb27d57c0d976621efe6b37c36f.tar.gz openbsd-d2c4b95c0364ddb27d57c0d976621efe6b37c36f.tar.bz2 openbsd-d2c4b95c0364ddb27d57c0d976621efe6b37c36f.zip |
Add examples to show why this is a terrible API. OK jmc@ henning@
-rw-r--r-- | src/lib/libc/string/stpcpy.3 | 61 |
1 files changed, 60 insertions, 1 deletions
diff --git a/src/lib/libc/string/stpcpy.3 b/src/lib/libc/string/stpcpy.3 index ea25610717..cb74942afa 100644 --- a/src/lib/libc/string/stpcpy.3 +++ b/src/lib/libc/string/stpcpy.3 | |||
@@ -1,4 +1,4 @@ | |||
1 | .\" $OpenBSD: stpcpy.3,v 1.4 2013/09/25 21:49:31 millert Exp $ | 1 | .\" $OpenBSD: stpcpy.3,v 1.5 2013/09/25 21:50:18 millert Exp $ |
2 | .\" | 2 | .\" |
3 | .\" Copyright (c) 1990, 1991 The Regents of the University of California. | 3 | .\" Copyright (c) 1990, 1991 The Regents of the University of California. |
4 | .\" All rights reserved. | 4 | .\" All rights reserved. |
@@ -103,7 +103,66 @@ if the length of | |||
103 | .Fa src | 103 | .Fa src |
104 | is greater than or equal to | 104 | is greater than or equal to |
105 | .Fa len . | 105 | .Fa len . |
106 | .Sh EXAMPLES | ||
107 | The most common use of | ||
108 | .Fn stpcpy | ||
109 | is to build up a string from multiple elements. | ||
110 | The following example builds up a pathname from | ||
111 | directory and file components using | ||
112 | .Fn stpcpy : | ||
113 | .Bd -literal -offset indent | ||
114 | char *dir, *file, pname[PATH_MAX]; | ||
115 | |||
116 | \&... | ||
117 | |||
118 | if (strlen(dir) + strlen("/") + strlen(file) >= sizeof(pname)) | ||
119 | goto toolong; | ||
120 | stpcpy(stpcpy(stpcpy(pname, dir), "/"), file); | ||
121 | .Ed | ||
122 | .Pp | ||
123 | However, the size check required to avoid a buffer overflow is error | ||
124 | prone since the check can become out of sync with the code that | ||
125 | performs the copy. | ||
126 | .Pp | ||
127 | One might expect that | ||
128 | .Fn stpncpy | ||
129 | could be safely used instead, but it suffers from the same defects as | ||
130 | .Fn strncpy . | ||
131 | The example below using | ||
132 | .Fn stpncpy | ||
133 | is even more prone to error and will not detect when truncation occurs: | ||
134 | .Bd -literal -offset indent | ||
135 | char *dir, *file, pname[PATH_MAX]; | ||
136 | char *p1, *p2; | ||
137 | |||
138 | \&... | ||
139 | |||
140 | p1 = stpncpy(pname, dir, sizeof(pname) - 1); | ||
141 | p2 = stpncpy(p1, "/", sizeof(pname) - 1 - (p1 - pname)); | ||
142 | stpncpy(p2, file, sizeof(pname) - 1 - (p2 - pname)); | ||
143 | pname[sizeof(pname) - 1] = '\e0'; | ||
144 | .Ed | ||
145 | .Pp | ||
146 | A safer (and simpler) approach is to use | ||
147 | .Fn snprintf : | ||
148 | .Bd -literal -offset indent | ||
149 | char *dir, *file, pname[PATH_MAX]; | ||
150 | int len; | ||
151 | |||
152 | \&... | ||
153 | |||
154 | len = snprintf(pname, sizeof(pname), "%s/%s", dir, file); | ||
155 | if (len >= sizeof(pname)) | ||
156 | goto toolong; | ||
157 | .Ed | ||
158 | .Pp | ||
159 | In most cases, it is better to use | ||
160 | .Fn snprintf , | ||
161 | .Fn strlcpy , | ||
162 | or | ||
163 | .Fn strlcat . | ||
106 | .Sh SEE ALSO | 164 | .Sh SEE ALSO |
165 | .Xr snprintf 3 , | ||
107 | .Xr strcpy 3 , | 166 | .Xr strcpy 3 , |
108 | .Xr strlcpy 3 , | 167 | .Xr strlcpy 3 , |
109 | .Xr strncpy 3 | 168 | .Xr strncpy 3 |