Line data Source code
1 : /*------------------------------------------------------------------
2 : * strncpy_s.c / strcpy_s.c / strnlen_s.c
3 : *
4 : * October 2008, Bo Berry
5 : *
6 : * Copyright � 2008-2011 by Cisco Systems, Inc
7 : * All rights reserved.
8 :
9 : * safe_str_constraint.c
10 : *
11 : * October 2008, Bo Berry
12 : * 2012, Jonathan Toppins <jtoppins@users.sourceforge.net>
13 : *
14 : * Copyright � 2008, 2009, 2012 Cisco Systems
15 : * All rights reserved.
16 :
17 : * ignore_handler_s.c
18 : *
19 : * 2012, Jonathan Toppins <jtoppins@users.sourceforge.net>
20 : *
21 : * Copyright � 2012 Cisco Systems
22 : * All rights reserved.
23 : *
24 : * Permission is hereby granted, free of charge, to any person
25 : * obtaining a copy of this software and associated documentation
26 : * files (the "Software"), to deal in the Software without
27 : * restriction, including without limitation the rights to use,
28 : * copy, modify, merge, publish, distribute, sublicense, and/or
29 : * sell copies of the Software, and to permit persons to whom the
30 : * Software is furnished to do so, subject to the following
31 : * conditions:
32 : *
33 : * The above copyright notice and this permission notice shall be
34 : * included in all copies or substantial portions of the Software.
35 : *
36 : * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
37 : * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
38 : * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
39 : * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
40 : * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
41 : * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
42 : * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
43 : * OTHER DEALINGS IN THE SOFTWARE.
44 : *------------------------------------------------------------------
45 : */
46 : #include "EbString.h"
47 :
48 : /* SAFE STRING LIBRARY */
49 :
50 : static constraint_handler_t str_handler = NULL;
51 :
52 : void
53 0 : eb_invoke_safe_str_constraint_handler(const char *msg,
54 : void *ptr,
55 : errno_t error)
56 : {
57 0 : if (NULL != str_handler)
58 0 : str_handler(msg, ptr, error);
59 : else
60 0 : sl_default_handler(msg, ptr, error);
61 0 : }
62 :
63 0 : void eb_ignore_handler_s(const char *msg, void *ptr, errno_t error)
64 : {
65 : (void)msg;
66 : (void)ptr;
67 : (void)error;
68 : sldebug_printf("IGNORE CONSTRAINT HANDLER: (%u) %s\n", error,
69 : (msg) ? msg : "Null message");
70 0 : return;
71 : }
72 :
73 : errno_t
74 0 : eb_strncpy_ss(char *dest, rsize_t dmax, const char *src, rsize_t slen)
75 : {
76 : rsize_t orig_dmax;
77 : char *orig_dest;
78 : const char *overlap_bumper;
79 :
80 0 : if (dest == NULL) {
81 0 : eb_invoke_safe_str_constraint_handler("strncpy_ss: dest is null",
82 : NULL, ESNULLP);
83 0 : return RCNEGATE(ESNULLP);
84 : }
85 :
86 0 : if (dmax == 0) {
87 0 : eb_invoke_safe_str_constraint_handler("strncpy_ss: dmax is 0",
88 : NULL, ESZEROL);
89 0 : return RCNEGATE(ESZEROL);
90 : }
91 :
92 0 : if (dmax > RSIZE_MAX_STR) {
93 0 : eb_invoke_safe_str_constraint_handler("strncpy_ss: dmax exceeds max",
94 : NULL, ESLEMAX);
95 0 : return RCNEGATE(ESLEMAX);
96 : }
97 :
98 : /* hold base in case src was not copied */
99 0 : orig_dmax = dmax;
100 0 : orig_dest = dest;
101 :
102 0 : if (src == NULL) {
103 0 : eb_handle_error(orig_dest, orig_dmax, (char*) ("strncpy_ss: "
104 : "src is null"),
105 : ESNULLP);
106 0 : return RCNEGATE(ESNULLP);
107 : }
108 :
109 0 : if (slen == 0) {
110 0 : eb_handle_error(orig_dest, orig_dmax, (char*)("strncpy_ss: "
111 : "slen is zero"),
112 : ESZEROL);
113 0 : return RCNEGATE(ESZEROL);
114 : }
115 :
116 0 : if (slen > RSIZE_MAX_STR) {
117 0 : eb_handle_error(orig_dest, orig_dmax, (char*)("strncpy_ss: "
118 : "slen exceeds max"),
119 : ESLEMAX);
120 0 : return RCNEGATE(ESLEMAX);
121 : }
122 :
123 0 : if (dest < src) {
124 0 : overlap_bumper = src;
125 :
126 0 : while (dmax > 0) {
127 0 : if (dest == overlap_bumper) {
128 0 : eb_handle_error(orig_dest, orig_dmax, (char*)("strncpy_ss: "
129 : "overlapping objects"),
130 : ESOVRLP);
131 0 : return RCNEGATE(ESOVRLP);
132 : }
133 :
134 0 : if (slen == 0) {
135 : /*
136 : * Copying truncated to slen chars. Note that the TR says to
137 : * copy slen chars plus the null char. We null the slack.
138 : */
139 0 : *dest = '\0';
140 0 : return RCNEGATE(EOK);
141 : }
142 :
143 0 : *dest = *src;
144 0 : if (*dest == '\0')
145 0 : return RCNEGATE(EOK);
146 0 : dmax--;
147 0 : slen--;
148 0 : dest++;
149 0 : src++;
150 : }
151 : }
152 : else {
153 0 : overlap_bumper = dest;
154 :
155 0 : while (dmax > 0) {
156 0 : if (src == overlap_bumper) {
157 0 : eb_handle_error(orig_dest, orig_dmax, (char*)( "strncpy_s: "
158 : "overlapping objects"),
159 : ESOVRLP);
160 0 : return RCNEGATE(ESOVRLP);
161 : }
162 :
163 0 : if (slen == 0) {
164 : /*
165 : * Copying truncated to slen chars. Note that the TR says to
166 : * copy slen chars plus the null char. We null the slack.
167 : */
168 0 : *dest = '\0';
169 0 : return RCNEGATE(EOK);
170 : }
171 :
172 0 : *dest = *src;
173 0 : if (*dest == '\0')
174 0 : return RCNEGATE(EOK);
175 0 : dmax--;
176 0 : slen--;
177 0 : dest++;
178 0 : src++;
179 : }
180 : }
181 :
182 : /*
183 : * the entire src was not copied, so zero the string
184 : */
185 0 : eb_handle_error(orig_dest, orig_dmax, (char*)("strncpy_ss: not enough "
186 : "space for src"),
187 : ESNOSPC);
188 0 : return RCNEGATE(ESNOSPC);
189 : }
190 :
191 : errno_t
192 0 : eb_strcpy_ss(char *dest, rsize_t dmax, const char *src)
193 : {
194 : rsize_t orig_dmax;
195 : char *orig_dest;
196 : const char *overlap_bumper;
197 :
198 0 : if (dest == NULL) {
199 0 : eb_invoke_safe_str_constraint_handler((char*)("strcpy_ss: dest is null"),
200 : NULL, ESNULLP);
201 0 : return RCNEGATE(ESNULLP);
202 : }
203 :
204 0 : if (dmax == 0) {
205 0 : eb_invoke_safe_str_constraint_handler((char*)("strcpy_ss: dmax is 0"),
206 : NULL, ESZEROL);
207 0 : return RCNEGATE(ESZEROL);
208 : }
209 :
210 0 : if (dmax > RSIZE_MAX_STR) {
211 0 : eb_invoke_safe_str_constraint_handler((char*)("strcpy_ss: dmax exceeds max"),
212 : NULL, ESLEMAX);
213 0 : return RCNEGATE(ESLEMAX);
214 : }
215 :
216 0 : if (src == NULL) {
217 0 : *dest = '\0';
218 0 : eb_invoke_safe_str_constraint_handler((char*)("strcpy_ss: src is null"),
219 : NULL, ESNULLP);
220 0 : return RCNEGATE(ESNULLP);
221 : }
222 :
223 0 : if (dest == src)
224 0 : return RCNEGATE(EOK);
225 : /* hold base of dest in case src was not copied */
226 0 : orig_dmax = dmax;
227 0 : orig_dest = dest;
228 :
229 0 : if (dest < src) {
230 0 : overlap_bumper = src;
231 :
232 0 : while (dmax > 0) {
233 0 : if (dest == overlap_bumper) {
234 0 : eb_handle_error(orig_dest, orig_dmax, (char*)("strcpy_ss: "
235 : "overlapping objects"),
236 : ESOVRLP);
237 0 : return RCNEGATE(ESOVRLP);
238 : }
239 :
240 0 : *dest = *src;
241 0 : if (*dest == '\0')
242 0 : return RCNEGATE(EOK);
243 0 : dmax--;
244 0 : dest++;
245 0 : src++;
246 : }
247 : }
248 : else {
249 0 : overlap_bumper = dest;
250 :
251 0 : while (dmax > 0) {
252 0 : if (src == overlap_bumper) {
253 0 : eb_handle_error(orig_dest, orig_dmax, (char*)("strcpy_ss: "
254 : "overlapping objects"),
255 : ESOVRLP);
256 0 : return RCNEGATE(ESOVRLP);
257 : }
258 :
259 0 : *dest = *src;
260 0 : if (*dest == '\0')
261 0 : return RCNEGATE(EOK);
262 0 : dmax--;
263 0 : dest++;
264 0 : src++;
265 : }
266 : }
267 :
268 : /*
269 : * the entire src must have been copied, if not reset dest
270 : * to null the string.
271 : */
272 0 : eb_handle_error(orig_dest, orig_dmax, (char*)("strcpy_ss: not "
273 : "enough space for src"),
274 : ESNOSPC);
275 0 : return RCNEGATE(ESNOSPC);
276 : }
277 :
278 : rsize_t
279 4 : eb_strnlen_ss(const char *dest, rsize_t dmax)
280 : {
281 : rsize_t count;
282 :
283 4 : if (dest == NULL)
284 0 : return RCNEGATE(0);
285 4 : if (dmax == 0) {
286 0 : eb_invoke_safe_str_constraint_handler((char*)("strnlen_ss: dmax is 0"),
287 : NULL, ESZEROL);
288 0 : return RCNEGATE(0);
289 : }
290 :
291 4 : if (dmax > RSIZE_MAX_STR) {
292 0 : eb_invoke_safe_str_constraint_handler((char*)("strnlen_ss: dmax exceeds max"),
293 : NULL, ESLEMAX);
294 0 : return RCNEGATE(0);
295 : }
296 :
297 4 : count = 0;
298 44 : while (*dest && dmax) {
299 40 : count++;
300 40 : dmax--;
301 40 : dest++;
302 : }
303 :
304 4 : return RCNEGATE(count);
305 : }
306 :
307 : /* SAFE STRING LIBRARY */
|