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