elf: Fix use-after-free in ldconfig [BZ #26779]
[glibc.git] / string / test-strncasecmp.c
bloba3c848165a07cc978e0de13db03e8679b718c2ac
1 /* Test and measure strncasecmp functions.
2 Copyright (C) 1999-2022 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>
21 #define TEST_MAIN
22 #define TEST_NAME "strncasecmp"
23 #include "test-string.h"
25 typedef int (*proto_t) (const char *, const char *, size_t);
26 static int simple_strncasecmp (const char *, const char *, size_t);
27 static int stupid_strncasecmp (const char *, const char *, size_t);
29 IMPL (stupid_strncasecmp, 0)
30 IMPL (simple_strncasecmp, 0)
31 IMPL (strncasecmp, 1)
33 static int
34 simple_strncasecmp (const char *s1, const char *s2, size_t n)
36 int ret;
38 if (n == 0)
39 return 0;
41 while ((ret = ((unsigned char) tolower (*s1)
42 - (unsigned char) tolower (*s2))) == 0
43 && *s1++)
45 if (--n == 0)
46 return 0;
47 ++s2;
49 return ret;
52 static int
53 stupid_strncasecmp (const char *s1, const char *s2, size_t max)
55 size_t ns1 = strlen (s1) + 1;
56 size_t ns2 = strlen (s2) + 1;
57 size_t n = ns1 < ns2 ? ns1 : ns2;
58 if (n > max)
59 n = max;
60 int ret = 0;
62 while (n--)
64 if ((ret = ((unsigned char) tolower (*s1)
65 - (unsigned char) tolower (*s2))) != 0)
66 break;
67 ++s1;
68 ++s2;
70 return ret;
73 static int
74 check_result (impl_t *impl, const char *s1, const char *s2, size_t n,
75 int exp_result)
77 int result = CALL (impl, s1, s2, n);
78 if ((exp_result == 0 && result != 0)
79 || (exp_result < 0 && result >= 0)
80 || (exp_result > 0 && result <= 0))
82 error (0, 0, "Wrong result in function %s %d %d", impl->name,
83 result, exp_result);
84 ret = 1;
85 return -1;
88 return 0;
91 static void
92 do_one_test (impl_t *impl, const char *s1, const char *s2, size_t n,
93 int exp_result)
95 if (check_result (impl, s1, s2, n, exp_result) < 0)
96 return;
99 static void
100 do_test (size_t align1, size_t align2, size_t n, size_t len, int max_char,
101 int exp_result)
103 size_t i;
104 char *s1, *s2;
106 if (len == 0)
107 return;
109 align1 &= 7;
110 if (align1 + len + 1 >= page_size)
111 return;
113 align2 &= 7;
114 if (align2 + len + 1 >= page_size)
115 return;
117 s1 = (char *) (buf1 + align1);
118 s2 = (char *) (buf2 + align2);
120 for (i = 0; i < len; i++)
122 s1[i] = toupper (1 + 23 * i % max_char);
123 s2[i] = tolower (s1[i]);
126 s1[len] = s2[len] = 0;
127 s1[len + 1] = 23;
128 s2[len + 1] = 24 + exp_result;
129 if ((s2[len - 1] == 'z' && exp_result == -1)
130 || (s2[len - 1] == 'a' && exp_result == 1))
131 s1[len - 1] += exp_result;
132 else
133 s2[len - 1] -= exp_result;
135 FOR_EACH_IMPL (impl, 0)
136 do_one_test (impl, s1, s2, n, exp_result);
139 static void
140 do_page_tests (void)
142 char *s1, *s2;
143 int exp_result;
144 const size_t maxoffset = 64;
146 s1 = (char *) buf1 + BUF1PAGES * page_size - maxoffset;
147 memset (s1, 'a', maxoffset - 1);
148 s1[maxoffset - 1] = '\0';
150 s2 = (char *) buf2 + page_size - maxoffset;
151 memset (s2, 'a', maxoffset - 1);
152 s2[maxoffset - 1] = '\0';
154 /* At this point s1 and s2 point to distinct memory regions containing
155 "aa..." with size of 63 plus '\0'. Also, both strings are bounded to a
156 page with read/write access and the next page is protected with PROT_NONE
157 (meaning that any access outside of the page regions will trigger an
158 invalid memory access).
160 The loop checks for all possible offsets up to maxoffset for both
161 inputs with a size larger than the string (so memory access outside
162 the expected memory regions might trigger invalid access). */
164 for (size_t off1 = 0; off1 < maxoffset; off1++)
166 for (size_t off2 = 0; off2 < maxoffset; off2++)
168 exp_result = (off1 == off2)
170 : off1 < off2
171 ? 'a'
172 : -'a';
174 FOR_EACH_IMPL (impl, 0)
175 check_result (impl, s1 + off1, s2 + off2, maxoffset + 1,
176 exp_result);
181 static void
182 do_random_tests (void)
184 size_t i, j, n, align1, align2, pos, len1, len2;
185 int result;
186 long r;
187 unsigned char *p1 = buf1 + page_size - 512;
188 unsigned char *p2 = buf2 + page_size - 512;
190 for (n = 0; n < ITERATIONS; n++)
192 align1 = random () & 31;
193 if (random () & 1)
194 align2 = random () & 31;
195 else
196 align2 = align1 + (random () & 24);
197 pos = random () & 511;
198 j = align1 > align2 ? align1 : align2;
199 if (pos + j >= 511)
200 pos = 510 - j - (random () & 7);
201 len1 = random () & 511;
202 if (pos >= len1 && (random () & 1))
203 len1 = pos + (random () & 7);
204 if (len1 + j >= 512)
205 len1 = 511 - j - (random () & 7);
206 if (pos >= len1)
207 len2 = len1;
208 else
209 len2 = len1 + (len1 != 511 - j ? random () % (511 - j - len1) : 0);
210 j = (pos > len2 ? pos : len2) + align1 + 64;
211 if (j > 512)
212 j = 512;
213 for (i = 0; i < j; ++i)
215 p1[i] = tolower (random () & 255);
216 if (i < len1 + align1 && !p1[i])
218 p1[i] = tolower (random () & 255);
219 if (!p1[i])
220 p1[i] = tolower (1 + (random () & 127));
223 for (i = 0; i < j; ++i)
225 p2[i] = toupper (random () & 255);
226 if (i < len2 + align2 && !p2[i])
228 p2[i] = toupper (random () & 255);
229 if (!p2[i])
230 toupper (p2[i] = 1 + (random () & 127));
234 result = 0;
235 memcpy (p2 + align2, p1 + align1, pos);
236 if (pos < len1)
238 if (tolower (p2[align2 + pos]) == p1[align1 + pos])
240 p2[align2 + pos] = toupper (random () & 255);
241 if (tolower (p2[align2 + pos]) == p1[align1 + pos])
242 p2[align2 + pos] = toupper (p1[align1 + pos]
243 + 3 + (random () & 127));
246 if (p1[align1 + pos] < tolower (p2[align2 + pos]))
247 result = -1;
248 else
249 result = 1;
251 p1[len1 + align1] = 0;
252 p2[len2 + align2] = 0;
254 FOR_EACH_IMPL (impl, 1)
256 r = CALL (impl, (char *) (p1 + align1), (char *) (p2 + align2),
257 pos + 1 + (random () & 255));
258 /* Test whether on 64-bit architectures where ABI requires
259 callee to promote has the promotion been done. */
260 asm ("" : "=g" (r) : "0" (r));
261 if ((r == 0 && result)
262 || (r < 0 && result >= 0)
263 || (r > 0 && result <= 0))
265 error (0, 0, "Iteration %zd - wrong result in function %s (%zd, %zd, %zd, %zd, %zd) %ld != %d, p1 %p p2 %p",
266 n, impl->name, align1, align2, len1, len2, pos, r, result, p1, p2);
267 ret = 1;
273 /* Regression test for BZ #12205 */
274 static void
275 bz12205 (void)
277 static char cp [4096+16] __attribute__ ((aligned(4096)));
278 static char gotrel[4096] __attribute__ ((aligned(4096)));
279 char *s1 = cp + 0xffa;
280 char *s2 = gotrel + 0xcbe;
281 int exp_result;
282 size_t n = 6;
284 strcpy (s1, "gottpoff");
285 strcpy (s2, "GOTPLT");
287 exp_result = simple_strncasecmp (s1, s2, n);
288 FOR_EACH_IMPL (impl, 0)
289 check_result (impl, s1, s2, n, exp_result);
292 /* Regression test for BZ #14195 */
293 static void
294 bz14195 (void)
296 const char *empty_string = "";
297 FOR_EACH_IMPL (impl, 0)
298 check_result (impl, empty_string, "", 5, 0);
301 static void
302 test_locale (const char *locale)
304 size_t i;
306 if (setlocale (LC_CTYPE, locale) == NULL)
308 error (0, 0, "cannot set locale \"%s\"", locale);
309 ret = 1;
312 bz12205 ();
313 bz14195 ();
315 printf ("%23s", locale);
316 FOR_EACH_IMPL (impl, 0)
317 printf ("\t%s", impl->name);
318 putchar ('\n');
320 for (i = 1; i < 16; ++i)
322 do_test (i, i, i - 1, i, 127, 0);
324 do_test (i, i, i, i, 127, 0);
325 do_test (i, i, i, i, 127, 1);
326 do_test (i, i, i, i, 127, -1);
328 do_test (i, i, i + 1, i, 127, 0);
329 do_test (i, i, i + 1, i, 127, 1);
330 do_test (i, i, i + 1, i, 127, -1);
333 for (i = 1; i < 10; ++i)
335 do_test (0, 0, (2 << i) - 1, 2 << i, 127, 0);
336 do_test (0, 0, 2 << i, 2 << i, 254, 0);
337 do_test (0, 0, (2 << i) + 1, 2 << i, 127, 0);
339 do_test (0, 0, (2 << i) + 1, 2 << i, 254, 0);
341 do_test (0, 0, 2 << i, 2 << i, 127, 1);
342 do_test (0, 0, (2 << i) + 10, 2 << i, 127, 1);
344 do_test (0, 0, 2 << i, 2 << i, 254, 1);
345 do_test (0, 0, (2 << i) + 10, 2 << i, 254, 1);
347 do_test (0, 0, 2 << i, 2 << i, 127, -1);
348 do_test (0, 0, (2 << i) + 10, 2 << i, 127, -1);
350 do_test (0, 0, 2 << i, 2 << i, 254, -1);
351 do_test (0, 0, (2 << i) + 10, 2 << i, 254, -1);
354 for (i = 1; i < 8; ++i)
356 do_test (i, 2 * i, (8 << i) - 1, 8 << i, 127, 0);
357 do_test (i, 2 * i, 8 << i, 8 << i, 127, 0);
358 do_test (i, 2 * i, (8 << i) + 100, 8 << i, 127, 0);
360 do_test (2 * i, i, (8 << i) - 1, 8 << i, 254, 0);
361 do_test (2 * i, i, 8 << i, 8 << i, 254, 0);
362 do_test (2 * i, i, (8 << i) + 100, 8 << i, 254, 0);
364 do_test (i, 2 * i, 8 << i, 8 << i, 127, 1);
365 do_test (i, 2 * i, (8 << i) + 100, 8 << i, 127, 1);
367 do_test (2 * i, i, 8 << i, 8 << i, 254, 1);
368 do_test (2 * i, i, (8 << i) + 100, 8 << i, 254, 1);
370 do_test (i, 2 * i, 8 << i, 8 << i, 127, -1);
371 do_test (i, 2 * i, (8 << i) + 100, 8 << i, 127, -1);
373 do_test (2 * i, i, 8 << i, 8 << i, 254, -1);
374 do_test (2 * i, i, (8 << i) + 100, 8 << i, 254, -1);
377 do_random_tests ();
378 do_page_tests ();
382 test_main (void)
384 test_init ();
386 test_locale ("C");
387 test_locale ("en_US.ISO-8859-1");
388 test_locale ("en_US.UTF-8");
389 test_locale ("tr_TR.ISO-8859-9");
390 test_locale ("tr_TR.UTF-8");
392 return ret;
395 #include <support/test-driver.c>