1 /* Test strlen functions.
2 Copyright (C) 1999-2023 Free Software Foundation, Inc.
3 This file is part of the GNU C Library.
5 The GNU C Library is free software; you can redistribute it and/or
6 modify it under the terms of the GNU Lesser General Public
7 License as published by the Free Software Foundation; either
8 version 2.1 of the License, or (at your option) any later version.
10 The GNU C Library is distributed in the hope that it will be useful,
11 but WITHOUT ANY WARRANTY; without even the implied warranty of
12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13 Lesser General Public License for more details.
15 You should have received a copy of the GNU Lesser General Public
16 License along with the GNU C Library; if not, see
17 <https://www.gnu.org/licenses/>. */
21 # define TEST_NAME "strnlen"
23 # define TEST_NAME "wcsnlen"
25 #include "test-string.h"
28 # define STRNLEN strnlen
29 # define MEMSET memset
31 # define BIG_CHAR CHAR_MAX
32 # define MIDDLE_CHAR 127
33 # define SIMPLE_STRNLEN simple_strnlen
36 # define STRNLEN wcsnlen
37 # define MEMSET wmemset
39 # define BIG_CHAR WCHAR_MAX
40 # define MIDDLE_CHAR 1121
41 # define SIMPLE_STRNLEN simple_wcsnlen
44 typedef size_t (*proto_t
) (const CHAR
*, size_t);
46 /* Also check the default implementation. */
49 # define MEMCHR __memchr_default
50 # define weak_alias(a, b)
51 # define libc_hidden_def(a)
52 # define libc_hidden_builtin_def(a)
53 # include "string/memchr.c"
55 # define STRNLEN __strnlen_default
56 # define memchr __memchr_default
57 # include "string/strnlen.c"
58 IMPL (__strnlen_default
, 1)
60 # define WMEMCHR __wmemchr_default
61 # define weak_alias(a, b)
62 # define libc_hidden_def(a)
63 # define libc_hidden_weak(a)
64 # include "wcsmbs/wmemchr.c"
65 # define WCSNLEN __wcsnlen_default
66 # define wmemchr __wmemchr_default
67 # include "wcsmbs/wcsnlen.c"
68 IMPL (__wcsnlen_default
, 1)
72 do_one_test (impl_t
*impl
, const CHAR
*s
, size_t maxlen
, size_t exp_len
)
74 size_t len
= CALL (impl
, s
, maxlen
);
77 error (0, 0, "Wrong result in function %s %zd %zd", impl
->name
,
85 do_test (size_t align
, size_t len
, size_t maxlen
, int max_char
)
89 align
&= (getpagesize () / sizeof (CHAR
) - 1);
90 if ((align
+ len
) * sizeof (CHAR
) >= page_size
)
93 CHAR
*buf
= (CHAR
*) (buf1
);
95 for (i
= 0; i
< len
; ++i
)
96 buf
[align
+ i
] = 1 + 11111 * i
% max_char
;
99 FOR_EACH_IMPL (impl
, 0)
100 do_one_test (impl
, (CHAR
*) (buf
+ align
), maxlen
, MIN (len
, maxlen
));
104 do_overflow_tests (void)
106 size_t i
, j
, al_idx
, repeats
, len
;
107 const size_t one
= 1;
108 uintptr_t buf_addr
= (uintptr_t) buf1
;
109 const size_t alignments
[] = { 0, 1, 7, 9, 31, 33, 63, 65, 95, 97, 127, 129 };
111 for (al_idx
= 0; al_idx
< sizeof (alignments
) / sizeof (alignments
[0]);
114 for (repeats
= 0; repeats
< 2; ++repeats
)
116 size_t align
= repeats
? (getpagesize () - alignments
[al_idx
])
117 : alignments
[al_idx
];
118 align
/= sizeof (CHAR
);
119 for (i
= 0; i
< 750; ++i
)
121 do_test (align
, i
, SIZE_MAX
, BIG_CHAR
);
123 do_test (align
, i
, SIZE_MAX
- i
, BIG_CHAR
);
124 do_test (align
, i
, i
- buf_addr
, BIG_CHAR
);
125 do_test (align
, i
, -buf_addr
- i
, BIG_CHAR
);
126 do_test (align
, i
, SIZE_MAX
- buf_addr
- i
, BIG_CHAR
);
127 do_test (align
, i
, SIZE_MAX
- buf_addr
+ i
, BIG_CHAR
);
130 for (j
= 8 * sizeof (size_t) - 1; j
; --j
)
133 do_test (align
, i
, len
, BIG_CHAR
);
134 do_test (align
, i
, len
- i
, BIG_CHAR
);
135 do_test (align
, i
, len
+ i
, BIG_CHAR
);
136 do_test (align
, i
, len
- buf_addr
- i
, BIG_CHAR
);
137 do_test (align
, i
, len
- buf_addr
+ i
, BIG_CHAR
);
139 do_test (align
, i
, ~len
- i
, BIG_CHAR
);
140 do_test (align
, i
, ~len
+ i
, BIG_CHAR
);
141 do_test (align
, i
, ~len
- buf_addr
- i
, BIG_CHAR
);
142 do_test (align
, i
, ~len
- buf_addr
+ i
, BIG_CHAR
);
144 do_test (align
, i
, -buf_addr
, BIG_CHAR
);
145 do_test (align
, i
, j
- buf_addr
, BIG_CHAR
);
146 do_test (align
, i
, -buf_addr
- j
, BIG_CHAR
);
154 do_random_tests (void)
156 size_t i
, j
, n
, align
, len
;
157 CHAR
*p
= (CHAR
*) (buf1
+ page_size
- 512 * sizeof (CHAR
));
159 for (n
= 0; n
< ITERATIONS
; n
++)
161 align
= random () & 15;
162 len
= random () & 511;
163 if (len
+ align
> 510)
164 len
= 511 - align
- (random () & 7);
165 j
= len
+ align
+ 64;
169 for (i
= 0; i
< j
; i
++)
171 if (i
== len
+ align
)
175 p
[i
] = random () & 255;
176 if (i
>= align
&& i
< len
+ align
&& !p
[i
])
177 p
[i
] = (random () & 127) + 1;
181 FOR_EACH_IMPL (impl
, 1)
184 && CALL (impl
, (CHAR
*) (p
+ align
), len
- 1) != len
- 1)
186 error (0, 0, "Iteration %zd (limited) - wrong result in function %s (%zd) %zd != %zd, p %p",
187 n
, impl
->name
, align
,
188 CALL (impl
, (CHAR
*) (p
+ align
), len
- 1), len
- 1, p
);
191 if (CALL (impl
, (CHAR
*) (p
+ align
), len
) != len
)
193 error (0, 0, "Iteration %zd (exact) - wrong result in function %s (%zd) %zd != %zd, p %p",
194 n
, impl
->name
, align
,
195 CALL (impl
, (CHAR
*) (p
+ align
), len
), len
, p
);
198 if (CALL (impl
, (CHAR
*) (p
+ align
), len
+ 1) != len
)
200 error (0, 0, "Iteration %zd (long) - wrong result in function %s (%zd) %zd != %zd, p %p",
201 n
, impl
->name
, align
,
202 CALL (impl
, (CHAR
*) (p
+ align
), len
+ 1), len
, p
);
209 /* Tests meant to unveil fail on implementation that does not access bytes
210 around the page boundary accordingly. */
214 size_t i
, exp_len
, start_offset
, offset
;
215 /* Calculate the null character offset. */
216 size_t last_offset
= (page_size
/ sizeof (CHAR
)) - 1;
218 CHAR
*s
= (CHAR
*) buf2
;
219 MEMSET (s
, 65, (last_offset
- 1));
222 /* Place short strings ending at page boundary. */
223 offset
= last_offset
;
224 for (i
= 0; i
< 128; i
++)
226 /* Decrease offset to stress several sizes and alignments. */
228 exp_len
= last_offset
- offset
;
229 FOR_EACH_IMPL (impl
, 0)
231 /* Varies maxlen value to cover the cases where it is:
232 - larger than length;
233 - slightly greater than length;
235 - slightly less than length. */
236 do_one_test (impl
, (CHAR
*) (s
+ offset
), page_size
, exp_len
);
237 do_one_test (impl
, (CHAR
*) (s
+ offset
), exp_len
+ 1, exp_len
);
238 do_one_test (impl
, (CHAR
*) (s
+ offset
), exp_len
, exp_len
);
240 do_one_test (impl
, (CHAR
*) (s
+ offset
), exp_len
- 1, exp_len
- 1);
244 /* Place long strings ending at page boundary. */
245 start_offset
= (last_offset
+ 1) / 2;
246 for (i
= 0; i
< 64; ++i
)
248 /* Increase offset to stress several alignments. */
249 offset
= start_offset
+ i
;
250 if (offset
>= (last_offset
+ 1))
252 exp_len
= last_offset
- offset
;
253 FOR_EACH_IMPL (impl
, 0)
255 /* Checks only for maxlen much larger than length because smaller
256 values are already covered in do_random_tests function. */
257 do_one_test (impl
, (CHAR
*) (s
+ offset
), page_size
, exp_len
);
262 /* Tests meant to unveil fail on implementations that access bytes
263 beyond the maximum length. */
266 do_page_2_tests (void)
268 size_t i
, exp_len
, offset
;
269 size_t last_offset
= page_size
/ sizeof (CHAR
);
271 CHAR
*s
= (CHAR
*) buf2
;
272 MEMSET (s
, 65, last_offset
);
274 /* Place short strings ending at page boundary without the null
276 offset
= last_offset
;
277 for (i
= 0; i
< 128; i
++)
279 /* Decrease offset to stress several sizes and alignments. */
281 exp_len
= last_offset
- offset
;
282 FOR_EACH_IMPL (impl
, 0)
284 /* If an implementation goes beyond EXP_LEN, it will trigger
286 do_one_test (impl
, (CHAR
*) (s
+ offset
), exp_len
, exp_len
);
294 size_t i
, length
, char_per_page
;
299 FOR_EACH_IMPL (impl
, 0)
300 printf ("\t%s", impl
->name
);
303 for (i
= 1; i
< 8; ++i
)
305 do_test (0, i
, i
- 1, MIDDLE_CHAR
);
306 do_test (0, i
, i
, MIDDLE_CHAR
);
307 do_test (0, i
, i
+ 1, MIDDLE_CHAR
);
310 for (i
= 1; i
< 8; ++i
)
312 do_test (i
, i
, i
- 1, MIDDLE_CHAR
);
313 do_test (i
, i
, i
, MIDDLE_CHAR
);
314 do_test (i
, i
, i
+ 1, MIDDLE_CHAR
);
317 for (i
= 2; i
<= 10; ++i
)
319 do_test (0, 1 << i
, 5000, MIDDLE_CHAR
);
320 do_test (1, 1 << i
, 5000, MIDDLE_CHAR
);
323 for (i
= 1; i
< 8; ++i
)
324 do_test (0, i
, 5000, BIG_CHAR
);
326 for (i
= 1; i
< 8; ++i
)
327 do_test (i
, i
, 5000, BIG_CHAR
);
329 for (i
= 2; i
<= 10; ++i
)
331 do_test (0, 1 << i
, 5000, BIG_CHAR
);
332 do_test (1, 1 << i
, 5000, BIG_CHAR
);
335 char_per_page
= getpagesize () / sizeof (CHAR
);
337 for (i
= 0; i
<= 127; i
++)
338 for (length
= i
; length
<= 512; length
++)
340 do_test (i
, length
, 512, BIG_CHAR
);
341 do_test (char_per_page
- i
, length
, 512, BIG_CHAR
);
347 do_overflow_tests ();
351 #include <support/test-driver.c>