summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authormillert <>1998-07-01 01:29:45 +0000
committermillert <>1998-07-01 01:29:45 +0000
commit919232a14a3b7ddefc332703407abaf2bc94107e (patch)
treebfbf75abccbb5ddfe2cf2a9d5a1211d80539b1cf
parentf17e8317cc47a8704164e9ea4730db5b3c45650b (diff)
downloadopenbsd-919232a14a3b7ddefc332703407abaf2bc94107e.tar.gz
openbsd-919232a14a3b7ddefc332703407abaf2bc94107e.tar.bz2
openbsd-919232a14a3b7ddefc332703407abaf2bc94107e.zip
add strlcpy/strlcat, safe and sensible string copy/append
-rw-r--r--src/lib/libc/string/Makefile.inc7
-rw-r--r--src/lib/libc/string/strlcat.c71
-rw-r--r--src/lib/libc/string/strlcpy.3140
-rw-r--r--src/lib/libc/string/strlcpy.c63
4 files changed, 278 insertions, 3 deletions
diff --git a/src/lib/libc/string/Makefile.inc b/src/lib/libc/string/Makefile.inc
index 461740e282..076db78945 100644
--- a/src/lib/libc/string/Makefile.inc
+++ b/src/lib/libc/string/Makefile.inc
@@ -1,10 +1,10 @@
1# $OpenBSD: Makefile.inc,v 1.4 1998/02/07 20:50:25 tholo Exp $ 1# $OpenBSD: Makefile.inc,v 1.5 1998/07/01 01:29:44 millert Exp $
2 2
3# string sources 3# string sources
4.PATH: ${.CURDIR}/arch/${MACHINE_ARCH}/string ${.CURDIR}/string 4.PATH: ${.CURDIR}/arch/${MACHINE_ARCH}/string ${.CURDIR}/string
5 5
6SRCS+= bm.c memccpy.c strcasecmp.c strcoll.c strdup.c strerror.c \ 6SRCS+= bm.c memccpy.c strcasecmp.c strcoll.c strdup.c strerror.c \
7 strmode.c strsignal.c strtok.c strxfrm.c \ 7 strlcat.c strlcpy.c strmode.c strsignal.c strtok.c strxfrm.c \
8 __strerror.c __strsignal.c 8 __strerror.c __strsignal.c
9 9
10# machine-dependent net sources 10# machine-dependent net sources
@@ -118,10 +118,11 @@ MAN+= bm.3 bcmp.3 bcopy.3 bstring.3 bzero.3 ffs.3 index.3 memccpy.3 memchr.3 \
118 memcmp.3 memcpy.3 memmove.3 memset.3 rindex.3 strcasecmp.3 strcat.3 \ 118 memcmp.3 memcpy.3 memmove.3 memset.3 rindex.3 strcasecmp.3 strcat.3 \
119 strchr.3 strcmp.3 strcoll.3 strcpy.3 strcspn.3 strerror.3 \ 119 strchr.3 strcmp.3 strcoll.3 strcpy.3 strcspn.3 strerror.3 \
120 string.3 strlen.3 strmode.3 strdup.3 strpbrk.3 strrchr.3 strsep.3 \ 120 string.3 strlen.3 strmode.3 strdup.3 strpbrk.3 strrchr.3 strsep.3 \
121 strsignal.3 strspn.3 strstr.3 strtok.3 strxfrm.3 swab.3 121 strsignal.3 strspn.3 strstr.3 strtok.3 strxfrm.3 swab.3 strlcpy.3
122 122
123MLINKS+=bm.3 bm_comp.3 bm.3 bm_exec.3 bm.3 bm_free.3 123MLINKS+=bm.3 bm_comp.3 bm.3 bm_exec.3 bm.3 bm_free.3
124MLINKS+=strcasecmp.3 strncasecmp.3 124MLINKS+=strcasecmp.3 strncasecmp.3
125MLINKS+=strcat.3 strncat.3 125MLINKS+=strcat.3 strncat.3
126MLINKS+=strcmp.3 strncmp.3 126MLINKS+=strcmp.3 strncmp.3
127MLINKS+=strcpy.3 strncpy.3 127MLINKS+=strcpy.3 strncpy.3
128MLINKS+=strlcpy.3 strlcat.3
diff --git a/src/lib/libc/string/strlcat.c b/src/lib/libc/string/strlcat.c
new file mode 100644
index 0000000000..2e8c56926e
--- /dev/null
+++ b/src/lib/libc/string/strlcat.c
@@ -0,0 +1,71 @@
1/* $OpenBSD: strlcat.c,v 1.1 1998/07/01 01:29:45 millert Exp $ */
2
3/*
4 * Copyright (c) 1998 Todd C. Miller <Todd.Miller@courtesan.com>
5 * All rights reserved.
6 *
7 * Redistribution and use in source and binary forms, with or without
8 * modification, are permitted provided that the following conditions
9 * are met:
10 * 1. Redistributions of source code must retain the above copyright
11 * notice, this list of conditions and the following disclaimer.
12 * 2. Redistributions in binary form must reproduce the above copyright
13 * notice, this list of conditions and the following disclaimer in the
14 * documentation and/or other materials provided with the distribution.
15 * 3. The name of the author may not be used to endorse or promote products
16 * derived from this software without specific prior written permission.
17 *
18 * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES,
19 * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY
20 * AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL
21 * THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
22 * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
23 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
24 * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
25 * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
26 * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
27 * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
28 */
29
30#if defined(LIBC_SCCS) && !defined(lint)
31static char *rcsid = "$OpenBSD: strlcat.c,v 1.1 1998/07/01 01:29:45 millert Exp $";
32#endif /* LIBC_SCCS and not lint */
33
34#include <sys/types.h>
35#include <string.h>
36
37/*
38 * Appends src to string dst of size siz (unlike strncat, siz is the
39 * full size of dst, not space left). At most siz-1 characters
40 * will be copied. Always NUL terminates (unless siz == 0).
41 * Returns strlen(src); if retval >= siz, truncation occurred.
42 */
43size_t strlcat(dst, src, siz)
44 char *dst;
45 const char *src;
46 size_t siz;
47{
48 register char *d = dst;
49 register const char *s = src;
50 register size_t n = siz;
51 size_t dlen;
52
53 /* Find the end of dst and adjust bytes left */
54 while (*d != '\0' && n != 0)
55 d++;
56 dlen = d - dst;
57 n -= dlen;
58
59 if (n == 0)
60 return(dlen + strlen(s));
61 while (*s != '\0') {
62 if (n != 1) {
63 *d++ = *s;
64 n--;
65 }
66 s++;
67 }
68 *d = '\0';
69
70 return(dlen + (s - src)); /* count does not include NUL */
71}
diff --git a/src/lib/libc/string/strlcpy.3 b/src/lib/libc/string/strlcpy.3
new file mode 100644
index 0000000000..e1ff016aaf
--- /dev/null
+++ b/src/lib/libc/string/strlcpy.3
@@ -0,0 +1,140 @@
1.\" $OpenBSD: strlcpy.3,v 1.1 1998/07/01 01:29:45 millert 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.Dd June 22, 1998
29.Dt STRLCPY 3
30.Os
31.Sh NAME
32.Nm strlcpy,
33.Nm strlcat
34.Nd size-bounded string copying and concatenation
35.Sh SYNOPSIS
36.Fd #include <string.h>
37.Ft char *
38.Fn strlcpy "char *dst" "const char *src" "size_t size"
39.Ft char *
40.Fn strlcat "char *dst" "const char *src" "size_t size"
41.Sh DESCRIPTION
42The
43.Fn strlcpy
44and
45.Fn strlcat
46functions copy and concatenate strings respectively. They are designed
47to be safer, more consistent, and less error prone replacements for
48.Xr strncpy 3
49and
50.Xr strncat 3 .
51Unlike those functions,
52.Fn strlcpy
53and
54.Fn strlcat
55take the full size of the buffer (not just the length) and guarantee to
56NUL-terminate the result (as long as
57.Fa size
58is larger than 0). Note that you should include a byte for the NUL in
59.Fa size .
60.Pp
61The
62.Fn strlcpy
63function copies up to
64.Fa size
65- 1 characters from the NUL-terminated string
66.Fa src
67to
68.Fa dst ,
69NUL-terminating the result.
70.Pp
71The
72.Fn strlcat
73function appends the NUL-terminated string
74.Fa src
75to the end of
76.Fa dst .
77It will append at most
78.Fa size
79- strlen(dst) - 1 bytes, NUL-terminating the result.
80.Sh RETURN VALUES
81The
82.Fn strlcpy
83and
84.Fn strlcat
85functions return the total length of the string they tried to
86create. For
87.Fn strlcpy
88that means the length of
89.Fa src .
90For
91.Fn strlcat
92that means the initial length of
93.Fa dst
94plus
95the length of
96.Fa src .
97While this may seem somewhat confusing it was done to make
98truncation detection simple.
99.Sh EXAMPLES
100The following code fragment illustrates the simple case:
101.Bd -literal -offset indent
102char *s, *p, buf[BUFSIZ];
103
104.Li ...
105
106(void)strlcpy(buf, s, sizeof(buf));
107(void)strlcat(buf, p, sizeof(buf));
108.Ed
109.Pp
110To detect truncation, perhaps while building a pathname, something
111like the following might be used:
112.Bd -literal -offset indent
113char *dir, *file, pname[MAXPATHNAMELEN];
114
115.Li ...
116
117if (strlcpy(pname, dir, sizeof(pname)) >= sizeof(pname))
118 goto toolong;
119if (strlcat(pname, file, sizeof(pname)) >= sizeof(pname))
120 goto toolong;
121.Ed
122.Pp
123Since we know how many characters we copied the first time, we can
124speed things up a bit by using a copy instead on an append:
125.Bd -literal -offset indent
126char *dir, *file, pname[MAXPATHNAMELEN];
127size_t n;
128
129.Li ...
130
131n = strlcpy(pname, dir, sizeof(pname));
132if (n >= sizeof(pname))
133 goto toolong;
134if (strlcpy(pname + n, file, sizeof(pname)) >= sizeof(pname) - n)
135 goto toolong;
136.Ed
137.Sh SEE ALSO
138.Xr snprintf 3 ,
139.Xr strncpy 3 ,
140.Xr strncat 3
diff --git a/src/lib/libc/string/strlcpy.c b/src/lib/libc/string/strlcpy.c
new file mode 100644
index 0000000000..1a60445599
--- /dev/null
+++ b/src/lib/libc/string/strlcpy.c
@@ -0,0 +1,63 @@
1/* $OpenBSD: strlcpy.c,v 1.1 1998/07/01 01:29:45 millert Exp $ */
2
3/*
4 * Copyright (c) 1998 Todd C. Miller <Todd.Miller@courtesan.com>
5 * All rights reserved.
6 *
7 * Redistribution and use in source and binary forms, with or without
8 * modification, are permitted provided that the following conditions
9 * are met:
10 * 1. Redistributions of source code must retain the above copyright
11 * notice, this list of conditions and the following disclaimer.
12 * 2. Redistributions in binary form must reproduce the above copyright
13 * notice, this list of conditions and the following disclaimer in the
14 * documentation and/or other materials provided with the distribution.
15 * 3. The name of the author may not be used to endorse or promote products
16 * derived from this software without specific prior written permission.
17 *
18 * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES,
19 * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY
20 * AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL
21 * THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
22 * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
23 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
24 * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
25 * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
26 * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
27 * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
28 */
29
30#if defined(LIBC_SCCS) && !defined(lint)
31static char *rcsid = "$OpenBSD: strlcpy.c,v 1.1 1998/07/01 01:29:45 millert Exp $";
32#endif /* LIBC_SCCS and not lint */
33
34#include <sys/types.h>
35#include <string.h>
36
37/*
38 * Copy src to string dst of size siz. At most siz-1 characters
39 * will be copied. Always NUL terminates (unless siz == 0).
40 * Returns strlen(src); if retval >= siz, truncation occurred.
41 */
42size_t strlcpy(dst, src, siz)
43 char *dst;
44 char *src;
45 size_t siz;
46{
47 register char *d = dst;
48 register const char *s = src;
49 register size_t n = siz;
50
51 if (n == 0)
52 return(strlen(s));
53 while (*s != '\0') {
54 if (n != 1) {
55 *d++ = *s;
56 n--;
57 }
58 s++;
59 }
60 *d = '\0';
61
62 return(s - src); /* count does not include NUL */
63}