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