1 
2 #include "EbAppString.h"
3 
4 /* SAFE STRING LIBRARY */
5 
6 static constraint_handler_t str_handler = NULL;
7 
8 void
invoke_safe_str_constraint_handler(const char * msg,void * ptr,errno_t error)9 invoke_safe_str_constraint_handler(const char *msg,
10 void *ptr,
11 errno_t error)
12 {
13 	if (NULL != str_handler) {
14 		str_handler(msg, ptr, error);
15 	}
16 	else {
17 		sl_default_handler(msg, ptr, error);
18 	}
19 }
20 
ignore_handler_s(const char * msg,void * ptr,errno_t error)21 void ignore_handler_s(const char *msg, void *ptr, errno_t error)
22 {
23 	(void)msg;
24 	(void)ptr;
25 	(void)error;
26 	sldebug_printf("IGNORE CONSTRAINT HANDLER: (%u) %s\n", error,
27 		(msg) ? msg : "Null message");
28 	return;
29 }
30 
31 errno_t
strncpy_ss(char * dest,rsize_t dmax,const char * src,rsize_t slen)32 strncpy_ss(char *dest, rsize_t dmax, const char *src, rsize_t slen)
33 {
34 	rsize_t orig_dmax;
35 	char *orig_dest;
36 	const char *overlap_bumper;
37 
38 	if (dest == NULL) {
39 		invoke_safe_str_constraint_handler("strncpy_ss: dest is null",
40 			NULL, ESNULLP);
41 		return RCNEGATE(ESNULLP);
42 	}
43 
44 	if (dmax == 0) {
45 		invoke_safe_str_constraint_handler("strncpy_ss: dmax is 0",
46 			NULL, ESZEROL);
47 		return RCNEGATE(ESZEROL);
48 	}
49 
50 	if (dmax > RSIZE_MAX_STR) {
51 		invoke_safe_str_constraint_handler("strncpy_ss: dmax exceeds max",
52 			NULL, ESLEMAX);
53 		return RCNEGATE(ESLEMAX);
54 	}
55 
56 	/* hold base in case src was not copied */
57 	orig_dmax = dmax;
58 	orig_dest = dest;
59 
60 	if (src == NULL) {
61 		handle_error(orig_dest, orig_dmax, (char*) ("strncpy_ss: "
62 			"src is null"),
63 			ESNULLP);
64 		return RCNEGATE(ESNULLP);
65 	}
66 
67 	if (slen == 0) {
68 		handle_error(orig_dest, orig_dmax, (char*)("strncpy_ss: "
69 			"slen is zero"),
70 			ESZEROL);
71 		return RCNEGATE(ESZEROL);
72 	}
73 
74 	if (slen > RSIZE_MAX_STR) {
75 		handle_error(orig_dest, orig_dmax, (char*)("strncpy_ss: "
76 			"slen exceeds max"),
77 			ESLEMAX);
78 		return RCNEGATE(ESLEMAX);
79 	}
80 
81 
82 	if (dest < src) {
83 		overlap_bumper = src;
84 
85 		while (dmax > 0) {
86 			if (dest == overlap_bumper) {
87 				handle_error(orig_dest, orig_dmax, (char*)("strncpy_ss: "
88 					"overlapping objects"),
89 					ESOVRLP);
90 				return RCNEGATE(ESOVRLP);
91 			}
92 
93 			if (slen == 0) {
94 				/*
95 				* Copying truncated to slen chars.  Note that the TR says to
96 				* copy slen chars plus the null char.  We null the slack.
97 				*/
98 				*dest = '\0';
99 				return RCNEGATE(EOK);
100 			}
101 
102 			*dest = *src;
103 			if (*dest == '\0') {
104 				return RCNEGATE(EOK);
105 			}
106 
107 			dmax--;
108 			slen--;
109 			dest++;
110 			src++;
111 		}
112 
113 	}
114 	else {
115 		overlap_bumper = dest;
116 
117 		while (dmax > 0) {
118 			if (src == overlap_bumper) {
119 				handle_error(orig_dest, orig_dmax, (char*)( "strncpy_s: "
120 					"overlapping objects"),
121 					ESOVRLP);
122 				return RCNEGATE(ESOVRLP);
123 			}
124 
125 			if (slen == 0) {
126 				/*
127 				* Copying truncated to slen chars.  Note that the TR says to
128 				* copy slen chars plus the null char.  We null the slack.
129 				*/
130 				*dest = '\0';
131 				return RCNEGATE(EOK);
132 			}
133 
134 			*dest = *src;
135 			if (*dest == '\0') {
136 				return RCNEGATE(EOK);
137 			}
138 
139 			dmax--;
140 			slen--;
141 			dest++;
142 			src++;
143 		}
144 	}
145 
146 	/*
147 	* the entire src was not copied, so zero the string
148 	*/
149 	handle_error(orig_dest, orig_dmax, (char*)("strncpy_ss: not enough "
150 		"space for src"),
151 		ESNOSPC);
152 	return RCNEGATE(ESNOSPC);
153 }
154 
155 errno_t
strcpy_ss(char * dest,rsize_t dmax,const char * src)156 strcpy_ss(char *dest, rsize_t dmax, const char *src)
157 {
158 	rsize_t orig_dmax;
159 	char *orig_dest;
160 	const char *overlap_bumper;
161 
162 	if (dest == NULL) {
163 		invoke_safe_str_constraint_handler((char*)("strcpy_ss: dest is null"),
164 			NULL, ESNULLP);
165 		return RCNEGATE(ESNULLP);
166 	}
167 
168 	if (dmax == 0) {
169 		invoke_safe_str_constraint_handler((char*)("strcpy_ss: dmax is 0"),
170 			NULL, ESZEROL);
171 		return RCNEGATE(ESZEROL);
172 	}
173 
174 	if (dmax > RSIZE_MAX_STR) {
175 		invoke_safe_str_constraint_handler((char*)("strcpy_ss: dmax exceeds max"),
176 			NULL, ESLEMAX);
177 		return RCNEGATE(ESLEMAX);
178 	}
179 
180 	if (src == NULL) {
181 		*dest = '\0';
182 		invoke_safe_str_constraint_handler((char*)("strcpy_ss: src is null"),
183 			NULL, ESNULLP);
184 		return RCNEGATE(ESNULLP);
185 	}
186 
187 	if (dest == src) {
188 		return RCNEGATE(EOK);
189 	}
190 
191 	/* hold base of dest in case src was not copied */
192 	orig_dmax = dmax;
193 	orig_dest = dest;
194 
195 	if (dest < src) {
196 		overlap_bumper = src;
197 
198 		while (dmax > 0) {
199 			if (dest == overlap_bumper) {
200 				handle_error(orig_dest, orig_dmax, (char*)("strcpy_ss: "
201 					"overlapping objects"),
202 					ESOVRLP);
203 				return RCNEGATE(ESOVRLP);
204 			}
205 
206 			*dest = *src;
207 			if (*dest == '\0') {
208 				return RCNEGATE(EOK);
209 			}
210 
211 			dmax--;
212 			dest++;
213 			src++;
214 		}
215 
216 	}
217 	else {
218 		overlap_bumper = dest;
219 
220 		while (dmax > 0) {
221 			if (src == overlap_bumper) {
222 				handle_error(orig_dest, orig_dmax, (char*)("strcpy_ss: "
223 					"overlapping objects"),
224 					ESOVRLP);
225 				return RCNEGATE(ESOVRLP);
226 			}
227 
228 			*dest = *src;
229 			if (*dest == '\0') {
230 				return RCNEGATE(EOK);
231 			}
232 
233 			dmax--;
234 			dest++;
235 			src++;
236 		}
237 	}
238 
239 	/*
240 	* the entire src must have been copied, if not reset dest
241 	* to null the string.
242 	*/
243 	handle_error(orig_dest, orig_dmax, (char*)("strcpy_ss: not "
244 		"enough space for src"),
245 		ESNOSPC);
246 	return RCNEGATE(ESNOSPC);
247 }
248 
249 rsize_t
strnlen_ss(const char * dest,rsize_t dmax)250 strnlen_ss(const char *dest, rsize_t dmax)
251 {
252 	rsize_t count;
253 
254 	if (dest == NULL) {
255 		return RCNEGATE(0);
256 	}
257 
258 	if (dmax == 0) {
259 		invoke_safe_str_constraint_handler((char*)("strnlen_ss: dmax is 0"),
260 			NULL, ESZEROL);
261 		return RCNEGATE(0);
262 	}
263 
264 	if (dmax > RSIZE_MAX_STR) {
265 		invoke_safe_str_constraint_handler((char*)("strnlen_ss: dmax exceeds max"),
266 			NULL, ESLEMAX);
267 		return RCNEGATE(0);
268 	}
269 
270 	count = 0;
271 	while (*dest && dmax) {
272 		count++;
273 		dmax--;
274 		dest++;
275 	}
276 
277 	return RCNEGATE(count);
278 }
279 
280 /* SAFE STRING LIBRARY */
281