Rev 197 | Only display areas with differences | Ignore whitespace | Details | Blame | Last modification | View Log | RSS feed
Rev 197 | Rev 198 | ||
---|---|---|---|
1 | /********************************************************************\ |
1 | /********************************************************************\ |
2 | 2 | ||
3 | Name: strlcpy.c |
3 | Name: strlcpy.c |
4 | Created by: Stefan Ritt |
4 | Created by: Stefan Ritt |
5 | Copyright 2000 + Stefan Ritt |
5 | Copyright 2000 + Stefan Ritt |
6 | 6 | ||
7 | Contents: Contains strlcpy and strlcat which are versions of |
7 | Contents: Contains strlcpy and strlcat which are versions of |
8 | strcpy and strcat, but which avoid buffer overflows |
8 | strcpy and strcat, but which avoid buffer overflows |
9 | 9 | ||
10 | |
10 | |
11 | This file is part of MIDAS XML Library. |
11 | This file is part of MIDAS XML Library. |
12 | 12 | ||
13 | MIDAS XML Library is free software: you can redistribute it and/or modify |
13 | MIDAS XML Library is free software: you can redistribute it and/or modify |
14 | it under the terms of the GNU General Public License as published by |
14 | it under the terms of the GNU General Public License as published by |
15 | the Free Software Foundation, either version 3 of the License, or |
15 | the Free Software Foundation, either version 3 of the License, or |
16 | (at your option) any later version. |
16 | (at your option) any later version. |
17 | 17 | ||
18 | MIDAS XML Library is distributed in the hope that it will be useful, |
18 | MIDAS XML Library is distributed in the hope that it will be useful, |
19 | but WITHOUT ANY WARRANTY; without even the implied warranty of |
19 | but WITHOUT ANY WARRANTY; without even the implied warranty of |
20 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
20 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
21 | GNU General Public License for more details. |
21 | GNU General Public License for more details. |
22 | 22 | ||
23 | You should have received a copy of the GNU General Public License |
23 | You should have received a copy of the GNU General Public License |
24 | along with MIDAS XML Library. If not, see <http://www.gnu.org/licenses/>. |
24 | along with MIDAS XML Library. If not, see <http://www.gnu.org/licenses/>. |
25 | |
25 | |
26 | \********************************************************************/ |
26 | \********************************************************************/ |
27 | 27 | ||
28 | #include <stdio.h> |
28 | #include <stdio.h> |
29 | #include <string.h> |
29 | #include <string.h> |
30 | #include "strlcpy.h" |
30 | #include "strlcpy.h" |
31 | 31 | ||
32 | /* |
32 | /* |
33 | * Copy src to string dst of size siz. At most siz-1 characters |
33 | * Copy src to string dst of size siz. At most siz-1 characters |
34 | * will be copied. Always NUL terminates (unless size == 0). |
34 | * will be copied. Always NUL terminates (unless size == 0). |
35 | * Returns strlen(src); if retval >= siz, truncation occurred. |
35 | * Returns strlen(src); if retval >= siz, truncation occurred. |
36 | */ |
36 | */ |
37 | #ifndef STRLCPY_DEFINED |
37 | #ifndef STRLCPY_DEFINED |
38 | 38 | ||
39 | size_t strlcpy(char *dst, const char *src, size_t size) |
39 | size_t strlcpy(char *dst, const char *src, size_t size) |
40 | { |
40 | { |
41 | char *d = dst; |
41 | char *d = dst; |
42 | const char *s = src; |
42 | const char *s = src; |
43 | size_t n = size; |
43 | size_t n = size; |
44 | 44 | ||
45 | /* Copy as many bytes as will fit */ |
45 | /* Copy as many bytes as will fit */ |
46 | if (n != 0 && --n != 0) { |
46 | if (n != 0 && --n != 0) { |
47 | do { |
47 | do { |
48 | if ((*d++ = *s++) == 0) |
48 | if ((*d++ = *s++) == 0) |
49 | break; |
49 | break; |
50 | } while (--n != 0); |
50 | } while (--n != 0); |
51 | } |
51 | } |
52 | 52 | ||
53 | /* Not enough room in dst, add NUL and traverse rest of src */ |
53 | /* Not enough room in dst, add NUL and traverse rest of src */ |
54 | if (n == 0) { |
54 | if (n == 0) { |
55 | if (size != 0) |
55 | if (size != 0) |
56 | *d = '\0'; /* NUL-terminate dst */ |
56 | *d = '\0'; /* NUL-terminate dst */ |
57 | while (*s++); |
57 | while (*s++); |
58 | } |
58 | } |
59 | 59 | ||
60 | return (s - src - 1); /* count does not include NUL */ |
60 | return (s - src - 1); /* count does not include NUL */ |
61 | } |
61 | } |
62 | 62 | ||
63 | /*-------------------------------------------------------------------*/ |
63 | /*-------------------------------------------------------------------*/ |
64 | 64 | ||
65 | /* |
65 | /* |
66 | * Appends src to string dst of size siz (unlike strncat, siz is the |
66 | * Appends src to string dst of size siz (unlike strncat, siz is the |
67 | * full size of dst, not space left). At most siz-1 characters |
67 | * full size of dst, not space left). At most siz-1 characters |
68 | * will be copied. Always NUL terminates (unless size <= strlen(dst)). |
68 | * will be copied. Always NUL terminates (unless size <= strlen(dst)). |
69 | * Returns strlen(src) + MIN(size, strlen(initial dst)). |
69 | * Returns strlen(src) + MIN(size, strlen(initial dst)). |
70 | * If retval >= size, truncation occurred. |
70 | * If retval >= size, truncation occurred. |
71 | */ |
71 | */ |
72 | size_t strlcat(char *dst, const char *src, size_t size) |
72 | size_t strlcat(char *dst, const char *src, size_t size) |
73 | { |
73 | { |
74 | char *d = dst; |
74 | char *d = dst; |
75 | const char *s = src; |
75 | const char *s = src; |
76 | size_t n = size; |
76 | size_t n = size; |
77 | size_t dlen; |
77 | size_t dlen; |
78 | 78 | ||
79 | /* Find the end of dst and adjust bytes left but don't go past end */ |
79 | /* Find the end of dst and adjust bytes left but don't go past end */ |
80 | while (n-- != 0 && *d != '\0') |
80 | while (n-- != 0 && *d != '\0') |
81 | d++; |
81 | d++; |
82 | dlen = d - dst; |
82 | dlen = d - dst; |
83 | n = size - dlen; |
83 | n = size - dlen; |
84 | 84 | ||
85 | if (n == 0) |
85 | if (n == 0) |
86 | return (dlen + strlen(s)); |
86 | return (dlen + strlen(s)); |
87 | while (*s != '\0') { |
87 | while (*s != '\0') { |
88 | if (n != 1) { |
88 | if (n != 1) { |
89 | *d++ = *s; |
89 | *d++ = *s; |
90 | n--; |
90 | n--; |
91 | } |
91 | } |
92 | s++; |
92 | s++; |
93 | } |
93 | } |
94 | *d = '\0'; |
94 | *d = '\0'; |
95 | 95 | ||
96 | return (dlen + (s - src)); /* count does not include NUL */ |
96 | return (dlen + (s - src)); /* count does not include NUL */ |
97 | } |
97 | } |
98 | 98 | ||
99 | /*-------------------------------------------------------------------*/ |
99 | /*-------------------------------------------------------------------*/ |
100 | 100 | ||
101 | #endif // STRLCPY_DEFINED |
101 | #endif // STRLCPY_DEFINED |
102 | 102 |