elf: Fix GL(dl_phdr) and GL(dl_phnum) for static builds [BZ #29864]
[glibc.git] / string / test-strncasecmp.c
blob6246fe5c1b324c2fc2a7363130c48f7083a2fe46
1 /* Test and measure strncasecmp 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/>. */
19 #include <locale.h>
20 #include <ctype.h>
22 #define TEST_LEN (getpagesize () * 3)
23 #define MIN_PAGE_SIZE (TEST_LEN + 2 * getpagesize ())
25 #define TEST_MAIN
26 #define TEST_NAME "strncasecmp"
27 #define TIMEOUT (5 * 60)
28 #include "test-string.h"
30 typedef int (*proto_t) (const char *, const char *, size_t);
31 static int simple_strncasecmp (const char *, const char *, size_t);
33 IMPL (strncasecmp, 1)
35 /* Naive implementation to verify results. */
36 static int
37 simple_strncasecmp (const char *s1, const char *s2, size_t n)
39 int ret;
41 if (n == 0)
42 return 0;
44 while ((ret = ((unsigned char) tolower (*s1)
45 - (unsigned char) tolower (*s2))) == 0
46 && *s1++)
48 if (--n == 0)
49 return 0;
50 ++s2;
52 return ret;
55 static int
56 check_result (impl_t *impl, const char *s1, const char *s2, size_t n,
57 int exp_result)
59 int result = CALL (impl, s1, s2, n);
60 if ((exp_result == 0 && result != 0)
61 || (exp_result < 0 && result >= 0)
62 || (exp_result > 0 && result <= 0))
64 error (0, 0, "Wrong result in function %s %d %d", impl->name,
65 result, exp_result);
66 ret = 1;
67 return -1;
70 return 0;
73 static void
74 do_one_test (impl_t *impl, const char *s1, const char *s2, size_t n,
75 int exp_result)
77 if (check_result (impl, s1, s2, n, exp_result) < 0)
78 return;
81 static void
82 do_test (size_t align1, size_t align2, size_t n, size_t len, int max_char,
83 int exp_result)
85 size_t i;
86 char *s1, *s2;
88 if (len == 0)
89 return;
91 align1 &= getpagesize () - 1;
92 if (align1 + (len + 2) >= page_size)
93 return;
95 align2 &= getpagesize () - 1;
96 if (align2 + (len + 2) >= page_size)
97 return;
100 s1 = (char *) (buf1 + align1);
101 s2 = (char *) (buf2 + align2);
103 for (i = 0; i < len; i++)
105 s1[i] = toupper (1 + 23 * i % max_char);
106 s2[i] = tolower (s1[i]);
109 s1[len] = s2[len] = 0;
110 s1[len + 1] = 23;
111 s2[len + 1] = 24 + exp_result;
113 if ((s2[len - 1] == 'z' && exp_result == -1)
114 || (s2[len - 1] == 'a' && exp_result == 1))
115 s1[len - 1] += exp_result;
116 else if ((s1[len - 1] == 'Z' + 1 && exp_result == 1)
117 || (s1[len - 1] == 'A' - 1 && exp_result == -1))
118 s1[len - 1] = tolower (s2[len - 1]) + exp_result;
119 else
120 s2[len - 1] -= exp_result;
122 /* For some locals this is not guranteed yet. */
123 if (tolower (s1[len - 1]) - tolower (s2[len - 1]) != exp_result)
125 if (exp_result == -1)
127 s1[len - 1] = tolower ('a');
128 s2[len - 1] = toupper (tolower ('a') - 1);
130 else if (exp_result == 0)
131 s1[len - 1] = toupper (s2[len - 1]);
132 else
134 s1[len - 1] = tolower ('a');
135 s2[len - 1] = toupper (tolower ('a') + 1);
139 FOR_EACH_IMPL (impl, 0)
140 do_one_test (impl, s1, s2, n, exp_result);
143 static void
144 do_page_tests (void)
146 char *s1, *s2;
147 int exp_result;
148 const size_t maxoffset = 64;
150 s1 = (char *) buf1 + BUF1PAGES * page_size - maxoffset;
151 memset (s1, 'a', maxoffset - 1);
152 s1[maxoffset - 1] = '\0';
154 s2 = (char *) buf2 + page_size - maxoffset;
155 memset (s2, 'a', maxoffset - 1);
156 s2[maxoffset - 1] = '\0';
158 /* At this point s1 and s2 point to distinct memory regions containing
159 "aa..." with size of 63 plus '\0'. Also, both strings are bounded to a
160 page with read/write access and the next page is protected with PROT_NONE
161 (meaning that any access outside of the page regions will trigger an
162 invalid memory access).
164 The loop checks for all possible offsets up to maxoffset for both
165 inputs with a size larger than the string (so memory access outside
166 the expected memory regions might trigger invalid access). */
168 for (size_t off1 = 0; off1 < maxoffset; off1++)
170 for (size_t off2 = 0; off2 < maxoffset; off2++)
172 exp_result = (off1 == off2)
174 : off1 < off2
175 ? 'a'
176 : -'a';
178 FOR_EACH_IMPL (impl, 0)
179 check_result (impl, s1 + off1, s2 + off2, maxoffset + 1,
180 exp_result);
185 static void
186 do_random_tests (void)
188 size_t i, j, n, align1, align2, pos, len1, len2;
189 int result;
190 long r;
191 unsigned char *p1 = buf1 + page_size - 512;
192 unsigned char *p2 = buf2 + page_size - 512;
194 for (n = 0; n < ITERATIONS; n++)
196 align1 = random () & 31;
197 if (random () & 1)
198 align2 = random () & 31;
199 else
200 align2 = align1 + (random () & 24);
201 pos = random () & 511;
202 j = align1 > align2 ? align1 : align2;
203 if (pos + j >= 511)
204 pos = 510 - j - (random () & 7);
205 len1 = random () & 511;
206 if (pos >= len1 && (random () & 1))
207 len1 = pos + (random () & 7);
208 if (len1 + j >= 512)
209 len1 = 511 - j - (random () & 7);
210 if (pos >= len1)
211 len2 = len1;
212 else
213 len2 = len1 + (len1 != 511 - j ? random () % (511 - j - len1) : 0);
214 j = (pos > len2 ? pos : len2) + align1 + 64;
215 if (j > 512)
216 j = 512;
217 for (i = 0; i < j; ++i)
219 p1[i] = tolower (random () & 255);
220 if (i < len1 + align1 && !p1[i])
222 p1[i] = tolower (random () & 255);
223 if (!p1[i])
224 p1[i] = tolower (1 + (random () & 127));
227 for (i = 0; i < j; ++i)
229 p2[i] = toupper (random () & 255);
230 if (i < len2 + align2 && !p2[i])
232 p2[i] = toupper (random () & 255);
233 if (!p2[i])
234 toupper (p2[i] = 1 + (random () & 127));
238 result = 0;
239 memcpy (p2 + align2, p1 + align1, pos);
240 if (pos < len1)
242 if (tolower (p2[align2 + pos]) == p1[align1 + pos])
244 p2[align2 + pos] = toupper (random () & 255);
245 if (tolower (p2[align2 + pos]) == p1[align1 + pos])
246 p2[align2 + pos] = toupper (p1[align1 + pos]
247 + 3 + (random () & 127));
250 if (p1[align1 + pos] < tolower (p2[align2 + pos]))
251 result = -1;
252 else
253 result = 1;
255 p1[len1 + align1] = 0;
256 p2[len2 + align2] = 0;
258 FOR_EACH_IMPL (impl, 1)
260 r = CALL (impl, (char *) (p1 + align1), (char *) (p2 + align2),
261 pos + 1 + (random () & 255));
262 /* Test whether on 64-bit architectures where ABI requires
263 callee to promote has the promotion been done. */
264 asm ("" : "=g" (r) : "0" (r));
265 if ((r == 0 && result)
266 || (r < 0 && result >= 0)
267 || (r > 0 && result <= 0))
269 error (0, 0, "Iteration %zd - wrong result in function %s (%zd, %zd, %zd, %zd, %zd) %ld != %d, p1 %p p2 %p",
270 n, impl->name, align1, align2, len1, len2, pos, r, result, p1, p2);
271 ret = 1;
277 /* Regression test for BZ #12205 */
278 static void
279 bz12205 (void)
281 static char cp [4096+16] __attribute__ ((aligned(4096)));
282 static char gotrel[4096] __attribute__ ((aligned(4096)));
283 char *s1 = cp + 0xffa;
284 char *s2 = gotrel + 0xcbe;
285 int exp_result;
286 size_t n = 6;
288 strcpy (s1, "gottpoff");
289 strcpy (s2, "GOTPLT");
291 exp_result = simple_strncasecmp (s1, s2, n);
292 FOR_EACH_IMPL (impl, 0)
293 check_result (impl, s1, s2, n, exp_result);
296 /* Regression test for BZ #14195 */
297 static void
298 bz14195 (void)
300 const char *empty_string = "";
301 FOR_EACH_IMPL (impl, 0)
302 check_result (impl, empty_string, "", 5, 0);
305 static void
306 test_locale (const char *locale, int extra_tests)
308 size_t i, j, k;
309 const size_t test_len = MIN(TEST_LEN, 3 * 4096);
310 if (setlocale (LC_CTYPE, locale) == NULL)
312 error (0, 0, "cannot set locale \"%s\"", locale);
313 ret = 1;
316 bz12205 ();
317 bz14195 ();
319 printf ("%23s", locale);
320 FOR_EACH_IMPL (impl, 0)
321 printf ("\t%s", impl->name);
322 putchar ('\n');
324 for (i = 1; i < 16; ++i)
326 do_test (i, i, i - 1, i, 127, 0);
328 do_test (i, i, i, i, 127, 0);
329 do_test (i, i, i, i, 127, 1);
330 do_test (i, i, i, i, 127, -1);
332 do_test (i, i, i + 1, i, 127, 0);
333 do_test (i, i, i + 1, i, 127, 1);
334 do_test (i, i, i + 1, i, 127, -1);
337 for (i = 1; i < 10; ++i)
339 do_test (0, 0, (2 << i) - 1, 2 << i, 127, 0);
340 do_test (0, 0, 2 << i, 2 << i, 254, 0);
341 do_test (0, 0, (2 << i) + 1, 2 << i, 127, 0);
343 do_test (0, 0, (2 << i) + 1, 2 << i, 254, 0);
345 do_test (0, 0, 2 << i, 2 << i, 127, 1);
346 do_test (0, 0, (2 << i) + 10, 2 << i, 127, 1);
348 do_test (0, 0, 2 << i, 2 << i, 254, 1);
349 do_test (0, 0, (2 << i) + 10, 2 << i, 254, 1);
351 do_test (0, 0, 2 << i, 2 << i, 127, -1);
352 do_test (0, 0, (2 << i) + 10, 2 << i, 127, -1);
354 do_test (0, 0, 2 << i, 2 << i, 254, -1);
355 do_test (0, 0, (2 << i) + 10, 2 << i, 254, -1);
358 for (i = 1; i < 8; ++i)
360 do_test (i, 2 * i, (8 << i) - 1, 8 << i, 127, 0);
361 do_test (i, 2 * i, 8 << i, 8 << i, 127, 0);
362 do_test (i, 2 * i, (8 << i) + 100, 8 << i, 127, 0);
364 do_test (2 * i, i, (8 << i) - 1, 8 << i, 254, 0);
365 do_test (2 * i, i, 8 << i, 8 << i, 254, 0);
366 do_test (2 * i, i, (8 << i) + 100, 8 << i, 254, 0);
368 do_test (i, 2 * i, 8 << i, 8 << i, 127, 1);
369 do_test (i, 2 * i, (8 << i) + 100, 8 << i, 127, 1);
371 do_test (2 * i, i, 8 << i, 8 << i, 254, 1);
372 do_test (2 * i, i, (8 << i) + 100, 8 << i, 254, 1);
374 do_test (i, 2 * i, 8 << i, 8 << i, 127, -1);
375 do_test (i, 2 * i, (8 << i) + 100, 8 << i, 127, -1);
377 do_test (2 * i, i, 8 << i, 8 << i, 254, -1);
378 do_test (2 * i, i, (8 << i) + 100, 8 << i, 254, -1);
381 for (j = 0; extra_tests && j < 160; ++j)
383 for (i = 0; i < test_len;)
385 do_test (getpagesize () - j - 1, 0, i + 1, i, 127, 0);
386 do_test (getpagesize () - j - 1, 0, i + 1, i, 127, 1);
387 do_test (getpagesize () - j - 1, 0, i + 1, i, 127, -1);
389 do_test (getpagesize () - j - 1, 0, i, i, 127, 0);
390 do_test (getpagesize () - j - 1, 0, i - 1, i, 127, 0);
392 do_test (getpagesize () - j - 1, 0, ULONG_MAX, i, 127, 0);
393 do_test (getpagesize () - j - 1, 0, ULONG_MAX, i, 127, 1);
394 do_test (getpagesize () - j - 1, 0, ULONG_MAX, i, 127, -1);
396 do_test (getpagesize () - j - 1, 0, ULONG_MAX - i, i, 127, 0);
397 do_test (getpagesize () - j - 1, 0, ULONG_MAX - i, i, 127, 1);
398 do_test (getpagesize () - j - 1, 0, ULONG_MAX - i, i, 127, -1);
400 do_test (getpagesize () - j - 1, j, i + 1, i, 127, 0);
401 do_test (getpagesize () - j - 1, j, i + 1, i, 127, 1);
402 do_test (getpagesize () - j - 1, j, i + 1, i, 127, -1);
404 do_test (getpagesize () - j - 1, j, i, i, 127, 0);
405 do_test (getpagesize () - j - 1, j, i - 1, i, 127, 0);
407 do_test (getpagesize () - j - 1, j, ULONG_MAX, i, 127, 0);
408 do_test (getpagesize () - j - 1, j, ULONG_MAX, i, 127, 1);
409 do_test (getpagesize () - j - 1, j, ULONG_MAX, i, 127, -1);
411 do_test (getpagesize () - j - 1, j, ULONG_MAX - i, i, 127, 0);
412 do_test (getpagesize () - j - 1, j, ULONG_MAX - i, i, 127, 1);
413 do_test (getpagesize () - j - 1, j, ULONG_MAX - i, i, 127, -1);
415 do_test (0, getpagesize () - j - 1, i + 1, i, 127, 0);
416 do_test (0, getpagesize () - j - 1, i + 1, i, 127, 1);
417 do_test (0, getpagesize () - j - 1, i + 1, i, 127, -1);
419 do_test (0, getpagesize () - j - 1, i, i, 127, 0);
420 do_test (0, getpagesize () - j - 1, i - 1, i, 127, 0);
422 do_test (0, getpagesize () - j - 1, ULONG_MAX, i, 127, 0);
423 do_test (0, getpagesize () - j - 1, ULONG_MAX, i, 127, 1);
424 do_test (0, getpagesize () - j - 1, ULONG_MAX, i, 127, -1);
426 do_test (0, getpagesize () - j - 1, ULONG_MAX - i, i, 127, 0);
427 do_test (0, getpagesize () - j - 1, ULONG_MAX - i, i, 127, 1);
428 do_test (0, getpagesize () - j - 1, ULONG_MAX - i, i, 127, -1);
430 do_test (j, getpagesize () - j - 1, i + 1, i, 127, 0);
431 do_test (j, getpagesize () - j - 1, i + 1, i, 127, 1);
432 do_test (j, getpagesize () - j - 1, i + 1, i, 127, -1);
434 do_test (j, getpagesize () - j - 1, i, i, 127, 0);
435 do_test (j, getpagesize () - j - 1, i - 1, i, 127, 0);
437 do_test (j, getpagesize () - j - 1, ULONG_MAX, i, 127, 0);
438 do_test (j, getpagesize () - j - 1, ULONG_MAX, i, 127, 1);
439 do_test (j, getpagesize () - j - 1, ULONG_MAX, i, 127, -1);
441 do_test (j, getpagesize () - j - 1, ULONG_MAX - i, i, 127, 0);
442 do_test (j, getpagesize () - j - 1, ULONG_MAX - i, i, 127, 1);
443 do_test (j, getpagesize () - j - 1, ULONG_MAX - i, i, 127, -1);
445 for (k = 2; k <= 128; k += k)
447 do_test (getpagesize () - k, getpagesize () - j - 1, i - 1, i,
448 127, 0);
449 do_test (getpagesize () - k - 1, getpagesize () - j - 1, i - 1,
450 i, 127, 0);
451 do_test (getpagesize () - k, getpagesize () - j - 1, i + 1, i,
452 127, 0);
453 do_test (getpagesize () - k - 1, getpagesize () - j - 1, i + 1,
454 i, 127, 0);
455 do_test (getpagesize () - k, getpagesize () - j - 1, i, i, 127,
457 do_test (getpagesize () - k - 1, getpagesize () - j - 1, i, i,
458 127, 0);
459 do_test (getpagesize () - k, getpagesize () - j - 1, i + 1, i,
460 127, -1);
461 do_test (getpagesize () - k - 1, getpagesize () - j - 1, i + 1,
462 i, 127, -1);
463 do_test (getpagesize () - k, getpagesize () - j - 1, i + 1, i,
464 127, 1);
465 do_test (getpagesize () - k - 1, getpagesize () - j - 1, i + 1,
466 i, 127, 1);
468 if (i < 32)
470 i += 1;
472 else if (i < 161)
474 i += 7;
476 else if (i + 161 < test_len)
478 i += 31;
479 i *= 17;
480 i /= 16;
481 if (i + 161 > test_len)
483 i = test_len - 160;
486 else if (i + 32 < test_len)
488 i += 7;
490 else
492 i += 1;
497 do_random_tests ();
498 do_page_tests ();
502 test_main (void)
504 test_init ();
506 test_locale ("C", 1);
507 test_locale ("en_US.ISO-8859-1", 0);
508 test_locale ("en_US.UTF-8", 0);
509 test_locale ("tr_TR.ISO-8859-9", 0);
510 test_locale ("tr_TR.UTF-8", 0);
512 return ret;
515 #include <support/test-driver.c>