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