]>
Commit | Line | Data |
---|---|---|
031e5cce SM |
1 | // SPDX-License-Identifier: BSD-2-Clause-Patent |
2 | /* | |
3 | * test-str.c - test our string functions. | |
4 | */ | |
5 | #pragma GCC diagnostic ignored "-Wunused-variable" | |
6 | #pragma GCC diagnostic error "-Wnonnull" | |
7 | #pragma GCC diagnostic error "-Wunused-function" | |
8 | ||
9 | #pragma GCC diagnostic warning "-Wcpp" | |
10 | ||
11 | #ifndef SHIM_UNIT_TEST | |
12 | #define SHIM_UNIT_TEST | |
13 | #endif | |
14 | #include "shim.h" | |
15 | ||
16 | #include <stdio.h> | |
17 | ||
18 | static int | |
19 | test_strlen(void) | |
20 | { | |
21 | const char s1[] = "abcd"; | |
22 | const char s2[] = ""; | |
23 | ||
24 | assert_equal_return(shim_strlen(s1), 4, -1, "got %d expected %d\n"); | |
25 | assert_equal_return(strlen(s1), 4, -1, "got %d expected %d\n"); | |
26 | assert_equal_return(shim_strlen(s2), 0, -1, "got %d expected %d\n"); | |
27 | assert_equal_return(strlen(s2), 0, -1, "got %d expected %d\n"); | |
28 | ||
29 | return 0; | |
30 | } | |
31 | ||
32 | static int | |
33 | test_strnlen(void) | |
34 | { | |
35 | const char s1[] = "abcd"; | |
36 | const char s2[] = ""; | |
37 | ||
38 | assert_equal_return(shim_strnlen(s1, 0), 0, -1, "got %d expected %d\n"); | |
39 | assert_equal_return(strnlen(s1, 0), 0, -1, "got %d expected %d\n"); | |
40 | assert_equal_return(shim_strnlen(s1, 1), 1, -1, "got %d expected %d\n"); | |
41 | assert_equal_return(strnlen(s1, 1), 1, -1, "got %d expected %d\n"); | |
42 | assert_equal_return(shim_strnlen(s1, 3), 3, -1, "got %d expected %d\n"); | |
43 | assert_equal_return(strnlen(s1, 3), 3, -1, "got %d expected %d\n"); | |
44 | assert_equal_return(shim_strnlen(s1, 4), 4, -1, "got %d expected %d\n"); | |
45 | assert_equal_return(strnlen(s1, 4), 4, -1, "got %d expected %d\n"); | |
46 | assert_equal_return(shim_strnlen(s1, 5), 4, -1, "got %d expected %d\n"); | |
47 | assert_equal_return(strnlen(s1, 5), 4, -1, "got %d expected %d\n"); | |
48 | assert_equal_return(shim_strnlen(s2, 0), 0, -1, "got %d expected %d\n"); | |
49 | assert_equal_return(strnlen(s2, 0), 0, -1, "got %d expected %d\n"); | |
50 | assert_equal_return(shim_strnlen(s2, 1), 0, -1, "got %d expected %d\n"); | |
51 | assert_equal_return(strnlen(s2, 1), 0, -1, "got %d expected %d\n"); | |
52 | ||
53 | return 0; | |
54 | } | |
55 | ||
56 | #pragma GCC diagnostic push | |
57 | #pragma GCC diagnostic ignored "-Wshadow" | |
58 | ||
59 | /* | |
60 | * these are constants so that the failures are readable if you get | |
61 | * it wrong. | |
62 | */ | |
63 | #define s0 "sbat," | |
64 | #define s0sz 6 | |
65 | #define s0len 5 | |
66 | #define s1 "sbat,1,2021030218" | |
67 | #define s1sz 18 | |
68 | #define s1len 17 | |
69 | #define s2 "sbat,1,20210302" | |
70 | #define s2sz 16 | |
71 | #define s2len 15 | |
72 | #define s3 "sbat,1,20210303" | |
73 | #define s3sz 16 | |
74 | #define s3len 15 | |
75 | #define s4 "sbat\314\234\014," | |
76 | #define s4sz 9 | |
77 | #define s4len 8 | |
78 | /* | |
79 | * same as s4 but with a UTF8 encoding error; one bit is cleared. | |
80 | */ | |
81 | #define s5 "sbat\314\034\014," | |
82 | #define s5sz 9 | |
83 | #define s5len 8 | |
84 | ||
85 | #define test_strcmp_helper(fn, invert_sign_errors, invert_encoding_errors) \ | |
86 | ({ \ | |
87 | printf("testing %s\n", #fn); \ | |
88 | int status_ = 0, rc_; \ | |
89 | \ | |
90 | rc_ = assert_zero_as_expr(fn(s0, s0), -1, "\n"); \ | |
91 | status_ = MIN(status_, rc_); \ | |
92 | \ | |
93 | if (invert_sign_errors) \ | |
94 | rc_ = assert_positive_as_expr(fn(s0, s1), -1, "\n"); \ | |
95 | else \ | |
96 | rc_ = assert_negative_as_expr(fn(s0, s1), -1, "\n"); \ | |
97 | status_ = MIN(status_, rc_); \ | |
98 | rc_ = assert_positive_as_expr(fn(s1, s0), -1, "\n"); \ | |
99 | status_ = MIN(status_, rc_); \ | |
100 | \ | |
101 | rc_ = assert_positive_as_expr(fn(s1, s2), -1, "\n"); \ | |
102 | status_ = MIN(status_, rc_); \ | |
103 | if (invert_sign_errors) \ | |
104 | rc_ = assert_positive_as_expr(fn(s2, s1), -1, "\n"); \ | |
105 | else \ | |
106 | rc_ = assert_negative_as_expr(fn(s2, s1), -1, "\n"); \ | |
107 | status_ = MIN(status_, rc_); \ | |
108 | \ | |
109 | if (invert_sign_errors) \ | |
110 | rc_ = assert_positive_as_expr(fn(s2, s3), -1, "\n"); \ | |
111 | else \ | |
112 | rc_ = assert_negative_as_expr(fn(s2, s3), -1, "\n"); \ | |
113 | status_ = MIN(status_, rc_); \ | |
114 | rc_ = assert_positive_as_expr(fn(s3, s2), -1, "\n"); \ | |
115 | status_ = MIN(status_, rc_); \ | |
116 | \ | |
117 | if (invert_encoding_errors) \ | |
118 | rc_ = assert_negative_as_expr(fn(s4, s5), -1, "\n"); \ | |
119 | else \ | |
120 | rc_ = assert_positive_as_expr(fn(s4, s5), -1, "\n"); \ | |
121 | status_ = MIN(status_, rc_); \ | |
122 | \ | |
123 | if (status_ < 0) \ | |
124 | printf("%s failed\n", #fn); \ | |
125 | status_; \ | |
126 | }) | |
127 | ||
128 | static int | |
129 | test_strcmp(void) | |
130 | { | |
131 | int status = 0; | |
132 | int rc; | |
133 | ||
134 | /* | |
135 | * shim's strcmp | |
136 | */ | |
137 | rc = test_strcmp_helper(shim_strcmp, false, false); | |
138 | status = MIN(rc, status); | |
139 | ||
140 | /* | |
141 | * libc's strcmp | |
142 | */ | |
143 | rc = test_strcmp_helper(strcmp, false, false); | |
144 | status = MIN(rc, status); | |
145 | ||
146 | return status; | |
147 | } | |
148 | ||
149 | #undef s0 | |
150 | #undef s0sz | |
151 | #undef s0len | |
152 | #undef s1 | |
153 | #undef s1sz | |
154 | #undef s1len | |
155 | #undef s2 | |
156 | #undef s2sz | |
157 | #undef s2len | |
158 | #undef s3 | |
159 | #undef s3sz | |
160 | #undef s3len | |
161 | #undef s4 | |
162 | #undef s4sz | |
163 | #undef s4len | |
164 | #undef s5 | |
165 | #undef s5sz | |
166 | #undef s5len | |
167 | ||
168 | /* | |
169 | * these are constants so that the failures are readable if you get | |
170 | * it wrong. | |
171 | */ | |
172 | #define s0 "sbAt," | |
173 | #define s0sz 6 | |
174 | #define s0len 5 | |
175 | #define s1 "sbaT,1,2021030218" | |
176 | #define s1sz 18 | |
177 | #define s1len 17 | |
178 | #define s2 "sbAt,1,20210302" | |
179 | #define s2sz 16 | |
180 | #define s2len 15 | |
181 | #define s3 "sbaT,1,20210303" | |
182 | #define s3sz 16 | |
183 | #define s3len 15 | |
184 | #define s4 "sbat\314\234\014," | |
185 | #define s4sz 9 | |
186 | #define s4len 8 | |
187 | /* | |
188 | * same as s4 but with a UTF8 encoding error; one bit is cleared. | |
189 | */ | |
190 | #define s5 "sbat\314\034\014," | |
191 | #define s5sz 9 | |
192 | #define s5len 8 | |
193 | ||
194 | #define test_strcasecmp_helper(fn, invert_sign_errors, invert_encoding_errors) \ | |
195 | ({ \ | |
196 | printf("testing %s\n", #fn); \ | |
197 | int status_ = 0, rc_; \ | |
198 | \ | |
199 | rc_ = assert_zero_as_expr(fn(s0, s0), -1, "\n"); \ | |
200 | status_ = MIN(status_, rc_); \ | |
201 | \ | |
202 | if (invert_sign_errors) \ | |
203 | rc_ = assert_positive_as_expr(fn(s0, s1), -1, "\n"); \ | |
204 | else \ | |
205 | rc_ = assert_negative_as_expr(fn(s0, s1), -1, "\n"); \ | |
206 | status_ = MIN(status_, rc_); \ | |
207 | rc_ = assert_positive_as_expr(fn(s1, s0), -1, "\n"); \ | |
208 | status_ = MIN(status_, rc_); \ | |
209 | \ | |
210 | rc_ = assert_positive_as_expr(fn(s1, s2), -1, "\n"); \ | |
211 | status_ = MIN(status_, rc_); \ | |
212 | if (invert_sign_errors) \ | |
213 | rc_ = assert_positive_as_expr(fn(s2, s1), -1, "\n"); \ | |
214 | else \ | |
215 | rc_ = assert_negative_as_expr(fn(s2, s1), -1, "\n"); \ | |
216 | status_ = MIN(status_, rc_); \ | |
217 | \ | |
218 | if (invert_sign_errors) \ | |
219 | rc_ = assert_positive_as_expr(fn(s2, s3), -1, "\n"); \ | |
220 | else \ | |
221 | rc_ = assert_negative_as_expr(fn(s2, s3), -1, "\n"); \ | |
222 | status_ = MIN(status_, rc_); \ | |
223 | rc_ = assert_positive_as_expr(fn(s3, s2), -1, "\n"); \ | |
224 | status_ = MIN(status_, rc_); \ | |
225 | \ | |
226 | if (invert_encoding_errors) \ | |
227 | rc_ = assert_negative_as_expr(fn(s4, s5), -1, "\n"); \ | |
228 | else \ | |
229 | rc_ = assert_positive_as_expr(fn(s4, s5), -1, "\n"); \ | |
230 | status_ = MIN(status_, rc_); \ | |
231 | \ | |
232 | if (status_ < 0) \ | |
233 | printf("%s failed\n", #fn); \ | |
234 | status_; \ | |
235 | }) | |
236 | ||
237 | static int | |
238 | test_strcasecmp(void) | |
239 | { | |
240 | int status = 0; | |
241 | int rc; | |
242 | ||
243 | /* | |
244 | * shim's strcasecmp | |
245 | */ | |
246 | rc = test_strcasecmp_helper(shim_strcasecmp, false, false); | |
247 | status = MIN(rc, status); | |
248 | ||
249 | /* | |
250 | * libc's strcasecmp | |
251 | */ | |
252 | rc = test_strcasecmp_helper(strcasecmp, false, false); | |
253 | status = MIN(rc, status); | |
254 | ||
255 | return status; | |
256 | } | |
257 | ||
258 | #undef s0 | |
259 | #undef s0sz | |
260 | #undef s0len | |
261 | #undef s1 | |
262 | #undef s1sz | |
263 | #undef s1len | |
264 | #undef s2 | |
265 | #undef s2sz | |
266 | #undef s2len | |
267 | #undef s3 | |
268 | #undef s3sz | |
269 | #undef s3len | |
270 | #undef s4 | |
271 | #undef s4sz | |
272 | #undef s4len | |
273 | #undef s5 | |
274 | #undef s5sz | |
275 | #undef s5len | |
276 | ||
277 | /* | |
278 | * these are constants so that the failures are readable if you get | |
279 | * it wrong. | |
280 | */ | |
281 | #define s0 "sbAt," | |
282 | #define s0sz 6 | |
283 | #define s0len 5 | |
284 | #define s1 "sbaT,1,2021030218" | |
285 | #define s1sz 18 | |
286 | #define s1len 17 | |
287 | #define s2 "sbAt,1,20210302" | |
288 | #define s2sz 16 | |
289 | #define s2len 15 | |
290 | #define s3 "sbaT,1,20210303" | |
291 | #define s3sz 16 | |
292 | #define s3len 15 | |
293 | #define s4 "sbat\314\234\014," | |
294 | #define s4sz 9 | |
295 | #define s4len 8 | |
296 | /* | |
297 | * same as s4 but with a UTF8 encoding error; one bit is cleared. | |
298 | */ | |
299 | #define s5 "sbat\314\034\014," | |
300 | #define s5sz 9 | |
301 | #define s5len 8 | |
302 | ||
303 | #define test_strncasecmp_helper(fn, test_cmp_magnitude, invert_sign_errors, \ | |
304 | invert_encoding_errors) \ | |
305 | ({ \ | |
306 | printf("testing %s\n", #fn); \ | |
307 | int status_ = 0, rc_; \ | |
308 | \ | |
309 | rc_ = assert_zero_as_expr(fn(s0, s0, s0len), -1, "\n"); \ | |
310 | status_ = MIN(status_, rc_); \ | |
311 | rc_ = assert_zero_as_expr(fn(s0, s0, s0sz), -1, "\n"); \ | |
312 | status_ = MIN(status_, rc_); \ | |
313 | \ | |
314 | rc_ = assert_zero_as_expr(fn(s0, s1, s0len), -1, "\n"); \ | |
315 | status_ = MIN(status_, rc_); \ | |
316 | if (invert_sign_errors) \ | |
317 | rc_ = assert_positive_as_expr(fn(s0, s1, s0sz), -1, \ | |
318 | "\n"); \ | |
319 | else \ | |
320 | rc_ = assert_negative_as_expr(fn(s0, s1, s0sz), -1, \ | |
321 | "\n"); \ | |
322 | status_ = MIN(status_, rc_); \ | |
323 | if (test_cmp_magnitude) { \ | |
324 | rc_ = assert_equal_as_expr(fn(s0, s1, s0sz), \ | |
325 | s0[s0len] - s1[s0len], -1, \ | |
326 | "expected %d got %d\n"); \ | |
327 | status_ = MIN(status_, rc_); \ | |
328 | } \ | |
329 | rc_ = assert_positive_as_expr(fn(s1, s0, s0sz), -1, "\n"); \ | |
330 | status_ = MIN(status_, rc_); \ | |
331 | if (test_cmp_magnitude) { \ | |
332 | rc_ = assert_equal_as_expr(fn(s1, s0, s0sz), \ | |
333 | s1[s0len] - s0[s0len], -1, \ | |
334 | "expected %d got %d\n"); \ | |
335 | status_ = MIN(status_, rc_); \ | |
336 | } \ | |
337 | \ | |
338 | rc_ = assert_positive_as_expr(fn(s1, s2, s1sz), -1, "\n"); \ | |
339 | status_ = MIN(status_, rc_); \ | |
340 | if (test_cmp_magnitude) { \ | |
341 | rc_ = assert_equal_as_expr(fn(s1, s2, s2sz), \ | |
342 | s1[s2len] - s2[s2len], -1, \ | |
343 | "expected %d got %d\n"); \ | |
344 | status_ = MIN(status_, rc_); \ | |
345 | } \ | |
346 | rc_ = assert_positive_as_expr(fn(s1, s2, s1len), -1, "\n"); \ | |
347 | status_ = MIN(status_, rc_); \ | |
348 | if (test_cmp_magnitude) { \ | |
349 | rc_ = assert_equal_as_expr( \ | |
350 | fn(s1, s2, s2len), \ | |
351 | s1[s2len - 1] - s2[s2len - 1], -1, \ | |
352 | "expected %d got %d\n"); \ | |
353 | status_ = MIN(status_, rc_); \ | |
354 | } \ | |
355 | if (invert_sign_errors) \ | |
356 | rc_ = assert_positive_as_expr(fn(s2, s1, s1sz), -1, \ | |
357 | "\n"); \ | |
358 | else \ | |
359 | rc_ = assert_negative_as_expr(fn(s2, s1, s1sz), -1, \ | |
360 | "\n"); \ | |
361 | status_ = MIN(status_, rc_); \ | |
362 | if (test_cmp_magnitude) { \ | |
363 | rc_ = assert_equal_as_expr(fn(s2, s1, s1sz), \ | |
364 | s2[s2len] - s1[s2len], -1, \ | |
365 | "expected %d got %d\n"); \ | |
366 | status_ = MIN(status_, rc_); \ | |
367 | } \ | |
368 | \ | |
369 | rc_ = assert_zero_as_expr(fn(s1, s2, s2len), -1, "\n"); \ | |
370 | status_ = MIN(status_, rc_); \ | |
371 | rc_ = assert_positive_as_expr(fn(s1, s2, s2sz), -1, "\n"); \ | |
372 | status_ = MIN(status_, rc_); \ | |
373 | if (test_cmp_magnitude) { \ | |
374 | rc_ = assert_equal_as_expr(fn(s1, s2, s2sz), \ | |
375 | s1[s2len] - s2[s2len], -1, \ | |
376 | "expected %d got %d\n"); \ | |
377 | status_ = MIN(status_, rc_); \ | |
378 | } \ | |
379 | \ | |
380 | if (invert_sign_errors) \ | |
381 | rc_ = assert_positive_as_expr(fn(s2, s3, s2sz), -1, \ | |
382 | "\n"); \ | |
383 | else \ | |
384 | rc_ = assert_negative_as_expr(fn(s2, s3, s2sz), -1, \ | |
385 | "\n"); \ | |
386 | status_ = MIN(status_, rc_); \ | |
387 | rc_ = assert_equal_as_expr(fn(s2, s3, s2sz), \ | |
388 | s2[s2len - 1] - s3[s2len - 1], -1, \ | |
389 | "expected %d got %d\n"); \ | |
390 | status_ = MIN(status_, rc_); \ | |
391 | rc_ = assert_equal_as_expr(fn(s2, s3, s2len), \ | |
392 | s2[s2len - 1] - s3[s2len - 1], -1, \ | |
393 | "expected %d got %d\n"); \ | |
394 | status_ = MIN(status_, rc_); \ | |
395 | if (invert_sign_errors) \ | |
396 | rc_ = assert_positive_as_expr(fn(s2, s3, s2len), -1, \ | |
397 | "\n"); \ | |
398 | else \ | |
399 | rc_ = assert_negative_as_expr(fn(s2, s3, s2len), -1, \ | |
400 | "\n"); \ | |
401 | status_ = MIN(status_, rc_); \ | |
402 | rc_ = assert_zero_as_expr(fn(s2, s3, s2len - 1), -1, "\n"); \ | |
403 | status_ = MIN(status_, rc_); \ | |
404 | rc_ = assert_false_as_expr(fn(s1, s2, s2len), -1, "\n"); \ | |
405 | status_ = MIN(status_, rc_); \ | |
406 | \ | |
407 | if (invert_encoding_errors) \ | |
408 | rc_ = assert_negative_as_expr(fn(s4, s5, s4sz), -1, \ | |
409 | "\n"); \ | |
410 | else \ | |
411 | rc_ = assert_positive_as_expr(fn(s4, s5, s4sz), -1, \ | |
412 | "\n"); \ | |
413 | status_ = MIN(status_, rc_); \ | |
414 | \ | |
415 | if (status_ < 0) \ | |
416 | printf("%s failed\n", #fn); \ | |
417 | status_; \ | |
418 | }) | |
419 | ||
420 | static int | |
421 | test_strncasecmp(void) | |
422 | { | |
423 | int status = 0; | |
424 | int rc; | |
425 | ||
426 | /* | |
427 | * shim's strncasecmp | |
428 | */ | |
429 | rc = test_strncasecmp_helper(shim_strncasecmp, true, false, false); | |
430 | status = MIN(rc, status); | |
431 | ||
432 | /* | |
433 | * libc's strncasecmp | |
434 | */ | |
435 | rc = test_strncasecmp_helper(strncasecmp, false, false, false); | |
436 | status = MIN(rc, status); | |
437 | ||
438 | return status; | |
439 | } | |
440 | ||
441 | #undef s0 | |
442 | #undef s0sz | |
443 | #undef s0len | |
444 | #undef s1 | |
445 | #undef s1sz | |
446 | #undef s1len | |
447 | #undef s2 | |
448 | #undef s2sz | |
449 | #undef s2len | |
450 | #undef s3 | |
451 | #undef s3sz | |
452 | #undef s3len | |
453 | #undef s4 | |
454 | #undef s4sz | |
455 | #undef s4len | |
456 | #undef s5 | |
457 | #undef s5sz | |
458 | #undef s5len | |
459 | ||
460 | /* | |
461 | * copy-pasta from gnu-efi | |
462 | */ | |
463 | static inline UINTN | |
464 | gnuefi_strncmp ( | |
465 | IN CONST CHAR8 *s1, | |
466 | IN CONST CHAR8 *s2, | |
467 | IN UINTN len | |
468 | ) | |
469 | { | |
470 | while (*s1 && len) { | |
471 | if (*s1 != *s2) { | |
472 | break; | |
473 | } | |
474 | ||
475 | s1 += 1; | |
476 | s2 += 1; | |
477 | len -= 1; | |
478 | } | |
479 | ||
480 | return len ? *s1 - *s2 : 0; | |
481 | } | |
482 | ||
483 | /* | |
484 | * This is still broken, and fails the test case as written on arm. | |
485 | * We no longer use this, so we do not strictly need to run it. | |
486 | */ | |
487 | #if !defined(__arm__) && !defined(__aarch64__) | |
488 | static inline INTN | |
489 | gnuefi_signed_strncmp ( | |
490 | IN CONST CHAR8 *s1, | |
491 | IN CONST CHAR8 *s2, | |
492 | IN UINTN len | |
493 | ) | |
494 | { | |
495 | while (*s1 && len) { | |
496 | if (*s1 != *s2) { | |
497 | break; | |
498 | } | |
499 | ||
500 | s1 += 1; | |
501 | s2 += 1; | |
502 | len -= 1; | |
503 | } | |
504 | ||
505 | return len ? *s1 - *s2 : 0; | |
506 | } | |
507 | #endif | |
508 | ||
509 | static inline INTN | |
510 | gnuefi_good_strncmp ( | |
511 | IN CONST CHAR8 *s1p, | |
512 | IN CONST CHAR8 *s2p, | |
513 | IN UINTN len | |
514 | ) | |
515 | { | |
516 | CONST UINT8 *s1 = (CONST UINT8 *)s1p; | |
517 | CONST UINT8 *s2 = (CONST UINT8 *)s2p; | |
518 | ||
519 | while (*s1 && len) { | |
520 | if (*s1 != *s2) { | |
521 | break; | |
522 | } | |
523 | ||
524 | s1 += 1; | |
525 | s2 += 1; | |
526 | len -= 1; | |
527 | } | |
528 | ||
529 | return len ? *s1 - *s2 : 0; | |
530 | } | |
531 | ||
532 | /* | |
533 | * these are constants so that the failures are readable if you get | |
534 | * it wrong. | |
535 | */ | |
536 | #define s0 "sbat," | |
537 | #define s0sz 6 | |
538 | #define s0len 5 | |
539 | #define s1 "sbat,1,2021030218" | |
540 | #define s1sz 18 | |
541 | #define s1len 17 | |
542 | #define s2 "sbat,1,20210302" | |
543 | #define s2sz 16 | |
544 | #define s2len 15 | |
545 | #define s3 "sbat,1,20210303" | |
546 | #define s3sz 16 | |
547 | #define s3len 15 | |
548 | #define s4 "sbat\314\234\014," | |
549 | #define s4sz 9 | |
550 | #define s4len 8 | |
551 | /* | |
552 | * same as s4 but with a UTF8 encoding error; one bit is cleared. | |
553 | */ | |
554 | #define s5 "sbat\314\034\014," | |
555 | #define s5sz 9 | |
556 | #define s5len 8 | |
557 | ||
558 | #define test_strncmp_helper(fn, test_cmp_magnitude, invert_sign_errors, \ | |
559 | invert_encoding_errors) \ | |
560 | ({ \ | |
561 | printf("testing %s\n", #fn); \ | |
562 | int status_ = 0, rc_; \ | |
563 | \ | |
564 | rc_ = assert_zero_as_expr(fn(s0, s0, s0len), -1, "\n"); \ | |
565 | status_ = MIN(status_, rc_); \ | |
566 | rc_ = assert_zero_as_expr(fn(s0, s0, s0sz), -1, "\n"); \ | |
567 | status_ = MIN(status_, rc_); \ | |
568 | \ | |
569 | rc_ = assert_zero_as_expr(fn(s0, s1, s0len), -1, "\n"); \ | |
570 | status_ = MIN(status_, rc_); \ | |
571 | if (invert_sign_errors) \ | |
572 | rc_ = assert_positive_as_expr(fn(s0, s1, s0sz), -1, \ | |
573 | "\n"); \ | |
574 | else \ | |
575 | rc_ = assert_negative_as_expr(fn(s0, s1, s0sz), -1, \ | |
576 | "\n"); \ | |
577 | status_ = MIN(status_, rc_); \ | |
578 | if (test_cmp_magnitude) { \ | |
579 | rc_ = assert_equal_as_expr(fn(s0, s1, s0sz), \ | |
580 | s0[s0len] - s1[s0len], -1, \ | |
581 | "expected %d got %d\n"); \ | |
582 | status_ = MIN(status_, rc_); \ | |
583 | } \ | |
584 | rc_ = assert_positive_as_expr(fn(s1, s0, s0sz), -1, "\n"); \ | |
585 | status_ = MIN(status_, rc_); \ | |
586 | if (test_cmp_magnitude) { \ | |
587 | rc_ = assert_equal_as_expr(fn(s1, s0, s0sz), \ | |
588 | s1[s0len] - s0[s0len], -1, \ | |
589 | "expected %d got %d\n"); \ | |
590 | status_ = MIN(status_, rc_); \ | |
591 | } \ | |
592 | \ | |
593 | rc_ = assert_positive_as_expr(fn(s1, s2, s1sz), -1, "\n"); \ | |
594 | status_ = MIN(status_, rc_); \ | |
595 | if (test_cmp_magnitude) { \ | |
596 | rc_ = assert_equal_as_expr(fn(s1, s2, s2sz), \ | |
597 | s1[s2len] - s2[s2len], -1, \ | |
598 | "expected %d got %d\n"); \ | |
599 | status_ = MIN(status_, rc_); \ | |
600 | } \ | |
601 | rc_ = assert_positive_as_expr(fn(s1, s2, s1len), -1, "\n"); \ | |
602 | status_ = MIN(status_, rc_); \ | |
603 | if (test_cmp_magnitude) { \ | |
604 | rc_ = assert_equal_as_expr( \ | |
605 | fn(s1, s2, s2len), \ | |
606 | s1[s2len - 1] - s2[s2len - 1], -1, \ | |
607 | "expected %d got %d\n"); \ | |
608 | status_ = MIN(status_, rc_); \ | |
609 | } \ | |
610 | if (invert_sign_errors) \ | |
611 | rc_ = assert_positive_as_expr(fn(s2, s1, s1sz), -1, \ | |
612 | "\n"); \ | |
613 | else \ | |
614 | rc_ = assert_negative_as_expr(fn(s2, s1, s1sz), -1, \ | |
615 | "\n"); \ | |
616 | status_ = MIN(status_, rc_); \ | |
617 | if (test_cmp_magnitude) { \ | |
618 | rc_ = assert_equal_as_expr(fn(s2, s1, s1sz), \ | |
619 | s2[s2len] - s1[s2len], -1, \ | |
620 | "expected %d got %d\n"); \ | |
621 | status_ = MIN(status_, rc_); \ | |
622 | } \ | |
623 | \ | |
624 | rc_ = assert_zero_as_expr(fn(s1, s2, s2len), -1, "\n"); \ | |
625 | status_ = MIN(status_, rc_); \ | |
626 | rc_ = assert_positive_as_expr(fn(s1, s2, s2sz), -1, "\n"); \ | |
627 | status_ = MIN(status_, rc_); \ | |
628 | if (test_cmp_magnitude) { \ | |
629 | rc_ = assert_equal_as_expr(fn(s1, s2, s2sz), \ | |
630 | s1[s2len] - s2[s2len], -1, \ | |
631 | "expected %d got %d\n"); \ | |
632 | status_ = MIN(status_, rc_); \ | |
633 | } \ | |
634 | \ | |
635 | if (invert_sign_errors) \ | |
636 | rc_ = assert_positive_as_expr(fn(s2, s3, s2sz), -1, \ | |
637 | "\n"); \ | |
638 | else \ | |
639 | rc_ = assert_negative_as_expr(fn(s2, s3, s2sz), -1, \ | |
640 | "\n"); \ | |
641 | status_ = MIN(status_, rc_); \ | |
642 | if (test_cmp_magnitude) { \ | |
643 | rc_ = assert_equal_as_expr( \ | |
644 | fn(s2, s3, s2sz), \ | |
645 | s2[s2len - 1] - s3[s2len - 1], -1, \ | |
646 | "expected %d got %d\n"); \ | |
647 | status_ = MIN(status_, rc_); \ | |
648 | rc_ = assert_equal_as_expr( \ | |
649 | fn(s2, s3, s2len), \ | |
650 | s2[s2len - 1] - s3[s2len - 1], -1, \ | |
651 | "expected %d got %d\n"); \ | |
652 | status_ = MIN(status_, rc_); \ | |
653 | } \ | |
654 | if (invert_sign_errors) \ | |
655 | rc_ = assert_positive_as_expr(fn(s2, s3, s2len), -1, \ | |
656 | "\n"); \ | |
657 | else \ | |
658 | rc_ = assert_negative_as_expr(fn(s2, s3, s2len), -1, \ | |
659 | "\n"); \ | |
660 | status_ = MIN(status_, rc_); \ | |
661 | rc_ = assert_zero_as_expr(fn(s2, s3, s2len - 1), -1, "\n"); \ | |
662 | status_ = MIN(status_, rc_); \ | |
663 | rc_ = assert_false_as_expr(fn(s1, s2, s2len), -1, "\n"); \ | |
664 | status_ = MIN(status_, rc_); \ | |
665 | \ | |
666 | if (invert_encoding_errors) \ | |
667 | rc_ = assert_negative_as_expr(fn(s4, s5, s4sz), -1, \ | |
668 | "\n"); \ | |
669 | else \ | |
670 | rc_ = assert_positive_as_expr(fn(s4, s5, s4sz), -1, \ | |
671 | "\n"); \ | |
672 | status_ = MIN(status_, rc_); \ | |
673 | \ | |
674 | if (status_ < 0) \ | |
675 | printf("%s failed\n", #fn); \ | |
676 | status_; \ | |
677 | }) | |
678 | ||
679 | static int | |
680 | test_strncmp(void) | |
681 | { | |
682 | int status = 0; | |
683 | int rc; | |
684 | ||
685 | /* | |
686 | * shim's strncmp | |
687 | */ | |
688 | rc = test_strncmp_helper(shim_strncmp, true, false, false); | |
689 | status = MIN(rc, status); | |
690 | ||
691 | /* | |
692 | * libc's strncmp | |
693 | */ | |
694 | /* | |
695 | * Deliberately not testing the difference between these two | |
696 | * comparisons for the symbol named "strncmp": | |
697 | * strncmp("b", "a", 1) | |
698 | * strncmp("c", "a", 1) | |
699 | * glibc, shim_strncmp(), and even the gnuefi ones will give you 1 | |
700 | * and 2, respectively, as will glibc's, but valgrind swaps in its | |
701 | * own implementation, in case you're doing something that's both | |
702 | * clever and dumb with the result, and it'll return 1 for both of | |
703 | * them. | |
704 | */ | |
705 | rc = test_strncmp_helper(strncmp, false, false, false); | |
706 | status = MIN(rc, status); | |
707 | ||
708 | /* | |
709 | * gnu-efi's broken strncmpa | |
710 | */ | |
711 | #pragma GCC diagnostic push | |
712 | #pragma GCC diagnostic ignored "-Wtype-limits" | |
713 | #pragma GCC diagnostic ignored "-Wsign-compare" | |
714 | rc = test_strncmp_helper(gnuefi_strncmp, true, true, false); | |
715 | status = MIN(rc, status); | |
716 | #pragma GCC diagnostic pop | |
717 | ||
718 | /* | |
719 | * This is still broken, and fails the test case as written on arm. | |
720 | * We no longer use this, so we do not strictly need to run it. | |
721 | */ | |
722 | #if !defined(__arm__) && !defined(__aarch64__) | |
723 | /* | |
724 | * gnu-efi's broken strncmpa with the return type fixed | |
725 | */ | |
726 | rc = test_strncmp_helper(gnuefi_signed_strncmp, true, false, true); | |
727 | status = MIN(rc, status); | |
728 | #endif | |
729 | ||
730 | /* | |
731 | * gnu-efi's strncmpa with the return type fixed and unsigned | |
732 | * comparisons internally | |
733 | */ | |
734 | rc = test_strncmp_helper(gnuefi_good_strncmp, true, false, false); | |
735 | status = MIN(rc, status); | |
736 | ||
737 | return status; | |
738 | } | |
739 | ||
740 | #undef s0 | |
741 | #undef s0sz | |
742 | #undef s0len | |
743 | #undef s1 | |
744 | #undef s1sz | |
745 | #undef s1len | |
746 | #undef s2 | |
747 | #undef s2sz | |
748 | #undef s2len | |
749 | #undef s3 | |
750 | #undef s3sz | |
751 | #undef s3len | |
752 | #undef s4 | |
753 | #undef s4sz | |
754 | #undef s4len | |
755 | #undef s5 | |
756 | #undef s5sz | |
757 | #undef s5len | |
758 | ||
759 | /* | |
760 | * Put -Wshadow back how it was | |
761 | */ | |
762 | #pragma GCC diagnostic pop | |
763 | ||
764 | static int | |
765 | test_strchr(void) | |
766 | { | |
767 | char s0[] = "abcbdbeb\0fbgb"; | |
768 | ||
769 | assert_equal_return(strchr(s0, 'a'), s0, -1, "got %p expected %p\n"); | |
770 | assert_equal_return(strchr(s0, 'b'), &s0[1], -1, "got %p expected %p\n"); | |
771 | assert_equal_return(strchr(&s0[1], 'b'), &s0[1], -1, "got %p expected %p\n"); | |
772 | assert_equal_return(strchr(&s0[2], 'b'), &s0[3], -1, "got %p expected %p\n"); | |
773 | assert_equal_return(strchr(&s0[4], 'b'), &s0[5], -1, "got %p expected %p\n"); | |
774 | assert_equal_return(strchr(&s0[6], 'b'), &s0[7], -1, "got %p expected %p\n"); | |
775 | assert_equal_return(strchr(&s0[8], 'b'), NULL, -1, "got %p expected %p\n"); | |
776 | ||
777 | assert_equal_return(shim_strchr(s0, 'a'), s0, -1, "got %p expected %p\n"); | |
778 | assert_equal_return(shim_strchr(s0, 'b'), &s0[1], -1, "got %p expected %p\n"); | |
779 | assert_equal_return(shim_strchr(&s0[1], 'b'), &s0[1], -1, "got %p expected %p\n"); | |
780 | assert_equal_return(shim_strchr(&s0[2], 'b'), &s0[3], -1, "got %p expected %p\n"); | |
781 | assert_equal_return(shim_strchr(&s0[4], 'b'), &s0[5], -1, "got %p expected %p\n"); | |
782 | assert_equal_return(shim_strchr(&s0[6], 'b'), &s0[7], -1, "got %p expected %p\n"); | |
783 | assert_equal_return(shim_strchr(&s0[8], 'b'), NULL, -1, "got %p expected %p\n"); | |
784 | return 0; | |
785 | } | |
786 | ||
787 | static int | |
788 | test_stpcpy(void) | |
789 | { | |
790 | char s0[] = "0123456789abcdef"; | |
791 | char s1[] = "xxxxxxxxxxxxxxxx"; | |
792 | char *s; | |
793 | ||
794 | s0[0xa] = 0; | |
795 | assert_equal_return(stpcpy(s1, s0), &s1[0xa], -1, "got %p expected %p\n"); | |
796 | assert_zero_return(memcmp(s0, s1, 11), -1, "\n"); | |
797 | assert_zero_return(memcmp(&s1[11], "xxxxx", sizeof("xxxxx")), -1, "\n"); | |
798 | ||
799 | memset(s1, 'x', sizeof(s1)); | |
800 | s1[16] = 0; | |
801 | assert_equal_return(shim_stpcpy(s1, s0), &s1[0xa], -1, "got %p expected %p\n"); | |
802 | assert_zero_return(memcmp(s0, s1, 11), -1, "\n"); | |
803 | assert_zero_return(memcmp(&s1[11], "xxxxx", sizeof("xxxxx")), -1, "\n"); | |
804 | ||
805 | return 0; | |
806 | } | |
807 | ||
808 | static int | |
809 | test_strdup(void) | |
810 | { | |
811 | char s0[] = "0123456789abcdef"; | |
812 | char *s = NULL; | |
813 | ||
814 | s = strdup(s0); | |
815 | assert_equal_goto(strcmp(s0, s), 0, err, "\n"); | |
816 | free(s); | |
817 | ||
818 | s = shim_strdup(s0); | |
819 | assert_equal_goto(strcmp(s0, s), 0, err, "\n"); | |
820 | free(s); | |
821 | ||
822 | return 0; | |
823 | err: | |
824 | if (s) | |
825 | free(s); | |
826 | return -1; | |
827 | } | |
828 | ||
829 | static int | |
830 | test_strndup(void) | |
831 | { | |
832 | char s0[] = "0123456789abcdef"; | |
833 | char *s = NULL; | |
834 | ||
835 | s = strndup(s0, 18); | |
836 | assert_equal_goto(strcmp(s0, s), 0, err, "\n"); | |
837 | free(s); | |
838 | s = strndup(s0, 15); | |
839 | assert_positive_goto(strcmp(s0, s), err, "\n"); | |
840 | free(s); | |
841 | ||
842 | s = shim_strndup(s0, 18); | |
843 | assert_equal_goto(strcmp(s0, s), 0, err, "\n"); | |
844 | free(s); | |
845 | s = strndup(s0, 15); | |
846 | assert_positive_goto(shim_strcmp(s0, s), err, "\n"); | |
847 | free(s); | |
848 | ||
849 | return 0; | |
850 | err: | |
851 | if (s) | |
852 | free(s); | |
853 | return -1; | |
854 | } | |
855 | ||
856 | static int | |
857 | test_strchrnul_helper(__typeof__(strchrnul) fn) | |
858 | { | |
859 | const char s0[] = "abcd\0fghi"; | |
860 | ||
861 | assert_equal_return(fn(s0, 'a'), &s0[0], -1, "got %p expected %p\n"); | |
862 | assert_equal_return(fn(s0, 'd'), &s0[3], -1, "got %p expected %p\n"); | |
863 | assert_equal_return(fn(s0, '\000'), &s0[4], -1, "got %p expected %p\n"); | |
864 | assert_equal_return(fn(s0, 'i'), &s0[4], -1, "got %p expected %p\n"); | |
865 | ||
866 | return 0; | |
867 | } | |
868 | ||
869 | static int | |
870 | test_strchrnul(void) | |
871 | { | |
872 | const char s0[] = "abcd\0fghi"; | |
873 | ||
874 | assert_equal_return(test_strchrnul_helper(shim_strchrnul), | |
875 | test_strchrnul_helper(strchrnul), | |
876 | -1, "got %d expected %d\n"); | |
877 | ||
878 | assert_equal_return(strnchrnul(s0, 0, 'b'), &s0[0], -1, "got %p expected %p\n"); | |
879 | assert_equal_return(strnchrnul(s0, -1, 'b'), &s0[1], 1, "got %p expected %p\n"); | |
880 | assert_equal_return(strnchrnul(s0, 2, 'b'), &s0[1], -1, "got %p expected %p\n"); | |
881 | assert_equal_return(strnchrnul(s0, 4, 'f'), &s0[3], -1, "got %p expected %p\n"); | |
882 | assert_equal_return(strnchrnul(s0, 5, 'f'), &s0[4], -1, "got %p expected %p\n"); | |
883 | assert_equal_return(strnchrnul(s0, 8, 'f'), &s0[4], -1, "got %p expected %p\n"); | |
884 | ||
885 | assert_equal_return(strnchrnul(&s0[4], 1, 'f'), &s0[4], -1, "got %p expected %p\n"); | |
886 | ||
887 | return 0; | |
888 | } | |
889 | ||
890 | static int | |
891 | test_strrchr(void) { | |
892 | char s0[] = "abcbebfb"; | |
893 | ||
894 | assert_equal_return(shim_strrchr(s0, '\n'), NULL, -1, "got %p expected %p\n"); | |
895 | assert_equal_return(strrchr(s0, '\n'), NULL, -1, "got %p expected %p\n"); | |
896 | assert_equal_return(shim_strrchr(s0, 'b'), &s0[7], -1, "got %p expected %p\n"); | |
897 | assert_equal_return(strrchr(s0, 'b'), &s0[7], -1, "got %p expected %p\n"); | |
898 | assert_equal_return(shim_strrchr(s0, 'c'), &s0[2], -1, "got %p expected %p\n"); | |
899 | assert_equal_return(strrchr(s0, 'c'), &s0[2], -1, "got %p expected %p\n"); | |
900 | ||
901 | return 0; | |
902 | } | |
903 | ||
904 | static int | |
905 | test_strcpy(void) | |
906 | { | |
907 | char s0[] = "0123456789abcdef\0000"; | |
908 | char s1[sizeof(s0)]; | |
909 | ||
910 | memset(s1, 0, sizeof(s1)); | |
911 | assert_equal_return(strcpy(s1, s0), s1, -1, "got %p expected %p\n"); | |
912 | assert_equal_return(strlen(s0), strlen(s1), -1, "got %d expected %d\n"); | |
913 | ||
914 | memset(s1, 0, sizeof(s1)); | |
915 | assert_equal_return(shim_strcpy(s1, s0), s1, -1, "got %p expected %p\n"); | |
916 | assert_equal_return(strlen(s0), strlen(s1), -1, "got %d expected %d\n"); | |
917 | ||
918 | memset(s1, 0, sizeof(s1)); | |
919 | assert_equal_return(shim_strcpy(s1, s0), s1, -1, "got %p expected %p\n"); | |
920 | assert_equal_return(strlen(s0), strlen(s1), -1, "got %d expected %d\n"); | |
921 | ||
922 | return 0; | |
923 | } | |
924 | ||
925 | static int | |
926 | test_strncpy(void) | |
927 | { | |
928 | char s[] = "0123456789abcdef\0000"; | |
e6ace38a SM |
929 | char s0[4096]; |
930 | char s1[4096]; | |
031e5cce SM |
931 | |
932 | memset(s0, 0, sizeof(s0)); | |
933 | memcpy(s0, s, sizeof(s)); | |
e6ace38a SM |
934 | #if __GNUC_PREREQ(8, 1) |
935 | # pragma GCC diagnostic push | |
936 | # pragma GCC diagnostic ignored "-Wstringop-truncation" | |
937 | #endif | |
031e5cce SM |
938 | memset(s1, 0, 4096); |
939 | assert_equal_return(strncpy(s1, s0, 0), s1, -1, "got %p expected %p\n"); | |
940 | assert_equal_return(strlen(s1), 0, -1, "got %d expected %d\n"); | |
941 | memset(s1, 0, 4096); | |
942 | assert_equal_return(shim_strncpy(s1, s0, 0), s1, -1, "got %p expected %p\n"); | |
943 | assert_equal_return(strlen(s1), 0, -1, "got %d expected %d\n"); | |
944 | ||
945 | memset(s1, 0, 4096); | |
946 | assert_equal_return(strncpy(s1, s0, 1), s1, -1, "got %p expected %p\n"); | |
947 | assert_equal_return(strlen(s1), 1, -1, "got %d expected %d\n"); | |
948 | assert_equal_return(s1[0], s0[0], -1, "got %#02hhx, expected %#02hhx\n"); | |
949 | assert_equal_return(s0[1], '1', -1, "got %#02hhx, expected %#02hhx\n"); | |
950 | assert_equal_return(s1[1], '\0', -1, "got %#02hhx, expected %#02hhx\n"); | |
951 | memset(s1, 0, 4096); | |
952 | assert_equal_return(shim_strncpy(s1, s0, 1), s1, -1, "got %p expected %p\n"); | |
953 | assert_equal_return(strlen(s1), 1, -1, "got %d expected %d\n"); | |
954 | assert_equal_return(s1[0], s0[0], -1, "got %#02hhx, expected %#02hhx\n"); | |
955 | assert_equal_return(s0[1], '1', -1, "got %#02hhx, expected %#02hhx\n"); | |
956 | assert_equal_return(s1[1], '\0', -1, "got %#02hhx, expected %#02hhx\n"); | |
957 | ||
958 | memset(s1, 0, 4096); | |
959 | assert_equal_return(strncpy(s1, s0, 15), s1, -1, "got %p expected %p\n"); | |
960 | assert_equal_return(s0[14], 'e', -1, "got %#02hhx expected %02hhx\n"); | |
961 | assert_equal_return(s0[15], 'f', -1, "got %#02hhx expected %02hhx\n"); | |
962 | assert_equal_return(s0[16], '\000', -1, "got %#02hhx expected %02hhx\n"); | |
963 | assert_equal_return(s0[17], '0', -1, "got %#02hhx expected %02hhx\n"); | |
964 | assert_equal_return(s0[18], '\000', -1, "got %#02hhx expected %02hhx\n"); | |
965 | assert_equal_return(s1[14], 'e', -1, "got %#02hhx expected %02hhx\n"); | |
966 | assert_equal_return(s1[15], '\000', -1, "got %#02hhx expected %02hhx\n"); | |
967 | assert_equal_return(s1[16], '\000', -1, "got %#02hhx expected %02hhx\n"); | |
968 | assert_equal_return(s1[17], '\000', -1, "got %#02hhx expected %02hhx\n"); | |
969 | assert_equal_return(s1[18], '\000', -1, "got %#02hhx expected %02hhx\n"); | |
970 | memset(s1, 0, 4096); | |
971 | assert_equal_return(shim_strncpy(s1, s0, 15), s1, -1, "got %p expected %p\n"); | |
972 | assert_equal_return(s0[14], 'e', -1, "got %#02hhx expected %02hhx\n"); | |
973 | assert_equal_return(s0[15], 'f', -1, "got %#02hhx expected %02hhx\n"); | |
974 | assert_equal_return(s0[16], '\000', -1, "got %#02hhx expected %02hhx\n"); | |
975 | assert_equal_return(s0[17], '0', -1, "got %#02hhx expected %02hhx\n"); | |
976 | assert_equal_return(s0[18], '\000', -1, "got %#02hhx expected %02hhx\n"); | |
977 | assert_equal_return(s1[14], 'e', -1, "got %#02hhx expected %02hhx\n"); | |
978 | assert_equal_return(s1[15], '\000', -1, "got %#02hhx expected %02hhx\n"); | |
979 | assert_equal_return(s1[16], '\000', -1, "got %#02hhx expected %02hhx\n"); | |
980 | assert_equal_return(s1[17], '\000', -1, "got %#02hhx expected %02hhx\n"); | |
981 | assert_equal_return(s1[18], '\000', -1, "got %#02hhx expected %02hhx\n"); | |
982 | ||
983 | memset(s1, 0, 4096); | |
984 | assert_equal_return(strncpy(s1, s0, 16), s1, -1, "got %p expected %p\n"); | |
985 | assert_equal_return(s0[14], 'e', -1, "got %#02hhx expected %02hhx\n"); | |
986 | assert_equal_return(s0[15], 'f', -1, "got %#02hhx expected %02hhx\n"); | |
987 | assert_equal_return(s0[16], '\000', -1, "got %#02hhx expected %02hhx\n"); | |
988 | assert_equal_return(s0[17], '0', -1, "got %#02hhx expected %02hhx\n"); | |
989 | assert_equal_return(s0[18], '\000', -1, "got %#02hhx expected %02hhx\n"); | |
990 | assert_equal_return(s1[14], 'e', -1, "got %#02hhx expected %02hhx\n"); | |
991 | assert_equal_return(s1[15], 'f', -1, "got %#02hhx expected %02hhx\n"); | |
992 | assert_equal_return(s1[16], '\000', -1, "got %#02hhx expected %02hhx\n"); | |
993 | assert_equal_return(s1[17], '\000', -1, "got %#02hhx expected %02hhx\n"); | |
994 | assert_equal_return(s1[18], '\000', -1, "got %#02hhx expected %02hhx\n"); | |
995 | memset(s1, 0, 4096); | |
996 | assert_equal_return(shim_strncpy(s1, s0, 16), s1, -1, "got %p expected %p\n"); | |
997 | assert_equal_return(s0[14], 'e', -1, "got %#02hhx expected %02hhx\n"); | |
998 | assert_equal_return(s0[15], 'f', -1, "got %#02hhx expected %02hhx\n"); | |
999 | assert_equal_return(s0[16], '\000', -1, "got %#02hhx expected %02hhx\n"); | |
1000 | assert_equal_return(s0[17], '0', -1, "got %#02hhx expected %02hhx\n"); | |
1001 | assert_equal_return(s0[18], '\000', -1, "got %#02hhx expected %02hhx\n"); | |
1002 | assert_equal_return(s1[14], 'e', -1, "got %#02hhx expected %02hhx\n"); | |
1003 | assert_equal_return(s1[15], 'f', -1, "got %#02hhx expected %02hhx\n"); | |
1004 | assert_equal_return(s1[16], '\000', -1, "got %#02hhx expected %02hhx\n"); | |
1005 | assert_equal_return(s1[17], '\000', -1, "got %#02hhx expected %02hhx\n"); | |
1006 | assert_equal_return(s1[18], '\000', -1, "got %#02hhx expected %02hhx\n"); | |
1007 | ||
1008 | memset(s1, 0, 4096); | |
1009 | s1[17] = '0'; | |
1010 | s1[18] = '1'; | |
1011 | assert_equal_return(strncpy(s1, s0, 4096), s1, -1, "got %p expected %p\n"); | |
1012 | assert_equal_return(s0[14], 'e', -1, "got %#02hhx expected %02hhx\n"); | |
1013 | assert_equal_return(s0[15], 'f', -1, "got %#02hhx expected %02hhx\n"); | |
1014 | assert_equal_return(s0[16], '\000', -1, "got %#02hhx expected %02hhx\n"); | |
1015 | assert_equal_return(s0[17], '0', -1, "got %#02hhx expected %02hhx\n"); | |
1016 | assert_equal_return(s0[18], '\000', -1, "got %#02hhx expected %02hhx\n"); | |
1017 | assert_equal_return(s1[14], 'e', -1, "got %#02hhx expected %02hhx\n"); | |
1018 | assert_equal_return(s1[15], 'f', -1, "got %#02hhx expected %02hhx\n"); | |
1019 | assert_equal_return(s1[16], '\000', -1, "got %#02hhx expected %02hhx\n"); | |
1020 | assert_equal_return(s1[17], '\000', -1, "got %#02hhx expected %02hhx\n"); | |
1021 | assert_equal_return(s1[18], '\000', -1, "got %#02hhx expected %02hhx\n"); | |
1022 | memset(s1, 0, 4096); | |
1023 | s1[17] = '0'; | |
1024 | s1[18] = '1'; | |
1025 | assert_equal_return(shim_strncpy(s1, s0, 4096), s1, -1, "got %p expected %p\n"); | |
1026 | assert_equal_return(s0[14], 'e', -1, "got %#02hhx expected %02hhx\n"); | |
1027 | assert_equal_return(s0[15], 'f', -1, "got %#02hhx expected %02hhx\n"); | |
1028 | assert_equal_return(s0[16], '\000', -1, "got %#02hhx expected %02hhx\n"); | |
1029 | assert_equal_return(s0[17], '0', -1, "got %#02hhx expected %02hhx\n"); | |
1030 | assert_equal_return(s0[18], '\000', -1, "got %#02hhx expected %02hhx\n"); | |
1031 | assert_equal_return(s1[14], 'e', -1, "got %#02hhx expected %02hhx\n"); | |
1032 | assert_equal_return(s1[15], 'f', -1, "got %#02hhx expected %02hhx\n"); | |
1033 | assert_equal_return(s1[16], '\000', -1, "got %#02hhx expected %02hhx\n"); | |
1034 | assert_equal_return(s1[17], '0', -1, "got %#02hhx expected %02hhx\n"); | |
1035 | assert_equal_return(s1[18], '1', -1, "got %#02hhx expected %02hhx\n"); | |
e6ace38a SM |
1036 | #if __GNUC_PREREQ(8, 1) |
1037 | # pragma GCC diagnostic pop | |
1038 | #endif | |
031e5cce SM |
1039 | return 0; |
1040 | } | |
1041 | ||
1042 | static int | |
1043 | test_strcat(void) | |
1044 | { | |
1045 | char s[] = "0123456789abcdef\0000"; | |
e6ace38a SM |
1046 | char s0[4096]; |
1047 | char s1[4096]; | |
031e5cce SM |
1048 | char *s2; |
1049 | char s3[] = "0123456789abcdef0123456789abcdef\000\000\000\000\000"; | |
1050 | ||
e6ace38a | 1051 | memset(s0, 0, sizeof(s0)); |
031e5cce SM |
1052 | memcpy(s0, s, sizeof(s)); |
1053 | ||
1054 | memset(s1, 0, 4096); | |
1055 | assert_equal_return(strcat(s1, s0), s1, -1, "got %p expected %p\n"); | |
1056 | /* For unknown reasons, gcc 4.8.5 gives us this here: | |
1057 | * | In file included from shim.h:64:0, | |
1058 | * | from test-str.c:14: | |
1059 | * | test-str.c: In function 'test_strcat': | |
1060 | * | include/test.h:85:10: warning: array subscript is below array bounds [-Warray-bounds] | |
1061 | * | printf("%s:%d:got %lld, expected zero " fmt, __func__, \ | |
1062 | * | ^ | |
1063 | * | include/test.h:112:10: warning: array subscript is below array bounds [-Warray-bounds] | |
1064 | * | printf("%s:%d:got %lld, expected < 0 " fmt, __func__, \ | |
1065 | * | ^ | |
1066 | * | |
1067 | * This clearly isn't a useful error message, as it doesn't tell us | |
1068 | * /anything about the problem/, but also it isn't reported on | |
1069 | * later compilers, and it isn't clear that there's any problem | |
1070 | * when examining these functions. | |
1071 | * | |
1072 | * I don't know. | |
1073 | */ | |
1074 | #pragma GCC diagnostic push | |
8529e0f7 | 1075 | #pragma GCC diagnostic ignored "-Warray-bounds" |
031e5cce SM |
1076 | assert_zero_return(strncmp(s1, s0, sizeof(s)-1), 0, -1, "\n"); |
1077 | assert_negative_return(memcmp(s1, s0, sizeof(s)), 0, -1, "\n"); | |
1078 | #pragma GCC diagnostic pop | |
1079 | ||
1080 | memset(s1, 0, 4096); | |
1081 | assert_equal_return(strcat(s1, s0), s1, -1, "got %p expected %p\n"); | |
1082 | s2 = s1 + strlen(s1); | |
1083 | assert_equal_return(s2, &s1[16], -1, "got %p expected %p\n"); | |
1084 | assert_equal_return(strcat(s2, s0), s2, -1, "got %p expected %p\n"); | |
1085 | assert_zero_return(strncmp(s1, s0, strlen(s)), -1, "got %p expected %p\n"); | |
1086 | assert_zero_return(strncmp(s2, s0, 2*(sizeof(s)-1)), -1, "\n"); | |
1087 | assert_positive_return(memcmp(s1, s0, 2*sizeof(s)-2), -1, "\n"); | |
1088 | assert_equal_return(memcmp(s1, s3, sizeof(s3)), 0, -1, "expected %d got %d\n"); | |
1089 | ||
1090 | return 0; | |
1091 | } | |
1092 | ||
1093 | static int | |
1094 | test_strntoken_null(void) { | |
1095 | bool ret; | |
1096 | char *token = NULL; | |
1097 | char state; | |
1098 | ||
1099 | char *delims = alloca(3); | |
1100 | memcpy(delims, ",.", 3); | |
1101 | ||
1102 | ret = strntoken(NULL, 1, delims, &token, &state); | |
1103 | assert_equal_return(ret, false, -1, "got %d expected %d\n"); | |
1104 | return 0; | |
1105 | } | |
1106 | ||
1107 | static int | |
1108 | test_strntoken_size_0(void) | |
1109 | { | |
1110 | const char s1[] = "abc,def,.,gh,"; | |
1111 | char s2[] = "abc,def,.,gh,"; | |
1112 | char *token = NULL; | |
1113 | bool ret; | |
1114 | size_t max; | |
1115 | char *s = s2; | |
1116 | size_t tokensz; | |
1117 | char state; | |
1118 | ||
1119 | ret = strntoken(s, 0, ",.", &token, &state); | |
1120 | assert_equal_return(ret, false, -1, "got %d expected %d\n"); | |
1121 | assert_equal_return(token, NULL, -1, "got %p expected %p\n"); | |
1122 | assert_equal_return(memcmp(s, "abc,def,.,gh,", sizeof(s2)), 0, 1, "got %d expected %d\n"); | |
1123 | ||
1124 | return 0; | |
1125 | } | |
1126 | ||
1127 | static int | |
1128 | test_strntoken_empty_size_1(void) | |
1129 | { | |
1130 | char s1[] = ""; | |
1131 | char *s; | |
1132 | bool ret; | |
1133 | char *token = NULL; | |
1134 | char *prevtok = NULL; | |
1135 | size_t max; | |
1136 | size_t tokensz; | |
1137 | char state; | |
1138 | ||
1139 | s = s1; | |
1140 | max = 1; | |
1141 | ||
1142 | ret = strntoken(s, max, ",.", &token, &state); | |
1143 | assert_equal_return(ret, true, -1, "got %d expected %d\n"); | |
1144 | assert_equal_return(token[0], '\0', -1, "got %#hhx expected %#hhx\n"); | |
1145 | prevtok = token; | |
1146 | ||
1147 | tokensz = strlen(token) + 1; | |
1148 | s += tokensz; | |
1149 | max -= tokensz; | |
1150 | assert_equal_return(s, &s1[1], -1, "got %p expected %p\n"); | |
1151 | assert_equal_return(max, 0, -1, "got %d expected %d\n"); | |
1152 | ||
1153 | ret = strntoken(s, max, ",.", &token, &state); | |
1154 | assert_equal_return(ret, false, -1, "got %d expected %d\n"); | |
1155 | assert_equal_return(token, prevtok, -1, "got %p expected %p\n"); | |
1156 | ||
1157 | return 0; | |
1158 | } | |
1159 | ||
1160 | static int | |
1161 | test_strntoken_size_1(void) | |
1162 | { | |
1163 | char s1[] = ","; | |
1164 | char *s; | |
1165 | bool ret; | |
1166 | char *token = NULL; | |
1167 | char *prevtok = NULL; | |
1168 | size_t max; | |
1169 | size_t tokensz; | |
1170 | char state; | |
1171 | ||
1172 | s = s1; | |
1173 | max = 1; | |
1174 | ||
1175 | ret = strntoken(s, max, ",.", &token, &state); | |
1176 | assert_equal_return(ret, true, -1, "got %d expected %d\n"); | |
1177 | assert_equal_return(token[0], '\0', -1, "got %#hhx expected %#hhx\n"); | |
1178 | prevtok = token; | |
1179 | ||
1180 | tokensz = strlen(token) + 1; | |
1181 | s += tokensz; | |
1182 | max -= tokensz; | |
1183 | assert_equal_return(s, &s1[1], -1, "got %p expected %p\n"); | |
1184 | assert_equal_return(max, 0, -1, "got %d expected %d\n"); | |
1185 | ||
1186 | ret = strntoken(s, max, ",.", &token, &state); | |
1187 | assert_equal_return(ret, false, -1, "got %d expected %d\n"); | |
1188 | assert_equal_return(token, prevtok, -1, "got %p expected %p\n"); | |
1189 | assert_equal_return(token[0], '\0', -1, "got %#hhx expected %#hhx\n"); | |
1190 | ||
1191 | return 0; | |
1192 | } | |
1193 | ||
1194 | static int | |
1195 | test_strntoken_size_2(void) | |
1196 | { | |
1197 | char s1[] = ","; | |
1198 | char *s; | |
1199 | bool ret; | |
1200 | char *token = NULL; | |
1201 | char *prevtok = NULL; | |
1202 | size_t max; | |
1203 | size_t tokensz; | |
1204 | char state; | |
1205 | ||
1206 | s = s1; | |
1207 | max = 2; | |
1208 | ||
1209 | ret = strntoken(s, max, ",.", &token, &state); | |
1210 | assert_equal_return(ret, true, -1, "got %d expected %d\n"); | |
1211 | assert_equal_return(token[0], '\0', -1, "got %#hhx expected %#hhx\n"); | |
1212 | ||
1213 | tokensz = strlen(token) + 1; | |
1214 | s += tokensz; | |
1215 | max -= tokensz; | |
1216 | assert_equal_return(s, &s1[1], -1, "got %p expected %p\n"); | |
1217 | assert_equal_return(max, 1, -1, "got %d expected %d\n"); | |
1218 | ||
1219 | ret = strntoken(s, max, ",.", &token, &state); | |
1220 | assert_equal_return(ret, true, -1, "got %d expected %d\n"); | |
1221 | assert_equal_return(token[0], '\0', -1, "got %#hhx expected %#hhx\n"); | |
1222 | prevtok = token; | |
1223 | ||
1224 | tokensz = strlen(token) + 1; | |
1225 | s += tokensz; | |
1226 | max -= tokensz; | |
1227 | assert_equal_return(s, &s1[2], -1, "got %p expected %p\n"); | |
1228 | assert_equal_return(max, 0, -1, "got %d expected %d\n"); | |
1229 | ||
1230 | ret = strntoken(s, max, ",.", &token, &state); | |
1231 | assert_equal_return(ret, false, -1, "got %d expected %d\n"); | |
1232 | assert_equal_return(token, prevtok, -1, "got %#hhx expected %#hhx\n"); | |
1233 | ||
1234 | return 0; | |
1235 | } | |
1236 | ||
1237 | static int | |
1238 | test_strntoken_no_ascii_nul(void) | |
1239 | { | |
1240 | const char s1[] = "abc,def,.,gh,"; | |
1241 | char s2[] = "abc,def,.,gh,"; | |
1242 | char *token = NULL; | |
1243 | bool ret; | |
1244 | size_t max; | |
1245 | char *s = s2; | |
1246 | size_t tokensz; | |
1247 | char state; | |
1248 | ||
1249 | s = s2; | |
1250 | max = sizeof(s2) - 1; | |
1251 | assert_equal_return(max, 13, -1, "got %d expected %d\n"); | |
1252 | /* | |
1253 | * s="abc,def,.,gh," -> "abc\0def,.,gh," | |
1254 | * ^ token | |
1255 | */ | |
1256 | ret = strntoken(s, max, ",.", &token, &state); | |
1257 | assert_equal_return(ret, true, -1, "got %d expected %d\n"); | |
1258 | assert_equal_return(token, s, -1, "got %p expected %p\n"); | |
1259 | assert_equal_return(s[2], 'c', -1, "got %#hhx expected %#hhx\n"); | |
1260 | assert_equal_return(s[3], '\0', -1, "got %#hhx expected %#hhx\n"); | |
1261 | assert_equal_return(s[4], 'd', -1, "got %#hhx expected %#hhx\n"); | |
1262 | ||
1263 | tokensz = strnlen(token, max) + 1; | |
1264 | s += tokensz; | |
1265 | max -= tokensz; | |
1266 | assert_equal_return(max, 9, -1, "got %d expected %d\n"); | |
1267 | ||
1268 | /* | |
1269 | * s="def,.,gh," -> "def\0.,gh," | |
1270 | * ^ token | |
1271 | */ | |
1272 | ret = strntoken(s, max, ",.", &token, &state); | |
1273 | assert_equal_return(ret, true, -1, "got %d expected %d\n"); | |
1274 | assert_equal_return(token, s, -1, "got %p expected %p\n"); | |
1275 | assert_equal_return(s[2], 'f', -1, "got %#hhx expected %#hhx\n"); | |
1276 | assert_equal_return(s[3], '\0', -1, "got %#hhx expected %#hhx\n"); | |
1277 | assert_equal_return(s[4], '.', -1, "got %#hhx expected %#hhx\n"); | |
1278 | ||
1279 | tokensz = strnlen(token, max) + 1; | |
1280 | s += tokensz; | |
1281 | max -= tokensz; | |
1282 | assert_equal_return(max, 5, -1, "got %d expected %d\n"); | |
1283 | ||
1284 | /* | |
1285 | * s=".,gh," -> "\0,gh," | |
1286 | * ^ token | |
1287 | */ | |
1288 | ret = strntoken(s, max, ",.", &token, &state); | |
1289 | assert_equal_return(ret, true, -1, "got %d expected %d\n"); | |
1290 | assert_equal_return(token, s, -1, "got %p expected %p\n"); | |
1291 | assert_equal_return(s[0], '\0', -1, "got %#hhx expected %#hhx\n"); | |
1292 | assert_equal_return(s[1], ',', -1, "got %#hhx expected %#hhx\n"); | |
1293 | ||
1294 | tokensz = strnlen(token, max) + 1; | |
1295 | s += tokensz; | |
1296 | max -= tokensz; | |
1297 | assert_equal_return(max, 4, -1, "got %d expected %d\n"); | |
1298 | ||
1299 | /* | |
1300 | * s=",gh," -> "\0gh," | |
1301 | * ^ token | |
1302 | */ | |
1303 | ret = strntoken(s, max, ",.", &token, &state); | |
1304 | assert_equal_return(ret, true, -1, "got %d expected %d\n"); | |
1305 | assert_equal_return(token, s, -1, "got %p expected %p\n"); | |
1306 | assert_equal_return(s[0], '\0', -1, "got %#hhx expected %#hhx\n"); | |
1307 | assert_equal_return(s[1], 'g', -1, "got %#hhx expected %#hhx\n"); | |
1308 | ||
1309 | tokensz = strnlen(token, max) + 1; | |
1310 | s += tokensz; | |
1311 | max -= tokensz; | |
1312 | assert_equal_return(max, 3, -1, "got %d expected %d\n"); | |
1313 | ||
1314 | /* | |
1315 | * s="gh," -> "gh\0" | |
1316 | * ^ token | |
1317 | */ | |
1318 | ret = strntoken(s, max, ",.", &token, &state); | |
1319 | assert_equal_return(ret, true, -1, "got %d expected %d\n"); | |
1320 | assert_equal_return(token, s, -1, "got %p expected %p\n"); | |
1321 | assert_equal_return(s[0], 'g', -1, "got %#hhx expected %#hhx\n"); | |
1322 | assert_equal_return(s[1], 'h', -1, "got %#hhx expected %#hhx\n"); | |
1323 | assert_equal_return(s[2], '\0', -1, "got %#hhx expected %#hhx\n"); | |
1324 | ||
1325 | tokensz = strnlen(token, max) + 1; | |
1326 | s += tokensz; | |
1327 | max -= tokensz; | |
1328 | assert_equal_return(max, 0, -1, "got %d expected %d\n"); | |
1329 | ||
1330 | char *prevtok = token; | |
1331 | ||
1332 | /* | |
1333 | * s="" -> "" | |
1334 | * ^ token, but max is 0 | |
1335 | */ | |
1336 | ret = strntoken(s, max, ",.", &token, &state); | |
1337 | assert_equal_return(ret, false, -1, "got %d expected %d\n"); | |
1338 | assert_equal_return(token, prevtok, -1, "got %p expected %p\n"); | |
1339 | assert_equal_return(s[0], '\0', -1, "got %#hhx expected %#hhx\n"); | |
1340 | ||
1341 | s[0] = 'x'; | |
1342 | ret = strntoken(s, max, ",.", &token, &state); | |
1343 | assert_equal_return(ret, false, -1, "got %d expected %d\n"); | |
1344 | assert_equal_return(token, prevtok, -1, "got %p expected %p\n"); | |
1345 | assert_equal_return(s[0], 'x', -1, "got %#hhx expected %#hhx\n"); | |
1346 | ||
1347 | return 0; | |
1348 | } | |
1349 | ||
1350 | static int | |
1351 | test_strntoken_with_ascii_nul(void) | |
1352 | { | |
1353 | const char s1[] = "abc,def,.,gh,"; | |
1354 | char s2[] = "abc,def,.,gh,"; | |
1355 | char *token = NULL; | |
1356 | bool ret; | |
1357 | size_t max; | |
1358 | char *s = s2; | |
1359 | size_t tokensz; | |
1360 | char s3[] = "abc,def,.,gh,"; | |
1361 | char state; | |
1362 | ||
1363 | s = s2; | |
1364 | max = sizeof(s2); | |
1365 | assert_equal_return(max, 14, 1, "got %d expected %d\n"); | |
1366 | /* | |
1367 | * s="abc,def,.,gh," -> "abc\0def,.,gh," | |
1368 | * ^ token | |
1369 | */ | |
1370 | ret = strntoken(s, max, ",.", &token, &state); | |
1371 | assert_equal_return(ret, true, 1, "got %d expected %d\n"); | |
1372 | assert_equal_return(s[2], 'c', 1, "got %#hhx expected %#hhx\n"); | |
1373 | assert_equal_return(s[3], '\0', 1, "got %#hhx expected %#hhx\n"); | |
1374 | assert_equal_return(s[4], 'd', 1, "got %#hhx expected %#hhx\n"); | |
1375 | ||
1376 | tokensz = strnlen(token, max) + 1; | |
1377 | s += tokensz; | |
1378 | max -= tokensz; | |
1379 | assert_equal_return(max, 10, 1, "got %d expected %d\n"); | |
1380 | ||
1381 | /* | |
1382 | * s="def,.,gh," -> "def\0.,gh," | |
1383 | * ^ token | |
1384 | */ | |
1385 | ret = strntoken(s, max, ",.", &token, &state); | |
1386 | assert_equal_return(ret, true, 1, "got %d expected %d\n"); | |
1387 | assert_equal_return(token, s, 1, "got %p expected %p\n"); | |
1388 | assert_equal_return(s[2], 'f', 1, "got %#hhx expected %#hhx\n"); | |
1389 | assert_equal_return(s[3], '\0', 1, "got %#hhx expected %#hhx\n"); | |
1390 | assert_equal_return(s[4], '.', 1, "got %#hhx expected %#hhx\n"); | |
1391 | ||
1392 | tokensz = strnlen(token, max) + 1; | |
1393 | s += tokensz; | |
1394 | max -= tokensz; | |
1395 | assert_equal_return(max, 6, 1, "got %d expected %d\n"); | |
1396 | ||
1397 | /* | |
1398 | * s=".,gh," -> "\0,gh," | |
1399 | * ^ token | |
1400 | */ | |
1401 | ret = strntoken(s, max, ",.", &token, &state); | |
1402 | assert_equal_return(ret, true, 1, "got %d expected %d\n"); | |
1403 | assert_equal_return(token, s, 1, "got %p expected %p\n"); | |
1404 | assert_equal_return(s[0], '\0', 1, "got %#hhx expected %#hhx\n"); | |
1405 | assert_equal_return(s[1], ',', 1, "got %#hhx expected %#hhx\n"); | |
1406 | ||
1407 | tokensz = strnlen(token, max) + 1; | |
1408 | s += tokensz; | |
1409 | max -= tokensz; | |
1410 | assert_equal_return(max, 5, 1, "got %d expected %d\n"); | |
1411 | ||
1412 | /* | |
1413 | * s=",gh," -> "\0gh," | |
1414 | * ^ token | |
1415 | */ | |
1416 | ret = strntoken(s, max, ",.", &token, &state); | |
1417 | assert_equal_return(ret, true, 1, "got %d expected %d\n"); | |
1418 | assert_equal_return(token, s, 1, "got %p expected %p\n"); | |
1419 | assert_equal_return(s[0], '\0', 1, "got %#hhx expected %#hhx\n"); | |
1420 | assert_equal_return(s[1], 'g', 1, "got %#hhx expected %#hhx\n"); | |
1421 | ||
1422 | tokensz = strnlen(token, max) + 1; | |
1423 | s += tokensz; | |
1424 | max -= tokensz; | |
1425 | assert_equal_return(max, 4, 1, "got %d expected %d\n"); | |
1426 | ||
1427 | /* | |
1428 | * s="gh," -> "gh\0" | |
1429 | * ^ token | |
1430 | */ | |
1431 | ret = strntoken(s, max, ",.", &token, &state); | |
1432 | assert_equal_return(ret, true, 1, "got %d expected %d\n"); | |
1433 | assert_equal_return(token, s, 1, "got %p expected %p\n"); | |
1434 | assert_equal_return(s[0], 'g', 1, "got %#hhx expected %#hhx\n"); | |
1435 | assert_equal_return(s[1], 'h', 1, "got %#hhx expected %#hhx\n"); | |
1436 | assert_equal_return(s[2], '\0', 1, "got %#hhx expected %#hhx\n"); | |
1437 | ||
1438 | tokensz = strnlen(token, max) + 1; | |
1439 | s += tokensz; | |
1440 | max -= tokensz; | |
1441 | assert_equal_return(max, 1, 1, "got %d expected %d\n"); | |
1442 | ||
1443 | /* | |
1444 | * s="" -> "" | |
1445 | * ^ token, max is 1 | |
1446 | */ | |
1447 | ret = strntoken(s, max, ",.", &token, &state); | |
1448 | assert_equal_return(ret, true, 1, "got %d expected %d\n"); | |
1449 | assert_equal_return(token, s, 1, "got %p expected %p\n"); | |
1450 | assert_equal_return(s[0], '\0', 1, "got %#hhx expected %#hhx\n"); | |
1451 | ||
1452 | char *prevtok = token; | |
1453 | tokensz = strnlen(token, max) + 1; | |
1454 | s += tokensz; | |
1455 | max -= tokensz; | |
1456 | assert_equal_return(max, 0, 1, "got %d expected %d\n"); | |
1457 | ||
1458 | /* | |
1459 | * s="" -> "" | |
1460 | * ^ token, max is 0 | |
1461 | */ | |
1462 | ret = strntoken(s, max, ",.", &token, &state); | |
1463 | assert_equal_return(ret, false, 1, "got %d expected %d\n"); | |
1464 | assert_equal_return(token, prevtok, 1, "got %p expected %p\n"); | |
1465 | ||
1466 | return 0; | |
1467 | } | |
1468 | ||
1469 | int | |
1470 | main(void) | |
1471 | { | |
1472 | int status = 0; | |
1473 | test(test_strlen); | |
1474 | test(test_strnlen); | |
1475 | test(test_strcmp); | |
1476 | test(test_strncmp); | |
1477 | test(test_strcasecmp); | |
1478 | test(test_strncasecmp); | |
1479 | test(test_strrchr); | |
1480 | test(test_strcpy); | |
1481 | test(test_strncpy); | |
1482 | test(test_strcat); | |
1483 | test(test_stpcpy); | |
1484 | test(test_strdup); | |
1485 | test(test_strndup); | |
1486 | test(test_strchr); | |
1487 | test(test_strchrnul); | |
1488 | test(test_strntoken_null); | |
1489 | test(test_strntoken_size_0); | |
1490 | test(test_strntoken_empty_size_1); | |
1491 | test(test_strntoken_size_1); | |
1492 | test(test_strntoken_size_2); | |
1493 | test(test_strntoken_no_ascii_nul); | |
1494 | test(test_strntoken_with_ascii_nul); | |
1495 | return status; | |
1496 | } | |
1497 | ||
1498 | // vim:fenc=utf-8:tw=75:noet |