1 /* Test for string function add boundaries of usable memory.
2 Copyright (C) 1996,1997,1999-2003,2007, 2009 Free Software Foundation, Inc.
3 This file is part of the GNU C Library.
4 Contributed by Ulrich Drepper <drepper@cygnus.com>, 1996.
6 The GNU C Library is free software; you can redistribute it and/or
7 modify it under the terms of the GNU Lesser General Public
8 License as published by the Free Software Foundation; either
9 version 2.1 of the License, or (at your option) any later version.
11 The GNU C Library is distributed in the hope that it will be useful,
12 but WITHOUT ANY WARRANTY; without even the implied warranty of
13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 Lesser General Public License for more details.
16 You should have received a copy of the GNU Lesser General Public
17 License along with the GNU C Library; if not, write to the Free
18 Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
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
53 #define STRINGIFY(s) STRINGIFY2 (s)
54 #define STRINGIFY2(s) #s
60 int size
= sysconf (_SC_PAGESIZE
);
61 int nchars
= size
/ sizeof (CHAR
);
66 adr
= (CHAR
*) mmap (NULL
, 3 * size
, PROT_READ
| PROT_WRITE
,
67 MAP_PRIVATE
| MAP_ANON
, -1, 0);
68 dest
= (CHAR
*) mmap (NULL
, 3 * size
, PROT_READ
| PROT_WRITE
,
69 MAP_PRIVATE
| MAP_ANON
, -1, 0);
70 if (adr
== MAP_FAILED
|| dest
== MAP_FAILED
)
73 puts ("No test, mmap not available.");
76 printf ("mmap failed: %m");
82 int inner
, middle
, outer
;
84 mprotect (adr
, size
, PROT_NONE
);
85 mprotect (adr
+ 2 * nchars
, size
, PROT_NONE
);
88 mprotect (dest
, size
, PROT_NONE
);
89 mprotect (dest
+ 2 * nchars
, size
, PROT_NONE
);
92 MEMSET (adr
, L('T'), nchars
);
94 /* strlen/wcslen test */
95 for (outer
= nchars
- 1; outer
>= MAX (0, nchars
- 128); --outer
)
97 for (inner
= MAX (outer
, nchars
- 64); inner
< nchars
; ++inner
)
101 if (STRLEN (&adr
[outer
]) != (size_t) (inner
- outer
))
103 printf ("%s flunked for outer = %d, inner = %d\n",
104 STRINGIFY (STRLEN
), outer
, inner
);
112 /* strnlen/wcsnlen test */
113 for (outer
= nchars
; outer
>= MAX (0, nchars
- 128); --outer
)
115 for (inner
= MAX (outer
, nchars
- 64); inner
< nchars
; ++inner
)
117 adr
[inner
] = L('\0');
119 if (STRNLEN (&adr
[outer
], inner
- outer
+ 1)
120 != (size_t) (inner
- outer
))
122 printf ("%s flunked for outer = %d, inner = %d\n",
123 STRINGIFY (STRNLEN
), outer
, inner
);
130 for (outer
= nchars
; outer
>= MAX (0, nchars
- 128); --outer
)
132 for (inner
= MAX (outer
, nchars
- 64); inner
< nchars
; ++inner
)
134 if (STRNLEN (&adr
[outer
], inner
- outer
+ 1)
135 != (size_t) (inner
- outer
+ 1))
137 printf ("%s flunked bounded for outer = %d, inner = %d\n",
138 STRINGIFY (STRNLEN
), outer
, inner
);
144 /* strchr/wcschr test */
145 for (outer
= nchars
- 1; outer
>= MAX (0, nchars
- 128); --outer
)
147 for (middle
= MAX (outer
, nchars
- 64); middle
< nchars
; ++middle
)
149 for (inner
= middle
; inner
< nchars
; ++inner
)
151 adr
[middle
] = L('V');
152 adr
[inner
] = L('\0');
154 CHAR
*cp
= STRCHR (&adr
[outer
], L('V'));
156 if ((inner
== middle
&& cp
!= NULL
)
158 && (cp
- &adr
[outer
]) != middle
- outer
))
160 printf ("%s flunked for outer = %d, middle = %d, "
162 STRINGIFY (STRCHR
), outer
, middle
, inner
);
167 adr
[middle
] = L('T');
173 adr
[nchars
- 1] = L('\0');
174 if (STRCHR (&adr
[nchars
- 1], L('\n')) != NULL
)
176 printf ("%s flunked test of empty string at end of page\n",
181 /* strrchr/wcsrchr test */
182 for (outer
= nchars
- 1; outer
>= MAX (0, nchars
- 128); --outer
)
184 for (middle
= MAX (outer
, nchars
- 64); middle
< nchars
; ++middle
)
186 for (inner
= middle
; inner
< nchars
; ++inner
)
188 adr
[middle
] = L('V');
189 adr
[inner
] = L('\0');
191 CHAR
*cp
= STRRCHR (&adr
[outer
], L('V'));
193 if ((inner
== middle
&& cp
!= NULL
)
195 && (cp
- &adr
[outer
]) != middle
- outer
))
197 printf ("%s flunked for outer = %d, middle = %d, "
199 STRINGIFY (STRRCHR
), outer
, middle
, inner
);
204 adr
[middle
] = L('T');
210 for (outer
= nchars
- 1; outer
>= MAX (0, nchars
- 128); --outer
)
212 for (middle
= MAX (outer
, nchars
- 64); middle
< nchars
; ++middle
)
214 adr
[middle
] = L('V');
216 CHAR
*cp
= MEMCHR (&adr
[outer
], L('V'), 3 * size
);
218 if (cp
- &adr
[outer
] != middle
- outer
)
220 printf ("%s flunked for outer = %d, middle = %d\n",
221 STRINGIFY (MEMCHR
), outer
, middle
);
225 adr
[middle
] = L('T');
228 for (outer
= nchars
- 1; outer
>= MAX (0, nchars
- 128); --outer
)
230 CHAR
*cp
= MEMCHR (&adr
[outer
], L('V'), nchars
- outer
);
234 printf ("%s flunked for outer = %d\n",
235 STRINGIFY (MEMCHR
), outer
);
240 /* This function only exists for single-byte characters. */
243 for (outer
= nchars
- 1; outer
>= MAX (0, nchars
- 128); --outer
)
245 for (middle
= MAX (outer
, nchars
- 64); middle
< nchars
; ++middle
)
247 adr
[middle
] = L('V');
249 CHAR
*cp
= rawmemchr (&adr
[outer
], L('V'));
251 if (cp
- &adr
[outer
] != middle
- outer
)
253 printf ("%s flunked for outer = %d, middle = %d\n",
254 STRINGIFY (rawmemchr
), outer
, middle
);
258 adr
[middle
] = L('T');
263 /* strcpy/wcscpy test */
264 for (outer
= nchars
- 1; outer
>= MAX (0, nchars
- 128); --outer
)
266 for (inner
= MAX (outer
, nchars
- 64); inner
< nchars
; ++inner
)
268 adr
[inner
] = L('\0');
270 if (STRCPY (dest
, &adr
[outer
]) != dest
271 || STRLEN (dest
) != (size_t) (inner
- outer
))
273 printf ("%s flunked for outer = %d, inner = %d\n",
274 STRINGIFY (STRCPY
), outer
, inner
);
283 adr
[nchars
- 1] = L('T');
284 for (outer
= nchars
- 1; outer
>= MAX (0, nchars
- 128); --outer
)
288 for (len
= 0; len
< nchars
- outer
; ++len
)
290 if (STRNCPY (dest
, &adr
[outer
], len
) != dest
291 || MEMCMP (dest
, &adr
[outer
], len
) != 0)
293 printf ("outer %s flunked for outer = %d, len = %Zd\n",
294 STRINGIFY (STRNCPY
), outer
, len
);
299 adr
[nchars
- 1] = L('\0');
301 for (outer
= nchars
- 1; outer
>= MAX (0, nchars
- 128); --outer
)
303 for (inner
= MAX (outer
, nchars
- 64); inner
< nchars
; ++inner
)
307 adr
[inner
] = L('\0');
309 for (len
= 0; len
< nchars
- outer
+ 64; ++len
)
311 if (STRNCPY (dest
, &adr
[outer
], len
) != dest
312 || MEMCMP (dest
, &adr
[outer
],
313 MIN (inner
- outer
, len
)) != 0
314 || (inner
- outer
< len
315 && STRLEN (dest
) != (inner
- outer
)))
317 printf ("%s flunked for outer = %d, inner = %d, "
319 STRINGIFY (STRNCPY
), outer
, inner
, len
);
322 if (STRNCPY (dest
+ 1, &adr
[outer
], len
) != dest
+ 1
323 || MEMCMP (dest
+ 1, &adr
[outer
],
324 MIN (inner
- outer
, len
)) != 0
325 || (inner
- outer
< len
326 && STRLEN (dest
+ 1) != (inner
- outer
)))
328 printf ("%s+1 flunked for outer = %d, inner = %d, "
330 STRINGIFY (STRNCPY
), outer
, inner
, len
);
339 /* stpcpy/wcpcpy test */
340 for (outer
= nchars
- 1; outer
>= MAX (0, nchars
- 128); --outer
)
342 for (inner
= MAX (outer
, nchars
- 64); inner
< nchars
; ++inner
)
344 adr
[inner
] = L('\0');
346 if ((STPCPY (dest
, &adr
[outer
]) - dest
) != inner
- outer
)
348 printf ("%s flunked for outer = %d, inner = %d\n",
349 STRINGIFY (STPCPY
), outer
, inner
);
357 /* stpncpy/wcpncpy test */
358 for (outer
= nchars
- 1; outer
>= MAX (0, nchars
- 128); --outer
)
360 for (middle
= MAX (outer
, nchars
- 64); middle
< nchars
; ++middle
)
362 adr
[middle
] = L('\0');
364 for (inner
= 0; inner
< nchars
- outer
; ++ inner
)
366 if ((STPNCPY (dest
, &adr
[outer
], inner
) - dest
)
367 != MIN (inner
, middle
- outer
))
369 printf ("%s flunked for outer = %d, middle = %d, "
371 STRINGIFY (STPNCPY
), outer
, middle
, inner
);
376 adr
[middle
] = L('T');
380 /* memcpy/wmemcpy test */
381 for (outer
= nchars
- 1; outer
>= MAX (0, nchars
- 128); --outer
)
382 for (inner
= 0; inner
< nchars
- outer
; ++inner
)
383 if (MEMCPY (dest
, &adr
[outer
], inner
) != dest
)
385 printf ("%s flunked for outer = %d, inner = %d\n",
386 STRINGIFY (MEMCPY
), outer
, inner
);
390 /* mempcpy/wmempcpy test */
391 for (outer
= nchars
- 1; outer
>= MAX (0, nchars
- 128); --outer
)
392 for (inner
= 0; inner
< nchars
- outer
; ++inner
)
393 if (MEMPCPY (dest
, &adr
[outer
], inner
) != dest
+ inner
)
395 printf ("%s flunked for outer = %d, inner = %d\n",
396 STRINGIFY (MEMPCPY
), outer
, inner
);
400 /* This function only exists for single-byte characters. */
403 memset (adr
, '\0', nchars
);
404 for (outer
= nchars
- 1; outer
>= MAX (0, nchars
- 128); --outer
)
405 for (inner
= 0; inner
< nchars
- outer
; ++inner
)
406 if (memccpy (dest
, &adr
[outer
], L('\1'), inner
) != NULL
)
408 printf ("memccpy flunked full copy for outer = %d, inner = %d\n",
412 for (outer
= nchars
- 1; outer
>= MAX (0, nchars
- 128); --outer
)
413 for (middle
= 0; middle
< nchars
- outer
; ++middle
)
415 memset (dest
, L('\2'), middle
+ 1);
416 for (inner
= 0; inner
< middle
; ++inner
)
418 adr
[outer
+ inner
] = L('\1');
420 if (memccpy (dest
, &adr
[outer
], '\1', middle
+ 128)
424 memccpy flunked partial copy for outer = %d, middle = %d, inner = %d\n",
425 outer
, middle
, inner
);
428 else if (dest
[inner
+ 1] != L('\2'))
431 memccpy copied too much for outer = %d, middle = %d, inner = %d\n",
432 outer
, middle
, inner
);
435 adr
[outer
+ inner
] = L('\0');
444 #define TEST_FUNCTION do_test ()
445 #include "../test-skeleton.c"