1 /*- 2 * SPDX-License-Identifier: BSD-2-Clause 3 * 4 * Copyright (c) 2023 Robert Clausecker 5 */ 6 7 #include <sys/cdefs.h> 8 9 #include <dlfcn.h> 10 #include <limits.h> 11 #include <string.h> 12 13 #include <atf-c.h> 14 15 static void *(*memrchr_fn)(const void *, int, size_t); 16 17 ATF_TC_WITHOUT_HEAD(null); 18 ATF_TC_BODY(null, tc) 19 { 20 ATF_CHECK_EQ(memrchr_fn(NULL, 42, 0), NULL); 21 } 22 23 ATF_TC_WITHOUT_HEAD(not_found); 24 ATF_TC_BODY(not_found, tc) 25 { 26 size_t i, j; 27 char buf[1+15+64+1]; /* offset [0..15] + 64 buffer bytes + sentinels */ 28 29 buf[0] = 'X'; 30 memset(buf + 1, '-', sizeof(buf) - 1); 31 32 for (i = 0; i < 16; i++) 33 for (j = 0; j < 64; j++) { 34 buf[i + j + 1] = 'X'; 35 ATF_CHECK_EQ(memrchr_fn(buf + i + 1, 'X', j), NULL); 36 buf[i + j + 1] = '-'; 37 } 38 } 39 40 static void 41 do_found_test(char buf[], size_t len, size_t first, size_t second) 42 { 43 /* invariant: first <= second */ 44 45 buf[first] = 'X'; 46 buf[second] = 'X'; 47 ATF_CHECK_EQ(memrchr_fn(buf, 'X', len), buf + second); 48 buf[first] = '-'; 49 buf[second] = '-'; 50 } 51 52 ATF_TC_WITHOUT_HEAD(found); 53 ATF_TC_BODY(found, tc) 54 { 55 size_t i, j, k, l; 56 char buf[1+15+64+1]; 57 58 buf[0] = 'X'; 59 memset(buf + 1, '-', sizeof(buf) - 1); 60 61 for (i = 0; i < 16; i++) 62 for (j = 0; j < 64; j++) 63 for (k = 0; k < j; k++) 64 for (l = 0; l <= k; l++) { 65 buf[i + j + 1] = 'X'; 66 do_found_test(buf + i + 1, j, l, k); 67 buf[i + j + 1] = '-'; 68 } 69 } 70 71 /* check that the right character is found */ 72 static void 73 do_values_test(unsigned char buf[], size_t len, size_t i, int c) 74 { 75 /* sentinels */ 76 buf[-1] = c; 77 buf[len] = c; 78 memset(buf, c + 1, len); 79 80 if (i < len) { 81 buf[i] = c; 82 ATF_CHECK_EQ(memrchr_fn(buf, c, len), buf + i); 83 } else 84 ATF_CHECK_EQ(memrchr_fn(buf, c, len), NULL); 85 } 86 87 ATF_TC_WITHOUT_HEAD(values); 88 ATF_TC_BODY(values, tc) 89 { 90 size_t i, j, k; 91 int c; 92 unsigned char buf[1+15+64+1]; 93 94 for (i = 0; i < 16; i++) 95 for (j = 0; j < 64; j++) 96 for (k = 0; k <= j; k++) 97 for (c = 0; c <= UCHAR_MAX; c++) 98 do_values_test(buf + i + 1, j, k, c); 99 } 100 101 ATF_TP_ADD_TCS(tp) 102 { 103 void *dl_handle; 104 105 dl_handle = dlopen(NULL, RTLD_LAZY); 106 memrchr_fn = dlsym(dl_handle, "test_memrchr"); 107 if (memrchr_fn == NULL) 108 memrchr_fn = memrchr; 109 110 ATF_TP_ADD_TC(tp, null); 111 ATF_TP_ADD_TC(tp, not_found); 112 ATF_TP_ADD_TC(tp, found); 113 ATF_TP_ADD_TC(tp, values); 114 115 return (atf_no_error()); 116 } 117