1 | /* Test strncmp and wcsncmp functions. |
2 | Copyright (C) 1999-2024 Free Software Foundation, Inc. |
3 | This file is part of the GNU C Library. |
4 | |
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. |
9 | |
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. |
14 | |
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/>. */ |
18 | |
19 | #define TEST_LEN (getpagesize () * 3) |
20 | #define MIN_PAGE_SIZE (TEST_LEN + 2 * getpagesize ()) |
21 | |
22 | #define TEST_MAIN |
23 | #ifdef WIDE |
24 | # define TEST_NAME "wcsncmp" |
25 | #else |
26 | # define TEST_NAME "strncmp" |
27 | #endif |
28 | #define TIMEOUT (5 * 60) |
29 | #include "test-string.h" |
30 | |
31 | #ifdef WIDE |
32 | # include <wchar.h> |
33 | |
34 | # define L(str) L##str |
35 | # define STRNCMP wcsncmp |
36 | # define STRCPY wcscpy |
37 | # define STRDUP wcsdup |
38 | # define MEMCPY wmemcpy |
39 | # define SIMPLE_STRNCMP simple_wcsncmp |
40 | # define CHAR wchar_t |
41 | # define UCHAR wchar_t |
42 | # define CHARBYTES 4 |
43 | # define CHAR__MAX WCHAR_MAX |
44 | # define CHAR__MIN WCHAR_MIN |
45 | |
46 | /* Wcsncmp uses signed semantics for comparison, not unsigned. |
47 | Avoid using subtraction since possible overflow */ |
48 | int |
49 | simple_wcsncmp (const CHAR *s1, const CHAR *s2, size_t n) |
50 | { |
51 | wchar_t c1, c2; |
52 | |
53 | while (n--) |
54 | { |
55 | c1 = *s1++; |
56 | c2 = *s2++; |
57 | if (c1 == L('\0') || c1 != c2) |
58 | return c1 > c2 ? 1 : (c1 < c2 ? -1 : 0); |
59 | } |
60 | return 0; |
61 | } |
62 | |
63 | #else |
64 | # define L(str) str |
65 | # define STRNCMP strncmp |
66 | # define STRCPY strcpy |
67 | # define STRDUP strdup |
68 | # define MEMCPY memcpy |
69 | # define SIMPLE_STRNCMP simple_strncmp |
70 | # define CHAR char |
71 | # define UCHAR unsigned char |
72 | # define CHARBYTES 1 |
73 | # define CHAR__MAX CHAR_MAX |
74 | # define CHAR__MIN CHAR_MIN |
75 | |
76 | /* Strncmp uses unsigned semantics for comparison. */ |
77 | int |
78 | simple_strncmp (const char *s1, const char *s2, size_t n) |
79 | { |
80 | int ret = 0; |
81 | |
82 | while (n-- && (ret = *(unsigned char *) s1 - * (unsigned char *) s2++) == 0 |
83 | && *s1++); |
84 | return ret; |
85 | } |
86 | |
87 | #endif |
88 | |
89 | typedef int (*proto_t) (const CHAR *, const CHAR *, size_t); |
90 | |
91 | IMPL (STRNCMP, 1) |
92 | |
93 | /* Also check the default implementation. */ |
94 | #undef STRNCMP |
95 | #undef libc_hidden_builtin_def |
96 | #define libc_hidden_builtin_def(a) |
97 | #undef attribute_hidden |
98 | #define attribute_hidden |
99 | #ifndef WIDE |
100 | # define STRNCMP __strncmp_default |
101 | # include "string/strncmp.c" |
102 | # define STRNCMP_DEFAULT STRNCMP |
103 | #else |
104 | # define WCSNCMP __wcsncmp_default |
105 | # include "wcsmbs/wcsncmp.c" |
106 | # define STRNCMP_DEFAULT WCSNCMP |
107 | #endif |
108 | IMPL (STRNCMP_DEFAULT, 1) |
109 | |
110 | static int |
111 | check_result (impl_t *impl, const CHAR *s1, const CHAR *s2, size_t n, |
112 | int exp_result) |
113 | { |
114 | int result = CALL (impl, s1, s2, n); |
115 | if ((exp_result == 0 && result != 0) |
116 | || (exp_result < 0 && result >= 0) |
117 | || (exp_result > 0 && result <= 0)) |
118 | { |
119 | error (status: 0, errnum: 0, format: "Wrong result in function %s %d %d" , impl->name, |
120 | result, exp_result); |
121 | ret = 1; |
122 | return -1; |
123 | } |
124 | |
125 | return 0; |
126 | } |
127 | |
128 | static void |
129 | do_one_test (impl_t *impl, const CHAR *s1, const CHAR *s2, size_t n, |
130 | int exp_result) |
131 | { |
132 | if (check_result (impl, s1, s2, n, exp_result) < 0) |
133 | return; |
134 | } |
135 | |
136 | static void |
137 | do_test_limit (size_t align1, size_t align2, size_t len, size_t n, int max_char, |
138 | int exp_result) |
139 | { |
140 | size_t i, align_n; |
141 | CHAR *s1, *s2; |
142 | |
143 | align1 &= ~(CHARBYTES - 1); |
144 | align2 &= ~(CHARBYTES - 1); |
145 | |
146 | if (n == 0) |
147 | { |
148 | s1 = (CHAR *) (buf1 + page_size); |
149 | s2 = (CHAR *) (buf2 + page_size); |
150 | |
151 | FOR_EACH_IMPL (impl, 0) |
152 | do_one_test (impl, s1, s2, n, exp_result: 0); |
153 | |
154 | return; |
155 | } |
156 | |
157 | align1 &= 15; |
158 | align2 &= 15; |
159 | align_n = (page_size - n * CHARBYTES) & 15; |
160 | |
161 | s1 = (CHAR *) (buf1 + page_size - n * CHARBYTES); |
162 | s2 = (CHAR *) (buf2 + page_size - n * CHARBYTES); |
163 | |
164 | if (align1 < align_n) |
165 | s1 = (CHAR *) ((char *) s1 - (align_n - align1)); |
166 | |
167 | if (align2 < align_n) |
168 | s2 = (CHAR *) ((char *) s2 - (align_n - align2)); |
169 | |
170 | for (i = 0; i < n; i++) |
171 | s1[i] = s2[i] = 1 + 23 * i % max_char; |
172 | |
173 | if (len < n) |
174 | { |
175 | s1[len] = 0; |
176 | s2[len] = 0; |
177 | if (exp_result < 0) |
178 | s2[len] = 32; |
179 | else if (exp_result > 0) |
180 | s1[len] = 64; |
181 | } |
182 | |
183 | FOR_EACH_IMPL (impl, 0) |
184 | do_one_test (impl, s1, s2, n, exp_result); |
185 | } |
186 | |
187 | static void |
188 | do_test_n (size_t align1, size_t align2, size_t len, size_t n, int n_in_bounds, |
189 | int max_char, int exp_result) |
190 | { |
191 | size_t i, buf_bound; |
192 | CHAR *s1, *s2, *s1_end, *s2_end; |
193 | |
194 | align1 &= ~(CHARBYTES - 1); |
195 | align2 &= ~(CHARBYTES - 1); |
196 | |
197 | if (n == 0) |
198 | return; |
199 | |
200 | buf_bound = n_in_bounds ? n : len; |
201 | |
202 | align1 &= getpagesize () - 1; |
203 | if (align1 + (buf_bound + 2) * CHARBYTES >= page_size) |
204 | return; |
205 | |
206 | align2 &= getpagesize () - 1; |
207 | if (align2 + (buf_bound + 2) * CHARBYTES >= page_size) |
208 | return; |
209 | |
210 | s1 = (CHAR *)(buf1 + align1); |
211 | s2 = (CHAR *)(buf2 + align2); |
212 | |
213 | if (n_in_bounds) |
214 | { |
215 | s1[n] = 24 + exp_result; |
216 | s2[n] = 23; |
217 | } |
218 | |
219 | for (i = 0; i < buf_bound; i++) |
220 | s1[i] = s2[i] = 1 + (23 << ((CHARBYTES - 1) * 8)) * i % max_char; |
221 | |
222 | s1[len] = 0; |
223 | s2[len] = 0; |
224 | if (exp_result < 0) |
225 | s2[len] = 32; |
226 | else if (exp_result > 0) |
227 | s1[len] = 64; |
228 | if (len >= n) |
229 | s2[n - 1] -= exp_result; |
230 | |
231 | /* Ensure that both s1 and s2 are valid null terminated strings. This is |
232 | * required by the standard. */ |
233 | s1_end = (CHAR *)(buf1 + MIN_PAGE_SIZE - CHARBYTES); |
234 | s2_end = (CHAR *)(buf2 + MIN_PAGE_SIZE - CHARBYTES); |
235 | *s1_end = 0; |
236 | *s2_end = 0; |
237 | |
238 | FOR_EACH_IMPL (impl, 0) |
239 | do_one_test (impl, s1, s2, n, exp_result); |
240 | } |
241 | |
242 | static void |
243 | do_test (size_t align1, size_t align2, size_t len, size_t n, int max_char, |
244 | int exp_result) |
245 | { |
246 | do_test_n (align1, align2, len, n, n_in_bounds: 1, max_char, exp_result); |
247 | } |
248 | |
249 | static void |
250 | do_page_test (size_t offset1, size_t offset2, CHAR *s2) |
251 | { |
252 | CHAR *s1; |
253 | int exp_result; |
254 | |
255 | if (offset1 * CHARBYTES >= page_size || offset2 * CHARBYTES >= page_size) |
256 | return; |
257 | |
258 | s1 = (CHAR *) buf1; |
259 | s1 += offset1; |
260 | s2 += offset2; |
261 | |
262 | exp_result= *s1; |
263 | |
264 | FOR_EACH_IMPL (impl, 0) |
265 | { |
266 | check_result (impl, s1, s2, n: page_size, exp_result: -exp_result); |
267 | check_result (impl, s1: s2, s2: s1, n: page_size, exp_result); |
268 | } |
269 | } |
270 | |
271 | static void |
272 | do_random_tests (void) |
273 | { |
274 | size_t i, j, n, align1, align2, pos, len1, len2, size; |
275 | int result; |
276 | long r; |
277 | UCHAR *p1 = (UCHAR *) (buf1 + page_size - 512 * CHARBYTES); |
278 | UCHAR *p2 = (UCHAR *) (buf2 + page_size - 512 * CHARBYTES); |
279 | |
280 | for (n = 0; n < ITERATIONS; n++) |
281 | { |
282 | align1 = random () & 31; |
283 | if (random () & 1) |
284 | align2 = random () & 31; |
285 | else |
286 | align2 = align1 + (random () & 24); |
287 | pos = random () & 511; |
288 | size = random () & 511; |
289 | j = align1 > align2 ? align1 : align2; |
290 | if (pos + j >= 511) |
291 | pos = 510 - j - (random () & 7); |
292 | len1 = random () & 511; |
293 | if (pos >= len1 && (random () & 1)) |
294 | len1 = pos + (random () & 7); |
295 | if (len1 + j >= 512) |
296 | len1 = 511 - j - (random () & 7); |
297 | if (pos >= len1) |
298 | len2 = len1; |
299 | else |
300 | len2 = len1 + (len1 != 511 - j ? random () % (511 - j - len1) : 0); |
301 | j = (pos > len2 ? pos : len2) + align1 + 64; |
302 | if (j > 512) |
303 | j = 512; |
304 | for (i = 0; i < j; ++i) |
305 | { |
306 | p1[i] = random () & 255; |
307 | if (i < len1 + align1 && !p1[i]) |
308 | { |
309 | p1[i] = random () & 255; |
310 | if (!p1[i]) |
311 | p1[i] = 1 + (random () & 127); |
312 | } |
313 | } |
314 | for (i = 0; i < j; ++i) |
315 | { |
316 | p2[i] = random () & 255; |
317 | if (i < len2 + align2 && !p2[i]) |
318 | { |
319 | p2[i] = random () & 255; |
320 | if (!p2[i]) |
321 | p2[i] = 1 + (random () & 127); |
322 | } |
323 | } |
324 | |
325 | result = 0; |
326 | MEMCPY (p2 + align2, p1 + align1, pos); |
327 | if (pos < len1) |
328 | { |
329 | if (p2[align2 + pos] == p1[align1 + pos]) |
330 | { |
331 | p2[align2 + pos] = random () & 255; |
332 | if (p2[align2 + pos] == p1[align1 + pos]) |
333 | p2[align2 + pos] = p1[align1 + pos] + 3 + (random () & 127); |
334 | } |
335 | |
336 | if (pos < size) |
337 | { |
338 | if (p1[align1 + pos] < p2[align2 + pos]) |
339 | result = -1; |
340 | else |
341 | result = 1; |
342 | } |
343 | } |
344 | p1[len1 + align1] = 0; |
345 | p2[len2 + align2] = 0; |
346 | |
347 | FOR_EACH_IMPL (impl, 1) |
348 | { |
349 | r = CALL (impl, (CHAR *) (p1 + align1), (CHAR *) (p2 + align2), size); |
350 | /* Test whether on 64-bit architectures where ABI requires |
351 | callee to promote has the promotion been done. */ |
352 | asm ("" : "=g" (r) : "0" (r)); |
353 | if ((r == 0 && result) |
354 | || (r < 0 && result >= 0) |
355 | || (r > 0 && result <= 0)) |
356 | { |
357 | error (status: 0, errnum: 0, format: "Iteration %zd - wrong result in function %s (%zd, %zd, %zd, %zd, %zd, %zd) %ld != %d, p1 %p p2 %p" , |
358 | n, impl->name, align1, align2, len1, len2, pos, size, r, result, p1, p2); |
359 | ret = 1; |
360 | } |
361 | } |
362 | } |
363 | } |
364 | |
365 | static void |
366 | check1 (void) |
367 | { |
368 | CHAR *s1 = (CHAR *) (buf1 + 0xb2c); |
369 | CHAR *s2 = (CHAR *) (buf1 + 0xfd8); |
370 | size_t i, offset; |
371 | int exp_result; |
372 | |
373 | STRCPY(s1, L("abcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrs" )); |
374 | STRCPY(s2, L("abcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijkLMNOPQRSTUV" )); |
375 | |
376 | /* Check possible overflow bug for wcsncmp */ |
377 | s1[4] = CHAR__MAX; |
378 | s2[4] = CHAR__MIN; |
379 | |
380 | for (offset = 0; offset < 6; offset++) |
381 | { |
382 | for (i = 0; i < 80; i++) |
383 | { |
384 | exp_result = SIMPLE_STRNCMP (s1: s1 + offset, s2: s2 + offset, n: i); |
385 | FOR_EACH_IMPL (impl, 0) |
386 | check_result (impl, s1: s1 + offset, s2: s2 + offset, n: i, exp_result); |
387 | } |
388 | } |
389 | } |
390 | |
391 | static void |
392 | check2 (void) |
393 | { |
394 | size_t i; |
395 | CHAR *s1, *s2; |
396 | |
397 | s1 = (CHAR *) buf1; |
398 | for (i = 0; i < (page_size / CHARBYTES) - 1; i++) |
399 | s1[i] = 23; |
400 | s1[i] = 0; |
401 | |
402 | s2 = STRDUP (s: s1); |
403 | |
404 | for (i = 0; i < 64; ++i) |
405 | do_page_test (offset1: (3988 / CHARBYTES) + i, offset2: (2636 / CHARBYTES), s2); |
406 | |
407 | free (ptr: s2); |
408 | } |
409 | |
410 | static void |
411 | check3 (void) |
412 | { |
413 | /* To trigger bug 25933, we need a size that is equal to the vector |
414 | length times 4. In the case of AVX2 for Intel, we need 32 * 4. We |
415 | make this test generic and run it for all architectures as additional |
416 | boundary testing for such related algorithms. */ |
417 | size_t size = 32 * 4; |
418 | CHAR *s1 = (CHAR *) (buf1 + (BUF1PAGES - 1) * page_size); |
419 | CHAR *s2 = (CHAR *) (buf2 + (BUF1PAGES - 1) * page_size); |
420 | int exp_result; |
421 | |
422 | memset (s1, 'a', page_size); |
423 | memset (s2, 'a', page_size); |
424 | s1[(page_size / CHARBYTES) - 1] = (CHAR) 0; |
425 | |
426 | /* Iterate over a size that is just below where we expect the bug to |
427 | trigger up to the size we expect will trigger the bug e.g. [99-128]. |
428 | Likewise iterate the start of two strings between 30 and 31 bytes |
429 | away from the boundary to simulate alignment changes. */ |
430 | for (size_t s = 99; s <= size; s++) |
431 | for (size_t s1a = 30; s1a < 32; s1a++) |
432 | for (size_t s2a = 30; s2a < 32; s2a++) |
433 | { |
434 | CHAR *s1p = s1 + (page_size / CHARBYTES - s) - s1a; |
435 | CHAR *s2p = s2 + (page_size / CHARBYTES - s) - s2a; |
436 | exp_result = SIMPLE_STRNCMP (s1: s1p, s2: s2p, n: s); |
437 | FOR_EACH_IMPL (impl, 0) |
438 | check_result (impl, s1: s1p, s2: s2p, n: s, exp_result); |
439 | } |
440 | } |
441 | |
442 | static void |
443 | check4 (void) |
444 | { |
445 | /* To trigger bug 28895; We need 1) both s1 and s2 to be within 32 bytes of |
446 | the end of the page. 2) For there to be no mismatch/null byte before the |
447 | first page cross. 3) For length (`n`) to be large enough for one string to |
448 | cross the page. And 4) for there to be either mismatch/null bytes before |
449 | the start of the strings. */ |
450 | |
451 | size_t size = 10; |
452 | size_t addr_mask = (getpagesize () - 1) ^ (sizeof (CHAR) - 1); |
453 | CHAR *s1 = (CHAR *)(buf1 + (addr_mask & 0xffa)); |
454 | CHAR *s2 = (CHAR *)(buf2 + (addr_mask & 0xfed)); |
455 | int exp_result; |
456 | |
457 | STRCPY (s1, L ("tst-tlsmod%" )); |
458 | STRCPY (s2, L ("tst-tls-manydynamic73mod" )); |
459 | exp_result = SIMPLE_STRNCMP (s1, s2, n: size); |
460 | FOR_EACH_IMPL (impl, 0) |
461 | check_result (impl, s1, s2, n: size, exp_result); |
462 | } |
463 | |
464 | static void |
465 | check5 (void) |
466 | { |
467 | const CHAR *s1 = L ("abc" ); |
468 | CHAR *s2 = STRDUP (s: s1); |
469 | |
470 | FOR_EACH_IMPL (impl, 0) |
471 | check_result (impl, s1, s2, SIZE_MAX, exp_result: 0); |
472 | |
473 | free (ptr: s2); |
474 | } |
475 | |
476 | static void |
477 | check_overflow (void) |
478 | { |
479 | size_t i, j, of_mask, of_idx; |
480 | const size_t of_masks[] |
481 | = { ULONG_MAX, LONG_MIN, ULONG_MAX - (ULONG_MAX >> 2), |
482 | ((size_t)LONG_MAX) >> 1 }; |
483 | const size_t test_len = MIN(TEST_LEN, 3 * 4096); |
484 | for (of_idx = 0; of_idx < sizeof (of_masks) / sizeof (of_masks[0]); ++of_idx) |
485 | { |
486 | of_mask = of_masks[of_idx]; |
487 | for (j = 0; j < 160; ++j) |
488 | { |
489 | for (i = 1; i <= 161; i += (32 / sizeof (CHAR))) |
490 | { |
491 | do_test_n (align1: j, align2: 0, len: i, n: of_mask, n_in_bounds: 0, max_char: 127, exp_result: 0); |
492 | do_test_n (align1: j, align2: 0, len: i, n: of_mask, n_in_bounds: 0, max_char: 127, exp_result: 1); |
493 | do_test_n (align1: j, align2: 0, len: i, n: of_mask, n_in_bounds: 0, max_char: 127, exp_result: -1); |
494 | |
495 | do_test_n (align1: j, align2: 0, len: i, n: of_mask - j / 2, n_in_bounds: 0, max_char: 127, exp_result: 0); |
496 | do_test_n (align1: j, align2: 0, len: i, n: of_mask - j * 2, n_in_bounds: 0, max_char: 127, exp_result: 1); |
497 | do_test_n (align1: j, align2: 0, len: i, n: of_mask - j, n_in_bounds: 0, max_char: 127, exp_result: -1); |
498 | |
499 | do_test_n (align1: j / 2, align2: j, len: i, n: of_mask, n_in_bounds: 0, max_char: 127, exp_result: 0); |
500 | do_test_n (align1: j / 2, align2: j, len: i, n: of_mask, n_in_bounds: 0, max_char: 127, exp_result: 1); |
501 | do_test_n (align1: j / 2, align2: j, len: i, n: of_mask, n_in_bounds: 0, max_char: 127, exp_result: -1); |
502 | |
503 | do_test_n (align1: j / 2, align2: j, len: i, n: of_mask - j, n_in_bounds: 0, max_char: 127, exp_result: 0); |
504 | do_test_n (align1: j / 2, align2: j, len: i, n: of_mask - j / 2, n_in_bounds: 0, max_char: 127, exp_result: 1); |
505 | do_test_n (align1: j / 2, align2: j, len: i, n: of_mask - j * 2, n_in_bounds: 0, max_char: 127, exp_result: -1); |
506 | |
507 | do_test_n (align1: 0, align2: j, len: i, n: of_mask - j * 2, n_in_bounds: 0, max_char: 127, exp_result: 0); |
508 | do_test_n (align1: 0, align2: j, len: i, n: of_mask - j, n_in_bounds: 0, max_char: 127, exp_result: 1); |
509 | do_test_n (align1: 0, align2: j, len: i, n: of_mask - j / 2, n_in_bounds: 0, max_char: 127, exp_result: -1); |
510 | |
511 | do_test_n (align1: getpagesize () - j - 1, align2: 0, len: i, n: of_mask, n_in_bounds: 0, max_char: 127, exp_result: 0); |
512 | do_test_n (align1: getpagesize () - j - 1, align2: 0, len: i, n: of_mask, n_in_bounds: 0, max_char: 127, exp_result: 1); |
513 | do_test_n (align1: getpagesize () - j - 1, align2: 0, len: i, n: of_mask, n_in_bounds: 0, max_char: 127, exp_result: -1); |
514 | |
515 | do_test_n (align1: getpagesize () - j - 1, align2: 0, len: i, n: of_mask - j / 2, n_in_bounds: 0, max_char: 127, |
516 | exp_result: 0); |
517 | do_test_n (align1: getpagesize () - j - 1, align2: 0, len: i, n: of_mask - j * 2, n_in_bounds: 0, max_char: 127, |
518 | exp_result: 1); |
519 | do_test_n (align1: getpagesize () - j - 1, align2: 0, len: i, n: of_mask - j, n_in_bounds: 0, max_char: 127, |
520 | exp_result: -1); |
521 | |
522 | do_test_n (align1: getpagesize () - j - 1, align2: getpagesize () - 2 * j - 1, len: i, |
523 | n: of_mask, n_in_bounds: 0, max_char: 127, exp_result: 0); |
524 | do_test_n (align1: getpagesize () - j - 1, align2: getpagesize () - 2 * j - 1, len: i, |
525 | n: of_mask, n_in_bounds: 0, max_char: 127, exp_result: 1); |
526 | do_test_n (align1: getpagesize () - j - 1, align2: getpagesize () - 2 * j - 1, len: i, |
527 | n: of_mask, n_in_bounds: 0, max_char: 127, exp_result: -1); |
528 | |
529 | do_test_n (align1: getpagesize () - j - 1, align2: getpagesize () - 2 * j - 1, len: i, |
530 | n: of_mask - j, n_in_bounds: 0, max_char: 127, exp_result: 0); |
531 | do_test_n (align1: getpagesize () - j - 1, align2: getpagesize () - 2 * j - 1, len: i, |
532 | n: of_mask - j / 2, n_in_bounds: 0, max_char: 127, exp_result: 1); |
533 | do_test_n (align1: getpagesize () - j - 1, align2: getpagesize () - 2 * j - 1, len: i, |
534 | n: of_mask - j * 2, n_in_bounds: 0, max_char: 127, exp_result: -1); |
535 | } |
536 | |
537 | for (i = 1; i < test_len; i += i) |
538 | { |
539 | do_test_n (align1: j, align2: 0, len: i - 1, n: of_mask, n_in_bounds: 0, max_char: 127, exp_result: 0); |
540 | do_test_n (align1: j, align2: 0, len: i - 1, n: of_mask, n_in_bounds: 0, max_char: 127, exp_result: 1); |
541 | do_test_n (align1: j, align2: 0, len: i - 1, n: of_mask, n_in_bounds: 0, max_char: 127, exp_result: -1); |
542 | |
543 | do_test_n (align1: j, align2: 0, len: i - 1, n: of_mask - j / 2, n_in_bounds: 0, max_char: 127, exp_result: 0); |
544 | do_test_n (align1: j, align2: 0, len: i - 1, n: of_mask - j * 2, n_in_bounds: 0, max_char: 127, exp_result: 1); |
545 | do_test_n (align1: j, align2: 0, len: i - 1, n: of_mask - j, n_in_bounds: 0, max_char: 127, exp_result: -1); |
546 | |
547 | do_test_n (align1: j / 2, align2: j, len: i - 1, n: of_mask, n_in_bounds: 0, max_char: 127, exp_result: 0); |
548 | do_test_n (align1: j / 2, align2: j, len: i - 1, n: of_mask, n_in_bounds: 0, max_char: 127, exp_result: 1); |
549 | do_test_n (align1: j / 2, align2: j, len: i - 1, n: of_mask, n_in_bounds: 0, max_char: 127, exp_result: -1); |
550 | |
551 | do_test_n (align1: j / 2, align2: j, len: i - 1, n: of_mask - j, n_in_bounds: 0, max_char: 127, exp_result: 0); |
552 | do_test_n (align1: j / 2, align2: j, len: i - 1, n: of_mask - j / 2, n_in_bounds: 0, max_char: 127, exp_result: 1); |
553 | do_test_n (align1: j / 2, align2: j, len: i - 1, n: of_mask - j * 2, n_in_bounds: 0, max_char: 127, exp_result: -1); |
554 | |
555 | do_test_n (align1: 0, align2: j, len: i - 1, n: of_mask - j * 2, n_in_bounds: 0, max_char: 127, exp_result: 0); |
556 | do_test_n (align1: 0, align2: j, len: i - 1, n: of_mask - j, n_in_bounds: 0, max_char: 127, exp_result: 1); |
557 | do_test_n (align1: 0, align2: j, len: i - 1, n: of_mask - j / 2, n_in_bounds: 0, max_char: 127, exp_result: -1); |
558 | |
559 | do_test_n (align1: getpagesize () - j - 1, align2: 0, len: i - 1, n: of_mask, n_in_bounds: 0, max_char: 127, exp_result: 0); |
560 | do_test_n (align1: getpagesize () - j - 1, align2: 0, len: i - 1, n: of_mask, n_in_bounds: 0, max_char: 127, exp_result: 1); |
561 | do_test_n (align1: getpagesize () - j - 1, align2: 0, len: i - 1, n: of_mask, n_in_bounds: 0, max_char: 127, |
562 | exp_result: -1); |
563 | |
564 | do_test_n (align1: getpagesize () - j - 1, align2: 0, len: i - 1, n: of_mask - j / 2, n_in_bounds: 0, |
565 | max_char: 127, exp_result: 0); |
566 | do_test_n (align1: getpagesize () - j - 1, align2: 0, len: i - 1, n: of_mask - j * 2, n_in_bounds: 0, |
567 | max_char: 127, exp_result: 1); |
568 | do_test_n (align1: getpagesize () - j - 1, align2: 0, len: i - 1, n: of_mask - j, n_in_bounds: 0, max_char: 127, |
569 | exp_result: -1); |
570 | |
571 | do_test_n (align1: getpagesize () - j - 1, align2: getpagesize () - 2 * j - 1, |
572 | len: i - 1, n: of_mask, n_in_bounds: 0, max_char: 127, exp_result: 0); |
573 | do_test_n (align1: getpagesize () - j - 1, align2: getpagesize () - 2 * j - 1, |
574 | len: i - 1, n: of_mask, n_in_bounds: 0, max_char: 127, exp_result: 1); |
575 | do_test_n (align1: getpagesize () - j - 1, align2: getpagesize () - 2 * j - 1, |
576 | len: i - 1, n: of_mask, n_in_bounds: 0, max_char: 127, exp_result: -1); |
577 | |
578 | do_test_n (align1: getpagesize () - j - 1, align2: getpagesize () - 2 * j - 1, |
579 | len: i - 1, n: of_mask - j, n_in_bounds: 0, max_char: 127, exp_result: 0); |
580 | do_test_n (align1: getpagesize () - j - 1, align2: getpagesize () - 2 * j - 1, |
581 | len: i - 1, n: of_mask - j / 2, n_in_bounds: 0, max_char: 127, exp_result: 1); |
582 | do_test_n (align1: getpagesize () - j - 1, align2: getpagesize () - 2 * j - 1, |
583 | len: i - 1, n: of_mask - j * 2, n_in_bounds: 0, max_char: 127, exp_result: -1); |
584 | } |
585 | } |
586 | } |
587 | } |
588 | |
589 | int |
590 | test_main (void) |
591 | { |
592 | size_t i, j, k; |
593 | const size_t test_len = MIN(TEST_LEN, 3 * 4096); |
594 | test_init (); |
595 | |
596 | check1 (); |
597 | check2 (); |
598 | check3 (); |
599 | check4 (); |
600 | check5 (); |
601 | |
602 | printf (format: "%23s" , "" ); |
603 | FOR_EACH_IMPL (impl, 0) |
604 | printf (format: "\t%s" , impl->name); |
605 | putchar (c: '\n'); |
606 | |
607 | for (i =0; i < 16; ++i) |
608 | { |
609 | do_test (align1: 0, align2: 0, len: 8, n: i, max_char: 127, exp_result: 0); |
610 | do_test (align1: 0, align2: 0, len: 8, n: i, max_char: 127, exp_result: -1); |
611 | do_test (align1: 0, align2: 0, len: 8, n: i, max_char: 127, exp_result: 1); |
612 | do_test (align1: i, align2: i, len: 8, n: i, max_char: 127, exp_result: 0); |
613 | do_test (align1: i, align2: i, len: 8, n: i, max_char: 127, exp_result: 1); |
614 | do_test (align1: i, align2: i, len: 8, n: i, max_char: 127, exp_result: -1); |
615 | do_test (align1: i, align2: 2 * i, len: 8, n: i, max_char: 127, exp_result: 0); |
616 | do_test (align1: 2 * i, align2: i, len: 8, n: i, max_char: 127, exp_result: 1); |
617 | do_test (align1: i, align2: 3 * i, len: 8, n: i, max_char: 127, exp_result: -1); |
618 | do_test (align1: 0, align2: 0, len: 8, n: i, max_char: 255, exp_result: 0); |
619 | do_test (align1: 0, align2: 0, len: 8, n: i, max_char: 255, exp_result: -1); |
620 | do_test (align1: 0, align2: 0, len: 8, n: i, max_char: 255, exp_result: 1); |
621 | do_test (align1: i, align2: i, len: 8, n: i, max_char: 255, exp_result: 0); |
622 | do_test (align1: i, align2: i, len: 8, n: i, max_char: 255, exp_result: 1); |
623 | do_test (align1: i, align2: i, len: 8, n: i, max_char: 255, exp_result: -1); |
624 | do_test (align1: i, align2: 2 * i, len: 8, n: i, max_char: 255, exp_result: 0); |
625 | do_test (align1: 2 * i, align2: i, len: 8, n: i, max_char: 255, exp_result: 1); |
626 | do_test (align1: i, align2: 3 * i, len: 8, n: i, max_char: 255, exp_result: -1); |
627 | } |
628 | |
629 | for (i = 1; i < 8; ++i) |
630 | { |
631 | do_test (align1: 0, align2: 0, len: 8 << i, n: 16 << i, max_char: 127, exp_result: 0); |
632 | do_test (align1: 0, align2: 0, len: 8 << i, n: 16 << i, max_char: 127, exp_result: 1); |
633 | do_test (align1: 0, align2: 0, len: 8 << i, n: 16 << i, max_char: 127, exp_result: -1); |
634 | do_test (align1: 0, align2: 0, len: 8 << i, n: 16 << i, max_char: 255, exp_result: 0); |
635 | do_test (align1: 0, align2: 0, len: 8 << i, n: 16 << i, max_char: 255, exp_result: 1); |
636 | do_test (align1: 0, align2: 0, len: 8 << i, n: 16 << i, max_char: 255, exp_result: -1); |
637 | do_test (align1: 8 - i, align2: 2 * i, len: 8 << i, n: 16 << i, max_char: 127, exp_result: 0); |
638 | do_test (align1: 8 - i, align2: 2 * i, len: 8 << i, n: 16 << i, max_char: 127, exp_result: 1); |
639 | do_test (align1: 2 * i, align2: i, len: 8 << i, n: 16 << i, max_char: 255, exp_result: 0); |
640 | do_test (align1: 2 * i, align2: i, len: 8 << i, n: 16 << i, max_char: 255, exp_result: 1); |
641 | } |
642 | |
643 | do_test_limit (align1: 0, align2: 0, len: 0, n: 0, max_char: 127, exp_result: 0); |
644 | do_test_limit (align1: 4, align2: 0, len: 21, n: 20, max_char: 127, exp_result: 0); |
645 | do_test_limit (align1: 0, align2: 4, len: 21, n: 20, max_char: 127, exp_result: 0); |
646 | do_test_limit (align1: 8, align2: 0, len: 25, n: 24, max_char: 127, exp_result: 0); |
647 | do_test_limit (align1: 0, align2: 8, len: 25, n: 24, max_char: 127, exp_result: 0); |
648 | |
649 | for (i = 0; i < 8; ++i) |
650 | { |
651 | do_test_limit (align1: 0, align2: 0, len: 17 - i, n: 16 - i, max_char: 127, exp_result: 0); |
652 | do_test_limit (align1: 0, align2: 0, len: 17 - i, n: 16 - i, max_char: 255, exp_result: 0); |
653 | do_test_limit (align1: 0, align2: 0, len: 15 - i, n: 16 - i, max_char: 127, exp_result: 0); |
654 | do_test_limit (align1: 0, align2: 0, len: 15 - i, n: 16 - i, max_char: 127, exp_result: 1); |
655 | do_test_limit (align1: 0, align2: 0, len: 15 - i, n: 16 - i, max_char: 127, exp_result: -1); |
656 | do_test_limit (align1: 0, align2: 0, len: 15 - i, n: 16 - i, max_char: 255, exp_result: 0); |
657 | do_test_limit (align1: 0, align2: 0, len: 15 - i, n: 16 - i, max_char: 255, exp_result: 1); |
658 | do_test_limit (align1: 0, align2: 0, len: 15 - i, n: 16 - i, max_char: 255, exp_result: -1); |
659 | } |
660 | |
661 | for (j = 0; j < 160; ++j) |
662 | { |
663 | for (i = 0; i < test_len;) |
664 | { |
665 | do_test_n (align1: getpagesize () - j - 1, align2: 0, len: i, n: i + 1, n_in_bounds: 0, max_char: 127, exp_result: 0); |
666 | do_test_n (align1: getpagesize () - j - 1, align2: 0, len: i, n: i + 1, n_in_bounds: 0, max_char: 127, exp_result: 1); |
667 | do_test_n (align1: getpagesize () - j - 1, align2: 0, len: i, n: i + 1, n_in_bounds: 0, max_char: 127, exp_result: -1); |
668 | |
669 | do_test_n (align1: getpagesize () - j - 1, align2: 0, len: i, n: i, n_in_bounds: 0, max_char: 127, exp_result: 0); |
670 | do_test_n (align1: getpagesize () - j - 1, align2: 0, len: i, n: i - 1, n_in_bounds: 0, max_char: 127, exp_result: 0); |
671 | |
672 | do_test_n (align1: getpagesize () - j - 1, align2: 0, len: i, ULONG_MAX, n_in_bounds: 0, max_char: 127, exp_result: 0); |
673 | do_test_n (align1: getpagesize () - j - 1, align2: 0, len: i, ULONG_MAX, n_in_bounds: 0, max_char: 127, exp_result: 1); |
674 | do_test_n (align1: getpagesize () - j - 1, align2: 0, len: i, ULONG_MAX, n_in_bounds: 0, max_char: 127, exp_result: -1); |
675 | |
676 | do_test_n (align1: getpagesize () - j - 1, align2: 0, len: i, ULONG_MAX - i, n_in_bounds: 0, max_char: 127, exp_result: 0); |
677 | do_test_n (align1: getpagesize () - j - 1, align2: 0, len: i, ULONG_MAX - i, n_in_bounds: 0, max_char: 127, exp_result: 1); |
678 | do_test_n (align1: getpagesize () - j - 1, align2: 0, len: i, ULONG_MAX - i, n_in_bounds: 0, max_char: 127, exp_result: -1); |
679 | |
680 | do_test_n (align1: getpagesize () - j - 1, align2: j, len: i, n: i + 1, n_in_bounds: 0, max_char: 127, exp_result: 0); |
681 | do_test_n (align1: getpagesize () - j - 1, align2: j, len: i, n: i + 1, n_in_bounds: 0, max_char: 127, exp_result: 1); |
682 | do_test_n (align1: getpagesize () - j - 1, align2: j, len: i, n: i + 1, n_in_bounds: 0, max_char: 127, exp_result: -1); |
683 | |
684 | do_test_n (align1: getpagesize () - j - 1, align2: j, len: i, n: i, n_in_bounds: 0, max_char: 127, exp_result: 0); |
685 | do_test_n (align1: getpagesize () - j - 1, align2: j, len: i, n: i - 1, n_in_bounds: 0, max_char: 127, exp_result: 0); |
686 | |
687 | do_test_n (align1: getpagesize () - j - 1, align2: j, len: i, ULONG_MAX, n_in_bounds: 0, max_char: 127, exp_result: 0); |
688 | do_test_n (align1: getpagesize () - j - 1, align2: j, len: i, ULONG_MAX, n_in_bounds: 0, max_char: 127, exp_result: 1); |
689 | do_test_n (align1: getpagesize () - j - 1, align2: j, len: i, ULONG_MAX, n_in_bounds: 0, max_char: 127, exp_result: -1); |
690 | |
691 | do_test_n (align1: getpagesize () - j - 1, align2: j, len: i, ULONG_MAX - i, n_in_bounds: 0, max_char: 127, exp_result: 0); |
692 | do_test_n (align1: getpagesize () - j - 1, align2: j, len: i, ULONG_MAX - i, n_in_bounds: 0, max_char: 127, exp_result: 1); |
693 | do_test_n (align1: getpagesize () - j - 1, align2: j, len: i, ULONG_MAX - i, n_in_bounds: 0, max_char: 127, exp_result: -1); |
694 | |
695 | do_test_n (align1: 0, align2: getpagesize () - j - 1, len: i, n: i + 1, n_in_bounds: 0, max_char: 127, exp_result: 0); |
696 | do_test_n (align1: 0, align2: getpagesize () - j - 1, len: i, n: i + 1, n_in_bounds: 0, max_char: 127, exp_result: 1); |
697 | do_test_n (align1: 0, align2: getpagesize () - j - 1, len: i, n: i + 1, n_in_bounds: 0, max_char: 127, exp_result: -1); |
698 | |
699 | do_test_n (align1: 0, align2: getpagesize () - j - 1, len: i, n: i, n_in_bounds: 0, max_char: 127, exp_result: 0); |
700 | do_test_n (align1: 0, align2: getpagesize () - j - 1, len: i, n: i - 1, n_in_bounds: 0, max_char: 127, exp_result: 0); |
701 | |
702 | do_test_n (align1: 0, align2: getpagesize () - j - 1, len: i, ULONG_MAX, n_in_bounds: 0, max_char: 127, exp_result: 0); |
703 | do_test_n (align1: 0, align2: getpagesize () - j - 1, len: i, ULONG_MAX, n_in_bounds: 0, max_char: 127, exp_result: 1); |
704 | do_test_n (align1: 0, align2: getpagesize () - j - 1, len: i, ULONG_MAX, n_in_bounds: 0, max_char: 127, exp_result: -1); |
705 | |
706 | do_test_n (align1: 0, align2: getpagesize () - j - 1, len: i, ULONG_MAX - i, n_in_bounds: 0, max_char: 127, exp_result: 0); |
707 | do_test_n (align1: 0, align2: getpagesize () - j - 1, len: i, ULONG_MAX - i, n_in_bounds: 0, max_char: 127, exp_result: 1); |
708 | do_test_n (align1: 0, align2: getpagesize () - j - 1, len: i, ULONG_MAX - i, n_in_bounds: 0, max_char: 127, exp_result: -1); |
709 | |
710 | do_test_n (align1: j, align2: getpagesize () - j - 1, len: i, n: i + 1, n_in_bounds: 0, max_char: 127, exp_result: 0); |
711 | do_test_n (align1: j, align2: getpagesize () - j - 1, len: i, n: i + 1, n_in_bounds: 0, max_char: 127, exp_result: 1); |
712 | do_test_n (align1: j, align2: getpagesize () - j - 1, len: i, n: i + 1, n_in_bounds: 0, max_char: 127, exp_result: -1); |
713 | |
714 | do_test_n (align1: j, align2: getpagesize () - j - 1, len: i, n: i, n_in_bounds: 0, max_char: 127, exp_result: 0); |
715 | do_test_n (align1: j, align2: getpagesize () - j - 1, len: i, n: i - 1, n_in_bounds: 0, max_char: 127, exp_result: 0); |
716 | |
717 | do_test_n (align1: j, align2: getpagesize () - j - 1, len: i, ULONG_MAX, n_in_bounds: 0, max_char: 127, exp_result: 0); |
718 | do_test_n (align1: j, align2: getpagesize () - j - 1, len: i, ULONG_MAX, n_in_bounds: 0, max_char: 127, exp_result: 1); |
719 | do_test_n (align1: j, align2: getpagesize () - j - 1, len: i, ULONG_MAX, n_in_bounds: 0, max_char: 127, exp_result: -1); |
720 | |
721 | do_test_n (align1: j, align2: getpagesize () - j - 1, len: i, ULONG_MAX - i, n_in_bounds: 0, max_char: 127, exp_result: 0); |
722 | do_test_n (align1: j, align2: getpagesize () - j - 1, len: i, ULONG_MAX - i, n_in_bounds: 0, max_char: 127, exp_result: 1); |
723 | do_test_n (align1: j, align2: getpagesize () - j - 1, len: i, ULONG_MAX - i, n_in_bounds: 0, max_char: 127, exp_result: -1); |
724 | |
725 | for (k = 2; k <= 128; k += k) |
726 | { |
727 | do_test (align1: getpagesize () - k, align2: getpagesize () - j - 1, len: i - 1, n: i, |
728 | max_char: 127, exp_result: 0); |
729 | do_test (align1: getpagesize () - k - 1, align2: getpagesize () - j - 1, len: i - 1, |
730 | n: i, max_char: 127, exp_result: 0); |
731 | do_test (align1: getpagesize () - k, align2: getpagesize () - j - 1, len: i + 1, n: i, |
732 | max_char: 127, exp_result: 0); |
733 | do_test (align1: getpagesize () - k - 1, align2: getpagesize () - j - 1, len: i + 1, |
734 | n: i, max_char: 127, exp_result: 0); |
735 | do_test (align1: getpagesize () - k, align2: getpagesize () - j - 1, len: i, n: i, max_char: 127, |
736 | exp_result: 0); |
737 | do_test (align1: getpagesize () - k - 1, align2: getpagesize () - j - 1, len: i, n: i, |
738 | max_char: 127, exp_result: 0); |
739 | do_test (align1: getpagesize () - k, align2: getpagesize () - j - 1, len: i + 1, n: i, |
740 | max_char: 127, exp_result: -1); |
741 | do_test (align1: getpagesize () - k - 1, align2: getpagesize () - j - 1, len: i + 1, |
742 | n: i, max_char: 127, exp_result: -1); |
743 | do_test (align1: getpagesize () - k, align2: getpagesize () - j - 1, len: i + 1, n: i, |
744 | max_char: 127, exp_result: 1); |
745 | do_test (align1: getpagesize () - k - 1, align2: getpagesize () - j - 1, len: i + 1, |
746 | n: i, max_char: 127, exp_result: 1); |
747 | } |
748 | |
749 | if (i < 32) |
750 | { |
751 | i += 1; |
752 | } |
753 | else if (i < 161) |
754 | { |
755 | i += 7; |
756 | } |
757 | else if (i + 161 < test_len) |
758 | { |
759 | i += 31; |
760 | i *= 17; |
761 | i /= 16; |
762 | if (i + 161 > test_len) |
763 | { |
764 | i = test_len - 160; |
765 | } |
766 | } |
767 | else if (i + 32 < test_len) |
768 | { |
769 | i += 7; |
770 | } |
771 | else |
772 | { |
773 | i += 1; |
774 | } |
775 | } |
776 | } |
777 | |
778 | check_overflow (); |
779 | do_random_tests (); |
780 | return ret; |
781 | } |
782 | |
783 | #include <support/test-driver.c> |
784 | |