Some more strncpy checks.
[kopensolaris-gnu/glibc.git] / string / stratcliff.c
1 /* Test for string function add boundaries of usable memory.
2    Copyright (C) 1996,1997,1999,2000,2001,2002 Free Software Foundation, Inc.
3    This file is part of the GNU C Library.
4    Contributed by Ulrich Drepper <drepper@cygnus.com>, 1996.
5
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.
10
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.
15
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
19    02111-1307 USA.  */
20
21 #define _GNU_SOURCE 1
22
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
26
27 #include <errno.h>
28 #include <stdio.h>
29 #include <string.h>
30 #include <unistd.h>
31 #include <sys/mman.h>
32 #include <sys/param.h>
33
34 #ifndef MAX
35 #define MAX(a, b) ((a) > (b) ? (a) : (b))
36 #endif
37
38 int
39 main (int argc, char *argv[])
40 {
41   int size = sysconf (_SC_PAGESIZE);
42   char *adr, *dest;
43   int result = 0;
44
45   adr = (char *) mmap (NULL, 3 * size, PROT_READ | PROT_WRITE,
46                        MAP_PRIVATE | MAP_ANON, -1, 0);
47   dest = (char *) mmap (NULL, 3 * size, PROT_READ | PROT_WRITE,
48                         MAP_PRIVATE | MAP_ANON, -1, 0);
49   if (adr == MAP_FAILED || dest == MAP_FAILED)
50     {
51       if (errno == ENOSYS)
52         puts ("No test, mmap not available.");
53       else
54         {
55           printf ("mmap failed: %m");
56           result = 1;
57         }
58     }
59   else
60     {
61       int inner, middle, outer;
62
63       mprotect(adr, size, PROT_NONE);
64       mprotect(adr + 2 * size, size, PROT_NONE);
65       adr += size;
66
67       mprotect(dest, size, PROT_NONE);
68       mprotect(dest + 2 * size, size, PROT_NONE);
69       dest += size;
70
71       memset (adr, 'T', size);
72
73       /* strlen test */
74       for (outer = size - 1; outer >= MAX (0, size - 128); --outer)
75         {
76           for (inner = MAX (outer, size - 64); inner < size; ++inner)
77             {
78               adr[inner] = '\0';
79
80               if (strlen (&adr[outer]) != (size_t) (inner - outer))
81                 {
82                   printf ("strlen flunked for outer = %d, inner = %d\n",
83                           outer, inner);
84                   result = 1;
85                 }
86
87               adr[inner] = 'T';
88             }
89         }
90
91       /* strchr test */
92       for (outer = size - 1; outer >= MAX (0, size - 128); --outer)
93         {
94           for (middle = MAX (outer, size - 64); middle < size; ++middle)
95             {
96               for (inner = middle; inner < size; ++inner)
97                 {
98                   char *cp;
99                   adr[middle] = 'V';
100                   adr[inner] = '\0';
101
102                   cp = strchr (&adr[outer], 'V');
103
104                   if ((inner == middle && cp != NULL)
105                       || (inner != middle
106                           && (cp - &adr[outer]) != middle - outer))
107                     {
108                       printf ("strchr flunked for outer = %d, middle = %d, "
109                               "inner = %d\n", outer, middle, inner);
110                       result = 1;
111                     }
112
113                   adr[inner] = 'T';
114                   adr[middle] = 'T';
115                 }
116             }
117         }
118
119       /* Special test.  */
120       adr[size - 1] = '\0';
121       if (strchr (&adr[size - 1], '\n') != NULL)
122         {
123           puts ("strchr flunked for test of empty string at end of page");
124           result = 1;
125         }
126
127       /* strrchr test */
128       for (outer = size - 1; outer >= MAX (0, size - 128); --outer)
129         {
130           for (middle = MAX (outer, size - 64); middle < size; ++middle)
131             {
132               for (inner = middle; inner < size; ++inner)
133                 {
134                   char *cp;
135                   adr[middle] = 'V';
136                   adr[inner] = '\0';
137
138                   cp = strrchr (&adr[outer], 'V');
139
140                   if ((inner == middle && cp != NULL)
141                       || (inner != middle
142                           && (cp - &adr[outer]) != middle - outer))
143                     {
144                       printf ("strrchr flunked for outer = %d, middle = %d, "
145                               "inner = %d\n", outer, middle, inner);
146                       result = 1;
147                     }
148
149                   adr[inner] = 'T';
150                   adr[middle] = 'T';
151                 }
152             }
153         }
154
155       /* rawmemchr test */
156       for (outer = size - 1; outer >= MAX (0, size - 128); --outer)
157         {
158           for (middle = MAX (outer, size - 64); middle < size; ++middle)
159             {
160               char *cp;
161               adr[middle] = 'V';
162
163               cp = rawmemchr (&adr[outer], 'V');
164
165               if (cp - &adr[outer] != middle - outer)
166                 {
167                   printf ("rawmemchr flunked for outer = %d, middle = %d\n",
168                           outer, middle);
169                   result = 1;
170                 }
171
172               adr[middle] = 'T';
173             }
174         }
175
176       /* strcpy test */
177       for (outer = size - 1; outer >= MAX (0, size - 128); --outer)
178         {
179           for (inner = MAX (outer, size - 64); inner < size; ++inner)
180             {
181               adr[inner] = '\0';
182
183               if (strcpy (dest, &adr[outer]) != dest
184                   || strlen (dest) != (size_t) (inner - outer))
185                 {
186                   printf ("strcpy flunked for outer = %d, inner = %d\n",
187                           outer, inner);
188                   result = 1;
189                 }
190
191               adr[inner] = 'T';
192             }
193         }
194
195       /* strncpy tests */
196       adr[size-1] = 'T';
197       for (outer = size - 1; outer >= MAX (0, size - 128); --outer)
198         {
199           size_t len;
200
201           for (len = 0; len < size - outer; ++len)
202             {
203               if (strncpy (dest, &adr[outer], len) != dest
204                   || memcmp (dest, &adr[outer], len) != 0)
205                 {
206                   printf ("outer strncpy flunked for outer = %d, len = %Zd\n",
207                           outer, len);
208                   result = 1;
209                 }
210             }
211         }
212       adr[size-1] = '\0';
213
214       for (outer = size - 1; outer >= MAX (0, size - 128); --outer)
215         {
216           for (inner = MAX (outer, size - 64); inner < size; ++inner)
217             {
218               size_t len;
219
220               adr[inner] = '\0';
221
222               for (len = 0; len < size - outer + 64; ++len)
223                 {
224                   if (strncpy (dest, &adr[outer], len) != dest
225                       || memcmp (dest, &adr[outer],
226                                  MIN (inner - outer, len)) != 0
227                       || (inner - outer < len
228                           && strlen (dest) != (inner - outer)))
229                     {
230                       printf ("strncpy flunked for outer = %d, inner = %d, len = %Zd\n",
231                               outer, inner, len);
232                       result = 1;
233                     }
234                   if (strncpy (dest + 1, &adr[outer], len) != dest + 1
235                       || memcmp (dest + 1, &adr[outer],
236                                  MIN (inner - outer, len)) != 0
237                       || (inner - outer < len
238                           && strlen (dest + 1) != (inner - outer)))
239                     {
240                       printf ("strncpy+1 flunked for outer = %d, inner = %d, len = %Zd\n",
241                               outer, inner, len);
242                       result = 1;
243                     }
244                 }
245
246               adr[inner] = 'T';
247             }
248         }
249
250       /* stpcpy test */
251       for (outer = size - 1; outer >= MAX (0, size - 128); --outer)
252         {
253           for (inner = MAX (outer, size - 64); inner < size; ++inner)
254             {
255               adr[inner] = '\0';
256
257               if ((stpcpy (dest, &adr[outer]) - dest) != inner - outer)
258                 {
259                   printf ("stpcpy flunked for outer = %d, inner = %d\n",
260                           outer, inner);
261                   result = 1;
262                 }
263
264               adr[inner] = 'T';
265             }
266         }
267
268       /* stpncpy test */
269       for (outer = size - 1; outer >= MAX (0, size - 128); --outer)
270         {
271           for (middle = MAX (outer, size - 64); middle < size; ++middle)
272             {
273               adr[middle] = '\0';
274
275               for (inner = 0; inner < size - outer; ++ inner)
276                 {
277                   if ((stpncpy (dest, &adr[outer], inner) - dest)
278                       != MIN (inner, middle - outer))
279                     {
280                       printf ("stpncpy flunked for outer = %d, middle = %d, "
281                               "inner = %d\n", outer, middle, inner);
282                       result = 1;
283                     }
284                 }
285
286               adr[middle] = 'T';
287             }
288         }
289
290       /* memcpy test */
291       for (outer = size - 1; outer >= MAX (0, size - 128); --outer)
292         for (inner = 0; inner < size - outer; ++inner)
293           if (memcpy (dest, &adr[outer], inner) !=  dest)
294             {
295               printf ("memcpy flunked for outer = %d, inner = %d\n",
296                       outer, inner);
297               result = 1;
298             }
299
300       /* mempcpy test */
301       for (outer = size - 1; outer >= MAX (0, size - 128); --outer)
302         for (inner = 0; inner < size - outer; ++inner)
303           if (mempcpy (dest, &adr[outer], inner) !=  dest + inner)
304             {
305               printf ("mempcpy flunked for outer = %d, inner = %d\n",
306                       outer, inner);
307               result = 1;
308             }
309     }
310
311   return result;
312 }