1 /* Test for string function add boundaries of usable memory.
2 Copyright (C) 1996,1997,1999-2003,2007,2009,2010,2011
3 Free Software Foundation, Inc.
4 This file is part of the GNU C Library.
5 Contributed by Ulrich Drepper <drepper@cygnus.com>, 1996.
7 The GNU C Library is free software; you can redistribute it and/or
8 modify it under the terms of the GNU Lesser General Public
9 License as published by the Free Software Foundation; either
10 version 2.1 of the License, or (at your option) any later version.
12 The GNU C Library is distributed in the hope that it will be useful,
13 but WITHOUT ANY WARRANTY; without even the implied warranty of
14 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15 Lesser General Public License for more details.
17 You should have received a copy of the GNU Lesser General Public
18 License along with the GNU C Library; if not, see
19 <http://www.gnu.org/licenses/>. */
23 /* Make sure we don't test the optimized inline functions if we want to
24 test the real implementation. */
25 #undef __USE_STRING_INLINES
32 #include <sys/param.h>
37 # define MEMSET memset
38 # define STRLEN strlen
39 # define STRNLEN strnlen
40 # define STRCHR strchr
41 # define STRRCHR strrchr
42 # define STRCPY strcpy
43 # define STRNCPY strncpy
44 # define MEMCMP memcmp
45 # define STPCPY stpcpy
46 # define STPNCPY stpncpy
47 # define MEMCPY memcpy
48 # define MEMPCPY mempcpy
49 # define MEMCHR memchr
50 # define STRCMP strcmp
51 # define STRNCMP strncmp
55 #define STRINGIFY(s) STRINGIFY2 (s)
56 #define STRINGIFY2(s) #s
62 int size
= sysconf (_SC_PAGESIZE
);
63 int nchars
= size
/ sizeof (CHAR
);
68 adr
= (CHAR
*) mmap (NULL
, 3 * size
, PROT_READ
| PROT_WRITE
,
69 MAP_PRIVATE
| MAP_ANON
, -1, 0);
70 dest
= (CHAR
*) mmap (NULL
, 3 * size
, PROT_READ
| PROT_WRITE
,
71 MAP_PRIVATE
| MAP_ANON
, -1, 0);
72 if (adr
== MAP_FAILED
|| dest
== MAP_FAILED
)
75 puts ("No test, mmap not available.");
78 printf ("mmap failed: %m");
84 int inner
, middle
, outer
;
86 mprotect (adr
, size
, PROT_NONE
);
87 mprotect (adr
+ 2 * nchars
, size
, PROT_NONE
);
90 mprotect (dest
, size
, PROT_NONE
);
91 mprotect (dest
+ 2 * nchars
, size
, PROT_NONE
);
94 MEMSET (adr
, L('T'), nchars
);
96 /* strlen/wcslen test */
97 for (outer
= nchars
- 1; outer
>= MAX (0, nchars
- 128); --outer
)
99 for (inner
= MAX (outer
, nchars
- 64); inner
< nchars
; ++inner
)
101 adr
[inner
] = L('\0');
103 if (STRLEN (&adr
[outer
]) != (size_t) (inner
- outer
))
105 printf ("%s flunked for outer = %d, inner = %d\n",
106 STRINGIFY (STRLEN
), outer
, inner
);
114 /* strnlen/wcsnlen test */
115 for (outer
= nchars
; outer
>= MAX (0, nchars
- 128); --outer
)
117 for (inner
= MAX (outer
, nchars
- 64); inner
< nchars
; ++inner
)
119 adr
[inner
] = L('\0');
121 if (STRNLEN (&adr
[outer
], inner
- outer
+ 1)
122 != (size_t) (inner
- outer
))
124 printf ("%s flunked for outer = %d, inner = %d\n",
125 STRINGIFY (STRNLEN
), outer
, inner
);
132 for (outer
= nchars
; outer
>= MAX (0, nchars
- 128); --outer
)
134 for (inner
= MAX (outer
, nchars
- 64); inner
<= nchars
; ++inner
)
136 if (STRNLEN (&adr
[outer
], inner
- outer
)
137 != (size_t) (inner
- outer
))
139 printf ("%s flunked bounded for outer = %d, inner = %d\n",
140 STRINGIFY (STRNLEN
), outer
, inner
);
146 /* strchr/wcschr test */
147 for (outer
= nchars
- 1; outer
>= MAX (0, nchars
- 128); --outer
)
149 for (middle
= MAX (outer
, nchars
- 64); middle
< nchars
; ++middle
)
151 for (inner
= middle
; inner
< nchars
; ++inner
)
153 adr
[middle
] = L('V');
154 adr
[inner
] = L('\0');
156 CHAR
*cp
= STRCHR (&adr
[outer
], L('V'));
158 if ((inner
== middle
&& cp
!= NULL
)
160 && (cp
- &adr
[outer
]) != middle
- outer
))
162 printf ("%s flunked for outer = %d, middle = %d, "
164 STRINGIFY (STRCHR
), outer
, middle
, inner
);
169 adr
[middle
] = L('T');
175 adr
[nchars
- 1] = L('\0');
176 if (STRCHR (&adr
[nchars
- 1], L('\n')) != NULL
)
178 printf ("%s flunked test of empty string at end of page\n",
183 /* strrchr/wcsrchr test */
184 for (outer
= nchars
- 1; outer
>= MAX (0, nchars
- 128); --outer
)
186 for (middle
= MAX (outer
, nchars
- 64); middle
< nchars
; ++middle
)
188 for (inner
= middle
; inner
< nchars
; ++inner
)
190 adr
[middle
] = L('V');
191 adr
[inner
] = L('\0');
193 CHAR
*cp
= STRRCHR (&adr
[outer
], L('V'));
195 if ((inner
== middle
&& cp
!= NULL
)
197 && (cp
- &adr
[outer
]) != middle
- outer
))
199 printf ("%s flunked for outer = %d, middle = %d, "
201 STRINGIFY (STRRCHR
), outer
, middle
, inner
);
206 adr
[middle
] = L('T');
212 for (outer
= nchars
- 1; outer
>= MAX (0, nchars
- 128); --outer
)
214 for (middle
= MAX (outer
, nchars
- 64); middle
< nchars
; ++middle
)
216 adr
[middle
] = L('V');
218 CHAR
*cp
= MEMCHR (&adr
[outer
], L('V'), 3 * size
);
220 if (cp
- &adr
[outer
] != middle
- outer
)
222 printf ("%s flunked for outer = %d, middle = %d\n",
223 STRINGIFY (MEMCHR
), outer
, middle
);
227 adr
[middle
] = L('T');
230 for (outer
= nchars
; outer
>= MAX (0, nchars
- 128); --outer
)
232 CHAR
*cp
= MEMCHR (&adr
[outer
], L('V'), nchars
- outer
);
236 printf ("%s flunked for outer = %d\n",
237 STRINGIFY (MEMCHR
), outer
);
242 /* These functions only exist for single-byte characters. */
245 for (outer
= nchars
- 1; outer
>= MAX (0, nchars
- 128); --outer
)
247 for (middle
= MAX (outer
, nchars
- 64); middle
< nchars
; ++middle
)
249 adr
[middle
] = L('V');
251 CHAR
*cp
= rawmemchr (&adr
[outer
], L('V'));
253 if (cp
- &adr
[outer
] != middle
- outer
)
255 printf ("%s flunked for outer = %d, middle = %d\n",
256 STRINGIFY (rawmemchr
), outer
, middle
);
260 adr
[middle
] = L('T');
265 for (outer
= nchars
- 1; outer
>= MAX (0, nchars
- 128); --outer
)
267 for (middle
= MAX (outer
, nchars
- 64); middle
< nchars
; ++middle
)
269 adr
[middle
] = L('V');
271 CHAR
*cp
= memrchr (&adr
[outer
], L('V'), nchars
- outer
);
273 if (cp
- &adr
[outer
] != middle
- outer
)
275 printf ("%s flunked for outer = %d, middle = %d\n",
276 STRINGIFY (memrchr
), outer
, middle
);
280 adr
[middle
] = L('T');
283 for (outer
= nchars
; outer
>= MAX (0, nchars
- 128); --outer
)
285 CHAR
*cp
= memrchr (&adr
[outer
], L('V'), nchars
- outer
);
289 printf ("%s flunked for outer = %d\n",
290 STRINGIFY (memrchr
), outer
);
296 /* strcpy/wcscpy test */
297 for (outer
= nchars
- 1; outer
>= MAX (0, nchars
- 128); --outer
)
299 for (inner
= MAX (outer
, nchars
- 64); inner
< nchars
; ++inner
)
301 adr
[inner
] = L('\0');
303 if (STRCPY (dest
, &adr
[outer
]) != dest
304 || STRLEN (dest
) != (size_t) (inner
- outer
))
306 printf ("%s flunked for outer = %d, inner = %d\n",
307 STRINGIFY (STRCPY
), outer
, inner
);
315 /* strcmp/wcscmp tests */
316 for (outer
= 1; outer
< 32; ++outer
)
317 for (middle
= 0; middle
< 16; ++middle
)
319 MEMSET (adr
+ middle
, L('T'), 256);
321 MEMSET (dest
+ nchars
- outer
, L('T'), outer
- 1);
322 dest
[nchars
- 1] = L('\0');
324 if (STRCMP (adr
+ middle
, dest
+ nchars
- outer
) <= 0)
326 printf ("%s 1 flunked for outer = %d, middle = %d\n",
327 STRINGIFY (STRCMP
), outer
, middle
);
331 if (STRCMP (dest
+ nchars
- outer
, adr
+ middle
) >= 0)
333 printf ("%s 2 flunked for outer = %d, middle = %d\n",
334 STRINGIFY (STRCMP
), outer
, middle
);
339 /* strncmp/wcsncmp tests */
340 for (outer
= 1; outer
< 32; ++outer
)
341 for (middle
= 0; middle
< 16; ++middle
)
343 MEMSET (adr
+ middle
, L('T'), 256);
345 MEMSET (dest
+ nchars
- outer
, L('T'), outer
- 1);
346 dest
[nchars
- 1] = L('U');
348 for (inner
= 0; inner
< outer
; ++inner
)
350 if (STRNCMP (adr
+ middle
, dest
+ nchars
- outer
, inner
) != 0)
352 printf ("%s 1 flunked for outer = %d, middle = %d, "
354 STRINGIFY (STRNCMP
), outer
, middle
, inner
);
358 if (STRNCMP (dest
+ nchars
- outer
, adr
+ middle
, inner
) != 0)
360 printf ("%s 2 flunked for outer = %d, middle = %d, "
362 STRINGIFY (STRNCMP
), outer
, middle
, inner
);
367 if (STRNCMP (adr
+ middle
, dest
+ nchars
- outer
, outer
) >= 0)
369 printf ("%s 1 flunked for outer = %d, middle = %d, full\n",
370 STRINGIFY (STRNCMP
), outer
, middle
);
374 if (STRNCMP (dest
+ nchars
- outer
, adr
+ middle
, outer
) <= 0)
376 printf ("%s 2 flunked for outer = %d, middle = %d, full\n",
377 STRINGIFY (STRNCMP
), outer
, middle
);
382 /* strncpy/wcsncpy tests */
383 adr
[nchars
- 1] = L('T');
384 for (outer
= nchars
; outer
>= MAX (0, nchars
- 128); --outer
)
388 for (len
= 0; len
< nchars
- outer
; ++len
)
390 if (STRNCPY (dest
, &adr
[outer
], len
) != dest
391 || MEMCMP (dest
, &adr
[outer
], len
) != 0)
393 printf ("outer %s flunked for outer = %d, len = %Zd\n",
394 STRINGIFY (STRNCPY
), outer
, len
);
399 adr
[nchars
- 1] = L('\0');
401 for (outer
= nchars
- 1; outer
>= MAX (0, nchars
- 128); --outer
)
403 for (inner
= MAX (outer
, nchars
- 64); inner
< nchars
; ++inner
)
407 adr
[inner
] = L('\0');
409 for (len
= 0; len
< nchars
- outer
+ 64; ++len
)
411 if (STRNCPY (dest
, &adr
[outer
], len
) != dest
412 || MEMCMP (dest
, &adr
[outer
],
413 MIN (inner
- outer
, len
)) != 0
414 || (inner
- outer
< len
415 && STRLEN (dest
) != (inner
- outer
)))
417 printf ("%s flunked for outer = %d, inner = %d, "
419 STRINGIFY (STRNCPY
), outer
, inner
, len
);
422 if (STRNCPY (dest
+ 1, &adr
[outer
], len
) != dest
+ 1
423 || MEMCMP (dest
+ 1, &adr
[outer
],
424 MIN (inner
- outer
, len
)) != 0
425 || (inner
- outer
< len
426 && STRLEN (dest
+ 1) != (inner
- outer
)))
428 printf ("%s+1 flunked for outer = %d, inner = %d, "
430 STRINGIFY (STRNCPY
), outer
, inner
, len
);
439 /* stpcpy/wcpcpy test */
440 for (outer
= nchars
- 1; outer
>= MAX (0, nchars
- 128); --outer
)
442 for (inner
= MAX (outer
, nchars
- 64); inner
< nchars
; ++inner
)
444 adr
[inner
] = L('\0');
446 if ((STPCPY (dest
, &adr
[outer
]) - dest
) != inner
- outer
)
448 printf ("%s flunked for outer = %d, inner = %d\n",
449 STRINGIFY (STPCPY
), outer
, inner
);
457 /* stpncpy/wcpncpy test */
458 adr
[nchars
- 1] = L('T');
459 for (outer
= nchars
; outer
>= MAX (0, nchars
- 128); --outer
)
463 for (len
= 0; len
< nchars
- outer
; ++len
)
465 if (STPNCPY (dest
, &adr
[outer
], len
) != dest
+ len
466 || MEMCMP (dest
, &adr
[outer
], len
) != 0)
468 printf ("outer %s flunked for outer = %d, len = %Zd\n",
469 STRINGIFY (STPNCPY
), outer
, len
);
474 adr
[nchars
- 1] = L('\0');
476 for (outer
= nchars
- 1; outer
>= MAX (0, nchars
- 128); --outer
)
478 for (middle
= MAX (outer
, nchars
- 64); middle
< nchars
; ++middle
)
480 adr
[middle
] = L('\0');
482 for (inner
= 0; inner
< nchars
- outer
; ++ inner
)
484 if ((STPNCPY (dest
, &adr
[outer
], inner
) - dest
)
485 != MIN (inner
, middle
- outer
))
487 printf ("%s flunked for outer = %d, middle = %d, "
489 STRINGIFY (STPNCPY
), outer
, middle
, inner
);
494 adr
[middle
] = L('T');
498 /* memcpy/wmemcpy test */
499 for (outer
= nchars
; outer
>= MAX (0, nchars
- 128); --outer
)
500 for (inner
= 0; inner
< nchars
- outer
; ++inner
)
501 if (MEMCPY (dest
, &adr
[outer
], inner
) != dest
)
503 printf ("%s flunked for outer = %d, inner = %d\n",
504 STRINGIFY (MEMCPY
), outer
, inner
);
508 /* mempcpy/wmempcpy test */
509 for (outer
= nchars
; outer
>= MAX (0, nchars
- 128); --outer
)
510 for (inner
= 0; inner
< nchars
- outer
; ++inner
)
511 if (MEMPCPY (dest
, &adr
[outer
], inner
) != dest
+ inner
)
513 printf ("%s flunked for outer = %d, inner = %d\n",
514 STRINGIFY (MEMPCPY
), outer
, inner
);
518 /* This function only exists for single-byte characters. */
521 memset (adr
, '\0', nchars
);
522 for (outer
= nchars
; outer
>= MAX (0, nchars
- 128); --outer
)
523 for (inner
= 0; inner
< nchars
- outer
; ++inner
)
524 if (memccpy (dest
, &adr
[outer
], L('\1'), inner
) != NULL
)
526 printf ("memccpy flunked full copy for outer = %d, inner = %d\n",
530 for (outer
= nchars
- 1; outer
>= MAX (0, nchars
- 128); --outer
)
531 for (middle
= 0; middle
< nchars
- outer
; ++middle
)
533 memset (dest
, L('\2'), middle
+ 1);
534 for (inner
= 0; inner
< middle
; ++inner
)
536 adr
[outer
+ inner
] = L('\1');
538 if (memccpy (dest
, &adr
[outer
], '\1', middle
+ 128)
542 memccpy flunked partial copy for outer = %d, middle = %d, inner = %d\n",
543 outer
, middle
, inner
);
546 else if (dest
[inner
+ 1] != L('\2'))
549 memccpy copied too much for outer = %d, middle = %d, inner = %d\n",
550 outer
, middle
, inner
);
553 adr
[outer
+ inner
] = L('\0');
562 #define TEST_FUNCTION do_test ()
563 #include "../test-skeleton.c"