Fix namespace violation in stdio.h and sys/stat.h if build with optimization. [BZ...
[glibc.git] / string / tst-cmp.c
blob13af0fcb83ecdaa2f872d1c161dfd948166a7c6c
1 /* Alignment/padding coverage test for string comparison.
2 Copyright (C) 2016-2020 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 /* This performs test comparisons with various (mis)alignments and
20 characters in the padding. It is partly a regression test for bug
21 20327. */
23 #include <limits.h>
24 #include <malloc.h>
25 #include <stdbool.h>
26 #include <stdint.h>
27 #include <stdlib.h>
28 #include <string.h>
29 #include <libc-diag.h>
31 static int
32 signum (int val)
34 if (val < 0)
35 return -1;
36 if (val > 0)
37 return 1;
38 else
39 return 0;
42 static size_t
43 max_size_t (size_t left, size_t right)
45 if (left > right)
46 return left;
47 else
48 return right;
51 /* Wrappers for strncmp and strncasecmp which determine the maximum
52 string length in some, either based on the input string length, or
53 using fixed constants. */
55 static int
56 strncmp_no_terminator (const char *left, const char *right)
58 size_t left_len = strlen (left);
59 size_t right_len = strlen (right);
60 return strncmp (left, right, max_size_t (left_len, right_len));
63 static int
64 strncasecmp_no_terminator (const char *left, const char *right)
66 size_t left_len = strlen (left);
67 size_t right_len = strlen (right);
68 return strncasecmp (left, right, max_size_t (left_len, right_len));
71 static int
72 strncmp_terminator (const char *left, const char *right)
74 size_t left_len = strlen (left);
75 size_t right_len = strlen (right);
76 return strncmp (left, right, max_size_t (left_len, right_len));
79 static int
80 strncasecmp_terminator (const char *left, const char *right)
82 size_t left_len = strlen (left);
83 size_t right_len = strlen (right);
84 return strncasecmp (left, right, max_size_t (left_len, right_len));
87 static int
88 strncmp_64 (const char *left, const char *right)
90 return strncmp (left, right, 64);
93 static int
94 strncasecmp_64 (const char *left, const char *right)
96 return strncasecmp (left, right, 64);
99 static int
100 strncmp_max (const char *left, const char *right)
102 DIAG_PUSH_NEEDS_COMMENT;
103 #if __GNUC_PREREQ (7, 0)
104 /* GCC 9 warns about the size passed to strncmp being larger than
105 PTRDIFF_MAX; the use of SIZE_MAX is deliberate here. */
106 DIAG_IGNORE_NEEDS_COMMENT (9, "-Wstringop-overflow=");
107 #endif
108 return strncmp (left, right, SIZE_MAX);
109 DIAG_POP_NEEDS_COMMENT;
112 static int
113 strncasecmp_max (const char *left, const char *right)
115 DIAG_PUSH_NEEDS_COMMENT;
116 #if __GNUC_PREREQ (7, 0)
117 /* GCC 9 warns about the size passed to strncasecmp being larger
118 than PTRDIFF_MAX; the use of SIZE_MAX is deliberate here. */
119 DIAG_IGNORE_NEEDS_COMMENT (9, "-Wstringop-overflow=");
120 #endif
121 return strncasecmp (left, right, SIZE_MAX);
122 DIAG_POP_NEEDS_COMMENT;
126 do_test (void)
128 enum {
129 max_align = 64,
130 max_string_length = 33
132 size_t blob_size = max_align + max_string_length + 1;
133 char *left = memalign (max_align, blob_size);
134 char *right = memalign (max_align, blob_size);
135 if (left == NULL || right == NULL)
137 printf ("error: out of memory\n");
138 return 1;
141 const struct
143 const char *name;
144 int (*implementation) (const char *, const char *);
145 } functions[] =
147 { "strcmp", strcmp },
148 { "strcasecmp", strcasecmp },
149 { "strncmp (without NUL)", strncmp_no_terminator},
150 { "strncasecmp (without NUL)", strncasecmp_no_terminator},
151 { "strncmp (with NUL)", strncmp_terminator},
152 { "strncasecmp (with NUL)", strncasecmp_terminator},
153 { "strncmp (length 64)", strncmp_64},
154 { "strncasecmp (length 64)", strncasecmp_64},
155 { "strncmp (length SIZE_MAX)", strncmp_max},
156 { "strncasecmp (length SIZE_MAX)", strncasecmp_max},
157 { NULL, NULL }
159 const char *const strings[] =
162 "0",
163 "01",
164 "01234567",
165 "0123456789abcde",
166 "0123456789abcdef",
167 "0123456789abcdefg",
168 "1",
169 "10",
170 "123456789abcdef",
171 "123456789abcdefg",
172 "23456789abcdef",
173 "23456789abcdefg",
174 "abcdefghijklmnopqrstuvwxyzABCDEF",
175 NULL
177 const unsigned char pads[] =
178 { 0, 1, 32, 64, 128, '0', '1', 'e', 'f', 'g', 127, 192, 255 };
180 bool errors = false;
181 for (int left_idx = 0; strings[left_idx] != NULL; ++left_idx)
182 for (int left_align = 0; left_align < max_align; ++left_align)
183 for (unsigned pad_left = 0; pad_left < sizeof (pads); ++pad_left)
185 memset (left, pads[pad_left], blob_size);
186 strcpy (left + left_align, strings[left_idx]);
188 for (int right_idx = 0; strings[right_idx] != NULL; ++right_idx)
189 for (unsigned pad_right = 0; pad_right < sizeof (pads);
190 ++pad_right)
191 for (int right_align = 0; right_align < max_align;
192 ++right_align)
194 memset (right, pads[pad_right], blob_size);
195 strcpy (right + right_align, strings[right_idx]);
197 for (int func = 0; functions[func].name != NULL; ++func)
199 int expected = left_idx - right_idx;
200 int actual = functions[func].implementation
201 (left + left_align, right + right_align);
202 if (signum (actual) != signum (expected))
204 printf ("error: mismatch for %s: %d\n"
205 " left: \"%s\"\n"
206 " right: \"%s\"\n"
207 " pad_left = %u, pad_right = %u,\n"
208 " left_align = %d, right_align = %d\n",
209 functions[func].name, actual,
210 strings[left_idx], strings[right_idx],
211 pad_left, pad_right,
212 left_align, right_align);
213 errors = true;
218 free (right);
219 free (left);
220 return errors;
223 /* The nested loops need a long time to complete on slower
224 machines. */
225 #define TIMEOUT 600
227 #include <support/test-driver.c>