1 /*-
2 * SPDX-License-Identifier: BSD-2-Clause
3 *
4 * Copyright (c) 2024 Strahinja Stanisic <strajabot@FreeBSD.org>
5 */
6
7 #include <string.h>
8 #include <unistd.h>
9 #include <stdio.h>
10 #include <stdlib.h>
11 #include <stdalign.h>
12 #include <stdint.h>
13
14 #include <atf-c.h>
15
16 ATF_TC(strnlen_alignments);
ATF_TC_HEAD(strnlen_alignments,tc)17 ATF_TC_HEAD(strnlen_alignments, tc)
18 {
19 atf_tc_set_md_var(tc, "descr", "Test strnlen(3) with different alignments");
20 }
21
ATF_TC_BODY(strnlen_alignments,tc)22 ATF_TC_BODY(strnlen_alignments, tc)
23 {
24 size_t (*strnlen_fn)(const char*, size_t) = strnlen;
25 char alignas(16) buffer[1 + 16 + 64 + 1 + 1];
26
27 memset(buffer, '/', sizeof(buffer));
28
29 for (int align = 1; align < 1 + 16; align++) {
30 char *s = buffer + align;
31
32 for (size_t maxlen = 0; maxlen <= 64; maxlen++) {
33 for (size_t len = 0; len <= maxlen; len++) {
34 /* returns length */
35
36 /* without sentinels */
37 s[len] = '\0';
38 size_t val = strnlen_fn(s, maxlen);
39 if (val != len) {
40 fprintf(stderr, "align = %d, maxlen = %zu, len = %zu",
41 align, maxlen, len);
42 atf_tc_fail("returned incorrect len");
43 }
44
45 /* with sentinels */
46 s[-1] = '\0';
47 s[maxlen + 1] = '\0';
48 val = strnlen_fn(s, maxlen);
49 if (val != len) {
50 fprintf(stderr, "align = %d, maxlen = %zu, len = %zu",
51 align, maxlen, len);
52 atf_tc_fail("returned incorrect len (sentinels)");
53 }
54
55 /* cleanup */
56 s[-1] = '/';
57 s[len] = '/';
58 s[maxlen + 1] = '/';
59
60 }
61
62 /* returns maxlen */
63
64 /* without sentinels */
65 size_t val = strnlen_fn(s, maxlen);
66 if (val != maxlen) {
67 fprintf(stderr, "align = %d, maxlen = %zu",
68 align, maxlen);
69 atf_tc_fail("should return maxlen");
70 }
71
72 /* with sentinels */
73 s[-1] = '\0';
74 s[maxlen + 1] = '\0';
75 val = strnlen_fn(s, maxlen);
76 if (val != maxlen) {
77 fprintf(stderr, "align = %d, maxlen = %zu",
78 align, maxlen);
79 atf_tc_fail("should return maxlen (sentinels)");
80 }
81
82 /* cleanup */
83 s[-1] = '/';
84 s[maxlen + 1] = '/';
85 }
86 }
87 }
88
89 ATF_TC(strnlen_size_max);
ATF_TC_HEAD(strnlen_size_max,tc)90 ATF_TC_HEAD(strnlen_size_max, tc)
91 {
92 atf_tc_set_md_var(tc, "descr", "Test strnlen(3) with maxlen=SIZE_MAX");
93 }
94
ATF_TC_BODY(strnlen_size_max,tc)95 ATF_TC_BODY(strnlen_size_max, tc)
96 {
97 size_t (*strnlen_fn)(const char*, size_t) = strnlen;
98 char alignas(16) buffer[1 + 16 + 64 + 1 + 1];
99
100 memset(buffer, '/', sizeof(buffer));
101
102 for (int align = 1; align < 1 + 16; align++) {
103 char* s = buffer + align;
104
105 for (size_t len = 0; len <= 64; len++) {
106 /* returns length */
107
108 /* without sentinels */
109 s[len] = '\0';
110 size_t val = strnlen_fn(s, SIZE_MAX);
111 if (val != len) {
112 fprintf(stderr, "align = %d, maxlen = %zu, len = %zu",
113 align, SIZE_MAX, len);
114 atf_tc_fail("returned incorrect len (SIZE_MAX)");
115 }
116
117 /* with sentinels */
118 s[-1] = '\0';
119 val = strnlen_fn(s, SIZE_MAX);
120 if (val != len) {
121 fprintf(stderr, "align = %d, maxlen = %zu, len = %zu",
122 align, SIZE_MAX, len);
123 atf_tc_fail("returned incorrect len (sentinels) (SIZE_MAX)");
124 }
125
126 /* cleanup */
127 s[-1] = '/';
128 s[len] = '/';
129 }
130 }
131 }
132
133
134
ATF_TP_ADD_TCS(tp)135 ATF_TP_ADD_TCS(tp)
136 {
137 ATF_TP_ADD_TC(tp, strnlen_alignments);
138 ATF_TP_ADD_TC(tp, strnlen_size_max);
139
140 return atf_no_error();
141 }
142