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/>. */
22 #define TEST_LEN (getpagesize () * 3)
23 #define MIN_PAGE_SIZE (TEST_LEN + 2 * getpagesize ())
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);
35 /* Naive implementation to verify results. */
37 simple_strncasecmp (const char *s1
, const char *s2
, size_t n
)
44 while ((ret
= ((unsigned char) tolower (*s1
)
45 - (unsigned char) tolower (*s2
))) == 0
56 check_result (impl_t
*impl
, const char *s1
, const char *s2
, size_t n
,
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
,
74 do_one_test (impl_t
*impl
, const char *s1
, const char *s2
, size_t n
,
77 if (check_result (impl
, s1
, s2
, n
, exp_result
) < 0)
82 do_test (size_t align1
, size_t align2
, size_t n
, size_t len
, int max_char
,
91 align1
&= getpagesize () - 1;
92 if (align1
+ (len
+ 2) >= page_size
)
95 align2
&= getpagesize () - 1;
96 if (align2
+ (len
+ 2) >= page_size
)
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;
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
;
120 s2
[len
- 1] -= exp_result
;
122 /* For some locals this is not guaranteed 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]);
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
);
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
)
178 FOR_EACH_IMPL (impl
, 0)
179 check_result (impl
, s1
+ off1
, s2
+ off2
, maxoffset
+ 1,
186 do_random_tests (void)
188 size_t i
, j
, n
, align1
, align2
, pos
, len1
, len2
;
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;
198 align2
= random () & 31;
200 align2
= align1
+ (random () & 24);
201 pos
= random () & 511;
202 j
= align1
> align2
? align1
: align2
;
204 pos
= 510 - j
- (random () & 7);
205 len1
= random () & 511;
206 if (pos
>= len1
&& (random () & 1))
207 len1
= pos
+ (random () & 7);
209 len1
= 511 - j
- (random () & 7);
213 len2
= len1
+ (len1
!= 511 - j
? random () % (511 - j
- len1
) : 0);
214 j
= (pos
> len2
? pos
: len2
) + align1
+ 64;
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);
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);
234 toupper (p2
[i
] = 1 + (random () & 127));
239 memcpy (p2
+ align2
, p1
+ align1
, pos
);
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
]))
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
);
277 /* Regression test for BZ #12205 */
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;
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 */
300 const char *empty_string
= "";
301 FOR_EACH_IMPL (impl
, 0)
302 check_result (impl
, empty_string
, "", 5, 0);
306 test_locale (const char *locale
, int extra_tests
)
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
);
319 printf ("%23s", locale
);
320 FOR_EACH_IMPL (impl
, 0)
321 printf ("\t%s", impl
->name
);
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
,
449 do_test (getpagesize () - k
- 1, getpagesize () - j
- 1, i
- 1,
451 do_test (getpagesize () - k
, getpagesize () - j
- 1, i
+ 1, i
,
453 do_test (getpagesize () - k
- 1, getpagesize () - j
- 1, i
+ 1,
455 do_test (getpagesize () - k
, getpagesize () - j
- 1, i
, i
, 127,
457 do_test (getpagesize () - k
- 1, getpagesize () - j
- 1, i
, i
,
459 do_test (getpagesize () - k
, getpagesize () - j
- 1, i
+ 1, i
,
461 do_test (getpagesize () - k
- 1, getpagesize () - j
- 1, i
+ 1,
463 do_test (getpagesize () - k
, getpagesize () - j
- 1, i
+ 1, i
,
465 do_test (getpagesize () - k
- 1, getpagesize () - j
- 1, i
+ 1,
476 else if (i
+ 161 < test_len
)
481 if (i
+ 161 > test_len
)
486 else if (i
+ 32 < test_len
)
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);
515 #include <support/test-driver.c>