1 /* Test for string function add boundaries of usable memory.
2 Copyright (C) 1996,1997,1999-2002,2003,2007 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
52 #define STRINGIFY(s) STRINGIFY2 (s)
53 #define STRINGIFY2(s) #s
59 int size
= sysconf (_SC_PAGESIZE
);
60 int nchars
= size
/ sizeof (CHAR
);
65 adr
= (CHAR
*) mmap (NULL
, 3 * size
, PROT_READ
| PROT_WRITE
,
66 MAP_PRIVATE
| MAP_ANON
, -1, 0);
67 dest
= (CHAR
*) mmap (NULL
, 3 * size
, PROT_READ
| PROT_WRITE
,
68 MAP_PRIVATE
| MAP_ANON
, -1, 0);
69 if (adr
== MAP_FAILED
|| dest
== MAP_FAILED
)
72 puts ("No test, mmap not available.");
75 printf ("mmap failed: %m");
81 int inner
, middle
, outer
;
83 mprotect (adr
, size
, PROT_NONE
);
84 mprotect (adr
+ 2 * nchars
, size
, PROT_NONE
);
87 mprotect (dest
, size
, PROT_NONE
);
88 mprotect (dest
+ 2 * nchars
, size
, PROT_NONE
);
91 MEMSET (adr
, L('T'), nchars
);
93 /* strlen/wcslen test */
94 for (outer
= nchars
- 1; outer
>= MAX (0, nchars
- 128); --outer
)
96 for (inner
= MAX (outer
, nchars
- 64); inner
< nchars
; ++inner
)
100 if (STRLEN (&adr
[outer
]) != (size_t) (inner
- outer
))
102 printf ("%s flunked for outer = %d, inner = %d\n",
103 STRINGIFY (STRLEN
), outer
, inner
);
111 /* strnlen/wcsnlen test */
112 for (outer
= nchars
; outer
>= MAX (0, nchars
- 128); --outer
)
114 for (inner
= MAX (outer
, nchars
- 64); inner
< nchars
; ++inner
)
116 adr
[inner
] = L('\0');
118 if (STRNLEN (&adr
[outer
], inner
- outer
+ 1)
119 != (size_t) (inner
- outer
))
121 printf ("%s flunked for outer = %d, inner = %d\n",
122 STRINGIFY (STRNLEN
), outer
, inner
);
129 for (outer
= nchars
; outer
>= MAX (0, nchars
- 128); --outer
)
131 for (inner
= MAX (outer
, nchars
- 64); inner
< nchars
; ++inner
)
133 if (STRNLEN (&adr
[outer
], inner
- outer
+ 1)
134 != (size_t) (inner
- outer
+ 1))
136 printf ("%s flunked bounded for outer = %d, inner = %d\n",
137 STRINGIFY (STRNLEN
), outer
, inner
);
143 /* strchr/wcschr test */
144 for (outer
= nchars
- 1; outer
>= MAX (0, nchars
- 128); --outer
)
146 for (middle
= MAX (outer
, nchars
- 64); middle
< nchars
; ++middle
)
148 for (inner
= middle
; inner
< nchars
; ++inner
)
150 adr
[middle
] = L('V');
151 adr
[inner
] = L('\0');
153 CHAR
*cp
= STRCHR (&adr
[outer
], L('V'));
155 if ((inner
== middle
&& cp
!= NULL
)
157 && (cp
- &adr
[outer
]) != middle
- outer
))
159 printf ("%s flunked for outer = %d, middle = %d, "
161 STRINGIFY (STRCHR
), outer
, middle
, inner
);
166 adr
[middle
] = L('T');
172 adr
[nchars
- 1] = L('\0');
173 if (STRCHR (&adr
[nchars
- 1], L('\n')) != NULL
)
175 printf ("%s flunked test of empty string at end of page\n",
180 /* strrchr/wcsrchr test */
181 for (outer
= nchars
- 1; outer
>= MAX (0, nchars
- 128); --outer
)
183 for (middle
= MAX (outer
, nchars
- 64); middle
< nchars
; ++middle
)
185 for (inner
= middle
; inner
< nchars
; ++inner
)
187 adr
[middle
] = L('V');
188 adr
[inner
] = L('\0');
190 CHAR
*cp
= STRRCHR (&adr
[outer
], L('V'));
192 if ((inner
== middle
&& cp
!= NULL
)
194 && (cp
- &adr
[outer
]) != middle
- outer
))
196 printf ("%s flunked for outer = %d, middle = %d, "
198 STRINGIFY (STRRCHR
), outer
, middle
, inner
);
203 adr
[middle
] = L('T');
208 /* This function only exists for single-byte characters. */
211 for (outer
= nchars
- 1; outer
>= MAX (0, nchars
- 128); --outer
)
213 for (middle
= MAX (outer
, nchars
- 64); middle
< nchars
; ++middle
)
215 adr
[middle
] = L('V');
217 CHAR
*cp
= rawmemchr (&adr
[outer
], L('V'));
219 if (cp
- &adr
[outer
] != middle
- outer
)
221 printf ("%s flunked for outer = %d, middle = %d\n",
222 STRINGIFY (rawmemchr
), outer
, middle
);
226 adr
[middle
] = L('T');
231 /* strcpy/wcscpy test */
232 for (outer
= nchars
- 1; outer
>= MAX (0, nchars
- 128); --outer
)
234 for (inner
= MAX (outer
, nchars
- 64); inner
< nchars
; ++inner
)
236 adr
[inner
] = L('\0');
238 if (STRCPY (dest
, &adr
[outer
]) != dest
239 || STRLEN (dest
) != (size_t) (inner
- outer
))
241 printf ("%s flunked for outer = %d, inner = %d\n",
242 STRINGIFY (STRCPY
), outer
, inner
);
251 adr
[nchars
- 1] = L('T');
252 for (outer
= nchars
- 1; outer
>= MAX (0, nchars
- 128); --outer
)
256 for (len
= 0; len
< nchars
- outer
; ++len
)
258 if (STRNCPY (dest
, &adr
[outer
], len
) != dest
259 || MEMCMP (dest
, &adr
[outer
], len
) != 0)
261 printf ("outer %s flunked for outer = %d, len = %Zd\n",
262 STRINGIFY (STRNCPY
), outer
, len
);
267 adr
[nchars
- 1] = L('\0');
269 for (outer
= nchars
- 1; outer
>= MAX (0, nchars
- 128); --outer
)
271 for (inner
= MAX (outer
, nchars
- 64); inner
< nchars
; ++inner
)
275 adr
[inner
] = L('\0');
277 for (len
= 0; len
< nchars
- outer
+ 64; ++len
)
279 if (STRNCPY (dest
, &adr
[outer
], len
) != dest
280 || MEMCMP (dest
, &adr
[outer
],
281 MIN (inner
- outer
, len
)) != 0
282 || (inner
- outer
< len
283 && STRLEN (dest
) != (inner
- outer
)))
285 printf ("%s flunked for outer = %d, inner = %d, "
287 STRINGIFY (STRNCPY
), outer
, inner
, len
);
290 if (STRNCPY (dest
+ 1, &adr
[outer
], len
) != dest
+ 1
291 || MEMCMP (dest
+ 1, &adr
[outer
],
292 MIN (inner
- outer
, len
)) != 0
293 || (inner
- outer
< len
294 && STRLEN (dest
+ 1) != (inner
- outer
)))
296 printf ("%s+1 flunked for outer = %d, inner = %d, "
298 STRINGIFY (STRNCPY
), outer
, inner
, len
);
307 /* stpcpy/wcpcpy test */
308 for (outer
= nchars
- 1; outer
>= MAX (0, nchars
- 128); --outer
)
310 for (inner
= MAX (outer
, nchars
- 64); inner
< nchars
; ++inner
)
312 adr
[inner
] = L('\0');
314 if ((STPCPY (dest
, &adr
[outer
]) - dest
) != inner
- outer
)
316 printf ("%s flunked for outer = %d, inner = %d\n",
317 STRINGIFY (STPCPY
), outer
, inner
);
325 /* stpncpy/wcpncpy test */
326 for (outer
= nchars
- 1; outer
>= MAX (0, nchars
- 128); --outer
)
328 for (middle
= MAX (outer
, nchars
- 64); middle
< nchars
; ++middle
)
330 adr
[middle
] = L('\0');
332 for (inner
= 0; inner
< nchars
- outer
; ++ inner
)
334 if ((STPNCPY (dest
, &adr
[outer
], inner
) - dest
)
335 != MIN (inner
, middle
- outer
))
337 printf ("%s flunked for outer = %d, middle = %d, "
339 STRINGIFY (STPNCPY
), outer
, middle
, inner
);
344 adr
[middle
] = L('T');
348 /* memcpy/wmemcpy test */
349 for (outer
= nchars
- 1; outer
>= MAX (0, nchars
- 128); --outer
)
350 for (inner
= 0; inner
< nchars
- outer
; ++inner
)
351 if (MEMCPY (dest
, &adr
[outer
], inner
) != dest
)
353 printf ("%s flunked for outer = %d, inner = %d\n",
354 STRINGIFY (MEMCPY
), outer
, inner
);
358 /* mempcpy/wmempcpy test */
359 for (outer
= nchars
- 1; outer
>= MAX (0, nchars
- 128); --outer
)
360 for (inner
= 0; inner
< nchars
- outer
; ++inner
)
361 if (MEMPCPY (dest
, &adr
[outer
], inner
) != dest
+ inner
)
363 printf ("%s flunked for outer = %d, inner = %d\n",
364 STRINGIFY (MEMPCPY
), outer
, inner
);
368 /* This function only exists for single-byte characters. */
371 memset (adr
, '\0', nchars
);
372 for (outer
= nchars
- 1; outer
>= MAX (0, nchars
- 128); --outer
)
373 for (inner
= 0; inner
< nchars
- outer
; ++inner
)
374 if (memccpy (dest
, &adr
[outer
], L('\1'), inner
) != NULL
)
376 printf ("memccpy flunked full copy for outer = %d, inner = %d\n",
380 for (outer
= nchars
- 1; outer
>= MAX (0, nchars
- 128); --outer
)
381 for (middle
= 0; middle
< nchars
- outer
; ++middle
)
383 memset (dest
, L('\2'), middle
+ 1);
384 for (inner
= 0; inner
< middle
; ++inner
)
386 adr
[outer
+ inner
] = L('\1');
388 if (memccpy (dest
, &adr
[outer
], '\1', middle
+ 128)
392 memccpy flunked partial copy for outer = %d, middle = %d, inner = %d\n",
393 outer
, middle
, inner
);
396 else if (dest
[inner
+ 1] != L('\2'))
399 memccpy copied too much for outer = %d, middle = %d, inner = %d\n",
400 outer
, middle
, inner
);
403 adr
[outer
+ inner
] = L('\0');
412 #define TEST_FUNCTION do_test ()
413 #include "../test-skeleton.c"